微服务没那么神秘

微服务架构详解

本文将介绍微服务架构和相关的组件,介绍他们是什么以及为什么要使用微服务架构和这些组件。本文侧重于简明地表达微服务架构的全局图景,因此不会涉及具体如何使用组件等细节。

要理解微服务,首先要先理解不是微服务的那些。通常跟微服务相对的是单体应用,即将所有功能都打包成在一个独立单元的应用程序。从单体应用到微服务并不是一蹴而就的,这是一个逐渐演变的过程。本文将以一个网上超市应用为例来说明这一过程。

最初的需求

几年前,小明和小皮一起创业做网上超市。小明负责程序开发,小皮负责其他事宜。当时互联网还不发达,网上超市还是蓝海。只要功能实现了就能随便赚钱。所以他们的需求很简单,只需要一个网站挂在公网,用户能够在这个网站上浏览商品、购买商品;另外还需一个管理后台,可以管理商品、用户、以及订单数据。

我们整理一下功能清单:

网站:

    • 用户注册、登录功能
    • 商品展示
    • 下单

管理后台:

    • 用户管理
    • 商品管理
    • 订单管理

由于需求简单,小明左手右手一个慢动作,网站就做好了。管理后台出于安全考虑,不和网站做在一起,小明右手左手慢动作重播,管理网站也做好了。总体架构图如下:

小明挥一挥手,找了家云服务部署上去,网站就上线了。上线后好评如潮,深受各类肥宅喜爱。小明小皮美滋滋地开始躺着收钱。

随着业务发展……

好景不长,没过几天,各类网上超市紧跟着拔地而起,对小明小皮造成了强烈的冲击。

在竞争的压力下,小明小皮决定开展一些营销手段:

  • 开展促销活动。比如元旦全场打折,春节买二送一,情人节狗粮优惠券等等。
  • 拓展渠道,新增移动端营销。除了网站外,还需要开发移动端APP,微信小程序等。
  • 精准营销。利用历史数据对用户进行分析,提供个性化服务。
  • ……

这些活动都需要程序开发的支持。小明拉了同学小红加入团队。小红负责数据分析以及移动端相关开发。小明负责促销活动相关功能的开发。

因为开发任务比较紧迫,小明小红没有好好规划整个系统的架构,随便拍了拍脑袋,决定把促销管理和数据分析放在管理后台里,微信和移动端APP另外搭建。通宵了几天后,新功能和新应用基本完工。这时架构图如下:

 

这一阶段存在很多不合理的地方:

  • 网站和移动端应用有很多相同业务逻辑的重复代码。
  • 数据有时候通过数据库共享,有时候通过接口调用传输。接口调用关系杂乱。
  • 单个应用为了给其他应用提供接口,渐渐地越改越大,包含了很多本来就不属于它的逻辑。应用边界模糊,功能归属混乱。
  • 管理后台在一开始的设计中保障级别较低。加入数据分析和促销管理相关功能后出现性能瓶颈,影响了其他应用。
  • 数据库表结构被多个应用依赖,无法重构和优化。
  • 所有应用都在一个数据库上操作,数据库出现性能瓶颈。特别是数据分析跑起来的时候,数据库性能急剧下降。
  • 开发、测试、部署、维护愈发困难。即使只改动一个小功能,也需要整个应用一起发布。有时候发布会不小心带上了一些未经测试的代码,或者修改了一个功能后,另一个意想不到的地方出错了。为了减轻发布可能产生的问题的影响和线上业务停顿的影响,所有应用都要在凌晨三四点执行发布。发布后为了验证应用正常运行,还得盯到第二天白天的用户高峰期……
  • 团队出现推诿扯皮现象。关于一些公用的功能应该建设在哪个应用上的问题常常要争论很久,最后要么干脆各做各的,或者随便放个地方但是都不维护。

尽管有着诸多问题,但也不能否认这一阶段的成果:快速地根据业务变化建设了系统。不过紧迫且繁重的任务容易使人陷入局部、短浅的思维方式,从而做出妥协式的决策。在这种架构中,每个人都只关注在自己的一亩三分地,缺乏全局的、长远的设计。长此以往,系统建设将会越来越困难,甚至陷入不断推翻、重建的循环。

是时候做出改变了

幸好小明和小红是有追求有理想的好青年。意识到问题后,小明和小红从琐碎的业务需求中腾出了一部分精力,开始梳理整体架构,针对问题准备着手改造。

要做改造,首先你需要有足够的精力和资源。如果你的需求方(业务人员、项目经理、上司等)很强势地一心追求需求进度,以致于你无法挪出额外的精力和资源的话,那么你可能无法做任何事……

在编程的世界中,最重要的便是抽象能力。微服务改造的过程实际上也是个抽象的过程。小明和小红整理了网上超市的业务逻辑,抽象出公用的业务能力,做成几个公共服务:

  • 用户服务
  • 商品服务
  • 促销服务
  • 订单服务
  • 数据分析服务

各个应用后台只需从这些服务获取所需的数据,从而删去了大量冗余的代码,就剩个轻薄的控制层和前端。这一阶段的架构如下:

这个阶段只是将服务分开了,数据库依然是共用的,所以一些烟囱式系统的缺点仍然存在:

  1. 数据库成为性能瓶颈,并且有单点故障的风险。
  2. 数据管理趋向混乱。即使一开始有良好的模块化设计,随着时间推移,总会有一个服务直接从数据库取另一个服务的数据的现象。
  3. 数据库表结构可能被多个服务依赖,牵一发而动全身,很难调整。

如果一直保持共用数据库的模式,则整个架构会越来越僵化,失去了微服务架构的意义。因此小明和小红一鼓作气,把数据库也拆分了。所有持久化层相互隔离,由各个服务自己负责。另外,为了提高系统的实时性,加入了消息队列机制。架构如下:

完全拆分后各个服务可以采用异构的技术。比如数据分析服务可以使用数据仓库作为持久化层,以便于高效地做一些统计计算;商品服务和促销服务访问频率比较大,因此加入了缓存机制等。

还有一种抽象出公共逻辑的方法是把这些公共逻辑做成公共的框架库。这种方法可以减少服务调用的性能损耗。但是这种方法的管理成本非常高昂,很难保证所有应用版本的一致性。
数据库拆分也有一些问题和挑战:比如说跨库级联的需求,通过服务查询数据颗粒度的粗细问题等。但是这些问题可以通过合理的设计来解决。总体来说,数据库拆分是一个利大于弊的。

微服务架构还有一个技术外的好处,它使整个系统的分工更加明确,责任更加清晰,每个人专心负责为其他人提供更好的服务。在单体应用的时代,公共的业务功能经常没有明确的归属。最后要么各做各的,每个人都重新实现了一遍;要么是随机一个人(一般是能力比较强或者比较热心的人)做到他负责的应用里面。在后者的情况下,这个人在负责自己应用之外,还要额外负责给别人提供这些公共的功能——而这个功能本来是无人负责的,仅仅因为他能力较强/比较热心,就莫名地背锅(这种情况还被美其名曰能者多劳)。结果最后大家都不愿意提供公共的功能。长此以往,团队里的人渐渐变得各自为政,不再关心全局的架构设计。

从这个角度上看,使用微服务架构同时也需要组织结构做相应的调整。所以说做微服务改造需要管理者的支持。

改造完成后,小明和小红分清楚各自的锅。两人十分满意,一切就像是麦克斯韦方程组一样漂亮完美。

然而……

没有银弹

春天来了,万物复苏,又到了一年一度的购物狂欢节。眼看着日订单数量蹭蹭地上涨,小皮小明小红喜笑颜开。可惜好景不长,乐极生悲,突然嘣的一下,系统挂了。

以往单体应用,排查问题通常是看一下日志,研究错误信息和调用堆栈。而微服务架构整个应用分散成多个服务,定位故障点非常困难。小明一个台机器一台机器地查看日志,一个服务一个服务地手工调用。经过十几分钟的查找,小明终于定位到故障点:促销服务由于接收的请求量太大而停止响应了。其他服务都直接或间接地会调用促销服务,于是也跟着宕机了。在微服务架构中,一个服务故障可能会产生雪崩效用,导致整个系统故障。其实在节前,小明和小红是有做过请求量评估的。按照预计,服务器资源是足以支持节日的请求量的,所以肯定是哪里出了问题。不过形势紧急,随着每一分每一秒流逝的都是白花花的银子,因此小明也没时间排查问题,当机立断在云上新建了几台虚拟机,然后一台一台地部署新的促销服务节点。几分钟的操作后,系统总算是勉强恢复正常了。整个故障时间内估计损失了几十万的销售额,三人的心在滴血……

事后,小明简单写了个日志分析工具(量太大了,文本编辑器几乎打不开,打开了肉眼也看不过来),统计了促销服务的访问日志,发现在故障期间,商品服务由于代码问题,在某些场景下会对促销服务发起大量请求。这个问题并不复杂,小明手指抖一抖,修复了这个价值几十万的Bug。

问题是解决了,但谁也无法保证不会再发生类似的其他问题。微服务架构虽然逻辑设计上看是完美的,但就像积木搭建的华丽宫殿一样,经不起风吹草动。微服务架构虽然解决了旧问题,也引入了新的问题:

  • 微服务架构整个应用分散成多个服务,定位故障点非常困难。
  • 稳定性下降。服务数量变多导致其中一个服务出现故障的概率增大,并且一个服务故障可能导致整个系统挂掉。事实上,在大访问量的生产场景下,故障总是会出现的。
  • 服务数量非常多,部署、管理的工作量很大。
  • 开发方面:如何保证各个服务在持续开发的情况下仍然保持协同合作。
  • 测试方面:服务拆分后,几乎所有功能都会涉及多个服务。原本单个程序的测试变为服务间调用的测试。测试变得更加复杂。

小明小红痛定思痛,决心好好解决这些问题。对故障的处理一般从两方面入手,一方面尽量减少故障发生的概率,另一方面降低故障造成的影响。

监控 - 发现故障的征兆

在高并发分布式的场景下,故障经常是突然间就雪崩式爆发。所以必须建立完善的监控体系,尽可能发现故障的征兆。

微服务架构中组件繁多,各个组件所需要监控的指标不同。比如Redis缓存一般监控占用内存值、网络流量,数据库监控连接数、磁盘空间,业务服务监控并发数、响应延迟、错误率等。因此如果做一个大而全的监控系统来监控各个组件是不大现实的,而且扩展性会很差。一般的做法是让各个组件提供报告自己当前状态的接口(metrics接口),这个接口输出的数据格式应该是一致的。然后部署一个指标采集器组件,定时从这些接口获取并保持组件状态,同时提供查询服务。最后还需要一个UI,从指标采集器查询各项指标,绘制监控界面或者根据阈值发出告警。

大部分组件都不需要自己动手开发,网络上有开源组件。小明下载了RedisExporter和MySQLExporter,这两个组件分别提供了Redis缓存和MySQL数据库的指标接口。微服务则根据各个服务的业务逻辑实现自定义的指标接口。然后小明采用Prometheus作为指标采集器,Grafana配置监控界面和邮件告警。这样一套微服务监控系统就搭建起来了:

定位问题 - 链路跟踪

在微服务架构下,一个用户的请求往往涉及多个内部服务调用。为了方便定位问题,需要能够记录每个用户请求时,微服务内部产生了多少服务调用,及其调用关系。这个叫做链路跟踪。

我们用一个Istio文档里的链路跟踪例子来看看效果:

从图中可以看到,这是一个用户访问productpage页面的请求。在请求过程中,productpage服务顺序调用了details和reviews服务的接口。而reviews服务在响应过程中又调用了ratings的接口。整个链路跟踪的记录是一棵树:

要实现链路跟踪,每次服务调用会在HTTP的HEADERS中记录至少记录四项数据:

  • traceId:traceId标识一个用户请求的调用链路。具有相同traceId的调用属于同一条链路。
  • spanId:标识一次服务调用的ID,即链路跟踪的节点ID。
  • parentId:父节点的spanId。
  • requestTime & responseTime:请求时间和响应时间。

另外,还需要调用日志收集与存储的组件,以及展示链路调用的UI组件。

以上只是一个极简的说明,关于链路跟踪的理论依据可详见Google的Dapper

了解了理论基础后,小明选用了Dapper的一个开源实现Zipkin。然后手指一抖,写了个HTTP请求的拦截器,在每次HTTP请求时生成这些数据注入到HEADERS,同时异步发送调用日志到Zipkin的日志收集器中。这里额外提一下,HTTP请求的拦截器,可以在微服务的代码中实现,也可以使用一个网络代理组件来实现(不过这样子每个微服务都需要加一层代理)。

链路跟踪只能定位到哪个服务出现问题,不能提供具体的错误信息。查找具体的错误信息的能力则需要由日志分析组件来提供。

分析问题 - 日志分析

日志分析组件应该在微服务兴起之前就被广泛使用了。即使单体应用架构,当访问数变大、或服务器规模增多时,日志文件的大小会膨胀到难以用文本编辑器进行访问,更糟的是它们分散在多台服务器上面。排查一个问题,需要登录到各台服务器去获取日志文件,一个一个地查找(而且打开、查找都很慢)想要的日志信息。

因此,在应用规模变大时,我们需要一个日志的“搜索引擎”。以便于能准确的找到想要的日志。另外,数据源一侧还需要收集日志的组件和展示结果的UI组件:

小明调查了一下,使用了大名鼎鼎地ELK日志分析组件。ELK是Elasticsearch、Logstash和Kibana三个组件的缩写。

  • Elasticsearch:搜索引擎,同时也是日志的存储。
  • Logstash:日志采集器,它接收日志输入,对日志进行一些预处理,然后输出到Elasticsearch。
  • Kibana:UI组件,通过Elasticsearch的API查找数据并展示给用户。

最后还有一个小问题是如何将日志发送到Logstash。一种方案是在日志输出的时候直接调用Logstash接口将日志发送过去。这样一来又(咦,为啥要用“又”)要修改代码……于是小明选用了另一种方案:日志仍然输出到文件,每个服务里再部署个Agent扫描日志文件然后输出给Logstash。

网关 - 权限控制,服务治理

拆分成微服务后,出现大量的服务,大量的接口,使得整个调用关系乱糟糟的。经常在开发过程中,写着写着,忽然想不起某个数据应该调用哪个服务。或者写歪了,调用了不该调用的服务,本来一个只读的功能结果修改了数据……

为了应对这些情况,微服务的调用需要一个把关的东西,也就是网关。在调用者和被调用者中间加一层网关,每次调用时进行权限校验。另外,网关也可以作为一个提供服务接口文档的平台。

使用网关有一个问题就是要决定在多大粒度上使用:最粗粒度的方案是整个微服务一个网关,微服务外部通过网关访问微服务,微服务内部则直接调用;最细粒度则是所有调用,不管是微服务内部调用或者来自外部的调用,都必须通过网关。折中的方案是按照业务领域将微服务分成几个区,区内直接调用,区间通过网关调用。

由于整个网上超市的服务数量还不算特别多,小明采用的最粗粒度的方案:

服务注册于发现 - 动态扩容

前面的组件,都是旨在降低故障发生的可能性。然而故障总是会发生的,所以另一个需要研究的是如何降低故障产生的影响。

最粗暴的(也是最常用的)故障处理策略就是冗余。一般来说,一个服务都会部署多个实例,这样一来能够分担压力提高性能,二来即使一个实例挂了其他实例还能响应。

