微服务的出现和意义的探索

随着互联网的推进,使用人数也在急剧增长,而各种原本简单的问题都因为流量的上涨而出现了一系列的问题。。。而传统应用架构模式也渐渐难以支撑起这么大的流量,那如何通过改变传统的架构模式来增大我们应用的承载量,成为了我们每一个程序员经常讨论的问题。。。

在原来的应用层上不做过多的更改,通过在web服务器上做负载均衡,来减轻web层的压力,通过mysql做读写分离,来减轻读操作的的压力(读写分离,只能很大程度上减轻数据成读操作的压力,对于写操作的压力作用并不多);通过引入缓存(redis等)来减轻数据层的压力。。。的确如此!通过机器的集群的确是快速提升应用承载量的重要途径;但是通过时间的检验,我们也发现:随着业务的发展,应用包含的东西会快速增长,应用变得越来越庞大,只是单纯的通过硬件的进群来解决承载力问题阻力会越来越大;如:

  1. 应用越发庞大,维护成本巨高无比
  2. 业务层面的东西无法,独立上线,很多时候会相互影响
  3. 应用内部的功能也离“低耦合、高内聚”越来越远了

其实问题很多上面只是随便写了一点,所以我们经常留意到一些大牛的分享他们的架构,总会说,因为某某原因,我们进行微服务,我们公司开发了一套服务治理框架。

那问题就来了什么是微服务呢?其实我的理解很简单,那就是功能“模块化”,当然这个模块化跟我们写代码时候的模块化不同,但是也八九不离十了,其实就是相当于将模块化的东西独立成项目,通过外部调用的方式实现解耦(简单理解就是接口方式),不同的功能模块提供不同的服务;

看了这么多还是有点是懂非懂的话!那下面我通过一个商城项目来详细叙述下我的看法:

1.传统的单一服务支撑应用

image

注意: 上述中的nginx服务层,还有数据层,还有一些动态代码的解析,单一提供服务,不代表都装在同一个电脑哟。。。这个是不一样的,例如:nginx,php-fpm,mysql不一定都装在一台电脑上,可以分开装在不同的电脑上通过网络调用的哟;

这种方式就是比较原始应用的模式;

开启一个服务对外提供整个商城项目的所有服务;其实我们不难看出,单一的服务层,难以为一个应用提供比较大的承载量;

既然单一机器提供的服务承载量有限,那么我们就尝试做一个机器的集群,用一群机器来处理。。。那就衍生了后面出现的集群模式的架构!

2.集群支撑服务

image

这个架构也是现在,中型项目普遍的使用的架构,web层通过负载均衡降低但台机器的压力,数据库通过主从复制实现读写分离,通过主主复制实现数据库热备份。在业务层再引入缓存组件(redis)来降低数据库压力。

其实上述的架构其实在我看来其实都属于单体架构:

那问题来了,什么是单体架构呢?

简单看来,所有的功能,业务都集中在一个项目中,统一发布,统一部署,部署在同一个进程中;这就是单体架构;上图可以看出其实可以看出 整个 商城项目所有功能,基本都会运行在同一进程;或者可以理解成 "同生共死";

那单体架构有什么好处呢?存在就必然有其合理性;
  1. 简单功能开发简便:单体功能添加简单
  2. 易于整个系统重新部署:直接所有代码打包发布到指定环境即可
  3. 易于测试:发布单系统即可测试
  4. 整体水平伸缩方便:nginx 简单做负载均衡即可
既然出现了进化,那必然是因为时代发展,单体架构面临新的挑战;
  1. 代码快速膨胀,维护成本巨大
  2. 持续交付时间边长
  3. 团队成员交接艰难
  4. 扩展性太差了(不同的模块需要的系统资源不同:CPU,内存,磁盘空间;没办法单点对应)

也许你会发现,单体架构的优缺点似乎有些矛盾,其实不然,毕竟在不同的环境下,不同的时间,优劣势相互转换的;下面我们详细举几个例子:

