微服务 Micro services

微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模组化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通讯。微服务架构运用于软件架构风格的其中一项概念是甘露运算 (Dew Computing),意指由许多的小露水 (代表微服务的功能元件) 汇集而成的运算能力。

微服务的起源是由 Peter Rodgers 博士于 2005 年度云端运算博览会提出的微 Web 服务 (Micro-Web-Service) 开始,Juval Löwy 则是与他有类似的前导想法,将类别变成细粒服务 (granular services),以作为 Microsoft 下一阶段的软件架构,其核心想法是让服务是由类似 Unix 管道的存取方式使用,而且复杂的服务背后是使用简单 URI 来开放界面,任何服务,任何细粒都能被开放 (exposed)。这个设计在 HP 的实验室被实现,具有改变复杂软件系统的强大力量。

2014年,Martin Fowler 与 James Lewis 共同提出了微服务的概念,定义了微服务是由以单一应用程序构成的小服务,自己拥有自己的行程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用 HTTP API 通讯。同时服务会使用最小的规模的集中管理 (例如 Docker) 能力,服务可以用不同的编程语言与数据库等元件实作。

概念

微服务是一种以业务功能为主的服务设计概念,每一个服务都具有自主运行的业务功能,对外开放不受语言限制的 API (最常用的是 HTTP),应用程序则是由一个或多个微服务组成。

微服务的另一个对比是单体式应用程序。单体式应用表示一个应用程序内包含了所有需要的业务功能,并且使用像主从式架构 (Client/Server) 或是多层次架构 (N-tier) 实作,虽然它也是能以分散式应用程序来实作,但是在单体式应用内,每一个业务功能是不可分割的。若要对单体式应用进行扩展则必须将整个应用程序都放到新的运算资源(如:虚拟机器) 内,但事实上应用程序中最吃资源、需要运算资源的仅有某个业务部分(例如跑分析报表或是数学算法分析),但因为单体式应用无法分割该部分,因此无形中会有大量的资源浪费的现象。

微服务运用了以业务功能的设计概念,应用程序在设计时就能先以业务功能或流程设计先行分割,将各个业务功能都独立实作成一个能自主执行的个体服务,然后再利用相同的协定将所有应用程序需要的服务都组合起来,形成一个应用程序。若需要针对特定业务功能进行扩充时,只要对该业务功能的服务进行扩展就好,不需要整个应用程序都扩展,同时,由于微服务是以业务功能导向的实作,因此不会受到应用程序的干扰,微服务的管理员可以视运算资源的需要来配置微服务到不同的运算资源内,或是布建新的运算资源并将它配置进去。

虽然使用一般的服务器虚拟化技术就能应用于微服务的管理,但容器技术 (Container Technology) 如 Docker 会更加地适合发展微服务的运算资源管理技术。

规划

微服务中每个服务都能够有自己的数据库。

微服务的规划与单体式应用程序十分不同,微服务中每个服务都需要避免与其他服务有所牵连,且都要能够自主,并在其他服务发生错误时不受干扰。

如果数据库都是分开的,那么新服务上线时就会遇到数据库为空的窘境。我们并不能从另一个服务复制资料过来,因为我们无法确定该服务拥有最新的资料。 此时应该从事件存储中心重播所有事件,如此一来就可以找回先前的所有、最新的资料。

数据库

微服务理念中有数个数据库的规划方式。

  • 每个服务都各有一个数据库,同属性的服务可共享同个数据库。
  • 所有服务都共享同个数据库,但是不同表格,并且不会跨域存取。
  • 每个服务都有自己的数据库,就算是同属性的服务也是,数据库并不会共享。

数据库并不会只存放该服务的资料,而是“该服务所会用到的所有资料”。更深层一点的举例:假设有个文章服务,而这个服务可能会需要判断使用者的账号⋯⋯等。那么文章服务的数据库就可以放入使用者的部分资料。此举是为了避免服务之间的相依性,避免文章服务呼叫使用者服务。

数据库的可弃性