冗余的一个问题是使用几个冗余?这个问题在时间轴上并没有一个确切的答案。根据服务功能、时间段的不同,需要不同数量的实例。比如在平日里,可能4个实例已经够用;而在促销活动时,流量大增,可能需要40个实例。因此冗余数量并不是一个固定的值,而是根据需要实时调整的。

一般来说新增实例的操作为:

  1. 部署新实例
  2. 将新实例注册到负载均衡或DNS上

操作只有两步,但如果注册到负载均衡或DNS的操作为人工操作的话,那事情就不简单了。想想新增40个实例后,要手工输入40个IP的感觉……

解决这个问题的方案是服务自动注册与发现。首先,需要部署一个服务发现服务,它提供所有已注册服务的地址信息的服务。DNS也算是一种服务发现服务。然后各个应用服务在启动时自动将自己注册到服务发现服务上。并且应用服务启动后会实时(定期)从服务发现服务同步各个应用服务的地址列表到本地。服务发现服务也会定期检查应用服务的健康状态,去掉不健康的实例地址。这样新增实例时只需要部署新实例,实例下线时直接关停服务即可,服务发现会自动检查服务实例的增减。

服务发现还会跟客户端负载均衡配合使用。由于应用服务已经同步服务地址列表在本地了,所以访问微服务时,可以自己决定负载策略。甚至可以在服务注册时加入一些元数据(服务版本等信息),客户端负载则根据这些元数据进行流量控制,实现A/B测试、蓝绿发布等功能。

服务发现有很多组件可以选择,比如说Zookeeper 、Eureka、Consul、Etcd等。不过小明觉得自己水平不错,想炫技,于是基于Redis自己写了一个……

熔断、服务降级、限流

熔断

当一个服务因为各种原因停止响应时,调用方通常会等待一段时间,然后超时或者收到错误返回。如果调用链路比较长,可能会导致请求堆积,整条链路占用大量资源一直在等待下游响应。所以当多次访问一个服务失败时,应熔断,标记该服务已停止工作,直接返回错误。直至该服务恢复正常后再重新建立连接。

服务降级

当下游服务停止工作后,如果该服务并非核心业务,则上游服务应该降级,以保证核心业务不中断。比如网上超市下单界面有一个推荐商品凑单的功能,当推荐模块挂了后,下单功能不能一起挂掉,只需要暂时关闭推荐功能即可。

限流

一个服务挂掉后,上游服务或者用户一般会习惯性地重试访问。这导致一旦服务恢复正常,很可能因为瞬间网络流量过大又立刻挂掉,在棺材里重复着仰卧起坐。因此服务需要能够自我保护——限流。限流策略有很多,最简单的比如当单位时间内请求数过多时,丢弃多余的请求。另外,也可以考虑分区限流。仅拒绝来自产生大量请求的服务的请求。例如商品服务和订单服务都需要访问促销服务,商品服务由于代码问题发起了大量请求,促销服务则只限制来自商品服务的请求,来自订单服务的请求则正常响应。

测试

微服务架构下,测试分为三个层次:

  1. 端到端测试:覆盖整个系统,一般在用户界面机型测试。
  2. 服务测试:针对服务接口进行测试。
  3. 单元测试:针对代码单元进行测试。

三种测试从上到下实施的容易程度递增,但是测试效果递减。端到端测试最费时费力,但是通过测试后我们对系统最有信心。单元测试最容易实施,效率也最高,但是测试后不能保证整个系统没有问题。

由于端到端测试实施难度较大,一般只对核心功能做端到端测试。一旦端到端测试失败,则需要将其分解到单元测试:则分析失败原因,然后编写单元测试来重现这个问题,这样我们便可以更快地捕获同样的错误。

服务测试的难度在于服务会经常依赖一些其他服务。这个问题可以通过Mock Server解决:

单元测试大家都很熟悉了。我们一般会编写大量的单元测试(包括回归测试)尽量覆盖所有代码。

 

微服务框架

指标接口、链路跟踪注入、日志引流、服务注册发现、路由规则等组件以及熔断、限流等功能都需要在应用服务上添加一些对接代码。如果让每个应用服务自己实现是非常耗时耗力的。基于DRY的原则,小明开发了一套微服务框架,将与各个组件对接的代码和另外一些公共代码抽离到框架中,所有的应用服务都统一使用这套框架进行开发。

使用微服务框架可以实现很多自定义的功能。甚至可以将程序调用堆栈信息注入到链路跟踪,实现代码级别的链路跟踪。或者输出线程池、连接池的状态信息,实时监控服务底层状态。

使用统一的微服务框架有一个比较严重的问题:框架更新成本很高。每次框架升级,都需要所有应用服务配合升级。当然,一般会使用兼容方案,留出一段并行时间等待所有应用服务升级。但是如果应用服务非常多时,升级时间可能会非常漫长。并且有一些很稳定几乎不更新的应用服务,其负责人可能会拒绝升级……因此,使用统一微服务框架需要完善的版本管理方法和开发管理规范。

另一条路 - Service Mesh

另一种抽象公共代码的方法是直接将这些代码抽象到一个反向代理组件。每个服务都额外部署这个代理组件,所有出站入站的流量都通过该组件进行处理和转发。这个组件被称为Sidecar。

Sidecar不会产生额外网络成本。Sidecar会和微服务节点部署在同一台主机上并且共用相同的虚拟网卡。所以sidecar和微服务节点的通信实际上都只是通过内存拷贝实现的。

Sidecar只负责网络通信。还需要有个组件来统一管理所有sidecar的配置。在Service Mesh中,负责网络通信的部分叫数据平面(data plane),负责配置管理的部分叫控制平面(control plane)。数据平面和控制平面构成了Service Mesh的基本架构。

Sevice Mesh相比于微服务框架的优点在于它不侵入代码,升级和维护更方便。它经常被诟病的则是性能问题。即使回环网络不会产生实际的网络请求,但仍然有内存拷贝的额外成本。另外有一些集中式的流量处理也会影响性能。

结束、也是开始

微服务不是架构演变的终点。往细走还有Serverless、FaaS等方向。另一方面也有人在唱合久必分,分久必合,重新发现单体架构……

不管怎样,微服务架构的改造暂时告一段落了。小明满足地摸了摸日益光滑的脑袋,打算这个周末休息一下约小红喝杯咖啡。

“微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务和服务之间采用轻量级的通信机制相互沟通(通常是基于HTTP的Restful API).每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构"---- Martin Fowler的博客

微服务的特征与界定

 

单体应用 vs 微服务架构

优点

  1. 提升开发交流,每个服务足够内聚,足够小,代码容易理解;
  2. 服务独立测试、部署、升级、发布;
  3. 按需定制的DFX,资源利用率,每个服务可以各自进行x扩展和z扩展,而且,每个服务可以根据自己的需要部署到合适的硬件服务器上;
  4. 每个服务按需要选择HA的模式,选择接受服务的实例个数;
  5. 容易扩大开发团队,可以针对每个服务(service)组件开发团队;
  6. 提高容错性(fault isolation),一个服务的内存泄露并不会让整个系统瘫痪;
  7. 新技术的应用,系统不会被长期限制在某个技术栈上;

缺点

  1. 没有银弹,微服务提高了系统的复杂度;
  2. 开发人员要处理分布式系统的复杂性;
  3. 服务之间的分布式通信问题;
  4. 服务的注册与发现问题;
  5. 服务之间的分布式事务问题;
  6. 数据隔离再来的报表处理问题;
  7. 服务之间的分布式一致性问题;
  8. 服务管理的复杂性,服务的编排;
  9. 不同服务实例的管理。

Chris Richardson提出的微服务的三维扩展模型:

X轴,服务实例水平扩展,保证可靠性与性能;

Y轴,功能的扩展,服务单一职责,功能独立;

Z轴,数据分区,数据独立,可靠性保证;

通信问题

微服务的拆分一般会带来IPC通信的问题。通信机制需要完备可靠,服务之间的通信选择应尽量单一,从两个维度对通信的模式进行划分:

第一个维度是一对一还是一对多:

一对一:每个客户端请求有一个服务实例来响应。

一对多:每个客户端请求有多个服务实例来响应。

第二个维度是这些交互是同步还是异步:

同步模式:客户端请求需要服务端即时响应,甚至可能由于等待而阻塞。

异步模式:客户端请求不会阻塞进程,服务端的响应可以是非即时的。

微服务架构认为,服务间通信应该就只有这几种模式。AC出于时延、编程模型等方面的考虑,提供了一套通信机制,业务之间的通信要按需选用。

服务的发现与注册

一般的微服务架构里都有两层API GetWay,一层是外部API GetWay,用于用户访问系统;一层是内部API GetWay,内部服务之间的API GetWay。内部API GetWay要解决的问题就是服务发现和服务注册。从这也能看出来,为什么通信的方式要尽量单一,API GetWay有一项工作就是协议转换。

微服务可能是HA主备的,也可能是LB的,怎么找到一个服务?有两种思路,客户端发现(左图),客户端去注册中心查询服务实例列表,自行选择;另一种是服务端发现(右图),添加LB模块,客户端把请求发向LB,由LB根据负载均衡策略选择服务实例;

     

微服务注册表的典型实现:

ETCD : 是一个高可用,分布式的,一致性的,键值表,用于共享配置和服务发现。两个著名案例包括Kubernetes和Cloud Foundry。
ZK: 是一个广泛使用,为分布式应用提供高性能整合的服务。Apache ZooKeeper最初是Hadoop的子项目,现在已经变成顶级项目。

微服务架构的部署

微服务架构对于部署的要求

部署速率,Amazon与NetFlix都有千个服务,每个服务都有持续部署的要求,Amazon的服务每秒都会部署一次;

部署自动化,一切都要自动化,IaaS与PaaS解决I层与P层自动化部署,微服务有自动部署与运维工具,并实现Auto-Scaling;

部署提供基础机制,为实现分布式部署要求,部署机制一般都有资源池化、服务的生命周期来看,部署服务 与服务注册是一体的;

部署的粒度:

VM: 部署系统管理的VM的生命周期,如当前AC的iDeploy部署,把AC部署拆分为每个VM的安装、配置与启动;这种方式粒度粗,支撑不了微服务的部署(除非一个服务占用一个VM);

App: 管理应用的生命周期及部署形态,生命周期分为部署、配置、启动、升级等,部署形态有主备、LB、Daemon等;

Container: 相比于APP,容器有更好的隔离性和移植性;

微服务:一般的微服务要么是APP,要么是Container,但AC就不是。受限于ONOS架构,我们的服务是一组feature;

MS部署的解决方案:

TOSCA: 云应用拓扑标准,一种描述云化部署的DSL,我司主推一个标准,PaaS的部署系统和MANO用的都是TOSCA;

Kubernetes:Google开源的容器管理系统,提出了Pod/Service/Labels等概念,以ETCD为中心,PaaS基于K8S开发出了我司的云化部署平台;

Mesosphere:DCOS,数据中心操作系统,基于mesos实现资源池化,有自身的编排工具;分布式LAB基于DCOS的思想做出了一套部署与集群管理系统(HASEN);

微服务的划分

微服务的划分主要是保证微服务功能内聚,职责单一。一般使用DDD(Domain Drive Design)的思想与方法对微服务进行划分,这种方法有点类似于数据库ER图的划分,不断分解数据,保证关系型数据库符合原子性、冗余性的范式要求。当然,微服务的划分比数据表划分更复杂,也没有微服务范式的概念,但思想是一致的。更多的内容,请参考《领域驱动设计》这本书。

分布式一致性

有两个大的思路:全局的分布式事务;事件驱动;

分布式事务就是现在AC的思路,在设计开发中;

事件驱动,忽略了事务的概念,由每个服务在应用层面保存服务的状态,服务之间的通信使用事件机制通知;此种方法可以保证微服务间的独立性,但把问题交给了服务的设计者;具体事件驱动的案例见参考材料;

数据隔离问题

微服务之间数据隔离可以保证服务的独立升级与部署,数据隔离有三个维度:

数据表级隔离;数据表之间独立,没有外键关系;

数据库级隔离;不同服务有不同的数据库;

DBMS级隔离;不同服务有不同的数据库管理系统;

一般做到数据库级隔离就可以了,服务之间的数据交换使用服务间接口。

从单体到微服务

微服务架构是一个衍生架构,都是从单体架构演化而来的。

因为微服务架构本身的复杂性,初创系统出于快速开发、快速验证的考虑,很少在一开始就使用微服务架构。加之微服务的概念在这两年才火,大型单体应用也是看到了开发与维护的成本在不断增加,才会有转型微服务的动力。因此,如何从单体到微服务是一个普遍问题。

从单体到微服务的原则:

逐步演进,不要全部重构

全部重构,带来极大的成本和风险,系统会有很长的不稳定期。而且,最终的效果也不会很好,在设计时很难想到所有问题。微服务架构的演化思路应该是一步步铺基础设施,一点点拆分微服务。

DevOps与微服务架构

DevOps是09年提出来的概念,但一直没有太火。直到14年,容器与微服务架构的提出,DevOps才得到了快速的发展。DevOps不单是一个实现自动化的工具链,而是组织、流程与技术的结合。组织上强调全栈团队、团队特性专一、团队自治;技术上打通开发与运维;流程上强调端到端、可视化、灰度升级、A/B测试等。

对于DevOps,MS不是必须的,但MS为DevOps提供了最好的架构支撑,对于组织和流程的要求也是一致的。所以,也有人称MS是DevOps架构。

【什么是微服务? 】

一、背景介绍:

 

传统的it架构的缺陷:

 

使用传统的整体式架构(Monolithic Architecture)应用开发系统,如CRM、ERP等大型应用,随着新需求的不断增加,企业更新和修复大型整体式应用变得越来越困难;

 

随着移动互联网的发展,企业被迫将其应用迁移至现代化UI界面架构以便能兼容移动设备,这要求企业能实现应用功能的快速上线;

 

许多企业在SOA投资中得到的回报有限,SOA可以通过标准化服务接口实现能力的重用,但对于快速变化的需求,受到整体式应用的限制,有时候显得力不从心;

 

二、什么是微服务?

 

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

 

可以在“自己的程序”中运行,并通过“轻量级设备与HTTP型API进行沟通”。关键在于该服务可以在自己的程序中运行。通过这一点我们就可以将服务公开与微服务架构(在现有系统中分布一个API)区分开来。在服务公开中,许多服务都可以被内部独立进程所限制。如果其中任何一个服务需要增加某种功能,那么就必须缩小进程范围。在微服务架构中,只需要在特定的某种服务中增加所需功能,而不影响整体进程。

 

三、微服务中的spring-cloud

 

Spring Cloud是一个相对比较新的微服务框架,2016n年推出1.0的release版本. 虽然Spring Cloud时间最短, 但是相比Dubbo等RPC框架, Spring Cloud提供的全套的分布式系统解决方案。

 

Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全居琐,leader选举,分布式session,集群状态)中快速构建的工具,使用Spring Cloud的开发者可以快速的启动服务或构建应用、同时能够快速和云平台资源进行对接。

 

三、什么是Eureak?

 

Eureak的结构特点

 

1. 是纯正的 servlet 应用,需构建成war包部署

 

2. 使用了 Jersey 框架实现自身的 RESTful HTTP接口

 

3. peer之间的同步与服务的注册全部通过 HTTP 协议实现

 

4. 定时任务(发送心跳、定时清理过期服务、节点同步等)通过 JDK 自带的 Timer 实现

 

5. 内存缓存使用Google的guava包实现

 

四、实战

项目结构如下

首先创建moduel

moudel里面创建服务:

配置application.yml

完成运行DemoApplication启动服务

界面如下,Application为空说明没有注册service。

 

接下来我们编写service-client

 

