微服务和微服务架构


微服务和微服务架构

什么是微服务?

概念: 把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议。

定义: 围绕业务领域组件来创建应用,这些应用可独立地进行开发、管理和迭代。在分散的组件中使用云架构和平台式部署、管理和服务功能,使产品交付变得更加简单。

本质: 用一些功能比较明确、业务比较精练的服务去解决更大、更实际的问题。

早些年的服务实现和实施思路是将很多功能从开发到交付都打包成一个很大的服务单元(一般称为 Monolith),而微服务实现和实施思路则更强调功能趋向单一,服务单元小型化和微型化。

微服务是一种用于构建应用的架构方案。微服务架构有别于更为传统的单体式方案,可将应用拆分成多个核心功能。每个功能都被称为一项服务,可以单独构建和部署,这意味着各项服务在工作(和出现故障)时不会相互影响。

如果用“茶壶煮饺子”来打比方的话,原来我们是在一个茶壶里煮很多个饺子,现在(微服务化之后)则基本上是在一个茶壶煮一个饺子,而这些饺子就是服务的功能,茶壶则是将这些服务功能打包交付的服务单元,如图 1 所示。

论茶壶里煮“饺子”的不同形式

所以,从思路和理念上来讲,微服务就是要倡导大家尽量将功能进行拆分,将服务粒度做小,使之可以独立承担对外服务的职责,沿着这个思路开发和交付的软件服务实体就叫作“微服务”,而围绕着这个思路和理念构建的一系列基础设施和指导思想,笔者将它称为“微服务体系”。

微服务的具体特征

官方的定义:

1、一些列的独立的服务共同组成系统

2、单独部署,跑在自己的进程中

3、每个服务为独立的业务开发

4、分布式管理

5、非常强调隔离性

大概的标准:

1、分布式服务组成的系统

2、按照业务,而不是技术来划分组织

3、做有生命的产品而不是项目

4、强服务个体和弱通信( Smart endpoints and dumb pipes )

5、自动化运维( DevOps )

6、高度容错性

7、快速演化和迭代

从 SOA 到微服务

有何区别?微服务可以相互通信,而且这种通信通常都是无状态的,所以采用这种方式构建的应用容错性更高,对于单个 ESB 的依赖性也更低。由于微服务可以通过与语言无关的应用编程接口(API)进行通信,开发团队也可以自行选用所需工具。

纵观 SOA 的整个历史,我们不能说微服务是一个全新的概念。但是,得益于容器化技术的不断改进,微服务的可行性也越来越高。现在,您可以借助 Linux 容器在同一硬件上单独运行一个应用的多个部分,还能更好地控制每个部分及其生命周期。与 API 和 DevOps 团队一样,容器化微服务也是云原生应用的重要基础。

SOA和微服务的区别

1、SOA喜欢重用,微服务喜欢重写
SOA 的主要目的是为了企业各个系统更加容易地融合在一起。说到SOA不得不说ESB(EnterpriseService Bus)。ESB是什么? 可以把ESB想象成一个连接所有企业级服务的脚手架。通过service broker,它可以把不同数据格式或模型转成canonical格式,把XML的输入转成CSV传给legacy服务,把SOAP
1.1服务转成 SOAP 1.2等等。它还可以把一个服务路由到另一个服务上,也可以集中化管理业务逻辑,规则和验证等等。它还有一个重要功能是消息队列和事件驱动的消息传递,比如把JMS服务转化成SOAP协议。各服务间可能有复杂的依赖关系。

微服务 通常由重写一个模块开始。要把整个巨石型的应用重写是有很大的风险的,也不一定必要。我们向微服务迁移的时候通常从耦合度最低的模块或对扩展性要求最高的模块开始,把它们一个一个剥离出来用敏捷地重写,可以尝试最新的技术和语言和框架,然 后单独布署。它通常不依赖其他服务。微服务中常用的API Gateway的模式主要目的也不是重用代码,而是减少客户端和服务间的往来。API gateway模式不等同与Facade模式,我们可以使用如future之类的调用,甚至返回不完整数据。

2、SOA喜欢水平服务,微服务喜欢垂直服务

SOA 设计喜欢给服务分层(如Service Layers模式)。我们常常见到一个Entity服务层的设计,美其名曰Data Access Layer。这种设计要求所有的服务都通过这个Entity服务层来获取数据。这种设计非常不灵活,比如每次数据层的改动都可能影响到所有业务层的服务。而每个微服务通常有它自己独立的data store。我们在拆分数据库时可以适当的做些去范式化(denormalization),让它不需要依赖其他服务的数据。

微服务 通常是直接面对用户的,每个微服务通常直接为用户提供某个功能。类似的功能可能针对手机有一个服务,针对机顶盒是另外一个服务。在SOA设计模式中这种情况通常会用到Multi-ChannelEndpoint的模式返回一个大而全的结果兼顾到所有的客户端的需求。

3、SOA喜欢自上而下,微服务喜欢自下而上

SOA 架构在设计开始时会先定义好服务合同(service contract)。它喜欢集中管理所有的服务,包括集中管理业务逻辑,数据,流程,schema,等等。它使用Enterprise Inventory和Service Composition等方法来集中管理服务。SOA架构通常会预先把每个模块服务接口都定义好。模块系统间的通讯必须遵守这些接口,各服务是针对他们的调用者。
SOA架构适用于TOGAF之类的架构方法论。

