注: 原文做者即 Micro 框架的开发者。html
过去几个月中,咱们收到了不少关于 micro 的微服务架构和设计模式的问题。因此今天咱们试着解释一下这两方面的问题。ios
Micro 是一个微服务工具集。它被用来实现它的特性和接口,同时提供强大的可插拔的架构来保证基础组件能够被替换掉。git
Micro 专一于解决构建微服务系统的基础需求。它采用了深思熟虑地富有预见性的方式来实现它的设计。github
若是你想深刻研究 Micro 工具集请点这里查看上一篇博客,或者若是你想学习微服务的基本概念请查看这里web
在咱们开始讨论 Micro 的架构以前,咱们将快速的介绍一下 Micro 的特性.算法
Go Micro是一个用 GO 来写微服务的、可插拔的 RPC 框架。它提供了服务发现,客户端负载均衡,编码,同步异步通信等功能的库。数据库
Micro API 是为访问微服务提供了 HTTP 服务和路由功能的 API 网管。在 Micro 中,它提供一个单一的入口,它能够被用做反向代理,或者将 HTTP 请求转换成 RPC.后端
Micro Web 是微型网络应用(micro web application)的仪表盘和反向代理。咱们相信 web 应用应该被构建成微服务所以应被看作微服务世界的一等公民。它像一个 API 的反向代理但它同时提供对 web socket 的支持。设计模式
Micro Sidecar 提供将 go-micro 用做 HTTP 服务的全部功能。Sidecar 提供使用其余语言写微服务应用的途径。api
Micro CLI 是和你的微服务们交互的命令行接口。它还可让你在不想直接链接服务的时候使用 Sidecar 做为一个代理。
下面让咱们更深刻的了解。
你的第一个疑问可能就是,为何是 RPC 而不是 REST? 咱们认为 RPC 更适合内部服务通讯的场景。或者更具体的, 使用 protobuf 编码而且用 protobuf IDL 定义 API 的 RPC。联合使用这些技术可以很方便的建立强定义的 API 接口和有效的消息编码。RPC 是很是直观的通讯协议。
咱们并非这一信条的独立拥护者。
Google 是 protobuf 的创造者,在内部使用 RPC 而且最近开源的 RPC 框架 gRPC. Hailo 一样也是 RPC/Protobuf 的强烈倡导者,并从中受益不浅,更有趣的是在跨团队协助方面得到的收益比系统性能上的收益更多。Uber 正则开发资金的 PRC 框架协议 TChannel。
我我的认为将来的 API 应该是使用 RPC 构建的,由于它有诸如 protobuf 这类的有良好的结构化的格式,有易用高效的编码方法的协议,从而能构建强定义的 API 和高效的通信。
然而在现实中,在 web 上使用 RPC 还有很长的路要走。尽管在数据中心内部使用 RPC 很完美,可是支撑高并发的网站和移动 API 又是另外一回事。好吧,彻底从 HTTP 切换到 RPC 来由很长的路要走。这也是为何 micro 提供了 API 网关组件,来支撑和转换 HTTP 请求。
API gateway 是微服务架构中使用的一种模式。它是微服务和外界沟通的惟一入口,它根据 HTTP 请求调用对应的服务。API gateway 使一个 HTTP API 可以组合调用多个不一样的微服务。
这是一个很强大的模式。因 API 一部分的更改致使整个单一部署的服务挂掉的日子将一去不复返。
微服务 API 使用 路径-服务 的解决方案,所以每一个请求路径可以调用不一样的微服务 API,例如 /user => user api, /order => order api
举个例子,到 /customer/orders 的请求将被带着方法名 Customer.Orders 转发到 API go.micro.api.customer 。
你可能好奇, API 服务究竟是什么。如今咱们来讨论不一样类型的服务。
微服务的概念主要是按关注点分离 -- 从著名的 unix 哲学 doing one thing and doing it well 中借鉴了不少。出于这个缘由,咱们认为有必要从逻辑上和架构上将拥有不一样任务的服务分离。
这些概念并非什么新的概念,最近变得很引人注目是由于它被一些很是成功的技术公司证实是可行的。咱们的目标是推广这些开发哲学并经过构建工具链来指导设计决策。
如下是咱们定义的服务的类型。
API - 基于 micro api,API 服务在设施的最顶端,通常直接支撑你的移动或 web 应用。你可使用 HTTP handler 建造它而后使用反向代理模式启动 micro api,或者,默认状况下处理这种专门格式的 RPC API 请求和响应。
Web - 基于 micro web, 专门用来提供 html 内容和管理面板访问的 Web 服务。micro web 为 HTTP 和 WebSockets 提供反向代理。目前,仅支持这两周格式,将来可能会支持更多的格式。就像以前提到过的那样,咱们相信 “web 应用即微服务”。
SRV - 基于 RPC 的后端服务。它们主要关注于为你的系统提供核心功能而且大多数状况下不会对外开放。若是你愿意,你仍可使用 micro api 或 micro web 使用 /rpc 路径来访问它,但通常使用 go-micro 客户端来直接调用它们。
基于以往的经验,咱们发现这种架构模式及其强大而且见到过使用它支撑数百个微服务的系统。
Namespacing(命名空间)
你可能会好奇,如何隔断 micro api 和 micro web 之间的通讯?咱们使用逻辑命名空间里作分离。经过给服务名加前缀(prefix)咱们清晰的肯定它的意图以及它在系统中的位置。这个简单但有效的模式让咱们受益良多。
micro api 和 micro web 将组成由命名空间和请求路径的第一个路径组成的服务名称。例如,访问 api/customer 的请求变为 go.micro.api.customer。
默认的命名空间为:
咱们常常听到微服务和响应式模式一同出现。对于大多数来讲,微服务是建立事件驱动的架构,而且主要经过异步通讯的服务。
Micro 将异步通讯做为一等公民对待而且将其构建成为微服务的基础组成部分之一。经过与事件异步通讯的方式容许任何人消费这些事件,并针对这些事件执行本身的任务。能够在此基础上新的单独部署的服务而不须要需改他们的其余任何方面。这是一个强大的设计模式而且正因为此咱们在 go-micro 中实现了一个异步的 broker 接口。
在 Micro 中,同步和异步通讯被放到隔离的需求中。Transport 接口用来建立服务间点对点的链接。构建在 transport 基础上的 go-micro 客户端和服务器可以提供请求-响应模式的 RPC 调用,也能够提供双向流模式下的调用。
在构建系统时两种通讯模型都应该被使用,但关键是要理解何时,在哪儿用哪一种方式更合适。不少状况下,没有对错,可是咱们仍是要权衡两种的利弊。
举个例子,在制做用来保存跟踪用户操做历史的审计系统时,broker 和异步通讯可能更合适。
在这个例子中,每一个 AI 或者说服务,当一些动做发生(客户登陆,更新简介或下订单)时都会肺部一个事件。审计服务将会订阅这些事件并将它们存储到按时间序列存储的数据库中。管理员或其余任何用户都能看到任何用户产生的任何事件发生的历史。
若是这个系统被设计成同步的,当流量高或服务数量增长时,审计系统很容易被压垮。若是审计系统宕机或者请求失败咱们可能会丢失这条历史记录。经过将这些事件发布给 broker 咱们能保持他们异步。这是事件驱动型架构构建的微服务的一种通用模式。
咱们讲了不少 Micro toolkit 提供的功能,也定义了不少类型的服务(API, WEB, SRV)可是并没怎么讲微服务究竟是什么。
关于微服务的定义和解释有不少,但这组是最合适的。
基于有限上下文的架构的低耦合的服务
--Adrian Cockcroft
将单个应用开发为一组跑在独立进程上而且互相之间使用轻量级方法进行通讯的微小的服务
--Martin Fowler
就像 unix 哲学说的那样 Do one thing and do it well
--Doug McIlroy
咱们认为一个微服务就是一个专一于一个实体(或领域)的应用 -- 而且经过强定义的 API 访问它。
让咱们拿社交网络来举个现实中的例子。
有一个软件架构模式随着 Ruby On Rails 的崛起而变得流行 -- 那就是 MVC(模型 -- 视图 -- 控制)。
在 MVC 的世界里,每一个实体,或者说,域,都被表示为一个从数据库中抽象而来的模型。模型可能和其余模型之间有相互关系,好比说一对多,多对多。控制层处理收到的请求,从 model 中查询数据,而后把它传递给用户,从而展示给用户。
如今举一个微服务架构中一样的例子。模型被服务取而代之,它经过 API 传递数据。用户请求,数据收集和数据呈现由多个 web service 处理。
每一个服务都有一个单一的关注点。当咱们想添加一个新功能或新的实体时,咱们能够简单的修改关注于那个功能的服务或者直接写一个新的服务。这种分离的方式提供了可以很好 scale 的软件开发方式。
接下来咱们回归正题。
版本管理是现实软件开发中重要的一部分。在微服务的世界中很重要的一点是 API 和业务逻辑是被分红不少不一样的服务的。正因为此,服务的版本控制很重要,被放到核心工具库中,提供更好的细粒度的控制和升级过程当中的流量迁移。
在 go-micro 中服务有一个名字和版本号定义。仓库(Registry)返回一个 list 表示一个服务 -- 经过节点
注册时的版本号来区分这些节点。
这是咱们用于构建基于版本的路由功能的构建模块的一段代码
type Service struct { Name string Version string Metadata map[string]string Endpoints []*Endpoint Nodes []*Node }
它和 Selector -- 一个客户端的负载均衡 -- 结合起来使用,从而在 go-micro 内部保证请求分发到不一样的版本上去。
Selector 是一个强大的接口。咱们在它之上提供不一样类型的路由算法:随机(默认),round robin(环形队列?),基于标签,基于延迟,等等。
经过默认的基于随机哈希的负载均衡算法,并逐步将新版本的服务实例加入,你能够执行蓝绿发布(link)并实行金丝雀测试。
将来咱们会实现一个内嵌 selector 的面向全球服务的负载均衡服务来提供为既存的系统作路由决策。它还能胜任在运行时为不一样版本的服务分配不一样的负载的职能,而且能动态地为服务添加原信息或标签,从而在此之上能够作动态的路由决策。
上文关于版本控制的说明经已说起了伸缩一个服务使用的基础模型。仓库(registry)用来存储服务的相关信息,selector 用来控制路由和负载均衡。
咱们再一次实践了关注点分离(separation of concoerns)和作一件事并把它作好(dooing one thing well)的哲学。伸缩基础设施、代码很依赖于简化、强定义的 API 以及分层的架构。经过编写上面那些构建模块,咱们可以开发伸缩性更强的软件系统,并专一于更高层面的东西。
这是 Micro 的基础,也是在微服务世界里咱们但愿引领的软件开发的方式。
在以前的文章 Micro on NATS中咱们简要讨论了关于云端架构模型的问题。如今咱们简单回顾下其中的一些观点。
当在生产环境部署服务时,你但愿你的系统是可伸缩的、能容错的、以及性能优异的。云计算使咱们能构建有很强伸缩性能的服务,但很难不受错误影响。事实上容错性是构建分布式系统时最关键的考察点之一。因此在构建基础设施时,咱们应该充分考虑容错性。
在云的世界里,咱们但愿能容忍可用区的错误,甚至是整个区域中断。过去,咱们尝试经过热备份,冷备份或者灾难恢复计划来应对。如今,技术最早进的公司们有一个国际惯例,那就是把每一个应用制做多个副本跑在世界各地的多个数据中心上。
咱们须要向 Google, Facebook, Netflix 和 Twitter 学习。咱们必须保证咱们构建的系统能在可用区失败时不影响用户并且在大多数状况下在数分钟内解决可用区失败。
经过提供可插拔的接口, Micro 能够构建这样的架构。咱们能为 micro toolkit 中的每一个需求选用最合适的分布式系统。
服务发现和仓库(registry)是 Micro 的构建模块。他能用来在可用区,区域或其余配置范围内隔离和发现服务。
而后 Micro API 可以在这个拓补结构中路由以及负责均衡一系列的服务。
Microservices is first and foremost about software design patterns. We can enable certain foundational patterns through tooling while providing flexibility for other patterns to emerge or be used.
Because Micro is a pluggable architecture it’s a powerful enabler of a variety of design patterns and can be appropriately used in many scenarios. For example if you’re building video streaming infrastructure you may opt for the HTTP transport for point to point communication. If you are not latency sensitive then you may choose a transport plugin such as NATS or RabbitMQ instead.
The future of software development with a tool such as Micro is very exciting.
If you want to learn more about the services we offer or microservices, check out the blog, the website micro.mu or the github repo.
但愿这篇文章讲清了 Micro 的架构和它如何使用可伸缩的设计模式来开发微服务应用。 微服务首先是一种软件设计模式。 .... 感受后面没啥用,就略了...