同样创建model

编写配置文件:

使用简单controller编写,告诉这个是Client端

 

启动服务

 

如果你懂或者不理解,希望你看到这篇文章之后就能搞懂。

以下:

正文

看到最近“微服务架构”这个概念这么火,作为一个积极上进的程序猿,成小胖忍不住想要学习学习。而架构师老王(不是隔壁老王)最近刚好在做公司基础服务的微服务化研究和落地,对此深有研究。

于是成小胖马上屁颠屁颠的跑过去向老王请教:“王哥,我看微服务架构这么火,我也想学,您给我讲讲啥是微服务架构呗?”

老王笑了笑说:“要想知道什么是微服务架构,你得先知道什么系统架构设计。”

成小胖的理想是成为一名架构师,平时积累了不少知识,因此对“系统架构设计”这个概念还是很熟悉的,因此他马上就给出了答案【1】:

系统架构设计描述了在应用系统的内部,如何根据业务、技术、组织、灵活性、可扩展性以及可维护性等多种因素,将应用系统划分成不同的部分,并使这些部分彼此之间相互分工、相互协作,从而为用户提供某种特定的价值的方式。

老王满意的点点头,继续问:“你看最近我在做微服务的研究和落地,你知道为什么要做这个事情吗?”

“因为目前的三层架构存在很多弊端,不满足业务发展的需求了呗。”

“对的,我看你对公司目前的架构也非常熟悉了,你来仔细说说现在的三层架构吧。”

于是成小胖拿了一张A4纸,图文并茂地给老王讲了他对三层架构的理解:

三层架构是指在业务和技术的发展过程中,系统中不同职责的部分被定义在不同的层次,每一层负责的功能更加具体化。三层架构通常包括表示层、业务逻辑层和数据访问层,层与层之间互相连接、互相协作,构成一个整体,并且层的内部可以被替换成其他可以工作的部分,但对整体的影响不大。

以 Web 应用程序为例,早期是将所有的表示逻辑、业务逻辑和数据访问逻辑放在一起,这就是一层架构。

后来随着 java、.NET 等高级语言的发展,提供了越来越方便的数据访问机制,如 java 的 JDBC 和 .NET 的 http://ADO.NET。这时数据访问部分被分离开来,形成了二层架构。

再后来,随着面向对象设计、企业架构模式等理念的不断发展,表示逻辑和业务逻辑也被分离开来,形成了现在的三层架构

三层架构的具体内容如下:

  • 表示层: 用户使用应用程序时,看到的、听见的、输入的或者交互的部分。
  • 业务逻辑层: 根据用户输入的信息,进行逻辑计算或者业务处理的部分。
  • 数据访问层: 关注有效地操作原始数据的部分,如将数据存储到存储介质(如数据库、文件系统)及从存储介质中读取数据等。

老王对这个解释非常满意,作了进一步的补充:“你看虽然现在程序被分成了三层,但只是逻辑上的分层,并不是物理上的分层。也就是说,对不同层的代码而言,经过编译、打包和部署后,所有的代码最终还是运行在同一个进程中。而这,就是所谓的单块架构。”

成小胖挠了挠头:“原来单块架构是这个意思啊~~”

“嗯。根据你的实际工作经验,你再总结下单块架构的优缺点吧。”

平时勤于总结的成小胖很快便列出了单块架构的优缺点:

优点:

  • 易于开发: 开发方式简单,IDE 支持好,方便运行和调试。
  • 易于测试: 所有功能运行在一个进程中,一旦进程启动,便可以进行系统测试。
  • 易于部署: 只需要将打好的一个软件包发布到服务器即可。
  • 易于水平伸缩: 只需要创建一个服务器节点,配置好运行时环境,再将软件包发布到新服务器节点即可运行程序(当然也需要采取分发策略保证请求能有效地分发到新节点)。

缺点:

  • 维护成本大: 当应用程序的功能越来越多、团队越来越大时,沟通成本、管理成本显著增加。当出现 bug 时,可能引起 bug 的原因组合越来越多,导致分析、定位和修复的成本增加;并且在对全局功能缺乏深度理解的情况下,容易在修复 bug 时引入新的 bug。
  • 持续交付周期长: 构建和部署时间会随着功能的增多而增加,任何细微的修改都会触发部署流水线。
  • 新人培养周期长: 新成员了解背景、熟悉业务和配置环境的时间越来越长。
  • 技术选型成本高: 单块架构倾向于采用统一的技术平台或方案来解决所有问题,如果后续想引入新的技术或框架,成本和风险都很大。
  • 可扩展性差: 随着功能的增加,垂直扩展的成本将会越来越大;而对于水平扩展而言,因为所有代码都运行在同一个进程,没办法做到针对应用程序的部分功能做独立的扩展。

老王拍了拍成小胖的肩膀,眼睛眯成了一条缝:“小伙子总结的很不错!既然你已经对目前的单块架构的优缺点有了很好的理解,那现在咱们就可以开始来学习微服务架构了。”

老王先从网上搜索“微服务架构”关键字,出来这么一段话:

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务于服务间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

成小胖看完了这段话,说:“看着有点晕,云里雾里的感觉……”

老王嘿嘿一笑:“莫慌,现在就给你详细讲讲微服务架构的特性。” 

1. 单一职责

微服务架构中的每个服务,都是具有业务逻辑的,符合高内聚、低耦合原则以及单一职责原则的单元,不同的服务通过“管道”的方式灵活组合,从而构建出庞大的系统。

2. 轻量级通信

服务之间通过轻量级的通信机制实现互通互联,而所谓的轻量级,通常指语言无关、平台无关的交互方式。

对于轻量级通信的格式而言,我们熟悉的 XML 和 JSON,它们是语言无关、平台无关的;对于通信的协议而言,通常基于 HTTP,能让服务间的通信变得标准化、无状态化。目前大家熟悉的 REST(Representational State Transfer)是实现服务间互相协作的轻量级通信机制之一。使用轻量级通信机制,可以让团队选择更适合的语言、工具或者平台来开发服务本身。

3. 独立性

每个服务在应用交付过程中,独立地开发、测试和部署。

在单块架构中所有功能都在同一个代码库,功能的开发不具有独立性;当不同小组完成多个功能后,需要经过集成和回归测试,测试过程也不具有独立性;当测试完成后,应用被构建成一个包,如果某个功能存在 bug,将导致整个部署失败或者回滚。

在微服务架构中,每个服务都是独立的业务单元,与其他服务高度解耦,只需要改变当前服务本身,就可以完成独立的开发、测试和部署。

4. 进程隔离

单块架构中,整个系统运行在同一个进程中,当应用进行部署时,必须停掉当前正在运行的应用,部署完成后再重启进程,无法做到独立部署。

有时候我们会将重复的代码抽取出来封装成组件,在单块架构中,组件通常的形态叫做共享库(如 jar 包或者 DLL),但是当程序运行时,所有组件最终也会被加载到同一进程中运行。

 

在微服务架构中,应用程序由多个服务组成,每个服务都是高度自治的独立业务实体,可以运行在独立的进程中,不同的服务能非常容易地部署到不同的主机上。

理论上所有服务可以部署在同一个服务器节点,但是并不推荐这么做,因为微服务架构的主旨就是高度自治和高度隔离。

“王哥你真厉害,您这么一说我的思维清晰了很多!”成小胖激动的几乎要叫起来。

“我之前了解过 SOA,好像跟微服务架构的思想很像啊,您能帮我区分一下吗?”成小胖追问到。

老王嘿嘿一笑,拿起成小胖手上的A4纸,翻到另外一面画了个表格:

接着老王又画了一张图:

成小胖看了之后说:“您这么一画我倒是大概明白了,但是图里面的 DevOps 这个概念我不懂诶……”

“这个 DevOps 就说来话长了,有时间你自己先去查查资料了解下吧。”

“好的。现在我对微服务架构的概念有了了解,您能再深入剖析下它的本质吗?”

“好,你可仔细听好了哈!”

1. 服务作为组件

微服务也可以被认为是一种组件,但是跟传统组件的区别在于它可以独立部署,因此它的一个显著的优势。另外一个优点是,它在组件与组件之间定义了清晰的、语言无关、平台无关的规范接口,耦合度低,灵活性非常高。但它的不足之处是,分布式调用严重依赖于网络的可靠性和稳定性。

2. 围绕业务组织团队

在单块架构中,企业一般会根据技能划分团队,在这种组织架构下,即便是简单的需求变更都有可能需要跨团队协作,沟通成本很高。而在微服务架构中,它提倡以业务为核心,按照业务能力来组织团队,团队中的成员具有多样性的技能。

3. 关注产品而非项目

在单块架构中,应用基本上是基于“项目模式”构建的,即项目启动时从不同技能资源池中抽取相关资源组成团队,项目结束后释放所有资源。这种情况下团队成员缺乏主人翁意识和产品成就感。

在微服务架构中,提倡采用“产品模式”构建,即更倾向于让团队负责整个服务的生命周期,以便提供更优质的服务。

4. 技术多样性

微服务架构中,提倡针对不同的业务特征选择合适的技术方案,有针对性的解决具体业务问题,而不是像单块架构中采用统一的平台或技术来解决所有问题。

5. 业务数据独立

微服务架构提供自主管理其相关的业务数据,这样可以随着业务的发展提供数据接口集成,而不是以数据库的方式同其他服务集成。另外,随着业务的发展,可以方便地选择更合的工具管理或者迁移业务数据。

6. 基础设施自动化

在微服务架构的实践过程中,对持续交付和部署流水线的要求很高,将促进企业不断寻找更高效的方式完成基础设施的自动化及 DevOps 运维能力的提升。

听完成小胖忍不住表达了敬佩之意:“老司机就是老司机,噢说错了……架构师就是架构师,总结得这么简洁又深刻!”

“咳咳,低调低调……”

“听您讲解了这么多,我觉得微服务架构解决了很多当前三层架构的痛点。不过我觉得没有任何一项技术或架构是完美的。”

“非常正确。进行微服务架构的落地是存在很多挑战的。” 

1. 分布式系统的复杂性

微服务架构是基于分布式的系统,而构建分布式系统必然会带来额外的开销。

  • 性能: 分布式系统是跨进程、跨网络的调用,受网络延迟和带宽的影响。
  • 可靠性: 由于高度依赖于网络状况,任何一次的远程调用都有可能失败,随着服务的增多还会出现更多的潜在故障点。因此,如何提高系统的可靠性、降低因网络引起的故障率,是系统构建的一大挑战。
  • 异步: 异步通信大大增加了功能实现的复杂度,并且伴随着定位难、调试难等问题。
  • 数据一致性: 要保证分布式系统的数据强一致性,成本是非常高的,需要在 C(一致性)A(可用性)P(分区容错性) 三者之间做出权衡。

2. 运维成本

运维主要包括配置、部署、监控与告警和日志收集四大方面。微服务架构中,每个服务都需要独立地配置、部署、监控和收集日志,成本呈指数级增长。

3. 自动化部署

在微服务架构中,每个服务都独立部署,交付周期短且频率高,人工部署已经无法适应业务的快速变化。因此如何有效地构建自动化部署体系,是微服务面临的另一个挑战。

4. DevOps 与组织架构

在微服务架构的实施过程中,开发人员和运维人员的角色发生了变化,开发者将承担起整个服务的生命周期的责任,包括部署和监控;而运维则更倾向于顾问式的角色,尽早考虑服务如何部署。因此,按需调整组织架构、构建全功能的团队,也是一个不小的挑战。

5. 服务间的依赖测试

单块架构中,通常使用集成测试来验证依赖是否正常。而在微服务架构中,服务数量众多,每个服务都是独立的业务单元,服务主要通过接口进行交互,如何保证依赖的正常,是测试面临的主要挑战。

6. 服务间的依赖管理

微服务架构中,服务数量众多,如何清晰有效地展示服务间的依赖关系也是个不小的挑战。

“微服务的落地需要经过全面的考察和完善的试验,并不是每个场景都适合使用微服务架构,也不是每个企业都有能力或者精力去面对这些挑战。”老王最后语重心长的说。

“嗯嗯,每件事都有两面性,最合适的才是最好的!对了王哥,您已经给我上完理论课了,啥时候带我实践下呗?”

“你先好好消化完今天讲的这些,下次再说吧……”

“好吧,很期待我们的下一次交流……”

一、全面了解微服务

a : 4个典型特点

1.单个服务尽量专注一件事情,高内聚、低耦合;

2.进程隔离;

3.每个服务可以独立的开发、测试、构建、部署;

4.小且灵活;

b : 无与伦比的优点

1.交付周期

每个服务可以独立的开发、测试和交付,降低周期;

2.快速沟通

小团队开发,降低代码耦合度导致的沟通成本;

业务按服务拆分,新人不需要了解整体架构,上手快;

3.定制化

可以根据市场需求,灵活多变的组合出新的业务场景;

4.隔离性

进程隔离方式,故障范围有效控制;

5.技术栈

可以根据需求按服务选择不同技术栈;

6.演进优化

可以按照服务粒度进行演进优化;

二、微服务基础架构关键点

下面脑图中芒果色标注的七个模块,被认为认为是构建微服务 2.0 技术栈的核心模块,本文后面的选型会分别基于这些模块展开。对于每个模块我也列出一些核心架构关注点,在选择具体产品时,需要尽可能覆盖到这些关注点。

下图是我近期工作总结和参考的一个微服务技术体系,我想同时分享给一线架构师或者工程师参考,其中粉红色标注的模块是和微服务关系最密切的模块,大家在做技术选型时,可以同时对照这个体系。

三、 服务框架选型

服务框架是一个比较成熟的领域,有太多可选项。Spring Boot/Cloud 由于 Spring 社区的影响力和 Netflix 的背书,目前可以认为是构建 Java 微服务的一个社区标准,Spring Boot 目前在 GitHub 上有超过 20k 星。

基于 Spring 的框架本质上可以认为是一种 RESTful 框架(不是 RPC 框架),序列化协议主要采用基于文本的 JSON,通讯协议一般基于 HTTP。RESTful 框架天然支持跨语言,任何语言只要有 HTTP 客户端都可以接入调用,但是客户端一般需要自己解析 payload。目前 Spring 框架也支持 Swagger 契约编程模型,能够基于契约生成各种语言的强类型客户端,极大方便不同语言栈的应用接入,但是因为 RESTful 框架和 Swagger 规范的弱契约特性,生成的各种语言客户端的互操作性还是有不少坑的。

Dubbo 是阿里多年构建生产级分布式微服务的技术结晶,服务治理能力非常丰富,在国内技术社区具有很大影响力,目前 github 上有超过 16k 星。Dubbo 本质上是一套基于 Java 的 RPC 框架,当当 Dubbox 扩展了 Dubbo 支持 RESTful 接口暴露能力。

Dubbo 主要面向 Java 技术栈,跨语言支持不足是它的一个弱项,另外因为治理能力太丰富,以至于这个框架比较重,完全用好这个框架的门槛比较高,但是如果你的企业基本上投资在 Java 技术栈上,选 Dubbo 可以让你在服务框架一块站在较高的起点上,不管是性能还是企业级的服务治理能力,Dubbo 都做的很出色。新浪微博开源的 Motan(GitHub 4k stars)也不错,功能和 Dubbo 类似,可以认为是一个轻量裁剪版的 Dubbo。

gRPC 是谷歌近年新推的一套 RPC 框架,基于 protobuf 的强契约编程模型,能自动生成各种语言客户端,且保证互操作。支持 HTTP2 是 gRPC 的一大亮点,通讯层性能比 HTTP 有很大改进。Protobuf 是在社区具有悠久历史和良好口碑的高性能序列化协议,加上 Google 公司的背书和社区影响力,目前 gRPC 也比较火,GitHub 上有超过 13.4k 星。

