Micro — a microservices toolkit

This is a repost of the original blog post from blog.micro.mu
By now you may have heard of this new phenomenon, microservices. If you’re not yet familiar and interested in learning more, checkout our introductory post here.
In this blog post we’re going to discuss Micro, an open source microservices toolkit. Micro provides the core requirements for building and managing microservices. It consists of a set of libraries and tools which are primarily geared towards development in the programming language Go, however looks to solve for other languages via HTTP using a Sidecar.
Before we get to the details of Micro, let’s talk about why we decided to dedicate our time to it.

Development or Deployment

It’s clear from our past experiences and what we’re seeing in the industry that there’s a need for a focus on development rather than deployment. PaaS solutions are readily available. Companies like AWS, Google and Microsoft are providing feature rich platforms while also rapidly moving towards supporting container orchestration if not already doing so. All of this gives us access to large scale compute with the click of a few buttons.
This new world sounds great. You might say this solves all your problems, right? Well, while we now have access to massive scale computing power, we’re still lacking the tools that enable us to write software that’s capable of leveraging it. Not only that, in this new world, containers are likely more ephemeral, coming and going as the runtime reschedules them or machines they’re running on fail.

Scaling challenges

The other issue we’ve seen time and time again is the way in which organisations fall victim to their monolithic architectures. With a need to grow at a blistering pace, there’s the tendency to cram features into the existing system and incur technical debt which snowballs into an unmanageable situation. Aside from this, as the organisation attempts to grow the engineering team, it becomes infinitely more difficult for developers to collaborate on a single code base or do feature development in parallel without being blocked at time of release.
There’s an inevitable need to rearchitect and an eventual path to SOA or microservice based architectures. Companies end up taking on an R&D effort in house, learning by trial and error. If only there were tools to help create scalable systems, reduce the likely hood of R&D and provide domain expertise from those with past experience.

Enter Micro

At Micro we’re building a microservice ecosystem that includes tools, services and solutions for microservice development. We’re building the foundation of that ecosystem with a tool by the same name. Micro is a microservice toolkit, which will enable the creation of a scalable architectures and increase speed of execution.
Let’s dig into the features of Micro.

Go Micro

Go Micro is a pluggable RPC framework used to build microservices in Go. It delivers the essential features required to create, discover and communicate with services. The core of any good microservice architecture begins by addressing service discovery, synchronous and asynchronous communication.
Included packages and features:
  • Registry — Client side service discovery
  • Transport — Synchronous communication
  • Broker — Asynchronous comunication
  • Selector — Node filtering and load balancing
  • Codec — Message encoding/decoding
  • Server — RPC server building on the above
  • Client — RPC client building on the above
Where Go Micro differs from most libraries is it’s pluggable architecture. This allows the implementation and backend system for every package to be swapped out. For example; the default service discovery mechanism for the registry is Consul but this can easily be swapped with a plugin for etcd, zookeeper or anything else you choose to implement. Plugins we’re implementing can be found at github.com/micro/go-plugins.
The value in a pluggable system is the ability to choose the platform used to support your microservices without having to rewrite any code. Go Micro requires zero code changes, just a mere import of a plugin and you’re done.
Go Micro is the starting point for writing microservices. The readme provides an overview of how to write, run and query a service. There’s a greeter example here micro/examples/greeter and more example services throughout the repo github.com/micro.

Sidecar

So Go Micro provides a way to write services in Go but how about other languages? How do we create a polygot ecosystem where anyone can leverage the advantages of Micro? While Micro is written in Go, we wanted to allow a quicky and easy way to integrate applications written in any language.
Enter the Sidecar, a lightweight companion service which is conceptually “attached” to the main (aka Parent) application and complements it by providing the features of the Micro system that are otherwise available using the Go Micro library. The sidecar is a process that runs alongside your application, delivering the features of Go Micro via a HTTP interface.
Features of the sidecar:
  • Registration with discovery system
  • Host discovery of other services
  • Healthchecking of the main application
  • A proxy to make RPC requests
  • PubSub via WebSockets


Examples of using the Sidecar with ruby or python can be found heremicro/examples/greeter. We’ll look to add more sample code in the near future to help with understanding how to integrate the sidecar.

API

