1. 微服务架构介绍
本文主要介绍了微服务架构治理与治理实践,介绍了微服务的相关历史,介绍了微服务的原理特征,服务发现,负载均衡,流量治理相关的知识点。
1.1 系统架构演进历史
为什么我们系统架构需要演进呢? 随着互联网行业的发展,硬件不断进步,需求得复杂性也在不断进步,由之前的文本图片位置变成了 文本,图片,视频,音频,VR各种形式交汇,模式的复杂程度指数级别上升。
并且随着老一辈互联网开发人员各种退休和现如今的易于上手的开发平台的演进和计算机李理论技术的发展,很多代码技术都需要进行重构。 举个简单的例子,随着数据量越来越大,对于分布式需求逐渐增加,因此计算机的分布式相关的研究理论飞速发展,很多理论相比之前性能提升50%甚至更多。
下面简单介绍一下系统架构演进的历史,因为之前的架构初探 详细谈过,现在简单讲解一下。
首先是最简单的单体架构,单机下开发,模块不好分工,功能不好解耦合,所有功能互相依赖,牵一发而动全身。
接下来垂直应用架构,按照不同业务线进行垂直划分,但是每个业务都要写一个自己的组件,比如数据相关的。因此整个开发工作非常冗余。
接下来分布式架构,我们将与业务无关的基础设施模块抽出,进行统一管理,而开发者只用关注于具体业务的开发,但是业务关系还是复杂,一个业务出现问题全站都会崩溃。
接下来为了更加解耦,引入了服务相关概念,通过服务来代替业务相关的开发模式,提出了SOA的概念。通过SOA开发者更加专注于开发,更加解耦合,系统更好维护。
最后通过SOA的分布式方向演进,便是我们的微服务了。
微服务的优点在于,高效开发,故障可以控制。而缺点在于分布式本身的复杂性和治理难题。
1.2 微服务系统架构的整体概览和核心要素
下面是一个微服务系统的整体架构:
我们使用微服务需要进行链路追踪,服务治理,监控打点
2. 微服务架构原理和特征
2.1基本概念
下面会简单讲述一下,微服务架构的一些基本概念:
服务(service)一组具有相同逻辑的运行实体
服务被看作一个个功能单元,微服务将不同的功能单元组合成一个大的功能。
实例(instance)一个服务中,每个运行实体即为一个实例
实例与进程之间没有必然对应关系,可以一个实例可以对应一个或多个进程(反之不常见)。因为实例的开销问题,一个进程对应多个实例比较少见。
集群(cluster)通常指服务内部的逻辑划分,包含多个实例。
下面这是他们彼此之间关系的一个示意图:
对于单体服务,不同模块通信只是简单的函数调用,但是对于微服务,服务间通信意味着网络传输。
2.2服务注册及发现
因此我们彼此之间微服务通过网络进行调用,那么我们怎么知道彼此的IP地址和端口的呢? 他不能写死,动态变化的。借助DNS的思想,创建了一个注册中心,所有服务都把自己的服务注册到注册中心,注册中心主要进行服务的注册以及服务下线。
服务下线的过程常见的过程如下:
- 从注册中心注销当前服务,这样就不会再有新的请求进入。
- 拒绝或者延迟新的请求,这样就可以保证正在处理的请求不会被中断。
- 等待一段时间,让旧的请求处理完毕,或者超时。
- 关闭服务,释放资源。
2流量特征
我们已经了解了微服务的基本概念和服务注册和发现的思想,我们再从流量的视角看看微服务架构的全貌。 流量特征的核心是弱化连接的概念,强调“请求”。
我们使用API gateway可以用作身份认证,进而将token附在请求上,通过Token来对请求进行分辨,其结构如下:
3. 核心服务治理功能
服务发布
服务发布就是服务进行系统升级的过程,其中主要难点在于发布过程可能服务不可用,服务可能会抖动,服务出现错误可能会需要进行回滚。
针对上面问题提出了蓝绿部分:一次发布一半的服务器,另外一半提供原本的服务,如果没有问题将全部流量切换到新发布服务上,然后去切换另外部分的流量。虽然简单稳定,但是需要一倍的服务器资源。
接下来就是灰度发布,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。这也是目前使用的主流的发布方法。下图是一个简单示意图:
流量治理
在微服务架构下,我们可以基于地区、集群、实例、请求等维度,对端到端流量的路由路径进行精确控制。 通常所说的缓冲、限流、降级、熔断等在本质上是一致的,均为流量控制手段,用于防止系统过载,区别在于流控的手段和程度不同。
负载均衡
负载均衡是指将任务平衡、分摊到多个操作单元上进行运行。常见的负载均衡手段:
- 轮询法:将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。
- 随机算法:通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。
- 加权轮询法:同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。
- 加权随机法:根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。
稳定性治理
线上服务总会出现问题,例如网络攻击,流量激增,机房断电,光纤被挖,机器故障 网络故障,机房空调故障。
微服务架构中典型的稳定性治理功能包括限流,熔断,过载保护,降级。
4. 字节跳动服务治理实践
4.1 重试的意义
重试可以避免掉偶发的错误,提高SLA(Service-Level Agreement),很多问题只是由于客户端或者运营商网络波动而已,因此重试具有重大意义。
- 重试可以降低错误率,假设单次请求的错误概率为0.01,那么连续两次错误概率则为0.0001.
- 某些时候系统会有暂时性异常(例如网络抖动),重试可以尽量规避。
- 重试可以避开下游故障实例 一个服务中可能会有少量实例故障(例如机器故障),重试其他实例可以成功。
4.2 重试的难点
重试的难点主要有三个部分分别是:
- 幂等性:多次请求可能会造成数据不一致
- 重试风暴:随着调用深度的增加,重试次数会指数级上涨
- 超时设置:如果允许一次重试,如何确定第一次请求经过多少时间时,什么时候开始重试
如上面所示,一次服务重试三次,三重服务就是27次了。
4.3 重试的策略
常用方法包括:
- 限制重试比例:一般来说不超过正常请求的1%
- 防止链路重试: 如果是链路调用,防止调用链路上面每一层都进行重试,只在发生错误的一段链路重试。
- Hedged requests: 对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应。