目前看 gRPC 更适合内部服务相互调用场景,对外暴露 RESTful 接口可以实现,但是比较麻烦(需要 gRPC Gateway 配合),所以对于对外暴露 API 场景可能还需要引入第二套 RESTful 框架作为补充。总体上 gRPC 这个东西还比较新,社区对于 HTTP2 带来的好处还未形成一致认同,建议谨慎投入,可以做一些试点。

四、 运行时支撑服务选型

运行时支撑服务主要包括服务注册中心,服务路由网关和集中式配置中心三个产品。

服务注册中心,如果采用 Spring Cloud 体系,则选择 Eureka 是最佳搭配,Eureka 在 Netflix 经过大规模生产验证,支持跨数据中心,客户端配合 Ribbon 可以实现灵活的客户端软负载,Eureka 目前在 GitHub 上有超过 4.7k 星;Consul 也是不错选择,天然支持跨数据中心,还支持 KV 模型存储和灵活健康检查能力,目前在 GitHub 上有超过 11k 星。

服务网关也是一个比较成熟的领域,有很多可选项。如果采用 Spring Cloud 体系,则选择 Zuul 是最佳搭配,Zuul 在 Netflix 经过大规模生产验证,支持灵活的动态过滤器脚本机制,异步性能不足(基于 Netty 的异步 Zuul 迟迟未能推出正式版)。Zuul 网关目前在 github 上有超过 3.7k 星。基于 Nginx/OpenResty 的 API 网关 Kong 目前在 github 上比较火,有超过 14.1k 星。因为采用 Nginx 内核,Kong 的异步性能较强,另外基于 lua 的插件机制比较灵活,社区插件也比较丰富,从安全到限流熔断都有,还有不少开源的管理界面,能够集中管理 Kong 集群。

配置中心,Spring Cloud 自带 Spring Cloud Config(GitHub 0.75k stars),个人认为算不上生产级,很多治理能力缺失,小规模场景可以试用。个人比较推荐携程的 Apollo 配置中心,在携程经过生产级验证,具备高可用,配置实时生效(推拉结合),配置审计和版本化,多环境多集群支持等生产级特性,建议中大规模需要对配置集中进行治理的企业采用。Apollo 目前在 github 上有超过 3.4k 星。

五、服务监控选型

主要包括日志监控,调用链监控,Metrics 监控,健康检查和告警通知等产品。

ELK 目前可以认为是日志监控的标配,功能完善开箱即用,ElasticSearch 目前在 GitHub 上有超过 28.4k 星。Elastalert(GitHub 4k stars) 是 Yelp 开源的针对 ELK 的告警通知模块。

调用链监控目前社区主流是点评 CAT(GitHub 4.3k stars),Twitter 之前开源现在由 OpenZipkin 社区维护的 Zipkin(GitHub 7.5k stars)和 Naver 开源的 Pinpoint(GitHub 5.3k stars)。个人比较推荐点评开源的 CAT,在点评和国内多家互联网公司有落地案例,生产级特性和治理能力较完善,另外 CAT 自带告警模块。下面是我之前对三款产品的评估表,供参考。

Metrics 监控主要依赖于时间序列数据库 (TSDB),目前较成熟的产品是 StumbleUpon 公司开源的基于 HBase 的 OpenTSDB(基于 Cassandra 的 KariosDB 也是一个选择,GitHub 1.1k stars,它基本上是 OpenTSDB 针对 Cassandra 的一个改造版),OpenTSDB 具有分布式能力可以横向扩展,但是相对较重,适用于中大规模企业,OpenTSDB 目前在 GitHub 上有近 2.9k 星。

OpenTSDB 本身不提供告警模块,Argus(GitHub 0.29k 星)是 Salesforce 开源的基于 OpenTSDB 的统一监控告警平台,支持丰富的告警函数和灵活的告警配置,可以作为 OpenTSDB 的告警补充。近年也出现一些轻量级的 TSDB,如 InfluxDB(GitHub 12.4k stars)和 Prometheus(GitHub 14.3k stars),这些产品函数报表能力丰富,自带告警模块,但是分布式能力不足,适用于中小规模企业。Grafana(GitHub 19.9k stars)是 Metrics 报表展示的社区标配。

社区还有一些通用的健康检查和告警产品,例如 Sensu(GitHub 2.7k stars),能够对各种服务(例如 Spring Boot 暴露的健康检查端点,时间序列数据库中的 metrics,ELK 中的错误日志等)定制灵活的健康检查 (check),然后用户可以针对 check 结果设置灵活的告警通知策略。Sensu 在 Yelp 等公司有落地案例。其它类似产品还有 Esty 开源的 411(GitHub 0.74k 星)和 Zalando 的 ZMon(GitHub 0.15k 星),它们是分别在 Esty 和 Zalando 落地的产品,但是定制 check 和告警配置的使用门槛比较高,社区不热,建议有定制自研能力的团队试用。ZMon 后台采用 KairosDB 存储,如果企业已经采用 KariosDB 作为时间序列数据库,则可以考虑 ZMon 作为告警通知模块。

六、服务容错选型

针对 Java 技术栈,Netflix 的 Hystrix(github 12.4k stars)把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)都可以封装在 Hystrix Command 之内,封装后自动具备容错能力。Hystrix 起源于 Netflix 的弹性工程项目,经过 Netflix 大规模生产验证,目前是容错组件的社区标准,GitHub 上有超 12k 星。其它语言栈也有类似 Hystrix 的简化版本组件。

Hystrix 一般需要在应用端或者框架内埋点,有一定的使用门槛。对于采用集中式反向代理(边界和内部)做服务路由的公司,则可以集中在反向代理上做熔断限流,例如采用 Nginx(GitHub 5.1k stars)或者 Kong(GitHub 11.4k stars)这类反向代理,它们都插件支持灵活的限流容错配置。Zuul 网关也可以集成 Hystrix 实现网关层集中式限流容错。集中式反向代理需要有一定的研发和运维能力,但是可以对限流容错进行集中治理,可以简化客户端。

七、 后台服务选型

后台服务主要包括消息系统,分布式缓存,分布式数据访问层和任务调度系统。后台服务是一个相对比较成熟的领域,很多开源产品基本可以开箱即用。

消息系统,对于日志等可靠性要求不高的场景,则 Apache 顶级项目 Kafka(GitHub 7.2k stars)是社区标配。对于可靠性要求较高的业务场景,Kafka 其实也是可以胜任,但企业需要根据具体场景,对 Kafka 的监控和治理能力进行适当定制完善,Allegro 公司开源的 hermes(GitHub 0.3k stars)是一个可参考项目,它在 Kafka 基础上封装了适合业务场景的企业级治理能力。阿里开源的 RocketMQ(GitHub 3.5k 星)也是一个不错选择,具备更多适用于业务场景的特性,目前也是 Apache 顶级项目。RabbitMQ(GitHub 3.6k 星)是老牌经典的 MQ,队列特性和文档都很丰富,性能和分布式能力稍弱,中小规模场景可选。

对于缓存治理,如果倾向于采用客户端直连模式(个人认为缓存直连更简单轻量),则 SohuTv 开源的 cachecloud(GitHub 2.5k stars)是一款不错的 Redis 缓存治理平台,提供诸如监控统计,一键开启,自动故障转移,在线伸缩,自动化运维等生产级治理能力,另外其文档也比较丰富。如果倾向采用中间层 Proxy 模式,则 Twitter 开源的 twemproxy(GitHub 7.5k stars)和 CodisLab 开源的 codis(GitHub 6.9k stars)是社区比较热的选项。

对于分布式数据访问层,如果采用 Java 技术栈,则当当开源的 shardingjdbc(GitHub 3.5k stars)是一个不错的选项,分库分表逻辑做在客户端 jdbc driver 中,客户端直连数据库比较简单轻量,建议中小规模场景采用。如果倾向采用数据库访问中间层 proxy 模式,则从阿里 Cobar 演化出来的社区开源分库分表中间件 MyCAT(GitHub 3.6k stars)是一个不错选择 。proxy 模式运维成本较高,建议中大规模场景,有一定框架自研和运维能力的团队采用。

任务调度系统,个人推荐徐雪里开源的 xxl-job(GitHub 3.4k stars),部署简单轻量,大部分场景够用。当当开源的 elastic-job(GitHub 3.2k stars)也是一个不错选择,相比 xxl-job 功能更强一些也更复杂。

八、 服务安全选型

对于微服务安全认证授权机制一块,目前业界虽然有 OAuth 和 OpenID connect 等标准协议,但是各家具体实现的做法都不太一样,企业一般有很多特殊的定制需求,整个社区还没有形成通用生产级开箱即用的产品。有一些开源授权服务器产品,比较知名的如 Apereo CAS(GitHub 3.6k stars),JBoss 开源的 keycloak(GitHub 1.9 stars),spring cloud security 等,大都是 opinionated(一家观点和做法)的产品,同时因支持太多协议造成产品复杂,也缺乏足够灵活性。个人建议基于 OAuth 和 OpenID connect 标准,在参考一些开源产品的基础上(例如 Mitre 开源的 OpenID-Connect-Java-Spring-Server,GitHub 0.62k stars),定制自研轻量级授权服务器。Wso2 提出了一种微服务安全的参考方案,建议参考,该方案的关键步骤如下:

1. 使用支持 OAuth 2.0 和 OpenID Connect 标准协议的授权服务器(个人建议定制自研);

2. 使用 API 网关作为单一访问入口,统一实现安全治理;

3. 客户在访问微服务之前,先通过授权服务器登录获取 access token,然后将 access token 和请求一起发送到网关;

4. 网关获取 access token,通过授权服务器校验 token,同时做 token 转换获取 JWT token。

5. 网关将 JWT Token 和请求一起转发到后台微服务。

6. JWT 中可以存储用户会话信息,该信息可以传递给后台的微服务,也可以在微服务之间传递,用作认证授权等用途;

7. 每个微服务包含 JWT 客户端,能够解密 JWT 并获取其中的用户会话信息。

8. 整个方案中,access token 是一种 by reference token,不包含用户信息可以直接暴露在公网上;JWT token 是一种 by value token,可以包含用户信息但不暴露在公网上。

九、 服务部署平台选型

容器已经被社区接受为交付微服务的一种理想手段,可以实现不可变(immutable)发布模式。一个轻量级的基于容器的服务部署平台主要包括容器资源调度,发布系统,镜像治理,资源治理和 IAM 等模块。

集群资源调度系统:屏蔽容器细节,将整个集群抽象成容器资源池,支持按需申请和释放容器资源,物理机发生故障时能够实现自动故障迁移 (fail over)。目前 Google 开源的 Kubernetes,在 Google 背书和社区的强力推动下,基本已经形成市场领导者地位,GitHub 上有 31.8k 星,社区的活跃度已经远远超过了 mesos(GitHub 3.5k stars)和 swarm 等竞争产品,所以容器资源调度建议首选 K8s。当然如果你的团队有足够定制自研能力,想深度把控底层调度算法,也可以基于 Mesos 做定制自研。

镜像治理:基于 Docker Registry,封装一些轻量级的治理功能。VMware 开源的 harbor(GitHub 3.5k stars) 是目前社区比较成熟的企业级产品,在 Docker Registry 基础上扩展了权限控制,审计,镜像同步,管理界面等治理能力,可以考虑采用。

资源治理:类似于 CMDB 思路,在容器云环境中,企业仍然需要对应用 app,组织 org,容器配额和数量等相关信息进行轻量级的治理。目前这块还没有生产级的开源产品,一般企业需要根据自己的场景定制自研。

发布平台:面向用户的发布管理控制台,支持发布流程编排。它和其它子系统对接交互,实现基本的应用发布能力,也实现如蓝绿,金丝雀和灰度等高级发布机制。目前这块生产级的开源产品很少,Netflix 开源的 spinnaker(github 4.2k stars)是一个,但是这个产品比较复杂重量(因为它既要支持适配对接各种 CI 系统,同时还要适配对接各种公有云和容器云,使得整个系统异常复杂),一般企业建议根据自己的场景定制自研轻量级的解决方案。

IAM:是 identity & access management 的简称,对发布平台各个组件进行身份认证和安全访问控制。社区有不少开源的 IAM 产品,比较知名的有 Apereo CAS(GitHub 3.6k stars),JBoss 开源的 keycloak(GitHub 1.9 stars)等。但是这些产品一般都比较复杂重量,很多企业考虑到内部各种系统灵活对接的需求,都会考虑定制自研轻量级的解决方案。

考虑到服务部署平台目前还没有端到端生产级解决方案,企业一般需要定制集成,下面给出一个可以参考的具备轻量级治理能力的发布体系:

简化发布流程如下:

1. 应用通过 CI 集成后生成镜像,用户将镜像推到镜像治理中心;

2. 用户在资产治理中心申请发布,填报应用,发布和配额相关信息,然后等待审批通过;

3. 发布审批通过,开发人员通过发布控制台发布应用;

4. 发布系统通过查询资产治理中心获取发布规格信息;

5. 发布系统向容器云发出启动容器实例指令;

6. 容器云从镜像治理中心拉取镜像并启动容器;

7. 容器内服务启动后自注册到服务注册中心,并保持定期心跳;

8. 用户通过发布系统调用服务注册中心调拨流量,实现蓝绿,金丝雀或灰度发布等机制;

9. 网关和内部微服务客户端定期同步服务注册中心上的服务路由表,将流量按负载均衡策略分发到新的服务实例上。

另外,持续交付流水线(CD Pipeline)也是微服务发布重要环节,这块主要和研发流程相关,一般需要企业定制,下面是一个可供参考的流水线模型,在镜像治理中心上封装一些轻量级的治理流程,例如只有通过测试环境测试的镜像才能升级发布到 UAT 环境,只有通过 UAT 环境测试的镜像才能升级发布到生产环境,通过在流水线上设置一些质量门,保障应用高质量交付到生产。

十、总结

注意,本文限于篇幅,对测试和 CI 等环节没有涉及,但它们同样是构建微服务架构的重要环节,也有众多成熟的开源产品可选。

技术选型虽然重要,但还只是微服务建设的一小部分工作,选型后的产品要在企业内部真正落地,形成完整的微服务技术栈体系,则后续还有大量集成、定制、治理、运维和推广等工作。

以上是理论部分,具体实践请详细参照各大公司的系统微服务演进,包括华为、阿里、百度、滴滴、豆瓣、七牛、小米、360、58等公司的实践案例以及两本最佳学习微服务的电子书,王磊著的《微服务架构与实践》以及国外Sam Newman著的《微服务设计》。

