微服务架构之演进历程
Posted ShuSheng007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务架构之演进历程相关的知识,希望对你有一定的参考价值。
[版权申明] 非商业目的注明出处可自由转载
出自:shusheng007
概述
当前软件系统不跟微服务沾边的话会给人很落后的感觉,但微服务的风刮的有点歪了,你见过只有2个开发者却有10个微服务,然后还都部署在同一台物理机上的系统吗?不要怀疑,真有。
不过微服务架构对于大型软件系统确实是个好东西,今天我们来聊一聊分布式架构的演进吧,水平有限,就当抛砖引玉,不喜勿喷。
前后端分离
现在我们谈论的系统架构一般指后端架构,只有存在后端才有后端架构,对吧?以前前后端是在一起的,所以不分前后端,都是软件架构。那什么是前后端分离呢?我现在觉得很简单,但说实话刚接触时死活搞球不明白,小朋友们不要笑话我…。要明白前后端分离是啥样,你先的明白不分离时候是啥样。
不分离时代
在不是很久以前,前后端是不分离的,也没有现在这个意义的前端后端程序员,都是web程序员。当时说的前端大概和现在的UI设计师职责差不多吧:负责设计和切图。做web的程序员不止需要会写业务代码也的懂html、css,为什么呢?因为浏览器展示的那个html就是由你在后端写的,浏览器请求的时候你根据业务逻辑计算好html中需要填充的那些值后,生成最终的html传给浏览器展示。
现在你使用SpringBoot开发web项目时候,还是可以集成一些web的模板引擎,例如Thymeleaf(三叶草),这个你要是以前没听过的话就当个历史听一下就好了,现在新项目基本没人用这种方式了。
分离时代
前后端分离后,web程序员也被分为前端程序员和后端程序员拉。分离后啥样呢?分离后后端程序员只管写接口,然后使用JSON格式与前端做交互(当然也可以使用别的格式,只是Json是主流)。那前端程序员干啥呢?前端程序员负责页面的渲染和交互,如果需要执行业务了就使用javascript向后端发起异步请求。
分离后,前端程序员终于是真的程序员了,用上了各种各样的js编程框架:ReactNative、Vue、Angular等等
不得不提一嘴,风风火火的移动互联网大潮也加速了前后端分离的步伐,因为你用的各种手机APP可以认为采用的是C/S架构而不是B/S,APP不认识HTML,所以前后端必须分离。
单体(All-in-One)
第一版
其实大部分业务,特别是传统业务整个生命周期单体都足够了,对于互联网应用,早期也是足够的。那这个架构一般是怎么样的呢?
我们简单介绍一下
首先最好是做成前后端分离,后端也非常简单,就是一个mysql数据库加上一个web服务器,优先使用nginx,ORM框架使用mybatis或者mybatis-plus,可以使用CDN来存储服务用到的图片,视频等变化频率不高而大量占据网络带宽的资源。
初期整个后端都部署在同一台服务器上都没有问题,
第二版
当流量不断提高后,前面的架构可能就不能应对了,此时要上分布式吗,暂时不用,还可以努力一下。
此时一台服务器就不够了,最好将数据库单独部署在独立的服务器上。不知道同学你是什么情况,但我当初接触后端的时候是分不清应用服务器与数据库服务器的,在我浅薄的认识里面应用和数据库都是在一台机器上的,为什么要分开呢?万事开头难…
然后对于读操作加上缓存,现在也别用什么本地缓存了,直接就上redis就行。应用服务以集群的形式部署,注意将其做成无状态的,那样你想部署多少个实例都没问题。 既然你的服务部署了多个实例,那么你就的有负载均衡组件,不然一个请求过来那么多服务实例,你到底让谁处理呢?所以在服务前方再部署一个Nginx作为反向代理,也提供负载均衡的功能。
第三版
当业务量继续增大,读写事务不断增多,那么数据库就会成为整个架构的瓶颈了。也就是一个数据库不能支持正常的增删改查了,表现就是你发起个操作半天没有响应,用户就不能忍了,老板也就不能忍了…
你也许会问,数据库怎么又是你,怎么老是你?那是因为数据库实在太重要了,一个软件系统一直在那边倒腾,你以为它在倒腾什么,还不是数据?
与第二版比数据库进行了读写分离,可以采用一主一从,或者一主多从,或者双主双从。但是有一点要牢记在心,不管如何折腾,每个数据库存储的数据都是一样的,而且连表的结构以及索引都一样,所以优化空间也不大。
主从复制的好处有如下几点
- 可实现读写分离,提高系统的吞吐量
- 可实现数据冗余,提高系统的可用性,一个挂了,另一个顶上。
你要记住提高系统可用性都是采用冗余的方式,这个思想非常朴素。你怕你生个儿子将来是个坑爹货,那就多生几个,万一有能光宗耀祖的呢。提高并发量就是降低响应时间,横向扩展加异步:假如现在咣当一下1000万请求过来,下面1000个实例每人分1万个请求,然后立马返回不做具体的业务处理,只是丢到消息中间件中,告诉用户我已经在加紧处理拉,一会通知你,然后背后慢慢处理。详情我们后面再讨论
我们这里可以看一个双主双从的实现方式
主1主2互为主从,主1主2只要有一个正常工作系统就可以正常读写,但是要是主1主2都挂了,那么就只能读了。整个系统完全挂了的条件非常苛刻,就是所有数据库都挂了,你这是倒了血霉了,认了吧
分布式
当用户暴增,流量继续暴增,数据量暴增,数据库主从架构已经完全顶不住了,要分库分表了。一般业务到了这种体量你的团队不可能只有一两个人了,该上分布式了,微服务该上场了。
任何事物都是具有两面性的,微服务也不例外,我们在享受微服务带来的一系列好处的同时也要面临微服务带来的一系列问题。下图只是初略的划了一下微服务的基本架构。
我们简单的论述一下一整套完整的微服务系统都需要具备哪些功能。
- 反向代理
一个请求首先遇到的就反向代理,同时这一级也会做负载均衡。如果系统非常庞大,也可以采用多级负载均衡,让能力强的大哥顶在最前面
- API 网关
网关是微服务系统非常重要的组件,外界访问微服务系统都要经过网关。我们可以在网关上做很多事情,例如认证,鉴权,限流,灰度发布,A/B测试等工作。
要想理解网关适合干的事情,想一想它的特点:门。流量都要通过它流入门内部,那你在这门这边就可以检查你这个流程是不是非法的流量啊,每秒钟允许多少个流量通过啊,某个特征的流量转到哪个服务去处理拉…
在SpringCloud中,API 网关使用SpringCloud API Gateway,或者Zuul
- 服务注册中心
这个组件也很好理解,因为希望微服务化后会存在很多个服务,这些服务还经常上线和下线。如果一个服务想要调用另一个服务的接口,那它必须知道这个服务的地址和端口号啊,所以得有一个维护这些信息的地方,这就是注册中心。
注册中心一般要以集群的模式部署,因为它容易形成单点,也就是说它挂了,整个系统就挂了。
- 服务配置中心
为什么需要这个组件呢,因为有非常多的微服务,每个微服务都有自己的配置,如果没有一个统一的地方来进行修改和维护这些配置,那么就会变的非常混乱,大部分情况下我们还有热更配置的需求,就是线上改完配置不需要重启服务就生效。
- 负载均衡
由于一个服务一般情况下会部署多了实例,所以就需要负载均衡来决定哪个服务来处理请求。例如商品服务调用订单服务来完成下单操作,如果订单服务启动了2个实例,那么商品服务就要使用负载均衡来决定请求哪个实例。
- 断路器
由于一个业务可能需要多个微服务互相调用才能完成,例如 A调用B调用C。 如果下游的C挂了,迟迟不能给B返回结果,而用户那边还源源断有请求过来,那么B就不断的向C发起新的请求,B不断的消耗程序资源,直到资源用净,B也挂了。B挂了,那么A的命运也就可想而知了。最后大家一起玩完,这叫系统雪崩了。
所以我需要一种保护机制,来将失败隔离在某个微服务内部,而不是让错误蔓延到整个系统。
- 链路追踪
前面也说了,在微服务系统中,完成一个业务操作一般都是需要多个微服务互相协作才能完成的。那么如果没有全链路追踪,业务一复杂了,理清业务,查找bug就会变得异常困难。
- 量度监控
服务上线了你至少的知道当前系统的情况吧?哪个服务挂了,哪个接口挂了,哪个服务的请求情况是怎么样的,程序资源目前是怎么样的等等
上面是一微服务本身需要的组件,除此之外消息中间件(rabbitmq/kafka),分布式缓存(redis),数据库(Sql(mysql),nosql(mongodb),newsql(TiDb))这些都是构建分布式系统都必须要掌握的知识。
总结
在我们的工作中,其中大部分都存在过度设计,真正那种亿级流量级别的系统可遇不可求,如果你有幸参与其中真是一件特别幸福的事情。很不幸,我没参与过…
请持续关注…
源码
以上是关于微服务架构之演进历程的主要内容,如果未能解决你的问题,请参考以下文章