Making RPC requests from one service to another is pretty straight forward with Go Micro but not ideal for external access. Instances of a service can fail, they may be rescheduled elsewhere or end up binding to any random port. TheAPI provides a single entry point to query microservices and should be used as the gateway for external access.
The API provides a few different types of request handlers.
1. /rpc
Individual services can be queried via RPC using the /rpc endpoint. Example:
curl \
 -d "service=go.micro.srv.greeter" \
 -d "method=Say.Hello" \
 -d "request={\"name\": \"John\"}" \
 http://localhost:8080/rpc
{"msg":"Hello John"}
2. api.Request
The API can be used to breakdown URLs to be served by individual microservices. This is a powerful method of API composition. Here the API uses the first part of the request path along with a namespace component to determine the service to route requests to. HTTP requests are then converted to an api.Request and forwarded appropriately.
At Micro we use a pattern of creating API microservices to serve requests at the edge. Separating the responsibility of backend versus frontend services.
An example of API request handling:
Request
GET /greeter/say/hello?name=John
Becomes
service: go.micro.api.greeter (default namespace go.micro.api is applied)
method: Say.Hello
request {
 "method": "GET",
 "path": "/greeter/say/hello",
 "get": {
  "name": "John"
 }
}
The structure of an api.Request and api.Response:
syntax = "proto3";
message Pair {
 optional string key = 1;
 repeated string values = 2;
}
message Request {
 optional string method = 1;   // GET, POST, etc
 optional string path = 2;     // e.g /greeter/say/hello
 map<string, Pair> header = 3; 
 map<string, Pair> get = 4;    // The URI query params
 map<string, Pair> post = 5;   // The post body params
 optional string body = 6;     // raw request body; if not application/x-www-form-urlencoded
}
message Response {
 optional int32 statusCode = 1;
 map<string, Pair> header = 2;
 optional string body = 3;
}
An example of how to create an API service can be found here. Greeter API
3. proxy
The final method of request handling for the API is a reverse proxy. Just as above, the API uses the request path and a namespace component to determine the service to route requests to. By providing reverse proxying and microservice request routing we’re able to support REST, a widely sought after requirement.
The proxy can be enabling by passing the — api_handler=proxy flag.
An example of how to build a RESTful API can be found heremicro/examples/greeter/api.

Web UI

The web UI provides a simple dashboard for observing and interacting with a running system. Not only that but it also provides a reverse proxy much like the API. Our goal with a “web proxy” is to enable the development of web apps as microservices. Again, just like the API, the request path is used along with a namespace to determine the service to route requests to. The web proxy also supports web sockets as we see realtime being a core part of delivering web apps.

CLI

The CLI is a command line tool which provides a way to observe, interact and manage services in a running environment. The current feature set allows you to inspect the registry, check basic health of services and execute queries against services themselves.

The other nifty feature, is the ability to use the Sidecar as a proxy for the CLI. It’s as simple as specifying the address for the sidecar as a flag — proxy_address=example.proxy.com when executing the CLI.

Putting it all together

We’ve written an example of full end-to-end flow through the system using a simple greeter service.
The flow is as follows:
  1. 1HTTP GET request is made to the micro API at path /greeter/say/hello with the query name=John.
  2. 2The API translates this using the default namespace to the api service go.micro.api.greeter and method Say.Hello. The request is structured as an api.Request.
  3. 3The API using Go Micro, queries the registry to find all the nodes for the service go.micro.api.greeter and forwards the request to one of the nodes.
  4. 4The greeter api parses the request, generates a hello.Request and makes a request to the rpc service go.micro.srv.greeter. Again the same registry/discovery mechanism is used to find the nodes for the service.
  5. 5The greeter rpc service responds with a hello.Response.
  6. 6The greeter api translates the response into a api.Response and passes it back to the API.
  7. 7The micro API parses the response and responds to the client’s HTTP request.


In a more complex example, an API service may call out to many other RPC services, aggregate and transform the data and then pass back a final summarised result to the client. This allows you to maintain a consistent external entry point and change services in the background without the knowledge of the client.

留言

這個網誌中的熱門文章

Json概述以及python對json的相關操作

Docker容器日誌查看與清理

遠程控制管理工具ipmitool