随着项目的发展,业务范围的扩张,用户量提升,开发团队壮大,由原来的5~6人维护,现在变成了上百号人共同维护,就会出现问题了:

  1. 随着用户体系的变大,部分模块的的的访问压力会不断提升,也有些模块其实不会随着用户体系的增大而需要较大的承载量;但是由于系统还是集中式的,所以没办法实现单模块扩容;这样其实也是一种资源的浪费;(eg:没有办法单一对 用户模块做负载)
  2. 业务范围扩张,单系统架构也给维护和升级带来巨大的困难,当单一模块发布更新的时候会导致整个系统的停止提供对外提供服务;为了避免这样的问题,往往需要大量的回归测试;这也导致大量的人力资源消耗。。
  3. 风险也是巨大的,当单一模块出现了问题;大量消耗系统资源,会导致其他模块也无法正常提供服务;
  4. 系统不断升级,功能大量堆积,导致系统代码量不断增加,系统代码复杂度越来越高,对于新员工上手也是一个巨大的挑战;
  5. 当系统出现问题时,因为系统的臃肿,也无法快速定位解决问题

3.微服务的出现

既然随着时代的发展,单体架构面临着巨大挑战,传统技术架构难以支撑现时代的互联网的用户体系;而微服务应运而生;

那么什么是微服务呢?
  1. 系统拆分成多个服务,每个服务运行在独立的进程里;
  2. 使用轻量级别的通讯机制
  3. 通过自动化方式进行部署
  4. 有着相对独立而完整的报警和故障切换机制
微服务的特性
  1. 单一职责 :每个服务提供单一的服务;这样也大大提高的问题的定位和解决的速度。。毕竟哪个服务是哪个人负责的,大家心里都知道明白。
  2. 轻量级的通讯:其实这个也很好理解,就是跨平台,跨语言通讯就变得尤为;系统划分成多个服务,分别提供不同的服务时,可能出现“百花齐放”的局面;而跨平台,跨语言通讯就变得尤为(http,rpc等)
  3. 隔离性:每个服务都将部署在相对独立的空间,实现系统资源的隔离;简单来说就是避免你的代码跑挂了我的业务。。(docker是一个不错的选择)
  4. 有着独立的数据: 简单理解就是使用独立的数据存储服务;
  5. 技术的多样性:不同的服务瓶颈不同会导致选择技术的多样性(eg:大量的推送可能会使用队列而是用rabbitmq;大量的cup运算可能会选用 go or c 作为开发语言的选择;业务层面的渲染较多的服务,可能会选用php来快速迭代 )
下面画一个简单的架构图

image

注意: 上图说道的API Gateway 是一个简单网关;可以实现ip限制,流量限制,访问统计,负载均衡等功能(这是一个有趣的东西。。后续会详细一起探讨和学习。。)

没有最好的架构,只有最适合的,其实微服务也会有其自身的劣势;尤其是团队成员不足,或者服务化过度的情况,相关机制没做好(心跳,风控,故障切换,日志汇总和分析等)会导致问题无限放大;(本人深受其害。。。)

  1. 服务划分: 抛开技术实现(毕竟市面上确实有成熟而且较为完整的技术架构可以照搬),我觉得服务划分是服务化成功与否最重要的关键,拆分多少个服务?什么功能应该在同一个服务?服务拆分的力度是多少?这些问题都需要按照具体项目和具体公司资源情况而定,只有通过不挺的试错和不挺的探测才能找到适合自己公司的答案。。。然而很多公司都没有办法,度过这个艰难和黑暗的时期。。所以微服务不适合每个公司。。但是我觉得却又是每个公司不得不学习和探讨的重要课题。。
  2. 数据的一致性: 当服务拆分后,数据一致性也成为了一个十分重要的问题;常见的方案有:a)通过中间件实现事务多次commit;实现最终的commit;有兴趣的可以了解下“TCC分布式事务” b)我所在公司使用的是事务最终一致性;通过队列(rabbitmq)保证所有服务相互调用最后的修改都必须提交成功。。
  3. 复杂功能的问题排查: 当服务化后,你会发现你的有写复杂功能在不同的服务间相互调用。当其中一个环节出现问题,你要找出对应的环节,你会发现无比艰难。。。当然如果你有完善的微服务中做了完善的“分布式日志链路” 和 你们有一套完善的 日志收集和分析报警(eg:elk)机制;你会发现 排查问题也是如此简单。。(然而很多公司却没有做到这些较好的基础建设。。)
  4. 沟通成本巨增: 这个也是显而易见的问题,以前系统你一个人单枪匹马搞出来。。现在几十个甚至上百个人一起搞。。。沟通成了最大的消耗。。。有时候你会发现,你一个功能会牵连到5-6个服务的协助(这并不夸张。。)

一只小蜗牛
318 声望12 粉丝