【架构】微服务治理
微服务评审点:
- 基本信息:正确的服务名
- 功能:业务场景,提供什么功能,比如以用例图方式表述
- 上下文:与周围服务关系,调用方,依赖哪些微服务
- 领域模型设计:资源模型、关键数据结构定义
- 关键API设计:通过Swagger
- 可靠性设计:熔断、降级、流控设计
- 性能设计:支持的业务规模,提供的性能数据,如TPS、时延
- 全球站点设计:组网、部署
降级熔断(有损)
熔断实现方式:断路器模式
限流算法:
漏桶、令牌桶
倾向于使用令牌桶算法,原因是漏桶算法在面对突发流量的时候,采用的解决方式是缓存在漏桶中, 这样流量的响应时间就会增长,这就与互联网业务低延迟的要求不符;而令牌桶算法可以在令牌中暂存一定量的令牌,能够应对一定的突发流量,所以一般我会使用令牌桶算法来实现限流方案,而 Guava 中的限流方案就是使用令牌桶算法来实现的。
使用令牌桶算法就需要存储令牌的数量,
单机上实现限流的话,可以在进程中使用一个变量来存储;
分布式环境下,不同的机器之间无法共享进程中的变量,我们就一般会使用 Redis 来存储这个令牌的数量。这样的话,每次请求的时候都需要请求一次 Redis 来获取一个令牌,会增加几毫秒的延迟,性能上会有一些损耗。 因此,一个折中的思路是: 我们可以在每次取令牌的时候,不再只获取一个令牌,而是获取一批令牌,这样可以尽量减少请求 Redis 的次数。
降级实现:
站在整体系统负载的角度上,放弃部分非核心功能或者服务,保证整体的可用性的方法,是一种有损的系统容错方式。熔断也是降级的一种,除此之外还有限流降级、开关降级等
常见场景下降级策略:
-
针对读取数据的场景,我们一般采用的策略是直接返回降级数据。
比如,如果数据库的压力比较大,我们在降级的时候,可以考虑只读取缓存的数据,而不再读取数据库中的数据;如果非核心接口出现问题,可以直接返回服务繁忙或者返回固定的降级数据。
-
对于一些轮询查询数据的场景,比如每隔 30 秒轮询获取未读数,可以降低获取数据的频率(将获取频率下降到 10 分钟一次)。
-
而对于写数据的场景,一般会考虑把同步写转换成异步写,这样可以牺牲一些数据一致性和实效性来保证系统的可用性。
1、实现方案:开关降级
代码中预先埋设一些 开关,用来控制服务调用的返回值。比方说,开关关闭的时候正常调用远程服务,开关打开时则执行降级的策略。这些开关的值可以存储在配置中心中,当系统出现问题需要降级时,只需要通过配置中心动态更改开关的值,就可以实现不重启服务快速地降级远程服务了。
场景:以电商系统为例,你的电商系统在商品详情页面除了展示商品数据以外,还需要展示评论的数据,但是主体还是商品数据,在必要时可以降级评论数据。
boolean switcherValue = getFromConfigCenter("degrade.comment"); // 从配置中心获取开关的值 if (!switcherValue) { List<Comment> comments = getCommentList(); // 开关关闭则获取评论数据 } else { List<Comment> comments = new ArrayList(); // 开关打开,则直接返回空评论数据 }
浙公网安备 33010602011771号