微服务这个概念最早是在2011年5月威尼斯的一个软件架构会议上讨论并提出的,用于描述一些作为通用架构风格的设计原则。2012年3月在波兰克拉科夫举行的33rd Degree Conference大会上,Thoughtworks首席咨询师James Lewis做了题为《Microservices - Java, the Unix Way》的演讲(http://2012.33degree.org/talk/show/67),这次演讲里James讨论了微服务的一些原则和特征,例如单一服务职责、康威定律、自动扩展、DDD等等。

微服务架构则是由Fred George在2012年的一次技术大会上所提出(http://oredev.org/oredev2012/2012/sessions/micro-service-architecture.html),在大会的演讲中他讲解了如何分拆服务以及如何利用MQ来进行服务间的解耦,这就是最早的微服务架构雏形。而后由Martin Fowler发扬光大并且在2014年发表了一篇著名的微服务文章(https://martinfowler.com/articles/microservices.html),这篇文章深入全面的讲解了什么是微服务架构。随后,微服务架构逐渐成为一种非常流行的架构模式,一大批的技术框架和文章涌现出来,越来越多的公司借鉴和使用微服务架构相关的技术。

然而微服务并不是万能药,我们在实施的过程中不能简单的使用某些个微服务框架或者组件一蹴而就,而是需要将业务、技术和运维有机结合起来,配合同步实施,并且在此过程中还需要趟过很多的坑才能够取得成功。

本书通过 Dubbo、Spring Cloud、Service Mesh 等技术构建微服务体系,并深入浅出的介绍了微服务架构发展历程、领域驱动设计、稳定性保证的常用手段、分布式事务的一致性方案,以及通过大量的案例探讨微服务落地方案,例如双活体系建设,分布式监控,微服务编排,百亿流量微服务网关的设计与实现,基于支付场景下的微服务改造等,展示了实现微服务架构的完整蓝图,并让读者了解到如何借助于微服务来增强和重构现有的遗留系统。不管你是还没听过或者刚接触过微服务的新手,还是正在尝试借助微服务解放生产力的开发人员或者运维人员,或者是立志于构建高可用可伸缩的微服务体系的架构师,阅读本书,对读者必有裨益。

本书的每一个章节都是相关领域的专家经过多年的技术积累提炼而成,秉承以理论为基础,以大量企业实战案例为核心,深入全面的介绍了微服务架构的实施方法以及在实施过程中所遇到的问题和解决方案,是一本内容详实、“可落地”的理论实践相结合的技术书籍。

内容简介

本书共分为十四章:

第一章:微服务概述

从软件架构的发展历程讲起,分别对单体架构、SOA架构和微服务架构的演进过程做了深入浅出的讲解,同时也深入介绍了微服务架构的特点,本章以宏观的视角为读者打开微服务的大门。

第二章:微服务领域驱动设计

本章介绍了领域驱动设计是什么,常见的领域架构有哪些,如何将领域驱动应用到微服务中,以及如何使用领域驱动进行合理的服务划分等,帮助读者在正式学习微服务前修炼内功。

第三章:Dubbo原理与实现

目前Dubbo已经被阿里巴巴技术团队重新维护并且得到了大力的发展和推广,使用Dubbo依然可以很好的进行微服务建设,本章较为深入的讲解了Dubbo的使用和技巧,以及通过源码的深入分析能够让读者对Dubbo的原理实现有一个全面的认识。

第四章:Spring Cloud实战案例

Spring Boot/Cloud是目前较为流行的微服务框架,本章以大量的实战案例为读者讲解如何才能应用好Spring Cloud框架,以及如何避免在使用过程中遇到的坑。

第五章:微服务稳定性保证常用手段

当业务发展越来越快,规模也越来越大的情况下,我们所面临的就是如何在服务越来越多的情况下保证微服务架构的稳定性,本章带领读者逐步揭开保障稳定性的常用技巧和手段。

第六章:微服务下事务的一致性保证

本章介绍了从本地事务到分布式事务的演变,深入分析了微服务在强一致性场景和最终一致性场景下的解决方案,探讨了二阶段提交协议、三阶段提交协议、TCC 模式、补偿模式、可靠事件模式等。同时,对开源项目的分布式事务进行解读,包括 RocketMQ 和 ServiceComb。

第七章:微服务亿级网关设计

本章从百亿流量交易系统微服务网关(API Gateway)的现状和面临问题出发,阐述微服务架构与 API 网关的关系,理顺流量网关与业务网关的脉络,带来最全面的 API 网关知识与经验。

第八章:微服务编排

本章以Netflix Conductor框架为核心,从框架的使用和原理深入介绍了什么是微服务编排,为微服务执行复杂的业务逻辑提供了一种新的思路。

第九章:微服务统计与数据抽取方案

在微服务架构下,服务必将越来越多,在这各情况下如何进行数据统计和分析将变得非常困难,本章将深入讲解如何从不同服务的数据库中抽取数据到统一的大数据平台中,帮忙使用者更方便的进行数据的统计。

第十章:微服务双活体系建设

在企业发展规模越来越大的情况下,用户对系统的稳定性要求也越来越高,那么单机房布署势必成为发展的瓶颈,本章将带领读者从零开始以实际案例出发进行同城双活的建设。

第十一章:基于支付场景下的微服务改造和性能优化

本章从实际的案例出发,在具体的支付业务场景下,从一个新项目开始逐步讲解如何利用领域驱动划分服务,如何利用微服务框架进行服务治理,以及项目完成后怎样提升微服务架构的性能。

第十二章:遗留系统的微服务改造

本章介绍了遗留系统的微服务架构改造,梳理了代码分层结构的转变,提出一个新的代码分层思路来应对微服务的流行与普及,并深入思考了遗留系统的债券,深入探讨单体系统拆分服务的方法论。同时,对遗留系统的微服务架构改造的解决方案给出 9 个切实可行的核心实践思路。

第十三章:Service Mesh的入门与案例

随着微服务的持续发展,下一代微服务架构已然出现,本章将深入介绍Service Mesh发展历程,以及结合具体案例带领读者使用Istio进行具体实践。

第十四章:微服务监控实战

本章重点介绍APM的原理,从零开始开发APM监控系统,还深入介绍Prometheus的安装和原理,以及如何使用Prometheus进行监控和预警。

 

1.6 架构的不同风格

典型的企业级应用系统或者互联网应用系统一般都是通过Web提供一组业务服务能力。这类系统包括提供给用户操作的、运行于浏览器中、具有UI的业务逻辑展示和输入部分,运行于服务器端、用后端编程语言构建的业务逻辑处理部分,以及用于存储业务数据的关系数据库或其他类型的存储软件。

根据软件系统在运行期的表现风格和部署结构,我们可以粗略地将其划分为两大类:

1) 整个系统的所有功能单元,整体部署到同一个进程(所有代码可以打包成1个或多个文件),我们可以称之为“单体架构”(Monolithic Architecture);

2) 整个系统的功能单元分散到不同的进程,然后由多个进程共同提供不同的业务能力,我们称之为“分布式架构”(Distributed Architecture);

任何一个体系(产品、平台、商业模式等)如果想要发展壮大,途径只有两个模式:
a) 容器模式:从外部提供越来越多的资源和能力,注入到体系的内部,不断的从内扩充自己。单体架构的系统类似这种模式。
b) 生态模式:以自己的核心能力为内核,持续的在外部吸引合作者,形成一个可以不断成长的生态体系。分布式架构越来越像这种模式。

再结合软件系统在整个生命周期的特点,我们可以进一步区分不同的架构风格。

对于单体架构,我们根据设计期和开发实现期的不同模式和划分结构,可以分为:

  • 简单单体模式:代码层面没有拆分,所有的业务逻辑都在一个项目(project)里打包成一个二进制的编译后文件,通过这个文件进行部署,并提供业务能力;
  • MVC模式:系统内每个模块的功能组件按照不同的职责划分为模型(Model)、视图(View)、控制器(Controller)等角色,并以此来组织研发实现工作;
  • 前后端分离模式:将前后端代码耦合的设计改为前端逻辑和后端逻辑独立编写实现的处理模式;
  • 组件模式:系统的每一个模块拆分为一个子项目(subproject),每个模块独立编译打包成一个组件,然后所有需要的组件一起再部署到同一个容器里;
  • 类库模式:A系统需要复用B系统的某些功能,这时可以直接把B系统的某些组件作为依赖库,打包到A系统来使用。

对于分布式架构,我们根据设计期的架构思想和运行期的不同结构,可以分为:

  • 面向服务架构(Service Oriented Architecture,SOA):以业务服务的角度和服务总线的方式(一般是WebService与ESB)考虑系统架构和企业IT治理;
  • 分布式服务架构(Distributed Service Architecture,DSA):基于去中心化的分布式服务框架与技术,考虑系统架构和服务治理;
  • 微服务架构(MicroServices Architecture,MSA):微服务架构可以看做是面向服务架构和分布式服务架构的拓展,使用更细粒度的服务(所以叫微服务)和一组设计准则来考虑大规模的复杂系统架构设计。

此外,传统的企业集成领域的EAI架构模式,本身还是各个系统独立部署,但是各系统之间的部分业务使用特定的技术打通了,因此我们可以看做是单体和分布式之间的过渡状态。

也有人把如上的各个架构风格总结为4个大的架构发展阶段,如图1-6所示:

1)单体架构阶段

2)垂直架构阶段

3)SOA架构阶段

4)微服务架构阶段

 

1.6.1 单体架构:简单单体模式

简单单体模式是最简单的架构风格,所有的代码全都在一个项目中。这样研发团队的任何一个人都可以随时修改任意的一段代码,或者增加一些新的代码。开发人员也可以只在自己的电脑上就可以随时开发、调试、测试整个系统的功能。也不需要额外的一些依赖条件和准备步骤,我们就可以直接编译打包整个系统代码,创建一个可以发布的二进制版本。这种方式对于一个新团队的创立初期,需要迅速开始从0到1,抓住时机实现产品最短时间推向市场,可以省去各种额外的设计,直接上手干活,争取了时间,因而是非常有意义的。

但是这种简单粗暴的方式对于一个系统的长期稳定发展确实有很多坏处的。但是正如一个新出生的小动物野蛮生长,如果没有正确的教导和规则的约束,最后成为一个忠实的导盲犬还是一条携带病毒的狂犬,就不得而知了。

首先,简单单体模式的系统存在代码严重耦合的问题。所有的代码都在一起,就算是按照package来切分了不同的模块,各不同模块的代码还是可以直接相互引用,这就导致了系统内的对象间依赖关系混乱,修改一处代码,可能会影响一大片的功能无法正常使用。为了保障每次上线时的可靠性,我们必须花费很多的精力做大量的回归测试,对于经常需要修改维护的系统,这种代价是可怕的。

第二,简单单体模式的系统变更对部署影响大,并且这个问题是所有的单体架构系统都存在的问题。系统作为一个单体部署,每次发布的部署单元就是一个新版本的整个系统,系统内的任何业务逻辑调整都会导致整个系统的重新打包,部署、停机、再重启,进而导致了系统的停机发布时间较长。每次发布上线都是生产系统的重大变更,这种部署模式大大提升了系统风险,降低了系统的可用性。

第三,简单单体模式的系统影响开发效率。如果一个使用Java的简单单体项目代码超过100万行,那么在一台笔记本电脑上修改了代码后执行自动编译,可能需要等待十分钟以上,并且内存可能不够编译过程使用,这是非常难以忍受的。

第四,简单单体模式打包后的部署结构可能过于庞大,导致业务系统启动很慢,进而也会影响系统的可用性。这一条也是所有单体架构的系统都有的问题。

第五,扩展性受限,也是所有单体架构的一个问题。如果任何一个业务存在性能问题,那么都需要考虑多部署几个完整的实例的集群,或者再加上负载均衡设备,才能保证整个系统的性能可以支撑用户的使用。

所以,简单单体模式比较适用于规模较小的系统,特别是需要快速推出原型实现,以质量换速度的场景。

1.6.2 分布式架构:面向服务架构(SOA)

随着IT技术逐渐成为各行各业的基础性支撑技术之一,并且很多大型公司内部的IT系统规模越来越大,传统架构思想的不足越来越明显。针对如何更好的利用企业内部的各个IT系统能力,解决数据孤岛问题,整合业务功能,先是出现了企业应用集成(Enterprise Application Integration,EAI)解决方案,即通过对现有各系统的数据接口改造,实现系统互通(特别是异构系统),这样不同系统的数据就可以被整合到一起了。在大量的EAI项目实施的基础上,架构设计关注的不仅仅是单个的项目,而是企业的整个IT系统集合。架构师们以超越单体架构的分布式思想和业务服务能力的角度来看待问题,这样面向服务架构即SOA就发展起来了。

2006年IBM、Oracle、SAP、普元公司等一起建立了OSOA联盟,共同制定 SCA/SDO标准。2007年4月,国际标准组织OASIS宣布成立OASIS Open Composite Services Architecture (Open CSA) 委员会,自此,OSOA的职能移转至Open CSA组织。
SOA的概念最初由Gartner公司提出,2000 年以后,业界普遍认识到SOA思想的重要性。从2005年开始,SOA推广和普及工作开始加速,几乎所有关心软件行业发展的人士都开始把目光投向SOA,各大厂商也通过建立厂商间的协作组织共同努力制定中立的SOA标准:SCA/SDO规范。同时产生了一个Apache基金会顶级项目Tuscany作为SCA/SDO的参考实现。SCA和SDO构成了SOA编程模型的基础。经过10多年的广泛探索研究和实际应用,SOA本身的理论、相关技术、工具等也已经发展到成熟、稳定的阶段,在信息化系统建设时普遍采用了SOA架构思想。

1.6.2.1 服务与SOA

面向服务架构(SOA)是一种建设企业IT生态系统的架构指导思想。SOA的关注点是服务。服务最基本的业务功能单元,由平台中立性的接口契约来定义。通过将业务系统服务化,可以将不同模块解耦,各种异构系统间可以轻松实现服务调用、消息交换和资源共享。

1) 从宏观的视角来看,不同于以往的孤立业务系统,SOA强调整个企业IT生态环境是一个大的整体。整个IT生态中的所有业务服务构成了企业的核心IT资源。各系统的业务拆解为不同粒度和层次的模块和服务,服务可以组装到更大的粒度,不同来源的服务可以编排到同一个处理流程,实现非常复杂的集成场景和更加丰富的业务功能。

2) 从研发的视角来看,系统的复用可以从以前代码级的粒度,扩展到业务服务的粒度;能够快速应对业务需求和集成需求的变更。

3) 从管理的角度来看,SOA从更高的层次对整个企业IT生态进行统一的设计与管理,对消息处理与服务调用进行监控,优化资源配置,降低系统复杂度和综合成本,为业务流程梳理和优化提供技术支撑。

在SOA体系下,应用软件被划分为具有不同功能的服务单元,并通过标准的软件接口把这些服务联系起来,以SOA架构实现的企业应用可以更灵活快速地响应企业业务变化,实现新旧软件资产的整合和复用,降低软件整体拥有成本。

1.6.2.2 SOA战略

SOA的实施对整个IT生态环境都有重要的影响,作为一种重大的IT变革和技术决策,必然要自上而下的进行。必须获得管理层的支持,由技术决策层面直接推动,并和技术部门、相关业务部门一起,根据目前各个IT业务系统的现状,统一规划SOA战略和分阶段目标,制定可行方案与计划步骤,逐步推进实施。

1.6.2.3 SOA落地方式

SOA的落地方式与水平,跟企业IT特点、服务能力和发展阶段直接相关。目前常见的落地方式主要有分布式服务化和集中式管理两种。

1) 分布式服务化
互联网类型的企业,业务与技术发展快,数据基数与增量都大,并发访问量高,系统间依赖关系复杂、调用频繁,分布式服务化与服务治理迫在眉睫。通过统一的服务化技术手段,进一步实现服务的注册与寻址、服务调用关系查找、服务调用与消息处理监控、服务质量与服务降级等等。现有的一些分布式服务化技术有dubbo(基于java)、finagle(基于scala)和ICE(跨平台)等。

2) 集中式管理化
传统企业的IT内部遗留系统包袱较重,资源整合很大一部分是需要打通新旧技术体系的任督二脉,所以更偏重于以esb作为基础支撑技术,以整合集成为核心,将各个新旧系统的业务能力逐渐的在ESB容器上聚合和集成起来。比较流行的商业ESB有IBM的WMB和oracle的osb,开源esb有mule、servicemix、jbossesb、wso2esb和openesb。

