Micro - 微服务工具箱

这是一系列介绍Micro框架的文章的第二篇,我将会把作者的博客翻译成中文,推广Micro这个微服务框架。

现在你也许听到了这个新现象:微服务。如果你对此不熟悉也有兴趣学习,欢迎参考上一篇文章。

这篇文章我们将讨论Micro - 一个开源的微服务工具箱,Micro提供了核心的必须工具来构建和管理微服务。它包含了一系列由golang开发的库和工具,同时也通过Sidecar特性与其他语言兼容。

在我们开始了解Micro之前,我们讨论一下为什么我们要把时间花费在它上面。

开发与部署

从我们过去在软件工程领域的经验可以很清晰的看到,我们有这样一种需求:专注于开发而不是部署。PasS的解决方案是可行的,类似AWS,Google和微软的公司,提供了功能丰富的平台,并快速的推进着容器技术(container)。所有的这些让我们点几下鼠标就能使用大规模计算服务。

新世界看着不错,你也许说这解决了你所有的问题,真的是这样吗?当我们能接触到大规模计算的能力时,仍然缺少工具来让我们发挥出大规模计算的优势。不仅如此,在这个新世界中,容器的生命周期变得更加短暂,在运行时调度中不断创建和销毁。

规模的挑战

另一个问题是,正如我们一次又一次看到的,我们一直是巨型架构的受害者。随着功能需求的增加,现在的趋势是在巨型系统上不断增加功能,直到不断增加的技术债务让我们回天乏术。除此以外,随着组织不断扩张工程师团队,开发者想要单独的进行代码开发,或者开发功能时不被其他人block,变得极其困难。

这是一种难以避免的需求:重新进行架构设计,使用SOA或者微服务架构。公司需要在研发上投入努力,在尝试和错误中学习。现在正需要这样一种工具来帮助我们构建可扩展系统,减少研发部门的阻碍,由在此领域有经验的人士为大家提供建议。

了解Micro

在Micro中我们构建了一个微服务生态系统,包括用于开发的基本的工具、服务和解决方案。我们已经构建好了基础的工具,这个工具与整个项目同名,也叫Micro,这一工具让我们更容易构建可扩展的架构,提供效率。

让我们更深入的挖掘Micro的特性。

Go Micro

Go Micro 是一个golang编写的用于构建微服务的插件化的RPC框架。它实现了服务创建、服务发现、服务间通信需要的功能需求。任何优秀的微服务架构都需要解决这三个基础问题:服务发现、同步通信和异步通信。

Go Micro包括以下这些包和功能

  • Registry:客户端的服务发现

  • Transport:同步通信

  • Broker:异步通信

  • Selector:节点过滤、负载均衡

  • Codec:消息编解码

  • Server:基于此库构建RPC服务端

  • Client:基于此库构建RPC客户端

Go Micro跟其他工具最大的不同是它是插件化的架构,这让上面每个包的具体实现都可以切换出去。举个例子,默认的服务发现的机制是通过Consul,但是如果想切换成etcd或者zookeeper 或者任何你实现的方案,都是非常便利的。官方实现的插件可以在这个地址看到:[github.com/micro/go-plugins]

插件化架构的最大好处是你可以选择你喜欢的平台来支撑微服务架构,但无需更改任何底层代码。Go Micro无需任何更改,只需要import你的插件,直接使用即可。

Go Micro是编写微服务的切入点,readme提供了说明包括怎样编写、运行和查询一个服务。这个greeter示例可以参考:micro/examples/greeter ,更多的服务示例可以在这个工程看到: github.com/micro

Sidecar

Go Micro提供了用Golang编写服务的方式,那么其他编程语言呢?我们怎样构建一个有兼容性的系统,让任何人都能受益于MIcro?虽然Micro是用golang编写的,我们提供了一个快速且方便的方式,让其他语言能够接入。

Sidecar是一个轻量级的组装服务,概念上来说就是将Micro的库提供的功能,依附于其他语言的主程序中。sidecar本质上是一个单独运行的服务,通过http提供接口,其他语言通过接口使用Go Micro提供的功能。

