微服务工具箱
现在你也许听到了这个新现象:微服务。如果你对此不熟悉也有兴趣学习,欢迎参考上一篇文章。
这篇文章我们将讨论 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 订阅
[图片上传失败...(image-e9608-1513045777103)]
用 ruby
和 python
借助Sidecar
进行使用的例子可以在这里看到 micro/examples/greeter,我们会提供更多示例,帮助理解 Sidecar
的使用。
API
服务之间请求调用是非常简单直接的,但外部调用就要复杂一些。具体的服务实例可能会崩溃,重新调度,并监听随机的端口。API 这个组件提供了一个接入点,外部的服务可以通过这个 API
网关向内部的服务发起请求。
API
提供了几种不同的请求方式
/rpc
每个单独的服务可以通过 /rpc
这个接入点进行访问,示例如下:
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
解析能将路径转换成实际的请求,示例如下
请求
GET /greeter/say/hello?name=John
将会处理成
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
定义的这个接口实现:
// 内部定义的接口
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
我们可以实时了解运行中系统的情况
[图片上传失败...(image-dac467-1513045777104)]
CLI
CLI
是一个命令行工具,让我们可以观察、交互和管理运行中的服务,当前的特性允许你查询服务注册,检查服务的健康情况,也可以对服务进行请求
[图片上传失败...(image-995294-1513045777104)]
其他有意思的特性包括,CLI
可以使用 Sidecar
作为代理,只需要简单的设置参数:--proxy_address=example.proxy.com
组装在一起
我们已经写了一个全功能的示例,整体的执行过程是这样的:
-
HTTP GET
请求到API
服务,请求地址是:/greeter/say/hello with the query name=John
-
API
服务将请求解析并转换成默认的服务形式,服务名是go.micro.api.greeter
,方法是Say.Hello
-
API
使用Go Micro
,查询注册器中服务go.micro.api.greeter
注册的所有节点,根据负载均衡算法,选择其中一个节点,发出请求 -
go.micro.api.greeter
服务收到请求,解析到结构体,去注册器查询到go.micro.srv.greeter
这个服务,发送请求 -
go.micro.srv.greeter
服务处理完成后,返回相应的内容到go.micro.api.greeter
-
go.micro.api.greeter
转换go.micro.srv.greeter
服务的响应内容到api.Response
,返回到API
服务 -
API
服务解析请求,返回HTTP
请求
整体流程如下:
[图片上传失败...(image-c77079-1513045777104)]
有更复杂的例子,比如 API
服务请求多个服务,组装多个服务的返回内容。示例如下:greeter service
总结一下就是: HTTP
请求发送到 Micro Api
服务,然后请求被解析到具体微服务的 api
服务,具体微服务的 api
服务再去请求对应的干活服务。
注意 Micro Api
并不需要我们去实现,是 Micro
自带的。
Demo
如果你想看看正在运行中的系统,在这个页面查看:web.micro.pm
我们运行了一个 Micro
在 Kubernetes
上,demo
是开源的,可以运行一下:github.com/micro/kubernetes
总结
Micro
提供了基础的工具用于编写和管理微服务,Go Micro
包括了核心的必须功能:服务发现、客户端、服务端和订阅、发布。CLI
可以让你与运行中的服务进行交互。Sidecar
可以让你接入其他非 Micro
应用。API
是一个单独的接入点来调用内部的服务。借助于插件化的接口,你可以灵活选择各种组件来提升你的微服务。