近几年,微服务成为最流行的技术名词之一,尤其受到亚马逊、阿里等电商巨头的影响,很多传统企业在实施电商过程中也纷纷往微服务架构靠拢,相比单体架构,微服务确实有很多优点,就像 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、阿里那个不是分散的组织结构。
至于后面两条的原因我将在下面一节深入探讨。
更长的学习曲线
主要包括:
更多的开发 / 测试工作
例如:
@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;
}
}
重构的代价
由于各种原因(特别是在对业务的理解不够或者业务变动频繁的情况下),已经上线的微服务发现并不合适从而需要重构,例如需要把计价服务重新合并回产品服务,至少遵循以下步骤(请参考下图):
当然这是在非常理想的情况下,现实情况比这个复杂的多,例如部分需要合并部分需要拆分,采用不同的编程语言,采用不同的数据库技术,其它微服务对相关微服务的依赖等等。另外典型的微服务架构中不同的微服务由不同的组 / 部门去维护,相关的沟通协作也是一个不容忽视的成本,所以在业务不稳定或者理解不充分的情况下贸然实施微服务的代价是非常巨大的!
微服务架构比单体服务更容易发生问题,不但是因为分布式计算本身复杂性带来的各种问题(如一致性问题),而且各种流行的微服务框架都有这样那样的坑,以电商业务为例,用户 1 需要上架一批新产品,为了提高并发性以及降低服务之间的耦合度,当前的微服务架构采用消息总线去通知计价服务 / 仓库服务 / 产品服务进行相应处理,不幸的是,由于消息的异步性,很可能对于某个产品而言,产品服务最后被通知到,期间如果用户 2 查询到了对应的库存但却发现相关的产品不存在(如下图所示),这显然违反了因果一致性(casual consistency)!
想象一下订单服务的实现需要调用仓库服务,计价服务,支付服务等多个服务,中间任何一个环节出错都将导致订单处理失败,有时为了提高处理的并发量,往往采用基于消息总线的异步方式,这样想做到快速定位到错误根源对开发人员是一个不小的挑战,一般而言,我们不得不从两个方面入手:
即便这样,出错调试的困难度和需要的时间也和单体服务不是一个量级的,而且大部分情况下,在单体服务中很容易重现并在本地通过单步跟踪快速解决的问题,对于微服务而言就变得不那么容易了。
在很多介绍微服务架构优点的文章中,常见的一条就是“易于部署”,实际上之所以“易于部署”,是拿单个“微服务“和单体服务相比较而言的,但是部署构成企业业务的几十个甚至上百个微服务的总体复杂度绝对比单体服务大的多,这就是为什么所有基于微服务架构的应用都必须依赖自动化的部署能力,这对体术团队提出了两方面要求:
从业务角度我们必须思考以下这些问题:
总之,作为系统架构师或者决策人员,我们要做的就是透过“绚丽包装”的外表理解各种技术架构的本质从而避免过度设计给企业带来巨大的风险,在这点上 Jeff Dean 在其稳重“challenges in building large-scale information retrieval systems”中的经典名言值得我们借鉴 [5]:
Design for ~10*growth, plan to rewrite before ~100*
Martin Fowler 在其“MonolithFirst”一文 [5] 中明确指出:
实际上作为传统行业实施电商一个稳妥的方案是从单体开始,随着业务变得越来越复杂逐步慢慢演进到微服务,具体来说:
微服务的出现给传统企业实施电商业提供了强大 / 灵活 / 敏捷的框架,但同时也对无论技术还是业务上都提出了更高 / 更严格的要求,不重视这些潜在风险将带来巨大风险,所以微服务不是企业电商解决方案的银弹,通常只有采取更为务实严谨的演进路线才能实现我们的目标。
参考资料
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。