微服务架构原理与治理实践 | 青训营

111 阅读3分钟

微服务是当前大多数互联网公司的标准架构

架构

image-20230814143742461.png

image-20230814143801078.png

单体架构

image-20230814144459625.png 将所有逻辑放在同一个服务器上面,模块之间相互影响 可以有一个模块有bug也会影响其他的模块

垂直应用架构

image-20230814144706786.png 不同的业务线分开在不同的服务器

每个业务线都有不同的单体架构,但是业务之间没有办法复用

分布式架构

image-20230814145635389.png 存在服务之间的冗余

SOA架构

image-20230814145751909.png 业务层和服务层之间 有了更清晰的划分 通过服务注册中心进行解耦

微服务架构

image-20230814153045668.png

image-20230814153346677.png 从下到上业务独立

核心要素

image-20230814153201922.png

原理及特征

基本概念

image-20230814153417776.png 服务:一个服务必须运行同一段代码,服务就是运行同一段代码的多个实例

类比:

image-20230814153705869.png

服务注册及发现

服务之间的通信

gprc 固定ip:port

image-20230814154834723.png 上面的代码在微服务中有问题,不能直接写死ip地址,因为在真实环境中目标ip是会变化的,而且在目标服务器中会有多个实例 如果将端口写死的话只能访问到那个固定的实例而忽略了其他实例

image-20230814155038690.png DNS

image-20230814155500222.png b.service.org可以配置不同的域名ip地址,但是不是随机出的三个ip 很大概率会选前面的

服务注册及发现

服务注册中心:hash或者是map表

image-20230814155707376.png 绿色的代码中用了random相当是一个简单的负载均衡的算法 而且可以直接注册ip和端口

image-20230814155817347.png 假如想要下线instance3

删掉服务注册中心的instance3 ,这时候还是有流量来instance3,所以需要服务a刷新之后就不会调用instance3了 ,这个时候才能删除instance3,不用担心流量问题

添加instance3

在服务发行之前就先放好instance3,并进行健康检查试一试这个实例是不是真的可以处理请求,检查完之后才能把实例放到注册中心、

流量特征

image-20230814160546760.png

核心服务治理

服务发布

image-20230814185129891.png 服务回滚:回滚到之前没有bug的代码(降低损失)

  1. 蓝绿部署:先将一部分实例流量断掉进行更新 这个时间段内 另一部分实例运行,这一部分更新完成之后 再给另一部分升级

    image-20230814185419894.png 简单稳定,但是需要两倍的资源(使用这种方法的话最好选在流量低峰期使用)

  2. 灰度发布/ 金丝雀发布

    image-20230814185702875.png 需要不停得切换流量 且回滚比较麻烦

流浪治理

image-20230814185851889.png 上图中北京的instance比较多 所以流量给北京的也比较多

稳定集群流量较多

负载均衡

希望每个instance接收到的请求是差不多的

image-20230814190311691.png

稳定性治理

线上问题

image-20230814190404396.png

稳定性治理

image-20230814190509809.png

image-20230814190538405.png 限流:如果服务器的处理能力不同,比如a是5000,b是1000 那么b会拒绝额外的4000

熔断:a给b发送请求 但是没有响应,那么a会自动熔断不会一直去请求b,而是隔一段时间再去请求

过载保护:b如果cpu占用太大 会直接拒绝掉a

降级:优先保证重要的

字节服务治理实践

重试

image-20230814191044794.png 本地函数调用 如果一次没有成功的话 那就不需要再试了

但是如果是远程函数调用的话 可以尝试多次,因为出错的可能不止程序本身

image-20230814191154686.png 所以远程函数调用可以写成下面的 就是多次调用 只要有一次成功就可以

好处

image-20230814191816200.png 涉及到网络调用都可以使用重试的方式或者写代码的时候就用for循环重试

难点

重试风暴

image-20230814192010019.png 每次调用都重试多次的话 因为调用链路很深,所以会导致重试风暴(重试时间到后面会越来越深)

解决

限制重试比例

image-20230814192245183.png 防止链路重试

image-20230814192324620.png 对冲请求

image-20230814192426161.png