实践微服务有许多的做法,但其中一种做法是将数据库作为短期的储存空间而不是储存长期的资料。这意味着数据库可以在离线时被清空。因为它们可以在上线时从事件存储中心回复,因此也能以内存快取(如:Redis) 作为数据库服务器。但这种做法需要将每个请求当作事件来进行广播。如此一来就可以从事件存储中心重播所有的事件来找回所有的资料。

沟通与事件广播

NSQ 是一个讯息伫列系统、平台。在微服务中所扮演的角色是将讯息、资料传递到其他服务。 此举是异步执行,所以不需要等到其他服务接收到讯息就能够执行下一步。这种方式能够避免服务之间有所牵连、呼叫。

微服务中最重要的就是每个服务的独立与自主,因此服务与服务之间也不应该有所沟通。倘若真有沟通,也应采用异步沟通的方式来避免紧密的相依性问题。要达到此目的,则可用下列两种方式:

事件存储中心(Event Store)

这可以让你在服务丛集中广播事件,并且在每个服务中监听这些事件并作处理,这令服务之间没有紧密的相依性,而这些发生的事件都会被保存在事件存储中心里。这意味着当微服务重新上线、部署时可以重播(Replay)所有的事件。这也造就了微服务的数据库随时都可以被删除、摧毁,且不需要从其他服务中取得资料。

讯息伫列(Message Queue)

这令你能够在服务丛集中广播消息,并传递到每个服务中。具有这个功能的像是 NSQ 或是 RabbitMQ。你能够在 A 服务上广播一个“建立新使用者”的事件,这个事件可以顺便带有新使用者的资料。而 B 服务可以监听这个事件并在接收到之后有所处理。这些过程都是异步处理的,这意味着 A 服务并不需要等到 B 服务处理完该事件后才能继续,而这也代表 A 服务无法取得 B 服务的处理结果。与事件存储中心近乎相似,但有所不同的是:讯息伫列并不会保存事件。一但事件被消化(接收)后就会从伫列中消失,这很适合用在像发送欢迎信件的时机。

内容

一个微服务架构的应用程序有下列特性:

  • 每个服务都容易被取代。
  • 服务是以能力来组织的,例如使用者界面、前端、推荐系统、账单或是物流等。
  • 由于功能被拆成多个服务,因此可以由不同的编程语言、数据库实作。
  • 架构是对称而非分层(即生产者与消费者的关系)。

一个微服务架构:

  • 适用于具持续交付 (Continuous Delivery) 的软件开发流程。
  • 与服务导向架构 (Service-Oriented Architecture) 不同,后者是整合各种业务的应用程序,但微服务只属于一个应用程序。

误解

微服务这个名词令许多人以为是非常轻量、非常微小的,且以为透过该理念实作程式就能够达到下列效果:

  • 微服务很轻量。
  • 程式码将会变得更加地简洁。
  • 变得更简单、开发时程变短。
  • 微服务处理的事情变得更单一。

但这些是误解,实际上:

  • 由于服务是独立自主的(也称:真空性),除了需要能够有自己的一套执行方式外,还不应该仰赖另一个服务。为此,服务内会有着与其他服务相同的逻辑,这也导致了服务并不轻量。这部分有两派说法,分别是在服务之间建立同套资源库、工具,但这可能导致额外的相依性存在。而另一种说法则是传统地将程式码复制与贴上,这将避免相依性问题,但在全域修改时可能不易管控,需要分散管理。
  • 微服务属于分布式系统的概念之一,程式码并不会因此变得简单、短少,反而有可能为了处理外来的事件而变得更多
  • 微服务需要额外处理事件的广播、甚至是分布式的错误回溯问题,这导致开发时可能会更加地复杂,且花上更多时间在处理错误上。
  • 基于第一点误解,微服务为了自主有可能会跨域实作,如文章服务有可能会带有使用者服务的理念,所以在处理事情上并不会特别专一。
posted @ 2017-03-31 09:58  Javi  阅读(682)  评论(0编辑  收藏  举报