微服务 则敏捷得多。只要用户用得到,就先把这个服务挖出来。然后针对性的,快速确认业务需求,快速开发迭代。

怎么具体实践微服务

要实际的应用微服务,需要解决一下四点核心问题

1、客户端如何访问这些服务?

2、每个服务之间如何通信?

3、如此多的服务,如何实现?

4、服务挂了,如何解决?(备份方案,应急处理机制)

(1)客户端如何访问这些服务
  原来的Monolithic方式开发,所有的服务都是本地的,UI可以直接调用,现在按功能拆分成独立的服务,跑在独立的一般都在独立的虚拟机上的 Java进程了。客户端UI如何访问他的?
  后台有N个服务,前台就需要记住管理N个服务,一个服务下线/更新/升级,前台就要重新部署,这明显不服务我们 拆分的理念,特别当前台是移动应用的时候,通常业务变化的节奏更快。
  另外,N个小服务的调用也是一个不小的网络开销。还有一般微服务在系统内部,通常是无 状态的,用户登录信息和权限管理最好有一个统一的地方维护管理(OAuth)。
  所以,一般在后台N个服务和UI之间一般会一个代理或者叫API Gateway,他的作用包括:
  ① 提供统一服务入口,让微服务对前台透明
  ② 聚合后台的服务,节省流量,提升性能
  ③ 提供安全,过滤,流控等API管理功能
  其实这个API Gateway可以有很多广义的实现办法,可以是一个软硬一体的盒子,也可以是一个简单的MVC框架,甚至是一个Node.js的服务端。他们最重要的作 用是为前台(通常是移动应用)提供后台服务的聚合,提供一个统一的服务出口,解除他们之间的耦合,不过API Gateway也有可能成为单点故障点或者性能的瓶颈。
用过Taobao Open Platform(淘宝开放平台)的就能很容易的体会,TAO就是这个API Gateway。

(2)每个服务之间如何通信
  所有的微服务都是独立的Java进程跑在独立的虚拟机上,所以服务间的通信就是IPC(inter process communication),已经有很多成熟的方案。现在基本最通用的有两种方式:
  同步调用:
  ①REST(JAX-RS,Spring Boot)
  ②RPC(Thrift, Dubbo)
  异步消息调用(Kafka, Notify, MetaQ)

同步和异步的区别:
  一般同步调用比较简单,一致性强,但是容易出调用问题,性能体验上也会差些,特别是调用层次多的时候。RESTful和RPC的比较也是一个很有意 思的话题。
一般REST基于HTTP,更容易实现,更容易被接受,服务端实现技术也更灵活些,各个语言都能支持,同时能跨客户端,对客户端没有特殊的要求,只要封装了HTTP的SDK就能调用,所以相对使用的广一些。RPC也有自己的优点,传输协议更高效,安全更可控,特别在一个公司内部,如果有统一个 的开发规范和统一的服务框架时,他的开发效率优势更明显些。就看各自的技术积累实际条件,自己的选择了。
  而异步消息的方式在分布式系统中有特别广泛的应用,他既能减低调用服务之间的耦合,又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方,同时能保证调用方的服务体验,继续干自己该干的活,不至于被后台性能拖慢。不过需要付出的代价是一致性的减弱,需要接受数据最终一致性;还有就是后台服务一般要 实现幂等性,因为消息发送出于性能的考虑一般会有重复(保证消息的被收到且仅收到一次对性能是很大的考验);最后就是必须引入一个独立的broker,如果公司内部没有技术积累,对broker分布式管理也是一个很大的挑战。

(3)如此多的服务,如何实现?
  在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。服务之间如何相互感知?服务如何管理?
  这就是服务发现的问题了。一般有两类做法,也各有优缺点。基本都是通过zookeeper等类似技术做服务注册信息的分布式管理。当服务上线时,服务提供者将自己的服务信息注册到ZK(或类似框架),并通过心跳维持长链接,实时更新链接信息。服务调用者通过ZK寻址,根据可定制算法,找到一个服务,还可以将服务信息缓存在本地以提高性能。当服务下线时,ZK会发通知给服务客户端。
  客户端做: 优点是架构简单,扩展灵活,只对服务注册器依赖。缺点是客户端要维护所有调用服务的地址,有技术难度,一般大公司都有成熟的内部框架支持,比如Dubbo。
  服务端做: 优点是简单,所有服务对于前台调用方透明,一般在小公司在云服务上部署的应用采用的比较多。

(4)服务挂了,如何解决
  前面提到,Monolithic方式开发一个很大的风险是,把所有鸡蛋放在一个篮子里,一荣俱荣,一损俱损。而分布式最大的特性就是网络是不可靠的。通过微服务拆分能降低这个风险,不过如果没有特别的保障,结局肯定是噩梦。所以当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多:
  ①重试机制
  ②限流
  ③熔断机制
  ④负载均衡
  ⑤降级(本地缓存)
  这些方法基本都很明确通用,比如Netflix的Hystrix:https://github.com/Netflix/Hystrix

参考

https://www.bilibili.com/read/cv9054449/


文章作者: Hailong Gao
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hailong Gao !
评论
  目录