微服务是传统企业电商解决方案的银弹吗?
近几年,微服务成为最流行的技术名词之一,尤其受到亚马逊、阿里等电商巨头的影响,很多传统企业在实施电商过程中也纷纷往微服务架构靠拢,相比单体架构,微服务确实有很多优点,就像 Sam Newman 在“Building Microservices”[1] 中所阐述的那样:
技术异构性
弹性
伸缩性
容易部署
…
但是计算机科学作为一门平衡的科学,任何技术架构在带来收益的同时也会有其局限性,作为系统架构师或者决策人员,一定要对此有清醒的认识。本文将重点阐述成功实施微服务的先决条件,所面临的主要挑战和风险,传统企业在实施电商过程中的决策要素以及正确的实施策略。BTW,作者本人对微服务没有任何成见,我在 amazon 工作期间一直接触的就是微服务架构,而且本人也是 Adrian Cockcroft 的超级粉丝。所以各位微服务控们千万不要拍砖。
一般而言,成功实施微服务的先决条件包括:
匹配的组织架构
实力雄厚的技术团队(包括开发 / 测试 / 运维)
清晰的业务边界
其中第一条换个洋气点的说法就是康维定律(Conway’s Law[2]),这是我最喜欢的定律之一,现实中接触到的各个案例无一例外:
"organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations."
康维定律简单来说,就是任何软件都反映出制造它的团队的组织结构,这是因为人们会以反映他们组织形式的方式工作。 换句话说,采用微服务架构的组织结构也应该是分散的。看看现实中成功实施微服务的那些公司:Amazon、Netflix、阿里那个不是分散的组织结构。
至于后面两条的原因我将在下面一节深入探讨。
主要包括:
除了需要了解业务逻辑外,也需要花大量精力去学习底层微服务框架提供的各种服务并遵从其契约,以下图为例,为了实施一个基于微服务架构的电商,技术团队需要掌握以下:
业务逻辑及其之间的接口
基于容器的部署和工具,比如 Docker、Kubernetes 等
微服务框架本身的学习,包括 API 网关、服务发现和注册机制、熔断、分布式配置等等
甚至背后的理论 / 设计模式,诸如 CAP、BASE 等等
例如:
因为常见微服务架构都是每个服务拥有自己的数据库,导致需要跨表实现统计报表等功能将变得很复杂
对于哪些需要依赖其他微服务的微服务开发及测试,你不得不在本地也安装所有需要依赖的微服务,即使采用 Docker 容器,根本问题并没有改变,与单体服务的开发相比较而言,开发测试变得很繁琐
代码本身也要遵从微服务框架的各种契约,例如一个使用 Hystrix 熔断机制的代码如下:
@Service
public class MyService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "errorHandler")
public String myService(String name) {
return restTemplate.getForObject("http://MYSERVICE/myservie?name="+name,String.class);
}
public String errorHandler(String name) {
return "There is an error for service "+name;
}
}
由于各种原因(特别是在对业务的理解不够或者业务变动频繁的情况下),已经上线的微服务发现并不合适从而需要重构,例如需要把计价服务重新合并回产品服务,至少遵循以下步骤(请参考下图):
首先在产品数据库中建立与计价有关的表,建立导入工具吧计价数据库中的数据导入到产品数据库中,需要注意的是,如果产品服务和计价服务采用不同的数据库,还需要额外的开发成本编写导入工具。在本步骤完成后,产品服务并不提供任何计价功能,只是所有计价服务中的数据会被不断(同步或异步)导入到产品数据库中。
在产品服务中引入计价功能并暴露相应接口,在充分测试后配置 API 网关(如 Zuul 或者 Istio)对计价功能调用进行分流,期间所有流入老的计价数据库的数据依然会被导入到产品数据库中。
经过一段时间的金丝雀发布后,最终所有的计价功能调用都进入产品 / 计价服务,老的计价服务和相应的数据库被卸载。
当然这是在非常理想的情况下,现实情况比这个复杂的多,例如部分需要合并部分需要拆分,采用不同的编程语言,采用不同的数据库技术,其它微服务对相关微服务的依赖等等。另外典型的微服务架构中不同的微服务由不同的组 / 部门去维护,相关的沟通协作也是一个不容忽视的成本,所以在业务不稳定或者理解不充分的情况下贸然实施微服务的代价是非常巨大的!
微服务架构比单体服务更容易发生问题,不但是因为分布式计算本身复杂性带来的各种问题(如一致性问题),而且各种流行的微服务框架都有这样那样的坑,以电商业务为例,用户 1 需要上架一批新产品,为了提高并发性以及降低服务之间的耦合度,当前的微服务架构采用消息总线去通知计价服务 / 仓库服务 / 产品服务进行相应处理,不幸的是,由于消息的异步性,很可能对于某个产品而言,产品服务最后被通知到,期间如果用户 2 查询到了对应的库存但却发现相关的产品不存在(如下图所示),这显然违反了因果一致性(casual consistency)!
想象一下订单服务的实现需要调用仓库服务,计价服务,支付服务等多个服务,中间任何一个环节出错都将导致订单处理失败,有时为了提高处理的并发量,往往采用基于消息总线的异步方式,这样想做到快速定位到错误根源对开发人员是一个不小的挑战,一般而言,我们不得不从两个方面入手:
应用级别的关联,所有异步调用都必须引入消息标识关联
借助于微服务框架的分布式追踪机制,日志聚合等功能(如 zipkin,CloudWatch 等)
即便这样,出错调试的困难度和需要的时间也和单体服务不是一个量级的,而且大部分情况下,在单体服务中很容易重现并在本地通过单步跟踪快速解决的问题,对于微服务而言就变得不那么容易了。
在很多介绍微服务架构优点的文章中,常见的一条就是“易于部署”,实际上之所以“易于部署”,是拿单个“微服务“和单体服务相比较而言的,但是部署构成企业业务的几十个甚至上百个微服务的总体复杂度绝对比单体服务大的多,这就是为什么所有基于微服务架构的应用都必须依赖自动化的部署能力,这对体术团队提出了两方面要求:
掌握自动化运维工具(如 Ansible)和相关的设计模式 (如服务器提供模式、服务器模版管理模式、基础架构定义模式等 [3])
微服务本身是快速部署匹配的,如果不是则需要进行重构 [4]。
从业务角度我们必须思考以下这些问题:
你的业务体量到底有多大,会不会成长为类似于 / 接近于 Amazon/Netflix/Google/ 阿里 / 腾讯这些巨头体量的下一个巨头?
如果会,那么多长时间,几年还是几十年?
实施电商后的产品升级 / 运维 / 扩展谁来做,能否提供足够的技术实力来应付微服务框架中的各种潜在风险
对业务的理解是否非常深刻,还是只停留在初级阶段?
公司组织结构是否有利于实施微服务架构?
是否有其他更为简单的解决方案
总之,作为系统架构师或者决策人员,我们要做的就是透过“绚丽包装”的外表理解各种技术架构的本质从而避免过度设计给企业带来巨大的风险,在这点上 Jeff Dean 在其稳重“challenges in building large-scale information retrieval systems”中的经典名言值得我们借鉴 [5]:
Design for ~10*growth, plan to rewrite before ~100*
Martin Fowler 在其“MonolithFirst”一文 [5] 中明确指出:
几乎所有成功的微服务案例全部来源于业务足够复杂的单体服务
几乎所有不成功的微服务案例都是直接从头开发
实际上作为传统行业实施电商一个稳妥的方案是从单体开始,随着业务变得越来越复杂逐步慢慢演进到微服务,具体来说:
单体服务的实施中需要采用良好的编程习惯,使得整个系统模块化而且业务边界清晰,如果一开始对业务不太熟悉,这需要不断的重构。
单体服务本身应该尽量遵循云部署的那些基本原则,诸如无状态、通过环境变量注入配置信息等 [4]。
在电商业务变得足够复杂的情况下,逐步对有关服务进行拆分,需要注意的是此处只是逻辑上的拆分
加强对自动化运维能力的建设。
最终随着企业组织结构的逐步调整过渡到微服务架构。
微服务的出现给传统企业实施电商业提供了强大 / 灵活 / 敏捷的框架,但同时也对无论技术还是业务上都提出了更高 / 更严格的要求,不重视这些潜在风险将带来巨大风险,所以微服务不是企业电商解决方案的银弹,通常只有采取更为务实严谨的演进路线才能实现我们的目标。
Building Microservices: Designing Fine-Grained Systems, Publisher: O'Reilly Media; 1 edition (February 20, 2015)
https://en.wikipedia.org/wiki/Conway%27s_law
Infrastructure as Code: Managing Servers in the Cloud, Publisher: O'Reilly Media; 1 edition (June 27, 2016)
https://12factor.net
https://static.googleusercontent.com/media/research.google.com/en//people/jeff/WSDM09-keynote.pdf
https://martinfowler.com/bliki/MonolithFirst.html
我大概在 2006 年开始参与架构设计,原以为学习架构就像学习编程语言一样,先了解基本的语法,再研究细节和原理,然后实践一下就能够快速掌握。 但真正深入后才发现,架构设计的难度和复杂度要高很多。
从最早开始接触架构设计,到自我感觉彻底掌握架构设计的精髓,我至少花费了 8 年的时间。 我曾经以为是自己天资愚笨才会这样,后来我带了团队,看到几乎每个程序员在尝试架构设计的时候,都面临着我曾经遇到过的各种困惑和瓶颈。
今天,我想把我过去所有的经验都分享在这里,希望能帮你快速成为一名架构师。
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 准确把握守正创新的辩证关系 7972610
- 2 中国黄金原董事长家搜出大量黄金 7990225
- 3 空调英文不会男生盯着考场空调看 7890367
- 4 消费品以旧换新“加速度” 7763438
- 5 被铁路售票员的手速惊到了 7636459
- 6 网红赤木刚宪爆改赵露思 7542823
- 7 县委原书记大搞“刷白墙”被通报 7442447
- 8 山姆代购在厕所分装蛋糕 7349036
- 9 马龙刘诗雯穿正装打混双 7294215
- 10 刘强东提前发年终奖 7145748