商业的esb,一般来说除了功能丰富以外,配套设置都比较齐全,对于比较简单的场景来说可以做到开箱即用,维护性也比较强,但是一般来说过于复杂非常难用、内部基本是黑盒、而且很贵。
开源的esb,由于开发成本和通用性开放性的考虑,往往在esb server上做的比较强大、扩展性比较好,但是配套设置做的很差(这也是绝大多数开源项目共有的问题,不仅是开源esb的问题)。对企业来说可管理性非常重要,选择开源esb的话,这一块需要结合企业的实际情况,一步步的积累,下大功夫来自己做好。

一方面,集中式管理的SOA,其优势在于管理和集成企业内部各处散落的业务服务能力,同时一个明显的不足在于其中心化的架构方法,并不同解决各个系统自己内部的问题。另一方面,随着自动化测试技术、轻量级容器技术等相关技术的发展,分布式服务技术越来越像微服务架构方向发展。

EIP(Enterprise Integration Patterns,企业集成模式)是集成领域的圣经,也是各种MOM和ESB的理论基础。我们在MQ和ESB中常见的各种概念和术语,基本都是来自于EIP,比如消息代理、消息通道、消息端点、消息路由、消息转换、消息增强、信息分支、消息聚合、消息分解、消息重排等等,并在《企业集成模式:设计、构建及部署消息传递解决方案》一书中详细的描述了它们的内容与特点。
EIP的直接实现一般叫EIP框架,开源的知名EIP框架有两个:camel和spring integration。EIP可以作为ESB的基础骨架,在这个基础上填充其他必要的部分,定制出来一个ESB容器。
EIP的介绍可以看这里:http://www.enterpriseintegrationpatterns.com/

1.6.2.4 SOA的两大基石:RPC与MQ

SOA关注于系统的服务化,不同系统服务间的相互通信就成为了一个重要的话题。并且随着RPC和MQ技术的发展,这两种技术逐渐成为SOA的两大基石,也是分布式技术体系里的重要基础设施。

1) RPC(Remote Procedure Call,远程过程调用)
两个不同系统间的数据通信,往往可以通过socket+自定义数据报文来实现。但是这种方式比较繁琐,需要针对每个通信场景定义自己的数据格式和报文标准,甚至交互的行为、异常和错误的处理等等。有没有一种通用的技术手段呢?答案就是RPC技术。
RPC是一种通用性的系统通信手段,使得我们可以像调用本地方法一样调用远程系统提供的方法。
一个场景的RPC机制如图1-7:

RPC的调用关系里,我们把提供具体的调用方法的系统叫服务提供者(Provider),调用服务的系统称为服务消费者(Consumer)。把对象转换为以便于网络传输的二进制或文本数据的过程,叫做序列化(Serialization);二进制或文本数据再还原为对象的过程,叫做反序列化(Deserialization)。
我们可以看到,典型的RPC处理机制包括两部分:

  • 通信协议,可以是基于tcp的,也可以是基于http的。
  • 数据格式,一般是一套序列化+反序列化机制。

常见的RPC技术有Cobra、RMI、.NET Remoting、WebService、JSON-RPC、XML-RPC、Hessian、Thrift、Protocol Buffer、gRPC等等。按照序列化机制的特点,我们可以把RPC技术分为文本的(WebService、JSON-RPC、XML-RPC等)和二进制的(RMI、Hessian、Thrift、Protocol Buffer等)。按照常见的通信协议来看,我们又可以分为基于HTTP的(WebService、Hessian等)和基于TCP的(RMI、.NET Remoting等)。按照是否可以用于多个不同平台,又可以分为平台特定的(RMI是Java平台特定的、.NET Remoting是.NET平台特定的)和平台无关的(比如WebService、JSON-RPC、Hessian等可以用于http://Java.Net\PHP\Python等就是平台无关的)。
在Java里,我们一般可以基于JDK自带的动态代理机制+Java的对象序列化方式实现一个简单的RPC,但是由于动态代理和Java对象序列化都比较低效,导致这种方式性能较低。目前更常见的是基于AOP和代码生成技术实现stub和skeleton,然后用一个紧凑的二进制序列化方式,实现一个高效的RPC框架。

按照调用方式来看,RPC有四种模式:

  • RR(Request-Response)模式,又叫请求响应模式,指每个调用都要有具体的返回结果信息。
  • Oneway模式,又叫单向调用模式,调用即返回,没有响应的信息。
  • Future模式,又叫异步模式,返回拿到一个Future对象,然后执行完获取到返回结果信息。
  • Callback模式,又叫回调模式,处理完请求以后,将处理结果信息作为参数传递给回调函数进行处理。

这四种调用模式中,前两种最常见,后两种一般是RR和Oneway方式的包装,所以从本质上看,RPC一般对于客户端的来说是一种同步的远程服务调用技术。与其相对应的,一般来说MQ恰恰是一种异步的调用技术。

2) MQ(Message Queue,消息队列)
异步的远程调用,如果能同时存在很多个请求,该如何处理呢?进一步地,由于不能立即拿到处理结果,假若需要考虑失败策略,重试次数等,应该怎么设计呢?
如果有N个不同系统相互之间都有RPC调用,这时候整个系统环境就是一个很大的网状结构,依赖关系有N*(N-1)/2个。任何一个系统出问题,都会影响剩下N-1个系统,怎么降低这种耦合呢?如图1-8所示:

基于这些问题,我们发展出来了消息队列(MQ)技术,所有的处理请求先作为一个消息发送到MQ(一般我们叫做broker),接着处理消息的系统从MQ拿到消息并进行处理。这样就实现了各个系统间的解耦,同时可以把失败策略、重试等作为一个机制,对各个应用透明,直接在MQ与各调用方的应用接口层面实现即可,如图1-9所示:

一般来说,我们把发送消息的系统称为消息生产者(message producer),接受处理消息的系统称为消息消费者(message consumer)。

根据消息处理的特点,我们又可以总结两种消息模式:

 

  • 点对点模式(Point to Point,PTP),一个生产者发送的每一个消息,都只能有一个消费者能消费,看起来消息就像从一个点传递到了另外一个点。
  • 发布订阅模式(Publish-Subscribe,PubSub),一个生产者发送的每一个消息,都会发送到所有订阅了此队列的消费者,这样对这个消息感兴趣的系统都可以拿到这个消息。

通过这两种消息模式的灵活应用以及功能扩展,我们可以实现各种具体的消息应用场景,比如高并发下的订单异步处理,海量日志数据的分析处理等等。如果要总结一下消息队列在各类架构设计中能起到的作用,一般有如下几点:

  • 为系统增加了通用性的异步业务处理能力,这个前面讨论过了。
  • 降低系统间的耦合性,无论是开发期的引用关系依赖,还是运行期的调用关系依赖,都明显简化或降低了。通信的双方只需要定义好消息的数据格式(消息头有什么字段,消息体是什么格式的数据),就可以各自开发和测试,最后再各自上线即可集成到一起。
  • 提升了系统间通信可靠性,无论是从通信本身的可靠性上(请求响应机制、重试),还是业务意义上(处理顺序、事务、失败策略),都相比RPC等方式有所增强。
  • 提升了系统的业务缓冲能力,一般又叫削峰填谷,指的是经过MQ做为中间的缓冲,如果业务量突然增大时可以先把处理请求缓冲到队列中,再根据业务消费处理能力逐个消息处理,保障了系统不会因为突然爆发的大量请求而过载瘫痪,影响系统的连续服务能力。
  • 增强了系统的扩展能力,通过消息队列处理的业务,消费端的处理能力如果不够,一般可以随时多加几个消费者来处理,从而可以直接扩展系统的业务处理能力,而不需要额外的代价。

1.6.3 分布式架构:微服务架构(MSA)

随着目前互联网的飞速发展,我们发现大型项目的设计开发和维护过程中,存在如下几个重点的困难点:

  • 扩容困难

我们之前开发项目用的是虚拟机,每次上线项目需要加机器总会遇到资源不足的情况,还要走非常复杂工单审批流程,还要与运维人员不断PK,才能申请下来资源,整个流程冗长,机器资源申请困难。

  • 部署困难
    每次上线采用专门的人进行布署,上线之前需要与上线人员沟通上线的环境,防止上线出错。
  • 发布回滚困难
    每次上线发现问题后,需要重新从SVN/GIT主干上面进行代码编译,但是有时候会因为各种问题回滚失败,而且重新编译很耗时导致回滚缓慢。
  • 适配新技术困难
    如果打算在不同的模块采用不同的语言开发,或者想在架构中做技术升级都很困难或者不支持。
  • 快速开发困难
    复杂项目中采用单体应用或者简单的分拆成2-3个系统,里面集成了太多功能模块,无法快速进行功能开发并且很容易牵一发动全身。
  • 测试困难
    测试人员没有自动化测试框架,或者Mock系统,导致只能采用简单的人工测试流程,而且还经常发生功能覆盖不全面等问题。
  • 学习困难
    业务变化日新月薪,功能和项目结构都太复杂,整个项目中的逻辑关系相互关联影响,采用的技术五花八门,技术本身的更新换代也很快,导致技术人员学习曲线非常陡峭。

我们把遇到以上这些问题的项目也叫做单体项目。

1.6.3.1 什么是微服务

The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services , which may be written in different programming languages and use different data storage technologies.

引用自http://martinfowler.com/articles/microservices.html 通过Martin Flowler的这段微服务描述,可以抽象出以下几个关键点:

  • 由一些独立的服务共同组成应用系统
  • 每个服务单独布署、独立跑在自己的进程中
  • 每个服务都是独立的业务
  • 分布式管理

通过几个关键点可以看出微服务重在独立布署和独立业务,而所谓的微服务,并不是越小越好,而是通过团队规模和业务复杂度由粗到细的划分过程,所遵循的原则是松耦合和高内聚,如图1-10所示:

 

  • 松耦合
    修改一个服务不需要同时修改另一个,每个微服务都可以单独修改和布署
  • 高内聚
    把相关的事务放在一起,把不相关的排除出去,聚集在一起的事务只能干同一件事

1.6.3.2 微服务和SOA的区别

1、微服务只是一种为经过良好架构设计的SOA解决方案,是面向服务的交付方案。

2、微服务更趋向于以自治的方式产生价值。

3、微服务与敏捷开发的思想高度结合在一起,服务的定义更加清晰,同时减少了企业ESB开发的复杂性。

4、微服务是SOA思想的一种提炼!

5、SOA是重ESB,微服务是轻网关。

1.6.3.3 大规模使用微服务

使用微服务也就面临着由单体项目向微服务项目过渡,而采用了微服务架构后也就意味着服务之间的调用链路会比以前延长了很多,在调用链路上发生故障的几率也就随之增大,同时调用链路越长,性能越会受影响。微服务架构中是存在很多陷阱的,并不是简单的拿来使用就可以,所以企业要大规模使用微服务不仅仅是从思想和业务上面进行合理划分,还需要诸多技术组件以及高效的运维来协同合作,如图1-11所示。

 

  • 防止雪崩

当一个服务无法承受大请求压力的时候,是否会影响所依赖的其他服务?这时候可以考虑限流等措施。

  • 功能降级

当某个服务出现故障时,是否有容错手段能够让业务继续跑下去,而不影响整体应用。

  • 冥等

当用户多次下同一订单时,得到的结果永远同一个。

  • 缓存

当请求量较大时,为避免对数据库造成较大压力,可以适当将一些变化较小,读取量较大的数据放入缓存。

  • 超时

超时时间对于调用服务来说非常重要,超时时间设置太长可能会把整体系统拖慢,而设置短了又会造成调用服务未完成而返回,我们在实际工作中需要根据业务场景进行分析,选择一个恰当的超时设定值。

  • 熔断

使用熔断器(断路器),当请求下游的服务时发生了一定数量的失败后,熔断器打开,接下来的请求快速返回失败。过一段时间后再来查看下游服务是否已恢复正常,重置熔断器。

  • 服务隔离

当所调用的服务发生故障的时候,上游服务能够隔离故障确保业务能够继续运行下去

  • 可伸缩

当并发量较大,原有服务集群无法满足现有业务场景时,可以采用扩容策略,而当并发量较小时,服务集群可以采用缩容策略,以节省资源。

微服务架构是解决企业 IT 长期演进的一种方案,适用于迭代很快的系统,10年不变的系统就算了。

  • 什么是微服务

简述 Martin Flower 大神的系统阐述:

  1. 微服务是一种架构风格,也是一种服务;
  2. 微服务的颗粒比较小,一个大型复杂软件应用由多个微服务组成,比如Netflix目前由500多个的微服务组成;
  3. 它采用UNIX设计的哲学,每种服务只做一件事,是一种松耦合的能够被独立开发和部署的无状态化服务(独立扩展、升级和可替换)。

微服务架构示例

采用微服务架构的主要收益:

  1. 效率高:一个微服务基本是一个能独立发布的应用服务,因此可以作为独立组件升级、灰度或复用等,对整个大应用的影响也较小,每个服务可以由专门的组织来单独完成,依赖方只要定好输入和输出口即可完全开发,甚至整个团队的组织架构也会更精简,因此沟通成本低、效率高。
  2. 灵活性:根据业务的需求,不同的服务可以根据业务特性进行不同的技术选型,是计算密集型还是I/O密集型应用都可以依赖不同的语言编程模型,各团队可以根据本身的特色独自运作。
  3. 高可用:服务在压力较大时,也可以有更多容错或限流服务。

微服务架构确实有很多吸引人的地方,然而它的引入也是有成本的,它并不是银弹,使用它会引入更多技术挑战,比如性能延迟、分布式事务、集成测试、故障诊断等方面,企业需要根据业务的不同的阶段进行合理的引入,不能完全为了微服务而“微服务”

* 以上内容摘自:《云原生应用架构实践》,本书第5章也会对如何解决微服务技术挑战提供不同的方案。

  • 怎么做微服务

微服务,就是系统划分成非常小的模块,而且这些模块都可以通过一种标准的服务接口进行沟通。我们做软件的,要向人类社会学习。为什么我们人类社会有这么发达的文明呢。是因为我们基于人这个最小的单位,设计了标准的语言、文字、货币、法律。微服务技术平台,也需要基于微服务这个基本单元,构建多维度完整的解决方案,让企业的架构就可以像人类社会一样持续发展。

完整的解决方案,网易云认为,应该包括微服务治理、API 网关、容器服务、DevOps、AIOps、和测试服务等 6 个模块,所以,网易云轻舟微服务的功能是这样设计的:

微服务(Microservices Architecture)是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

 

单体架构(Monolithic Architecture )

企业级的应用一般都会面临各种各样的业务需求,而常见的方式是把大量功能堆积到同一个单体架构中去。比如:常见的ERP、CRM等系统都以单体架构的方式运行,同时由于提供了大量的业务功能,随着功能的升级,整个研发、发布、定位问题,扩展,升级这样一个“怪物”系统会变得越来越困难。

 

这种架构模式就是把应用整体打包部署,具体的样式依赖本身应用采用的语言,如果采用java语言,自然你会打包成war包,部署在Tomcat或者Jetty这样的应用服务器上,如果你使用spring boot还可以打包成jar包部署。其他还有Rails和Node.js应用以目录层次的形式打包

上图:单体架构

 

大部分企业通过SOA来解决上述问题,SOA的思路是把应用中相近的功能聚合到一起,以服务的形式提供出去。因此基于SOA架构的应用可以理解为一批服务的组合。SOA带来的问题是,引入了大量的服务、消息格式定义和规范。

 

