版权声明:欢迎关注公众号:java4all,作者微信:w1186355422,欢迎探讨交流! https://blog.csdn.net/weixin_39800144/article/details/89531716
微服务架构,是系统架构的一种设计风格,与之相对的是,传统企业系统架构中的单体架构,本文谈谈为什么我们要实施微服务结构。
1.架构演进
这里借助dubbo官网的一张图来说明架构演进之路:
图片来源:dubbo官网 随着互联网的发展,用户基数变得越来越大,网站应用的规模也不断扩大, 常规的单体应用和垂直应用架构已无法应对, 分布式服务架构以及流动计算架构正在成为一种趋势。
1.1单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
1.2垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
1.3分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。
1.4弹性计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
我们这里重点谈谈单体架构和微服务架构设计的差异。
2.单体架构
单体服务应用部署比较简单,在项目早期代码库比较小,开发人员比较少的时候,用单体服务开发,测试,部署都比较简单,但随着人员的增加,代码库也在一直膨胀,这样的话,整个单体服会变得越来越大,越来约复杂,可维护性和灵活性都会降低,而且维护成本会越来越高,这个时候整个服务随着业务的发展,提供的功能将会越来越多,比如说支付,用户,权限,订单,积分,仓储等,或者金融系统中的借款,授信,资金,支付,日志等,当用户量的少的时候,这些都不是问题,一个war包搞定,但是随着业务的发展,用户量越来越多,开发团队也越来越庞大,就逐渐会遇到以下的一些问题:
2.1复杂性
可能最初的代码数量是几万十几万行规模的,但是慢慢的会变成几十万,几百万级别的规模,不同的人,写代码的风格不一样,代码质量也不一样,而且随着业务的发展,提供的功能越来越多,边界也变得模糊不清,这个时候修改和维护越来约复杂;
2.2技术债
随着时间的推移,需求的不断变更和人员的不断迭代,整个项目已经很少有一个人可以完整的说清整个项目的业务规划和代码逻辑了,开发的时候可能会发现历史代码可能有地方不够优雅,或者说实现的非常粗糙,甚至有潜在的漏洞,但这个代码不是发现者本人写的,这个时候这个代码可能就不去更改,因为更改需要了解这个部分的整个逻辑,不然该处问题了,责任是谁的?这导致整个代码库的代码质量会变得越来越差,越来越难以维护;
2.3可靠性
可靠性,由于所有的代码都是在一个服务里面,做一次改动,可能会牵一发而动全身,小公司的开发模式,很多都是面向领导开发,而不是面向客户,开发模式也多样,有瀑布开发,有敏捷开发,也有“闪电”开发,这种时候,开发完,压根没有时间去做系统化的测试,只能是改哪里测哪里,这种做法,没有覆盖到的地方,就会有潜在的风险,只是当下可能没有暴漏。
2.4拓展能力
单体服务,作为一个整体部署,遇到性能瓶颈,可以换更强劲的机器,但是实际的需求,比如说在这个应用中有多个服务模块,其中一个模块,而是计算密集型的,他需要更强大的cpu,而另一个模块可能是io密集型的,他需要更大的内存,但是由于在一个服务上面,我们在这个硬件的选择上不得不做出一些综合性的妥协;
2.5技术迭代
由于单体服往往都是用同一套技术解决方案,或者用同一种语言来编写的,如果想要引入新的框架或者说新的语言,基本上就意味着整个项目需要大的重构或者重写,这种替换成本,或者说代码的升级,技术的升级,切换成本是非常高的。
这里仅仅列出以上几点单体服务在业务不断发展的过程中,可能会遇到的问题,当然,细细挖掘,还会存在着更多的问题,如何来解决单体服务面临的问题呢?微服务架构的产生,就是为了解决这个问题而来。
3.微服务架构
微服务可以理解为一种架构风格,就是将一个单一的服务拆分为一组小的服务,每个服务运行在自己的服务器上,服务与服务之间通过轻量级的通信机制,比如说http的restful api来进行通信,这一组服务在一起,共同完成整个项目的业务需求。
3.1微服务的优点
3.1.1 边界清晰
比如说一个电商平台,我们以前是部署在一台服务器上,所有的代码打成一个war包。现在,我们可以给它拆分开:用户服务,积分服务,支付服务,仓储服务,信息服务,地图服务等等,每一个微服务只关注一个特定的业务功能,这样的话开发和维护单个服务都比较简单,因为它的边界足够清晰,业务也足够清晰,支付服务,只做好支付的事情就好了,相较于之前的大而全的单体服而言,每个微服务的代码量也比较少。
3.1.2 效率搞
单体服务随着代码量变得越来越多,比如说百万行级别的代码,仅仅编译一次应用可能就需要花费很久,但是现在,如果一个地方有问题,比如说支付模块有问题,只需要单独修改支付模块,修改完支付模块之后,单独测试支付功能,单独部署支付模块就可以了,而不会影响整体的部署速度。
3.1.3 技术迭代
每一个服务可以使用不同的技术栈来实现,由于不同的服务之间是通过restful API来通信的,所以每个服务可以使用不同的技术框架,使用不同的存储库来实现;
3.3.4 拓展性
随着业务的发展,用户量变得越来越多,或者说订单量猛增,这时我们可以专门去优化这个订单服务,给这个订单服务提供更高配置的机器,而其他并没有遇到瓶颈的业务,比如说短信服务,我们可以暂时不用动。
当然,微服架构也不是万能的,使用微服务架构也是有一些代价的,比如:
3.2 微服务的缺点
3.2.1 运维成本
以前只需要打个war包扔在tomcat下面就可以了,但现在,我们可能需要部署几个甚至几十个微服务,这样的话,如何保证这几十甚至上百个微服务正常的运行和互相通信协作,这给运维带来了很大的挑战;
3.2.2 分布式问题
使用微服务这种架构,构建的是一个分布式的系统,在分布式系统当中会引入很多问题,比如说分布式锁,分布式事务等等,这个时候我们需要对这个系统的,事务,幂等,网络延迟,分区,熔断,降级等问题都要有一个妥善的处理和应对方案;
3.2.3 通信
由于之前的接口调用都在同一个进程内,我需要支付调用支付方法,需要积分直接调用添加积分的方法,但现在,由于积分模块或者支付模块都被拆成了单独的服务,这个时候如果再想去调用的话,就是通过http方式的请求去调用,这种频繁的跨服务通信是有很高的成本的,选择一个适合自己业务的轻量级低成本的通信方式,也很关键。
3.2.4 服务拆分
如何做好微服务的拆分?这个是需要我们不断摸索的,从单体服务向微服务架构的演进,它是一个循序渐进的过程,在演进的过程中常常会根据业务变化来对微服务进行重构,甚至是重新划分,从而让这个架构更加合理。
如何把握拆分的粒度,在一些相关书籍中,提到了一些原则,我们需要尽量的遵守,这几个原则有助于我们更加合理的 进行微服务的架构。 单一职责 单一职责指的是一个单元,这个单元可以是一个方法或者一个服务等,这个单元应该尽量关注自身的一部分,要搞清这个边界,这样的话,我们可以降低跟其他服务之间的耦合。 服务自治 服务自制,每一个微服务都应该具备独立的业务能力,在微服架构中,每一个服务都是一个独立的业务单元,应该与其他服务高度解耦,每一个微服务,该服务都应该可以独立运行,而不应该再依赖于其他的服务。 轻量级通信 轻量级通信机制,由于我们是在不同的服务之间通信,而且会高频率的通讯,所以我们认为好的通信机制应该具备两点:一,应该是轻量,二,应该是跨平台跨语言的。
服务粒度 服务拆分的粒度,这个是一个重点,也是一个难点,不能一味的把这个服务拆小,也不能以代码量作为这个微服拆分的依据,我们应该划清整个系统中有几个大的服务模块,根据不同的业务模块本身的业务特点来进行划分。