在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Micro architecture & design patterns for microservices注: 原文作者即 Micro 框架的开发者。 过去几个月中,我们收到了很多关于 micro 的微服务架构和设计模式的问题。所以今天我们试着解释一下这两方面的问题。 关于 MicroMicro 是一个微服务工具集。它被用来实现它的特性和接口,同时提供强大的可插拔的架构来保证基础组件可以被替换掉。 Micro 专注于解决构建微服务系统的基础需求。它采用了深思熟虑地富有预见性的方式来实现它的设计。 如果你想深入研究 Micro 工具集请点这里查看上一篇博客,或者如果你想学习微服务的基本概念请查看这里 在我们开始讨论 Micro 的架构之前,我们将快速的介绍一下 Micro 的特性. 工具集Go MicroGo Micro是一个用 GO 来写微服务的、可插拔的 RPC 框架。它提供了服务发现,客户端负载均衡,编码,同步异步通讯等功能的库。 Micro APIMicro API 是为访问微服务提供了 HTTP 服务和路由功能的 API 网管。在 Micro 中,它提供一个单一的入口,它可以被用作反向代理,或者将 HTTP 请求转换成 RPC. Micro WebMicro Web 是微型网络应用(micro web application)的仪表盘和反向代理。我们相信 web 应用应该被构建成微服务因此应被看做微服务世界的一等公民。它像一个 API 的反向代理但它同时提供对 web socket 的支持。 Micro SidecarMicro Sidecar 提供将 go-micro 用作 HTTP 服务的所有功能。Sidecar 提供使用其他语言写微服务应用的途径。 Micro CLIMicro CLI 是和你的微服务们交互的命令行接口。它还可以让你在不想直接连接服务的时候使用 Sidecar 作为一个代理。 下面让我们更深入的了解。 RPC, REST, Proto...你的第一个疑问可能就是,为什么是 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 和高效的通讯。 HTTP 到 RPC, 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 将异步通信作为一等公民对待并且将其构建成为微服务的基础组成部分之一。通过与事件异步通信的方式允许任何人消费这些事件,并针对这些事件执行自己的任务。可以在此基础上新的单独部署的服务而不需要需改他们的其他任何方面。这是一个强大的设计模式并且正由于此我们在 go-micro 中实现了一个异步的 broker 接口。 在 Micro 中,同步和异步通信被放到隔离的需求中。Transport 接口用来创建服务间点对点的连接。构建在 transport 基础上的 go-micro 客户端和服务器能够提供请求-响应模式的 RPC 调用,也可以提供双向流模式下的调用。 在构建系统时两种通信模型都应该被使用,但关键是要理解什么时候,在哪儿用哪种方式更合适。很多情况下,没有对错,但是我们还是要权衡两种的利弊。 在这个例子中,每个 AI 或者说服务,当一些动作发生(客户登录,更新简介或下订单)时都会肺部一个事件。审计服务将会订阅这些事件并将它们存储到按时间序列存储的数据库中。管理员或其他任何用户都能看到任何用户产生的任何事件发生的历史。 如果这个系统被设计成同步的,当流量高或服务数量增加时,审计系统很容易被压垮。如果审计系统宕机或者请求失败我们可能会丢失这条历史记录。通过将这些事件发布给 broker 我们能保持他们异步。这是事件驱动型架构构建的微服务的一种通用模式。 咳咳,暂停一下,微服务的定义是什么呢?我们讲了很多 Micro toolkit 提供的功能,也定义了很多类型的服务(API, WEB, SRV)但是并没怎么讲微服务到底是什么。 关于微服务的定义和解释有很多,但这组是最合适的。 基于有限上下文的架构的低耦合的服务 将单个应用开发为一组跑在独立进程上并且互相之间使用轻量级方法进行通信的微小的服务 就像 unix 哲学说的那样 Do one thing and do it well 我们认为一个微服务就是一个专注于一个实体(或领域)的应用 -- 并且通过强定义的 API 访问它。 有一个软件架构模式随着 Ruby On Rails 的崛起而变得流行 -- 那就是 MVC(模型 -- 视图 -- 控制)。 现在举一个微服务架构中同样的例子。模型被服务取而代之,它通过 API 传递数据。用户请求,数据收集和数据呈现由多个 web service 处理。 接下来我们回归正题。 版本管理版本管理是现实软件开发中重要的一部分。在微服务的世界中很重要的一点是 API 和业务逻辑是被分成很多不同的服务的。正由于此,服务的版本控制很重要,被放到核心工具库中,提供更好的细粒度的控制和升级过程中的流量迁移。 在 go-micro 中服务有一个名字和版本号定义。仓库(Registry)返回一个 list 表示一个服务 -- 通过节点
它和 Selector -- 一个客户端的负载均衡 -- 结合起来使用,从而在 go-micro 内部保证请求分发到不同的版本上去。 Selector 是一个强大的接口。我们在它之上提供不同类型的路由算法:随机(默认),round robin(环形队列?),基于标签,基于延迟,等等。 未来我们会实现一个内嵌 selector 的面向全球服务的负载均衡服务来提供为既存的系统做路由决策。它还能胜任在运行时为不同版本的服务分配不同的负载的职能,并且能动态地为服务添加原信息或标签,从而在此之上可以做动态的路由决策。 伸缩上文关于版本控制的说明经已提及了伸缩一个服务使用的基础模型。仓库(registry)用来存储服务的相关信息,selector 用来控制路由和负载均衡。 我们再一次实践了关注点分离(separation of concoerns)和做一件事并把它做好(dooing one thing well)的哲学。伸缩基础设施、代码很依赖于简化、强定义的 API 以及分层的架构。通过编写上面那些构建模块,我们能够开发伸缩性更强的软件系统,并专注于更高层面的东西。 这是 Micro 的基础,也是在微服务世界里我们希望引领的软件开发的方式。 在之前的文章 Micro on NATS中我们简要讨论了关于云端架构模型的问题。现在我们简单回顾下其中的一些观点。 我们需要向 Google, Facebook, Netflix 和 Twitter 学习。我们必须保证我们构建的系统能在可用区失败时不影响用户而且在大多数情况下在数分钟内解决可用区失败。 通过提供可插拔的接口, Micro 可以构建这样的架构。我们能为 micro toolkit 中的每个需求选用最合适的分布式系统。 服务发现和仓库(registry)是 Micro 的构建模块。他能用来在可用区,区域或其他配置范围内隔离和发现服务。 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 的架构和它如何使用可伸缩的设计模式来开发微服务应用。 |
请发表评论