这两年,微服务架构火了。在国内,从消费级互联网应用,到企业级应用;从金融领域,到电信领域;从新开发系统到已经开发了十几二十年的遗留系统;一夜之间,好像所有的团队都在谈微服务。
然而,我们为什么采用微服务呢?
“让我们的系统尽可能快地响应变化“ - Rebecca Parson
是的,让我们的系统尽可能快地去响应变化。其实几十年来我们一直在尝试解决这个问题。如果一定要在前面加个限制的话,那就是低成本的快速响应变化。上世纪九十年代Kent Beck提出要拥抱变化,在同期出现了诸多轻量级开发方法(诸如 XP、Scrum);2001年敏捷宣言诞生,之后又出现了精益、看板等新的管理方式。如果说,这些是为了尽快的响应变化,在软件开发流程和实践方面提出的解决方案,那么微服务架构就是在软件技术和架构层面提出的应对之道。
微服务是如何做到的?
微服务是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。 — James Lewis and Martin Fowler
这是James和Martin2014年在《微服务》一文中提到的对于“微服务”的定义。相对于单体架构和SOA,它的主要特点是组件化、松耦合、自治、去中心化,体现在以下几个方面:
- 一组小的服务
服务粒度要小,而每个服务是针对一个单一职责的业务能力的封装,专注做好一件事情。
- 独立部署运行和扩展
每个服务能够独立被部署并运行在一个进程内。这种运行和部署方式能够赋予系统灵活的代码组织方式和发布节奏,使得快速交付和应对变化成为可能。
- 独立开发和演化
技术选型灵活,不受遗留系统技术约束。合适的业务问题选择合适的技术可以独立演化。服务与服务之间采取与语言无关的API进行集成。相对于单体架构,微服务架构是更面向业务创新的一种架构模式。
- 独立团队和自治
团队对服务的整个生命周期负责,工作在独立的上下文中,自己决策自己治理,而不需要统一的指挥中心。团队和团队之间通过松散的社区部落进行衔接。
我们可以看到整个微服务的思想就如我们现在面对信息爆炸、知识爆炸是一样的:通过解耦我们所做的事情,分而治之以减少不必要的损耗,使得整个复杂的系统和组织能够快速的应对变化。
My First Law of Distributed Object Design: Don’t distribute your objects (From P of EAA). - Martin Fowler
然而谈到微服务,我们不能忽视的一点是:微服务仍然是典型的分布式系统,它必然有分布式系统固有的问题:诸如怎么部署,出错怎么办,怎么保证数据的最后一致性;与此同时,还有服务要多微?业务变化后服务如何调整?服务规模化后怎么办?如何避免一个服务改动导致的多个级联服务的失败?如何进行测试等等问题。
“微服务不是免费的午餐”。从实战中我们清楚地认识到选择任何架构都有利有弊,服务化也是一样。企业从微服务架构获益的同时,必然要面对切换到由众多服务组成的分布式系统后所带来的挑战。我们认为只有提升团队应对这些挑战的成熟度,才能真正使企业从这种微服务架构中获益。
那么对于即将和已经开始实施微服务的团队,应该如何应对呢?结合我们项目的经验,我认为应从DevOps、服务构建、团队和文化四点入手:
- 首先需要考虑构建DevOps能力,这是保证微服务架构在持续交付和应对复杂运维问题的动力之源;
- 其次保持服务持续演进,使之能够快速、低成本地被拆分和合并,以快速响应业务的变化;
- 同时要保持团队和架构对齐。微服务貌似是技术层面的变革,但它对团队结构和组织文化有很强的要求和影响。识别和构建匹配架构的团队是解决问题的另一大支柱。
- 最后,打造持续改进的自组织文化是实施微服务的关键基石。只有持续改进,持续学习和反馈,持续打造这样一个文化氛围和团队,微服务架构才能持续发展下去,保持新鲜的生命力,进而实现我们的初衷。
在本文中会针对第一点,并以我们项目微服务的发展历程为例介绍我们遇到的各种坑和采取的相关措施,希望能够给正在准备实施和已经实施微服务的团队一些借鉴。
背景
我们于2012年在系统集成需求的驱动下走上了服务化之路,通过将重复的业务能力封装在几个服务之间完成了系统集成,并成功上线。最初只有8个服务支持我们的业务系统,服务与服务之间采取基于HTTP的RESTful API的方式进行通信,通过自动化脚本将应用部署到生产环境。
在随后的2年中我们的业务快速发展,增加到了60多个站点和服务。服务的上线周期也越来越短,从两年到两周。而这样的一套生产环境是由客户的2名运维人员手工维护的(包括基础设施构建),每次发布都会存在大量的人工干预,比如对部署结构和系统权限的修改等,给我们的整个生产部署和运维带来了较大的问题:
- 大量的人工干预,频频出错。
手工方式始终是易错和低效的,而且会导致各种难以重现的环境问题(就如雪花服务器),这使得一些复杂点的运维工作,包括技术平台的整体升级、灾备系统搭建等很难开展,往往要提前半年甚至一年来进行筹备。当我们服务规模化和发布周期缩短之后,它带来的伤害又进一步明显起来。为了减小这种伤害,业务部门不得不降低发布频率,从两周延迟到一个月,因此也影响到了对最终用户的响应速度,并不得不采取Hotfix的方式来修正发布速度的问题,实际上又增加了问题的复杂度。
- 缺乏有效的监控和日志管理,产品环境定位困难。
没有监控,无法及时知晓服务的运行状态。很多问题直到最终用户才能发现,问题反馈周期很长。同时,运维人员不懂开发人员的服务设计和调用流程,开发人员不懂产品环境的配置结构。当产品环境出错之后,往往要花费数小时才能定位到问题根源。
另外,负载均衡和单点服务降级无法真正开展,当一个服务出现问题时,需要关掉其所在的服务器。产品环境资源利用率低,运维成本居高不下。
2015年初,当我们遇到了Powershell的bug和服务不能正常启动的貌似随机问题时,就如遇到了那根压倒骆驼的最后一根稻草,客户对我们明确的提出“不要再添加任何一个服务了”。
残酷的事实再一次向我们证明,在这样一个复杂系统下,传统的手工运维方式必然要被淘汰,微服务的实施有一定的先决条件:基础的运维能力(如监控、快速配置、快速部署)需提前构建,否则就会陷入像我们一般如此被动的局面。而我们也看到,当服务规模化后需要更多自动化和标准化的手段来提升效能和降低成本。
……
阅读下半部分内容&文中蓝色字体对应链接请点击【阅读原文】