多数情况下,SOA的服务直接相互独立,但是部署在同一个运行环境中(类似于一个Tomcat实例下,运行了很多web应用)。和单体架构类似,随着业务功能的增多SOA的服务会变得越来越复杂,本质上看没有因为使用SOA而变的更好。图1,是一个包含多种服务的在线零售网站,所有的服务部署在一个运行环境中,是一个典型的单体架构。

 

单体架构的应用一般有以下特点:

 

设计、开发、部署为一个单独的单元。

会变得越来越复杂,最后导致维护、升级、新增功能变得异常困难

很难以敏捷研发模式进行开发和发布

部分更新,都需要重新部署整个应用

水平扩展:必须以应用为单位进行扩展,在资源需求有冲突时扩展变得比较困难(部分服务需要更多的计算资源,部分需要更多内存资源)

可用性:一个服务的不稳定会导致整个应用出问题

创新困难:很难引入新的技术和框架,所有的功能都构建在同质的框架之上

运维困难:变更或升级的影响分析困难,任何一个小修改都可能导致单体应用整体运行出现故障。

微服务架构的核心思想是,一个应用是由多个小的、相互独立的、微服务组成,这些服务运行在自己的进程中,开发和发布都没有依赖。不同服务通过一些轻量级交互机制来通信,例如 RPC、HTTP 等,服务可独立扩展伸缩,每个服务定义了明确的边界,不同的服务甚至可以采用不同的编程语言来实现,由独立的团队来维护。简单的来说,一个系统的不同模块转变成不同的服务!而且服务可以使用不同的技术加以实现!

1 基于Consul的服务注册与发现

Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,比如 Airbnb的SmartStack等相比,Consul的方案更“一站式”,内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等),使用起来也较 为简单。

Consul用Golang实现,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与Docker等轻量级容器可无缝配合

2 基于Ocelot实现API网关服务

Ocelot是一个使用.NET Core平台上的一个API Gateway,这个项目的目标是在.NET上面运行微服务架构。Ocelot框架内部集成了IdentityServer(身份验证)和Consul(服务注册发现),还引入了Polly来处理进行故障处理。目前,腾讯和微软是Ocelot在官网贴出来的客户。

3 基于Polly+AspectCore实现熔断与降级机制

Polly是一个被.NET基金会认可的弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略,其主要功能如下:

  • 功能1:重试(Retry)
  • 功能2:断路器(Circuit-Breaker)
  • 功能3:超时检测(Timeout)
  • 功能4:缓存(Cache)
  • 功能5:降级(Fallback)

Polly的策略主要由“故障”和“动作”两个部分组成,“故障”可以包括异常、超时等情况,“动作”则包括Fallback(降级)、重试(Retry)、熔断(Circuit-Breaker)等。策略则用来执行业务代码,当业务代码出现了“故障”中的情况时就开始执行“动作”。

4 基于IdentityServer建立授权与验证服务

IdentityServer4(这里只使用版本号为4)是一个基于OpenID Connect和OAuth 2.0的针对http://ASP.NET Core 2.0的框架。IdentityServer是将规范兼容的OpenID Connect和OAuth 2.0终结点添加到任意http://ASP.NET Core应用程序的中间件。通常,你构建(或重新使用)包含登录和注销页面的应用程序,IdentityServer中间件会向其添加必要的协议头,以便客户端应用程序可以使用这些标准协议与其对话。

5 基于Exceptionless实现分布式日志记录

Exceptionless 是一个开源的实时的日志收集框架,它可以应用在基于 http://ASP.NEThttp://ASP.NET Core,Web API,Web Forms,WPF,Console,http://ASP.NET MVC 等技术开发的应用程序中,并且提供了REST接口可以应用在 Javascript,Node.js 中。它将日志收集变得简单易用并且不需要了解太多的相关技术细节及配置,对于微服务架构的应用程序来说,统一的日志收集系统的建立更是有必要。

6 基于Ocelot+SkyWalking实现分布式追踪

微服务的特点决定了功能模块的部署是分布式的,以往在单应用环境下,所有的业务都在同一个服务器上,如果服务器出现错误和异常,我们只要盯住一个点,就可以快速定位和处理问题,但是在微服务的架构下,大部分功能模块都是单独部署运行的,彼此通过总线交互,都是无状态的服务,这种架构下,前后台的业务流会经过很多个微服务的处理和传递,我们会面临以下问题:

  • 分散在各个服务器上的日志怎么处理?
  • 如果业务流出现了错误和异常,如何定位是哪个点出的问题?
  • 如何快速定位问题?
  • 如何跟踪业务流的处理顺序和结果?

  以前在单应用下的日志监控很简单,在微服务架构下却成为了一个大问题,如果无法跟踪业务流,无法定位问题,我们将耗费大量的时间来查找和定位问题,在复杂的微服务交互关系中,我们就会非常被动。因此,我们需要对其进行追踪!

SkyWalking-netcore是一个使用Open Tracing规范来设计追踪数据的开源追踪组件,只需要做很少的配置即可对经过网关的所有API服务进行Tracing。

7 基于Apollo实现统一配置中心

 

在微服务架构环境中,项目中配置文件比较繁杂,而且不同环境的不同配置修改相对频繁,每次发布都需要对应修改配置,如果配置出现错误,需要重新打包发布,时间成本较高,因此需要做统一的配置中心,能做到自动更新配置文件信息,解决以上问题。

Apollo(阿波罗)是携程框架部门研发的配置管理平台,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。其服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。

到这里,基本上一个微服务架构的组件齐活儿了,当然还缺docker、k8s、jenkins等持续部署工具,还需要解决分布式锁、分布式事务、一致性问题等。微服务架构是一个全新的架构模式,内里的东西是非常非常非常多的,欢迎感兴趣的小伙伴儿私信交流,共同进步!

简单地说,微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行通信协作。被拆分成的每一个小型服务都围绕着系统中的某一项或一些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发、自动化测试案例以及独立部署机制。由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。

与单体系统的区别

在以往传统的企业系统架构中,我们针对一个复杂的业务需求通常使用对象或业务类型来构建一个单体项目。在项目中我们通常将需求分为三个主要部分:数据库、服务端处理、前端展现。在业务发展初期,由于所有的业务逻辑在一个应用中,开发、测试、部署都还比较容易且方便。但是,随着企业的发展,系统为了应对不同的业务需求会不断为该单体项目增加不同的业务模块;同时随着移动端设备的进步,前端展现模块已经不仅仅局限于Web的形式,这对于系统后端向前端的支持需要更多的接口模块。单体应用由于面对的业务需求更为宽泛,不断扩大的需求会使得单体应用变得越来越臃肿。单体应用的问题就逐渐凸显出来,由于单体系统部署在一个进程内,往往我们修改了一个很小的功能,为了部署上线会影响其他功能的运行。并且,单体应用中的这些功能模块的使用场景、并发量、消耗的资源类型都各有不同,对于资源的利用又互相影响,这样使得我们对各个业务模块的系统容量很难给出较为准确的评估。所以,单体系统在初期虽然可以非常方便地进行开发和使用,但是随着系统的发展,维护成本会变得越来越大,且难以控制。

为了解决单体系统变得庞大臃肿之后产生的难以维护的问题,微服务架构诞生了并被大家所关注。我们将系统中的不同功能模块拆分成多个不同的服务,这些服务都能够独立部署和扩展。由于每个服务都运行在自己的进程内,在部署上有稳固的边界,这样每个服务的更新都不会影响其他服务的运行。同时,由于是独立部署的,我们可以更准确地为每个服务评估性能容量,通过配合服务间的协作流程也可以更容易地发现系统的瓶颈位置,以及给出较为准确的系统级性能容量评估。

如何实施微服务

在实施微服务之前,我们必须要知道,微服务虽然有非常多吸引人的优点,但是也因为服务的拆分引发了诸多原本在单体应用中没有的问题。

运维的新挑战:在微服务架构中,运维人员需要维护的进程数量会大大增加。有条不紊地将这些进程编排和组织起来不是一件容易的事,传统的运维人员往往很难适应这样的改变。我们需要运维人员有更多的技能来应对这样的挑战,运维过程需要更多的自动化,这就要求运维人员具备一定的开发能力来编排运维过程并让它们能自动运行起来。

接口的一致性:虽然我们拆分了服务,但是业务逻辑上的依赖并不会消除,只是从单体应用中的代码依赖变为了服务间的通信依赖。而当我们对原有接口进行了一些修改,那么交互方也需要协调这样的改变来进行发布,以保证接口的正确调用。我们需要更完善的接口和版本管理,或是严格地遵循开闭原则。

分布式的复杂性:由于拆分后的各个微服务都是独立部署并运行在各自的进程内,它们只能通过通信来进行协作,所以分布式环境的问题都将是微服务架构系统设计时需要考虑的重要因素,比如网络延迟、分布式事务、异步消息等。

尽管微服务架构有很多缺点和问题,但是其实现的敏捷开发和自动化部署等优点依然被广大优秀的架构师和开发着青睐。所以解决这些问题时这些年诸多架构大师努力的目标。

在架构师对于一个大型系统的设计与实施的过程中,面对环境、资源、团队等各种因素的影响,几乎不会出现完全相同的架构设计。对于微服务架构而言更是如此,由于并没有一个标准或正式的定义,每位架构师都根据自身的理解与实际情况进行设计,并在发展过程当中不断演化与完善。经过多年的发展,Martin Fowler在Microservices一文中,提炼出了微服务架构的九大特性,用于指导大家设计架构。

服务组件化、按业务组织团队、做“产品”的态度、智能端点与哑通道、去中心化治理、去中心化管理数据、基础设施自动化、容错设计、演进式设计。

 

小故事 大白话 什么是微服务?为什么要有微服务?微服务中为啥会有那么多组件?

  • 为什么要有微服务呢?
  • 什么是微服务?
  • SpringCloud 中为什么会有那么多的组件?

……

作为SpringCloud教程的第一篇,不讲解具体的技术使用,通过一个通俗易懂的小故事,来解决这些疑惑。

本文分为三个部分:

  1. 架构的演变,即为什么会出现微服务技术
  2. 什么是微服务,即微服务的标准概念
  3. 微服务要解决什么问题,即微服务中那么多的组件都是干嘛的

从单体到微服务「小故事讲解架构演变」 

新技术会站在老技术的基础上,解决老技术出现的问题的同时,进行迭代和演化

这年,可能是十年前也可能是十五年前,小鹿入职了一家处于萌芽期的电商公司—并夕夕商城。

这个时候公司初创,人少,事儿少,用户少,当然了老板的钱也少,本着多快好省的信念,作为公司唯一开发工程师小鹿,跌跌撞撞的开发了一款能用的商城网站,架构如下:

网站整体非常的简单,在没什么用户的现阶段也是非常的好用,而且还非常的省心,但是没有想到的是,公司业务越来越好,用户量是越来越大,随着访问量的不断增大,项目经常卡死故障。

于是老板大手一挥,指引商城技术改革,emmm,还加钱招人,又招了小羊,小马数位同事,对并夕夕商城进行升级优化。

经过激烈的讨论,优化方向为:增加应用负载能力,即负载均衡,应用服务器集群

于是,噔噔蹬蹬,新的架构出现了

负载均衡

增加负载均衡之后,应用服务器不再是系统的瓶颈了,可以灵活的随着访问量增大的同时增加应用服务器集群的数量。

但是,时间长了,数据库出问题了,由于数据量的不断增加,再加上促销,日志等新业务模块的出现,数据库存取出现了问题,一个数据库能够承受的人生压力毕竟是有限的。

于是老板大手一挥,指引商城技术改革,emmm,又加钱招人,又招了小牛,小明等数位同事,对并夕夕商城进行升级优化。

经过激烈的讨论,优化方向为:数据库读写分离

于是,噔噔蹬蹬,新的架构出现了

读写分离

通过将数据库进行集群,读写分离,让数据库能够承受的压力得到大幅提升,但是随着对业务的进一步深根细作,新的问题暴露了。

  • 新增加的商品搜索功能,使用数据库的模糊查询,效率低下,且查询结果不准确
  • 不同模块的数据访问热度不一样,有部分数据,例如首页数据,需要频繁的进行查询展示,每次都查询数据库效率太低
    ……

于是老板大手一挥,指引商城技术改革,emmm,又加钱招人,又招了数位同事,对并夕夕商城进行升级优化。

经过激烈的讨论,优化方向为:引入全文搜索,Redis等技术。

于是,噔噔蹬蹬,新的架构出现了

ES+Redis集群

新的架构一切看上去都是这么完美的亚子,团队众人终于可以过个好年了。

岁月静好。

随着并夕夕商城不断壮大,公司迎来了风投,风投两个亿,于是商城发展的更快了,新的问题出现了。

什么问题呢?

  • 不同的业务模块之间代码耦合度太高,一个模块出问题,整个项目宕机
  • 维护困难,每次代码更新都要对所有的服务器进行重新的部署
  • 有些业务模块的用户访问量实在太小,没有必要部署在多台服务器上
    ……

于是老板大手一挥,指引商城技术改革,emmm,有钱了就要做一些符合土豪身份的枯燥事情,大手一挥,挥金如土直接买了一个大牛团队来对商城进行技术优化。

优化方向:服务化。

服务化

所谓服务化,就是将公司的项目按照模块来进行分割,把每个模块都做成一个可以独立运行,单独部署的的应用程序,如图所示:

订单,商品,首页,促销等,每一个业务模块都是一个独立的应用程序,我们把这样按照模块划分的应用程序称之为服务。

  • 可以根据需要独立的部署在服务器上,首页模块被访问的比较多,就可以多部署几个
  • 可以独立的访问数据库,每个服务都可以有自己的数据库
    ……

等等等,好处不要太多。这样情况我们实际上也称之为微服务

服务化要解决的问题?「更多问题到来」 

当项目进行服务化改造的时候,这个过程并不是一蹴而就,一拍脑袋就成功了。要把项目服务化,需要解决很多的问题,例如:

  1. 服务之间怎么调用?订单服务想要调用到商品服务的数据,怎么调用?怎么调用更加的稳定,更加高效?【服务调用技术】
  2. 服务之间怎么负载均衡?订单服务要调用商品服务,商品服务可能有很多个,怎么负载均衡【负载均衡技术】
  3. 服务怎么被管理?服务怎么定位?有故障了怎么处理?【服务注册与发现技术】
  4. 故障怎么监控?微服务系统中业务模块很多,组件也很多,不同组件的指标不同,那么这些组件怎么进行监控【监控技术】
  5. 故障怎么定位?微服务架构中,一个用户的请求会涉及到多个内部服务的调用,那么如何定位问题呢?【链路追踪技术】
  6. 日志怎么分析处理?业务模块多了,日志也就多了,直接查看日志文件已经变的不显示了,那么如何对日志进行分析查找呢?【日志分析技术】
  7. 权限管理?微服务拆分服务之后,会有很多服务对外暴露接口,这些接口如何进行统一的权限处理呢?【网关技术】
  8. 服务调用出现问题怎么处理?当一个服务因为各种原因停止响应时,调用方通常会等待一段时间,然后超时或者收到错误返回。如果调用链路比较长,可能会导致请求堆积,整条链路占用大量资源一直在等待下游响应。怎么解决呢?【熔断,降级,限流】

还有测试,自动化部署等等问题,都随着微服务的出现到来了,上面的每个问题要进行解决都需要在项目中引入一个或者多个新技术,而这些新技术我们一般称之为组件,也是微服务学习的重点,一整套技术,一套解决上述所有问题的解决方案。

