这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
前言
微服务架构是当前大多数互联网公司的标准架构。
本文主要介绍:
1. 微服务架构的由来及原理
2. 服务治理功能是如何工作的。
一、微服务架构介绍
1.1 架构演变历史
单体架构
垂直应用架构
分布式架构
SOA架构
微服务架构
1.2 微服务架构概览
1.3 微服务架构核心要素
二、微服务架构原理及特征
2.1 基本概念
HDFS(分布式文件系统)
企业中 HTTP 和 gRPC 是用的比较多的
2.2 服务注册与发现
问题:1.IP一般不固定 2.一般服务里面不止有一个实例。如果按照上图的代码来实现服务A向服务B进行调用,则服务B只有一个实例会收到请求
如果使用DNS来解决这个问题呢?
不行。问题:1.本地DNS会缓存域名对应的IP,如果后端更新IP则本地缓存需要一段时间才能更新 2.负载均衡问题:虽然负载均衡里面给一个域名写了很多的IP,但是大概率还是走第一个IP的 3.即使配置了非法IP也是可以的 4.IP解决了端口还是没有解决
因此,为了解决上述问题,应该加一层服务注册中心(服务名——服务实例的映射(哈希表))
服务上线和下线的过程
下线一个实例
- 先删除服务注册中心中服务B中的实例3
- 等过一段时间后,服务A中的实例的流量全都打到服务B中除了实例3之外的其他实例上之后
- 下线服务B中的实例3
上线一个实例
- 先启动一个实例,并进行健康检查(比如端口起码要监听,发送一个TCP建联试一试)
- 健康检查通过后,将该实例注册到服务注册中心里面
- 此时服务A向服务注册中心请求注册之后,实现了服务A流量发送到服务B
2.3 流量特征
HTTP是文本协议,运行效率比较低,性能较差。gRPC是二进制协议,无论是传输信息的大小或者编解码的效率都会高很多。因此内部的服务调用之间通常采用RPC的协议
offline training job:常见的是机器学习训练,一般也会走RPC
三、核心服务治理功能
3.1 服务发布
服务发布,指让一个服务升级运行新的代码的过程(IDE底下点一下run就行了,terminal底下重新编译一下也实现了)
服务发布的难点
解决方法:
- 蓝绿部署(适合流量低的时候使用:比如抖音早上或者凌晨刷的比较少那就早上或者凌晨进行升级)
将实例分成两个部分先将所有的流量引到一半的实例上,对另一半的实例进行升级。
完成升级后再将流量引入回升级好的实例上,对没有升级的一半实例进行升级。
- 灰度发布(金丝雀发布)
先增加一个升级后的实例(+),若该实例没有问题,则下线一个老的实例(-),若没有问题则重复上述步骤,直至所有实例都变为新的实例
回滚很困难(k8s提供了强大的基础)
3.2 流量治理
对内部用户测试自己的功能
3.3 负载均衡
3.4 稳定性治理(重要)
线上服务总是会出问题,这与程序的正确性无关
典型的微服务治理功能
降级:保证重要的服务(优先级高的服务)能够正常运行,优先级低的服务拒绝
小结
四、字节跳动服务治理实践(重试)
4.1 重试的意义
- 本地函数的调用没有重试的必要,除非一些特殊的场景
- 远程函数的调用有重试的意义,比如下游机器正好这个时候宕机,那么重试一次可能就可以了(避免偶发的错误)
重试的意义
长尾延时(看pcd95小于一个阈值)
4.2 重试的难点
- 幂等性
- 重试风暴(雪崩)
微服务里面的调用链路很深,实际开发的时候可能会有几十层(下图为3层,每次失败都重试3次)
4.3 重试策略
应对重试风暴的方法
1)限制重试比例: 设定一个重试比例阈值(比如 1%),重试次数占所有请求比例不超过该阈值
2)防止链路重试
服务C如果失败了那就返回一个全局的返回值(“请求失败,但别重试”),这样就能防止链路重试
3)Hedged requests
- 超时设置(重试之间的间隔不好设置)
PS
本文主要作用是作为上课笔记,如有错误,欢迎大家评论指正,我会及时改正