这是我参与「第三届青训营 -后端场」笔记创作活动的的第 4 篇笔记
微服务架构介绍
系统架构演变历史
随着互联网的爆炸式发展,需求变的越来越复杂,开发人员也不断增加。应用的架构随着发展也在不断演进:
单体架构
这种架构是性能最高,冗余最小的架构,但代价就是debug异常困难,我们在自己编写程序的时候,如果一个功能的代码达到几百行就要考虑封装成一个函数了。而这种架构规模一旦做大几乎是无法debug的,模块间耦合极高。对于分工合作开发也是灾难。
垂直应用架构
这种架构按照业务的不同进行垂直划分,这样业务独立出来对于开发维护友好了很多。但每个业务仍然是单体,存在功能冗余无法复用。
分布式架构
这种架构开始抽出与业务线无关的各个模块,分布式独立部署运行。从图中也可以看出来服务层的调用关系错综复杂,一个模块服务有问题可能导致整个系统奔溃,且不同服务间依然存在冗余。
SOA架构
这种架构开始引入“服务”,“服务注册”等概念,通过访问服务注册中心来调用不同的服务,解决了服务间调用混乱的问题。但这种设计在结构上依然是中心化的,需要从上至下来设计划分,在架构好之后如果项目需要重构也会比较困难。
微服务架构
SOA架构的进一步演进就是当前比较流行的微服务架构,它彻底的将应用服务化,将服务作为一等公民。服务只需关心本服务需要维护的功能,之间通过网络来通信。同时一个服务的更新也不会影响到其他服务。提供了高效的开发迭代效率。
但这么做当然也有代价,服务间通过网络通信会让治理和运维的难度急剧增加,服务间的安全问题该如何保证,分布式系统本身的复杂性都带来了新的挑战
为了确保基于微服务架构的应用可以稳定,高效的运行,需要在架构上做一系列的拓展来保证:
微服务架构原理及特征
基本概念
- 服务:一组具有相同逻辑的运行实体
- 实例:一个服务中,每个运行实体即为一个实例,实例与进程没有必然对应关系,往往一个实例对应一个或多个实例。常见的实例承载形式有进程,VM,k8s pod....
- 集群:通常指服务内部的逻辑划分,包含多个实例
- 有状态/无状态服务:指服务的实例是否存储了可持久化的数据(比如磁盘文件)
服务发现
我们都知道对于微服务,服务间的通信是通过网络完成的,其实在单体服务中也是有模块通信的,只不过这种通信仅体现为简单的函数调用,所以我们一般不会在单体应用关注模块通信的问题。回到微服务,通信意味着网络传输,那么在代码层面,如何指定调用一个服务的地址呢?
很容易想到,知道了ip和端口号就可以调用了,像下面一样:
client := grpc.NewClient("10.23.45.67:8080")
但实际上,服务往往会有多个实例,一个服务的所有实例都是运行同一份代码,这种硬编码的方式让服务全都访问同一个地址。而且服务实例ip和端口是动态变化的。那样就更没法请求成功了。造成下面的结果
业界公认的一个解决方法是新增一个统一的服务注册中心,用于存储服务名到服务实例的映射:
流量特征
刚刚了解了微服务的基本概念和服务发现的思想,我们再从流量的角度看看微服务架构的全貌:
- 统一网关入口
- 内网通信多数采用RTC,效率更高
- 网状调用链路
我们弱化了连接的概念,强调请求。即同一个客户端长连接发出的请求,理论上可以到达服务中所有实例,API gateway 可以用作身份认证,进而将token附在请求上