上面出现的问题,在此处我们暂时一笔带过,在所有的教程中,再进行详细的分析和讲解。

什么是微服务【重点】 

the microservice architectural style [1] is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

  • 每个服务可独立运行在自己的进程里
  • 一系列独立运行的微服务共同构建起整个系统
  • 每个服务为独立的业务开发,一个微服务只关注某个特定的功能,例如订单管理,用户管理
  • 微服务之间通过一些轻量的通信机制进行通信,例如Restful API进行调用
  • 可以使用不同的编程语言与数据存储技术开发

官网链接https://www.martinfowler.com/articles/microservices.html

 

最正宗的解释(维基百科的解释)

微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。

微服务的起源是由 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) 能力,服务可以用不同的编程语言与数据库等组件实现。

简单的理解:

微服务架构的系统是一个分布式的系统,按业务进行划分为独立的服务单元,解决单体系统的不足,同时也满足越来越复杂的业务需求。

 

相比于传统集中式的应用系统,微服务的优点

  • 每个服务独立存在,所以可以单独部署,不用每次发布某个功能都经历一次全服务发布。
  • 遵循单一功能原则,服务之间可以通过RESTFUL或者RPC调用,功能解藕
  • “细粒度” 的高可扩展性,每个服务都可以单独扩展,单独负载均衡
  • 去中心化,尽可能地实现 “自服务”
  • 有利于简化单独的开发测试以及部署,对开发团队友好

微服务缺点

  • 服务的可用性和维护性高度依赖于服务治理,如果治理得不好将会是灾难
  • 某些服务可能造成性能瓶颈,某些服务的宕机可能导致很多服务受影响
  • 服务配置繁琐

 

微服务框架对比

如果架构世界中也存在热搜的话,那么微服务必须是热门第一。微服务是一种服务导向型的软件结构,它之所以如此受技术咖的欢迎,在于它改进了模块化、减少了测试负担、更好的功能组成以及隔离和开发团队的高自主权。

随着移动互联网的发展和应用云化的普及,微服务已经成为企业应用服务化架构最流行的设计理念。以微服务、容器、DevOps等为支撑的云原生设计理念,缓解了随着新需求的不断增加,大型单体式应用变更越来越困难的现状,与移动互联网时代下对企业IT架构高效稳定、敏捷响应的要求之间的矛盾。

一、微服务推行的方式

企业在推行微服务架构时,主要有以下两种方案:

第一个是演进式方案。这个方案是在现有的应用架构上进行演进化的改造。在演进过程中,根据应用的实际需求,逐步引入微服务的组件,最终实现微服务平台的搭建。优势很明显,搭建的服务平台是按需定制的,微服务的文化也随着演进深入企业文化。适用于规模迅速膨胀的初创企业,而且对企业的自动化测试和持续交付能力有一定的要求。

第二个是服务平台建设方案。建设支持微服务应用架构的服务平台,通过平台的试点项目的示范作用,在组织内部推动微服务化改造。微服务平台通常包括服务治理框架,开发框架,容器,部署发布和日志监控工具等。平台可以有效降低微服务开发的门槛,提高开发效率和开发服务的质量。

对于大型企业,由于系统多分工较细,不同部门对新技术的理解和接受能力不同,采用第一种方式进行建设的时候,容易出现技术分化,就是组织内形成多种完全不同微服务平台技术栈,这些平台采用不同的协议和接口,需要在对接上花费大量的资源,不利于内部服务的打通。

二、微服务的实施门槛

企业实施微服务架构是有“门槛”的,并不是简单的技术组件堆砌,要构建微服务架构平台,首先得拥有超过这条基准线的“身高”。

1、平台就绪:在容器平台和微服务框架之上,提供一个开发管理平台。开发管理包括以下的能力:契约管理、打包管理、部署管理、代码工程管理(内部的http://Start.spring.io),应用架构管理和CI工具自动对接等。让微服务研发过程可视化、工具化、自动化,让管理者能够实时管控和规范微服务研发过程。

2、微服务实施能力就绪:包括认知能力、技术能力,交付能力。项目在上微服务架构前,需要进行相应的培训,避免由于不合理的设计,导致生产问题。培训的内容可以是业界的优秀实践,比如12 Factors的云原生开发建议,也可以是开发过程中的案例。

3、建立和微服务相对应的小团队机制:控制团队的规模,根据团队的分工来划分微服务。微服务接口定义标准化,服务拆分按照业务逻辑拆分,服务之间架构合理,实现服务的弹性、自治、容错等能力。同时可以参考DDD(领域驱动设计)的一些方法来帮助设计。

4、避免过度设计,因为微服务而微服务:微服务是工具而不是目标。微服务是服务设计架构方法,微服务开发、运维、监控平台等是工具。微服务设计的目标是更好的支持企业业务应用的敏捷创新和变更需求。传统应用可以处理的技术问题,就不建议使用微服务。

三、微服务部署的关键

微服务架构无疑是好的,但在企业实施部署过程中,如何将这些微服务科学地部署在IT基础架构上,并保证各个微服务的高效运行,需要抓住关键点:

1、动态平衡:微服务的识别

我们的经验是,不必纠结于微服务怎样拆分最合理,因为企业的业务和管理要求在不断变化和提升,在微服务的设计和实施过程中,不断寻找业务拆分与软件架构设计的平衡点才是微服务拆分的必由之路。

2、构建平台:微服务的管理

通过构建服务管理平台的方式,支撑微服务全生命周期的可视化管理。

3、新旧兼容:微服务与现有系统整合

简单来说,就是传统系统负责系统间的信息交互,而微服务架构则负责每一个微服务内部的信息交互。

4、后台集中:工作流引擎和流程管理的考量

微服务架构的引入,可以帮助大型企业在IT系统建设上从容应对业务流程的复杂多变,以及业务的灵活可扩展,但选择一个灵活可扩展的业务流程管理工具同样至关重要。

5、灵活扩展:虚拟机和容器的部署

与传统的物理服务器相比,采用虚拟机不需要冗长的固定资产采购流程,具有更高的效率和更低的成本。开发人员可以快速部署,运维人员可以弹性伸缩。容器技术则更加先进,它可以让微服务的打包和部署更加简单、高效。

6、善用外脑:开发及运维团队

在系统交付中要满足快速迭代实施及优化的需求,通过建立一支专业化的队伍来支撑软件交付周期的闭环(计划、分析、设计、开发、测试、部署、运维、运营)。

 

四、Nebulogy助力企业数字化云转型

技术是一个不断发展的过程,对于微服务和容器这些技术,微服务不是结果,而是一种工具。通过建设微服务平台,引入现有的成熟的微服务解决方案,平台和框架提供了微服务应用开发、运维的基础环境支持,是企业在内部快速的推广和实现微服务的一条“捷径”。

Nebulogy旗下的三款云产品解决方案:容器云平台(NKS+PKS)、微服务开发及治理平台(NDP)、BPM PaaS(NBS)。在云原生PaaS平台构建、容器治理平台、应用迁移咨询及服务、微服务应用构建、应用微服务化改造等方面,基于丰富的技术落地经验及对客户应用场景的深入了解,为客户提供产品及服务。

在通往数字化未来的路上,Nebulogy将助力企业成为敏捷和数字化组织,令企业的应用云化转型之路更加顺畅无阻,一往无前。

Why Microservices?

回答这个问题前,我们先看下之前大行其道的单体架构 - Monolithic Architecture,对于非专业人士来讲,所谓的单体架构,其就像一个超大容器,容器内集中包含了该应用的所有软件组件,并且组件与组件之间紧密耦合。

 

对于这种架构,其缺陷或者说潜在不足也很明显,简单总结如下:

  • 臃肿僵化不灵活: 单体架构很难采用多种技术
  • 可靠性较差: 这种架构最明显的特征就是牵一发而动全身,一个小小的功能失效可能会导致整个系统的不可用
  • 扩展性较差: 应用本身无法轻易的进行扩展,一旦需要进行对某个或者某些功能进行扩展或者更新,我们需要重新构建整个系统
  • 阻碍连续性的开发: 应用的许多功能特性无法被同时构建和部署
  • 开发速度慢: 单体应用的开发耗时较长,因为我们需要依次构建相应的功能模块
  • 不适用于复杂的应用: 复杂应用的各个功能特性紧耦合

何为微服务?

微服务,又称微服务架构,这种架构聚焦业务领域,将应用通过一个个小而自治的服务组织起来。在微服务架构中,每一个服务都是自包含的且唯一实现某个单一业务功能。

微服务与传统单体架构的区别

为了便于理解,我们这里以我们常见的电子商务应用为示例说明,很明显,传统的单体架构下,所有服务共享一个应用实例并且共享同一个后台数据库,而微服务架构下则应用本身业务功能划分为不同的微小服务,每个服务都自行处理各自业务数据,处理不同的业务功能。

微服务架构

接下来,我们进一步了解下微服务架构究竟有哪些特征以及什么是微服务,看下面的架构图例。

设备不同,各客户端所使用的服务也不尽相同,比如:检索、构建、配置抑或其他管理功能

基于各自业务领域的不同,每个服务都相对独立,而且会根据实际被进一步细化为更小粒度的服务

每个服务都有各自的负载均衡和运行环境,并且各自拥有相对独立的数据源

服务间的通信通常采用无状态通信协议,比如:REST或者消息总线

借助服务发现机制,服务消费方与提供方可以彼此无忧通信,并可进行一些自动化及监控操作

服务与客户端的交互都是通过服务网关进行的

所有内部联通节点均与服务网关相连,即一旦你连接到服务网关,你即可访问网关后的所有服务端口

微服务的主要特征

  • 解耦
  • 组件化
  • 业务功能化
  • 自治
  • 持续集成
  • 单一责任
  • 去中心化
  • 敏捷

微服务架构的优势

  • 独立部署
  • 独立开发
  • 故障隔离
  • 混合技术栈
  • 细粒度级扩展,即单个组件可以自由横向扩展

微服务架构设计最佳实践

一、首先谈谈传统系统架构和微服务架构

传统的系统架构是单一架构模式。这种架构模式就是把应用整体打包部署,具体的样式依赖本身应用采用的语言,如果采用java语言,自然你会打包成war包,部署在Tomcat或者Jetty这样的应用服务器上,如果你使用spring boot还可以打包成jar包部署。其他还有Rails和Node.js应用以目录层次的形式打包。

微服务架构则是将单个的整体应用程序分割成更小的项目关联的独立的服务。一个服务通常实现一组独立的特性或功能,包含自己的业务逻辑和适配器。各个微服务之间的关联通过暴露api来实现。这些独立的微服务不需要部署在同一个虚拟机,同一个系统和同一个应用服务器中。

二、为什么需要微服务架构?

单一架构模式在项目初期很小的时候开发方便,测试方便,部署方便,运行良好。可是当应用随着时间的推进,加入的功能越来越多,最终会变得巨大,一个项目中很有可能数百万行的代码,互相之间繁琐的jar包。

1、 不再适用敏捷开发,过于复杂,任何开发者都不能够完全理解,修复漏洞和实现新功能变得困难和耗时。

2、 规模越大,启动时间越长,自然会拖慢开发进度,一个小功能的修改部署起来变得困难,必须重新部署整个应用。

3、 系统的不同的模块的需要不同的特定的虚拟机环境时,由于是整体应用,那么只能折中选择。

4、 任意模块的漏洞或者错误都会影响这个应用,降低系统的可靠性

5、 还有一个如果想整体应用采用新的技术,新的框架或者语言,那是不可能的。

如果采用微服务架构模式,则可以解决单一架构模式带来的系统复杂性。主要包括以下几个好处:

1、 由于每个服务都是独立并且微小的,由单独的团队负责,仍然可以采用敏捷开发模式,自由的选择合适的技术,甚至可以重写老服务,当然都要遵守统一的API约定。

2、 每一个微服务都是独立部署的,可以进行快速迭代部署,根据各自服务需求选择合适的虚拟机和使用最匹配的服务资源要求的硬件。

3、 整体应用程序被分解成可管理的模块和服务,单个的服务可以更快的开发、更简单的理解和维护。

4、 一些需要进行负载均衡的服务可以部署在多个云虚拟机上,加入NGINX这样的负载均衡器在多个实例之间分发请求,这样不需要整个应用进行负载均衡了。

每个后端服务暴露一套REST API,大部分服务调用其他服务提供的API。每个服务都有自己的数据库模式,而不是共享单个数据库模式。尽管这会造成某些数据的冗余,但是对于微服务架构这个独立数据库模式是必要的,确保了独立服务之间的松散耦合。

以上介绍的微服务架构模式表面上类似于SOA,两种架构都包含一组服务。可以认为微服务架构是不包括Web服务规范(WS-)、企业服务总线(ESB)的SOA。基于微服务的应用倾向于使用更简单轻量级的协议,比如 REST 而不是 WS-。微服务自己实现类似 ESB 的功能并且拒绝 SOA 的其他部分,比如规范模式的概念。

三、不可否认的微服务缺点

1、 微服务应用作为分布式系统带来了复杂性。当应用是整体应用程序时,模块之间调用都在应用之内,即使进行分布式部署,依然在应用内调用。可是微服务是多个独立的服务,当进行模块调用的时候,分布式将会麻烦。

2、 多个独立数据库,事务的实现更具挑战性。

3、 测试微服务变得复杂,当一个服务依赖另外一个服务时,测试时候需要另外一个服务的支持。

4、 部署基于微服务的应用也很复杂,整体应用程序部署只需要部署在一组相同的服务器上,在这些服务前面加入传统的负载均衡器即可。独立服务的不是讲变得复杂,需要更高的自动化形式。

总结:以上就是微服务的基础介绍,那么如何实现微服务架构,Spring Cloud将起到什么作用,敬请期待。

过去的企业软件多是按管理域划分的大软件,如ERP、PLM、SCM等等,这些软件往往模块众多,功能复杂,强调以自身管理视角的产品全生命周期协同工作。但在数字化转型的背景驱动下,面对批量较小的产品订单,更加个性化、人性化的产品特性组合,工作业务流程从长流程变成短流程,鼠标点击变成手指触屏,线性协作变成点状聚合,大软件系统不得不适应而被拆解为更小功能服务的小软件服务。互联网需求的长尾效应推动软件碎片化,让工作无时无处都可以被处理,而越来越多的碎片化的需求又进一步反身强化更多智能设备的推广使用。应用交付的速度永远跟不上业务需求的变化,业务部署与运维复杂度提高导致应用的可用性下降,多元化业务和复杂体系架构导致IT治理的困难,技术人员不断的重复 “开发—测试—上线”的轮回。

传统应用架构 Vs 微服务架构

ThoughtWorks首席科学家Martin Fowler在2014年提出了微服务的概念,把一个大型的应用软件按照功能和服务分类拆分为数十个微服务,每个服务运用于自己的独立进程,通常是采用基于HTTP协议的RESTful API的轻量级通信机制,松耦合的服务能够被独立更新的部署,每一个微服务可满足用户的一个需求,用来提升企业的敏捷运营与快速的业务拓展。这种架构将原本大而复杂的单体架构,重组为小而精美的独立服务,让工作变得更加高效、便捷、直击重点。当企业对某些微服务有特殊需要时,只需将针对这部分微服务的IT资源进行升级,对这些微服务进行更新。在系统出现故障时,微服务也可实现对故障部分单独隔离,以免影响到整个系统的使用。开发人员也可更便捷地基于“云”进行应用系统开发。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/Tom_sensen/article/details/109839373