浅谈服务化和微服务化(下)
这篇文章发表于2017年,最近才发现,只发布了上,而没有发布下篇,故在此补上,以保证完整性。
上篇主要讲服务化,下篇我们谈谈微服务。很显然,服务化来自于真实世界的映射。对于微服务,我们也要寻找真实世界的隐喻。
1. 微服务,让服务化走向专业化和精细分工。
2017年的某一天早上,我路过了一段因为修地铁而导致的破落的街区,又穿过稼先路与坂雪岗大道交叉路口的滚滚灰尘,转眼看到了拐角处幸存的中国银行。这一天,我要体验中国银行的服务化。大堂入口的笑容可掬的两位美女大堂经理,证实了BOC作为四大国行之首应有的风范,也说明了其服务化能力非同小可。我要办的业务很简单,换几K泰铢,作为通向一个让我神往已久之地的盘缠。
原以为要排很长时间的队,跟着大部队一起等待叫号,然后在综合窗口完成业务,没有想到的是,BOC在外币兑换业务上实现了“微服务”,大大提升了我办事的效率。我在一楼的自助机上完成了现汇购买,然后去到二楼,穿过一处沙发所在地,感觉一点都不像在银行。8号窗口是外币兑换窗口,银行职员已经等待多时,他拿走了我的银行卡,让我输入密码,然后给了我5000泰铢。
这个外币兑换窗口从综合业务中剥离出来,成了单独的“微服务”,着实有一些好处。
其一,是这个窗口的服务更加专业化,这个窗口的职员只干这一件事,效率自然高很多,因为避免了从不同的“限界上下文”中来回切换导致的效率损失。
其二,我不会因为办理其他业务的人太多,而排队等候。
其三,这个窗口的职员不会因为处理了其他难缠的业务而导致疲倦宕机,影响这个窗口的业务开展。开卡柜台的职员去嘘嘘了,并不会导致这个窗口的服务中止。
其四,银行的职员不必精通所有业务,只要能搞定当前业务即可。
其五,我们针对这个服务的改进更加容易,我们可以优化当前的服务水平而不影响其他的服务。
很显然,真实世界中的服务的微服务化让服务化走向了专业化,走向了精细分工,带来的好处也显而易见。
2. 微服务并不是2014年才有的
谁第一个提出了微服务?看这里:http://www.sohu.com/a/136026819_609518。然而微服务的相关理念就源远流长了。
a. Amazon 2004年已经在实践 Two Pizza Team,其实已经是在做微服务了。
b. 2005~2009年期间,Fred George和所在的团队是将100万行的传统J2EE程序,通过解耦、自动化验证等实践,逐渐分解成20多个5K行代码的小服务,又分解成200多个500行代码的服务。在这个过程中,他们使用了基于Kafka的消息解耦服务间依赖。
后来的事情就比较清楚了,Martin Fowler 2014年3月正式喊出了Microservices的概念。
3. 小烟囱不是微服务
上篇已经提到,SOA的本质是前后分离,实现服务在分布式环境中的重用。如果我们简单把原来非服务化的应用分拆成多个非服务化的应用,相当于把原来的大烟囱分割成很多小烟囱,那么,连服务化都算不上,因为服务化根本的目标---在分布式环境中的重用服务,并没有得到实现。
4. 团队太大不是微服务
Sam Newman在“微服务设计”一书开篇就提到,微服务的初衷是解决“代码库过大”(或者说团队过大)的问题。为什么代码库过大是个问题?因为难以维护。通常情况下,大的代码库需要大的团队维护。漫长的软件技术发展历史早已证明,越大的团队越是效率低下,越是难以管理,这好像已经是不争的事实。这个世界上,真正能管理好大型软件开发团队的公司,基本没有。有一些公司看起来有这个能力,但往往其软件业务也在走下坡路,或者软件团队真的软了,因此,并不见得是真正的好。
我也曾经管理过比较大的开发团队,每天忙忙碌碌,过的很充实,但最后的效果一般。后来我终于明白了一件事情 --- “3-5个人做不好的事情,30-50人做的更烂。(腾讯云CEO陈磊)”。
Amazon的经验表明,6-10个人的团队是比较合适的。
5. 团队过小也不是微服务
有时候,我们过度的进行了“微服务化”,往往是违背了微服务的初衷和本质。微服务化其实是有代价的,这也是众所周知的事实。
当我们把服务拆到6-10个人的小团队可以维护的时候,就不应该继续分拆了。如果我们将服务拆的太散,最后一个人维护10来个服务,那已经背离了初衷。我们的程序猿就是这些的服务的爹妈,这些服务出现任何问题、需求、故障, 都要爹妈来负责,想想,养那么多孩子,容易么?
6. 拉通过多不是微服务
前面讲到团队太大不是微服务,其实大团队的问题并不在于大,而在于“拉通”上,“One Team,One Dream”,团队的目标是一定的,如果要在7月份交付某个火车一样的版本,各服务之间复杂的依赖关系,最终导致两个结果,要么是团队效率极低,要么是拉而不通、痛苦不堪。
微服务强调的独立,自治,就是尽量不要依赖其他服务,要内聚,这里涉及到架构上的控制,架构师如果看到某些微服务总是纠缠不清,那么应该考虑将这些微服务适当合并。
话说回来,实际情况总比理想情况复杂,总有些情况是必须依赖的,那么应该依赖那些稳定、可靠的服务。
7. 微服务的边界如何定义?
Martin Fowler 2003年的时候就讲过,分布式架构的第一原则,就是不要分布对象。任何违背这一原则的实践都会带来很大的代价。N年前,我们使用了已故公司SUN专家广为推崇的的远程EJB技术,号称可以更好的分离业务层和WEB层,最后下场是苦不堪言。
好的微服务设计就是在维持合适的团队规模的前提下,尽量少的去分布对象。Eric Evans的“Domain-Driven Design”(领域驱动设计)一书值得一读,其中提出的“Bounded Context”(限界上下文)有助于理解这一点。通常来说,一个微服务中可以包含1个或者多个 Bounded Context,但是一般不应该将一个 Bounded Context 分散到不同的微服务中。
举个例子,对于商品交易来说,销售和技术支持是两个 Bounded Context,可以实现为两个微服务。这两个微服务中,都有 Customer 和 Product,但其保有的属性不完全相同,Service Context 中一定要保留 Customer 的联系方式,而 Sales Context 则未必;甚至两个 Customer 都不是同一个对象,比如买手机的 Customer 和修手机的 Customer 未必是同一个人。如果将销售和支持放在一个单体中实现,那很可能 Customer 和 Product 两个实体(表),会被 Sales 和 Service 两个功能共用。而在微服务架构中,他们是两个不同的实体,各自属性不完全相同,并很有可能存储于不同的数据库中,为了保持微服务的独立性,Customer 和 Product 的数据在两个微服务中有一定程度的冗余。
那回到最初的问题,在微服务模式下,对象到底有没有分布?答案很多时候都是没有,就拿 Product 来说,Sales Context 中的 Product 跟 Service Context 和 R&D Context 中的 Product 也不完全一致,是可销售的 Product ,可销售的 Product 的数据就存储于 Sales Context 所在的微服务中,虽然,其最终可能仍然来自 PBI 。同理, Service Context 微服务中,一般也存储有待服务的 Product 数据。
通过合理的 Bounded Context 来引导微服务的拆分,并适当的安排数据的分布和冗余,有助于提高微服务边界划分的合理性。
8. 微服务的代价
微服务架构小独轻松,都是优点,难道就没有缺点么?当然有:
a. 系统的可用性受到比单体应用更大的挑战。一个由10个微服务构成的系统,如果每个微服务的可用性是99%,那么总体的可用性是99%的10次方,大概是90%左右。如何解决这个问题?答案当然是技术,通过多活、限流、容错、熔断等多种技术组合,来保障系统总体的可用性不受单点故障的影响。
b. 性能的下降。单体应用中本地的调用有部分会转化成远程调用,再牛逼的远程调用也比本地调用要慢1个数量级以上。解决方案也不复杂,恰当的运用缓存技术来提升性能。
c. 更多的硬件资源消耗。就我们观察到的在多个领域的实际经验来看,应用服务器占用的资源数量增加了数倍到数十倍。一般来说,要借用容器或者Serverless技术,来改善利用率。
9. 数据库的独立是不是必要的?
很多对微服务信念坚定的人认为,“数据库不独立不是真正的微服务”。
支持独立的人认为:
a. 微服务强调独立性,如果数据都不独立,那服务不可能独立。
b. 数据独立之后,所有依赖都采用服务方式进行,有更好的内聚性。
c. A服务的数据库挂了不会影响B服务。
支持不需要独立的人认为:
a. 用户不关心你不是独立数据库。用户需要的是良好的体验。如果分割数据库导致性能下降或者可用性下降,用户可能情绪不稳定。
b. 码农基本不希望分割数据库。分割数据库之后,很多原本简单的问题,变得很复杂。
c. 架构师的担心有时候是多余的。在大型互联网应用中,因为数据量巨大,要分库分表,因此,Join一般是严格禁止的。而在企业级应用中,这种情况比较少。另外,有人担心数据库不独立,导致互相扯皮影响的事,毕竟还是比较少的。
看来各有道理,因此需要中庸之道来解决,数据既需要独立,又需要共享,那怎么办呢?一般采用集成来解决,集成可以基于服务、JMS、数据库集成,具体哪种方案,取决于对实时性的要求。
一般来说,主数据会被多个微服务共享,如上面例子中的 Product 和 Customer ,而交易数据则主要体现为各微服务独享,如订单、维修单数据。
10. 单体应用仍然是有价值的
讲了这么多微服务,这个世界上其实一直存在一个最大的反面典型,就是 Salesforce,Salesforce 其实是个巨大的单体应用。那难道 Salesforce 就不好么?其实未必。不管白猫黑猫,能解决老鼠问题的就是好猫。
不能因为走的太远,就忘了为什么要出发。从根本上来说,我们要实现的目的,无非是提供更好的用户体验和实现更大的价值重用,从这两个目的来说,微服务并非是唯一的途径,而只是一条比较流行和时尚的途径。
正如很多兄弟所说,3MS上有100篇关于微服务的文章,各有各的看法,关于微服务的争论仍然不会停止。微服务模式的价值显而易见,但微服务的关键并非技术,而是服务边界的重新定义,我们不能过度渲染微服务的技术或者框架,而忽略了对合理的服务边界的划分。另外,正如开头所讲,微服务让服务化走向专业化和精细分工,目标仍然是要实现更好的服务效率和体验。至于架构,仍然只有最合适的,没有最好的。
- 点赞
- 收藏
- 关注作者
评论(0)