一篇文章带你读懂“热坏了”的微服务
年度总结,看完这个你应该知道如何回答别人的问题了。
一、微服务的定义
实际上没有太明确的定义,我觉得很多互联网公司已经是微服务了,Martin Fowler的定义也比较模糊,简单的几个特征,可以总结为:
- 专注做一件事;
- 独立的进程;
- 独立的部署;
- 小;
- 轻量级的通信机制。
如果联想一下相关词汇,又会想到服务化、SOA,在我看来,根本不需要纠结这些概念性的东西,就好比SOA的时代,也不是所有的应用都采用ws,而微服务,代码行数,通信机制这些也未必能满足定义。最重要的是适合业务场景,不必完全按照微服务的定义来做。每个公司都有自己的业务特色,适合的一定是个性的。因为架构不只是技术因素决定的,跟业务、公司文化、组织结构、人员水平都息息相关。例如facebook一直奉行的单体应用,据说一个应用有千万行代码级别,同时发布,做的也非常棒,也能很好的持续交付,那是因为上面我说的那些因素都能满足,如果换一个公司,未必能做的很好。当然,对于我们来说,我们要选的是那条最好走的路。
二、微服务带来的好处
实际上所说的所有微服务的好处都是来自于和单体应用的对比。
组织结构。组织结构和架构是映射关系,如果你想知道某个公司的架构是怎么做的,完全可以根据组织结构推导出来。当一个团队的人数太多的时候,沟通效率急剧下降,团队成员的主人翁精神也降低一个层次。这和敏捷开发是一致的。
功能复用。抽象通用的部分,减少重复代码,本身就是效率的提升。另一点,因为服务被切分为足够小的粒度,容易变更。假设是一个大的应用,要进行重构,相对于微服务来说,要复杂的多,因为你不可能只做重构,而不去接新的需求。如果切分的粒度够小,完全可以在接口不变的情况下,神不知鬼不觉的重构。
容错。服务运行在不同的进程中,无疑隔离性更好,某一个点导致的故障影响面更小。
三、微服务带来的灾难
最重要的是适合业务场景,不必非得采用微服务,微服务并不是一种炫酷的技术或者架构思想,同时采用微服务会带来很多问题:
依赖关系。原来一个应用可能会被拆分成几个或者几十个应用,服务数量爆炸式增长,导致依赖关系复杂,除非有一套非常好的服务注册发现机制,漂亮的依赖关系统计图,否则在服务数量超过100的时候,无论哪个架构师都搞不明白他们之间到底是什么关系。同时对开发人员遵守标准、规范的要求也空前提升。
性能。原本进程内的调用关系变成了网络调用,一次rpc变成了几次或者几十次rpc,同等条件下性能损失严重。(如果采用http+json,比netty+kryo、protobuf、thrift又会下降几乎一半性能,包括响应时间和吞吐量)
一致性。原本本地事务有可能变成了分布式事务,这个非常考验服务切分的规则,考验架构师对业务的理解程度。就算采用最终一致性,也要在各个服务中做好容错机制,假设调用失败如何处理,如果重试,重试几次失败怎么办?调用成功,返回ack失败时,怎么保证生产者的幂等性。
复杂度。服务数量多,依赖关系多,给开发、测试都带来了更大的挑战。架构师也需要定义一些规则,服务分层。例如服务分为原子服务、组合服务、流程服务,下层是不能调用上层的,如果允许调用,会导致循环依赖的问题。同一份数据可能上上下下调用了好多次。有可能只需要调用一次原子服务,因为上层的混乱,下来可能变成了几次。
四、如何做好微服务
要做好,就要先做好准备。
提升架构能力非常重要的一个手段就是平台化驱动。通过抽离通用部分,用最核心的人去研发,做到最稳定。如果非要说google的架构能力远远领先于百度,那并不是百度的业务开发人员比google的差很多,而是google平台化的架构远远强于百度。例如容器、分布式数据库。
So,要做好微服务,先要解决的是相关的框架、中间件、组件、通用服务。在这些都准备好的了情况下,业务开发人员根本不需要关心太多。
举几个例子,
- 要解决依赖关系问题,就要有一个服务发现注册中心。
- 要解决性能问题,读的问题可以通过缓存来补偿。可以采用并行、异步、非阻塞等方式补偿性能,当然这些都可以封装到通用的rpc框架里面。
- 要解决一致性问题,就要有一个通用的事务处理平台。如果采用最终一致性,就把重试策略封装到框架。
- 要解决复杂度问题,就要定义一系列标准、规范,通过工具来检测问题。建立一整套devops平台,自动化测试平台。通过调用链分析,迅速定位问题。
五、大师寄语
ThoughtWorks首席科学家MartinFowler 在Monolith First中写道:
i. Almost all the successful microservicestories have started with a monolith that got too big and was broken up ii.Almost all the cases where I've heard ofa system that was built as a microservice system from scratch, it has ended upin serious trouble. |
所有的成功的微服务的故事都是以单体应用太大开始的,逐步的拆分。我听到的所有的一个从无到有被创建为微服务的系统,他们都以遇到很大麻烦而告终。
六、总结
总结一下,做微服务之前,需要审视一下,目前的业务场景、技术实力,是不是需要把应用拆分到“微”的粒度。优雅的架构总是和实用的架构有距离的。在没有足够的能力之前,应该尽量选择更实用的架构。
微服务之所以被炒的如此之热,主要是因为容器的出现,PaaS服务提供商,不断的鼓吹微服务带来的好处,以此来吸引众多中小开发者使用其服务。像go语言一样,中国似乎又领先世界了。
如果你的体量还不大,首先应该解决的是搭建好一套绝对稳定的平台化服务,待体量逐渐长大,再去根据实际需要进行不断发分裂。团队也随之变化。