sidecar的特性:

  • 在服务发现系统进行注册
  • 发现其他服务
  • 与主程序进行健康检查
  • 作为代理与RPC系统通信
  • 通过websocket订阅

用ruby和python借助sidecar进行使用的例子可以在这里看到micro/examples/greeter,我们会提供更多示例,帮助理解sidecar的使用。

API

服务之间的请求是非常简单直接的,但从外部接入就要复杂一些。具体的服务实例可能会崩溃,重新调度,并监听随机的端口。API这个组件提供了一个接入点,外部的服务可以通过这个API网关向内部的服务发起请求。

API提供了几种不同的请求方式

/rpc

每个单独的服务可以通过/rpc这个接入点进行访问,示例如下:

1
2
3
4
5
6
7
curl \
-d "service=go.micro.srv.greeter" \
-d "method=Say.Hello" \
-d "request={\"name\": \"John\"}" \
http://localhost:8080/rpc

{"msg":"Hello John"}

api.Request

API也可以通过约定好的URL格式,请求到内部的服务,这是API服务的一个强大功能。经过URL解析能将路径转换成实际的请求,示例如下

请求

1
GET /greeter/say/hello?name=John

将会处理成

1
2
3
4
5
6
7
8
9
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"
}
}

这里看看通过protobuf定义的这个接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}

使用示例可以在这里看到:Greeter API

反向代理

最后一个API服务提供的功能是反向代理。正如上面例子中提到的,API服务可以通过路径解析到具体的服务,通过添加参数--api_handler=proxy 我们就可以支持REST风格的请求。反向代理只需要简单的在运行时天机--api_handler=proxy 参数即可。

使用API构建RESTful 风格的API可以在这个例子中看到:micro/examples/greeter/api

Web UI

web UI 提供了一个简单的界面观察运行中的系统,也可以进行一些交互。它提供了类似API这样的反向代理功能,我们的『web代理』也可以把开发好的其他web应用接入到web UI中,web UI与API一样仍然通过路径解析实现与内部服务的通信,通过websocket我们可以实时了解运行中系统的情况

CLI

CLI是一个命令行工具,让我们可以观察、交互和管理运行中的服务,当前的特性允许你查询服务注册,检查服务的健康情况,也可以对服务进行请求

其他有意思的特性包括,CLI可以使用Sidecar作为代理,只需要简单的设置参数:--proxy_address=example.proxy.com

组装在一起

我们已经写了一个全功能的示例,整体的执行过程是这样的:

  1. HTTP GET请求到API服务,请求地址是:/greeter/say/hello with the query name=John
  2. API服务将请求解析并转换成默认的服务形式,服务是go.micro.api.greeter,方法是 Say.Hello
  3. API使用Go Micro,查询注册器中服务go.micro.api.greeter注册的所有节点,根据负载均衡算法,选择其中一个节点,发出请求
  4. go.micro.api.greeter服务收到请求,解析到结构体,去注册器查询到go.micro.srv.greeter这个服务,发送请求
  5. greet server处理完成后,返回相应的内容到greet api
  6. greet api转换greet服务的响应内容到 api.Response,返回到API服务
  7. API服务解析请求,返回HTTP请求

整体流程如下:

有更复杂的例子,比如API服务请求多个服务,组装多个服务的返回内容。示例如下:greeter service

Demo

如果你想看看正在运行中的系统,在这个页面查看:web.micro.pm

我们运行了一个Micro在Kubernetes上,demo是开源的,你可以运行一下:github.com/micro/kubernetes

总结

Micro提供了基础的工具用于编写和管理微服务,Go Micro包括了核心的必须功能:服务发现、客户端、服务端和订阅、发布。CLI可以让你与运行中的服务进行交互。Sidecar可以让你接入其他非Micro应用。API是一个单独的接入点来调用内部的服务。借助于插件化的接口,你可以灵活选择各种组件来提升你的微服务。

在Micro我们的目标是让开发人员在一开始就能应对大规模开发,提高工作效率。我们感觉Micro是最好的选择。随着时间推移,整个微服务生态系统功能会更加完善。

如果你想了解更多,请看这个blog,或者这个repo,Twitter可以关注@MicroHQ,Slack社区在这里