Nebula

A framework and runtime for microservices.

Design

Whatever we build as long as there is a need for scalability or communication between distributed applications, we found ourselves writing some programs or configurations over and over again. Although there are some libraries and frameworks that have succeeded in reducing such boilerplate works for developers, I still felt like getting exhausted soon after starting a project. I just wanted to write a service. Why would I bother with so many toolkits and configurations? Why wouldn’t writing service be like drawing a picture? I need to see right at every color I put in the picture.

That is, I need a runtime when developing microservices, and Micro is the only framework I’ve found that made such an approach. With a service runtime, a microservice framework could become a serverless engine reducing the pain of development to an extreme.

Unfortunately, I encountered so many troubles using Micro, and to be honest, it is too heavy either for me or the team I’m currently working with. So I made a hard decision to redesign and simplify Micro with some features it doesn’t include. And thus we got Nebula, a zero-config, all-in-one framework and runtime for microservices.

Micro has made an extraordinary abstraction over every component in distributed systems. And there is no reason not to reuse its API design. So the top-level APIs of Nebula would look pretty much like Micro’s, which makes Nebula much cooler.

RPCx, described as the best microservice framework written in Go, also inspired me of the design in Nebula, the client component in particular. But instead of implementing a new protocol as RPCx does, Nebula uses HTTP2 over the transport layout for multiplexed streaming. It may be slower than RPCx but does solve my problems by now.

Now let’s see what’s behind Nebula.

Nebula’s 7-layer model

In a microservice architecture, a service may have to call one or more services, and each service may have more than one node running, and the addresses of nodes may change manually or by the orchestrator like Kubernetes. Those are where load-balancing and service governance comes into play, and are abstracted then by Nebula into something called the service virtual connection layer.

Underneath, a service needs to dial a node of the other service to make a connection through which messages flow back and forth between the two ends, the client and the server. But a node may receive multiple invocations from different services or nodes at a time, so there must be a way of what they call multiplexed streaming or stream-oriented communication, and that is done by HTTP2, which is abstracted by Nebula into the HTTP2 streaming layer.

Anyways, HTTP2 is just a protocol defined at the top of the OSI model, it needs a lower transport protocol to work. So Nebula defined its transport interface that can be implemented by not just TCP but other better protocols like quic.

nebula

With Nebula, we can just focus on the application layer on which most of our businesses are. Years ago, HTTP1 freed our hands off cross-language communication, now with Nebula on HTTP2 can we free ourselves from everything. Bazinga 🙂

Features

  • dynamic client
  • unary invocation
  • client streaming
  • server streaming
  • bidirectional streaming
  • asynchronous invocation
  • service registration and discovery
  • load balancing
  • circuit breaker on each node
  • retry on failure
  • distributed tracing
  • metrics
  • general service runtime
  • dynamic API gateway
  • configuration discovery
  • builtin access control
  • SQL interfaces
  • key-value storage
  • compatible with HTTP 1.1 and WebSocket (really?)
  • proxy on services in external clusters
  • code generation using protobuf
  • CLI

Feedback

Bugs here and ideas here, please.

References

License

Nebula is Apache 2.0 licensed.

GitHub

View Github