从0到1实现RPC | 09 故障隔离与恢复

一、应用场景

故障隔离解决的是:当服务提供者provider出现异常时,消费者consumer就不再调用异常实例,而是选择好的实例,避免频繁出错。

故障恢复解决的是:一段时间过后,服务提供者provider可以正常提供服务时,可以自动加入到正常的服务列表。供消费者调用。

二、数据结构

使用到的数据结构包括:

  • providers:所有服务提供者,List类型;

  • isolatedProviders:被隔离的服务提供者列表,List类型;

  • halfOpenProviders:处于半开的服务提供者,用于自动探活,自动恢复,List类型;

  • SlidingTimeWindow:滑动窗口,用于统计在指定时间内发生的异常次数;

  • windows:一个实例对应一个滑动窗口,Map类型。

三、代码实现

在消费者端远程调用的动态代理类RpcInvocationHandler中,添加探活、故障隔离和故障恢复的实现逻辑。

图片

探活

为了能够拿到故障的实例,使用了halfOpenProviders,里面存储的就是故障的实例,使用定时任务,10s后启动,每隔60s执行一次半开逻辑:从故障实例中添加到半开实例中,用于请求探活。

图片

halfOpenProviders不为空,说明里面有处于故障中的实例,在请求中可以尝试使用该实例,进行一次远程调用。

如果为空,说明都是正常的实例,就走之前实现的负载均衡的逻辑。

使用synchronized防止并发异常。

图片

故障隔离

当某次调用出现异常时,使用滑动窗口记录该实例的异常调用次数,每发生一次异常就记录一次,当发生的异常次数达到指定阈值后,就隔离该实例。当前默认参数是:在30s内发生两次异常就会被隔离。

图片

隔离的逻辑其实很简单,就是将该实例从能够提供正常服务的实例providers中移除,添加到被隔离的提供者中。

图片

故障恢复

假如能够提供正常服务的实例providers不包含当前请求的实例,就从故障实例isolatedProviders中移除,添加到正常实例providers中。

使用synchronized防止并发异常。

图片

四、测试

  1. 在服务提供者provide端,添加方法isolate(),实现逻辑是当请求端口为8081时,使用除法,在测试时传入id=0,抛出异常。

图片

  1. 在消费者consumer端提供调用接口。

图片

  1. 启动zookeepr作为注册中心。
  2. 分别使用端口8081,8082,8083启动服务提供者provider。

图片

  1. 启动consumer。
  2. 多次发起请求调用。

传入参数id,使用的是轮询负载均衡,消费者会依次调用端口为8081,8082, 8083 的提供者,当前id为0,端口是8081会抛出异常。

在30s内发生超过两次的异常就会被隔离,每隔60s会有定时任务添加半开故障实例。

图片

  1. 观察日志。

先是8081发生故障次数达到指定阈值,加入到故障实例集合isolatedProviders当中。能够提供正常服务的providers就只有8082和8083

图片

接下来的请求,就不会走故障实例8081,达到故障隔离的目的。轮询调用的是8082和8083.

图片

60s后,定时任务执行,故障实例8081添加到半开实例 halfOpenProviders 中。

再进行一次请求时,会进行探活,尝试调用8081,传入参数id=1,调用成功,故障实例8081又重新添加到正常实例providers当中,故障实例成功恢复。

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/610352.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python+Selenium+Unittest 之Unittest5(常用装饰器-跳过用例执行)

目录 1、unittest.skip()(跳过该装饰器下的用例) 2、unittest.skipIf()(跳过该装饰器下判断条件为True的用例) 3、unittest.skipUnless()(跳过该装饰器下判断条件为False的用例) 4、unittest.expectedF…

Thingsboard PE智慧运维仪表板实例(二)【智慧排口截污实例】

ThingsBoard 的仪表板是一个用于可视化和监控物联网数据的重要组件。 它具有以下特点: 1. 可定制性:用户可以根据自己的需求创建各种类型的图表、表格和指标。 2. 数据可视化:以直观的方式展示设备数据,帮助用户快速了解系统状态。 3. 实时更新:实时反映设备的最新数据…

【RV1106的ISP使用记录之一】基础环境搭建

公司缺少ISP工程师,做为图像算法工程师的我这就不就给顶上来了么,也没给发两份工资,唉~ 先写个标题,占一个新坑,记录RK平台的传统ISP工作。 一、基础环境的硬件包括三部分: 1、相机环境,用于采…

【示例】MySQL-4类SQL语言-DDL-DML-DQL-DCL

前言 本文主要讲述MySQL中4中SQL语言的使用及各自特点。 SQL语言总共分四类:DDL、DML、DQL、DCL。 SQL-DDL | Data Definition Language 数据定义语言:用来定义/更改数据库对象(数据库、表、字段) 用途 | 操作数据库 # 查询所…

蓝桥杯嵌入式之ADC采集(R37、R38电位器上的电压)

一、CubeMX配置 R37------->ADC2_IN15 PB15 R38------->ADC1_IN11 PB12 1.ADC1的配置 2.ADC2的配置 二、ADC头文件、源文件 1.头文件 #ifndef __ADC_H__ #define __ADC_H__ #include "main.h"u32 GetADC_Value( ADC_HandleTypeDef *hadc); #end…

2024高交会-2024深圳高新技术展-高新技术成果交易会

2024高交会-2024深圳高新技术展-2024高新技术成果展-中国高校技术交易会-第26届高交会-深圳高交会-深圳高科技展-深圳新科技展-深圳高新技术成果展 第二十六届中国国际高新技术成果交易会(简称高交会) 时间:2024年11月15日-19日 地址&#…

牛客 NC252 多数组中位数【中等 模拟 Java,Go】

题目 题目链接: https://www.nowcoder.com/practice/b6bb0bce88894108bfc23e9b7b012420 思路 模拟,2数组合并一个数组helphelp长度为奇数,直接取中间值,为偶数,中间2个值,哪个小返回哪个参考答案Java imp…

Post表单提交后端接不到参数

项目背景: 框架:Springboot 版本:1.5.6.REAEASE 问题描述 Postman通过表单提交请求时后端接不到值 原因分析: 启动项中注入其他Bean时取名叫dispatcherServlet,当发现http接口无法访问时,原开发人员又…

开源项目若依放大招了?

前言 鉴于之前写了篇插件式相关的文章,阅读量比起其它文章可不要好太多,所以我决定继续这个主题! 以前我们公司用的就是Ruoyi,代码比较简单易懂。但是有些功能确实用不上,比如部门和岗位,每次新项目我拉了…

Python的基础知识学习路线1—python简介与环境配置(最全路线,每部分附有代码操作结果)

一、Python简介 (1)发展史 Python是由创始人贵铎范罗萨姆(Guido van Rossum)在阿姆斯特丹于1989年圣诞节期间,为了打发圣诞节的无趣,开发的一个新的解释型脚本语言。之所以选中Python(大蟒蛇的…

睿尔曼超轻量仿人机械臂之双臂复合机器人手眼标定软件在Arm架构系统上的使用实操

双臂复合升降机器人的手眼标定是属于眼在手外的标定模式,相机在机器人的头部,标定前应固定相机的位置,再打开我们的标定软件程序如下,给足文件权限后,打开主程序,运行后会出现如下界面。 首次连接&#xff…

linux的io的知识大全

C语言的io操作 写文件 #include<stdio.h> #include<string.h>#define FILE_NAME "log.txt" int main() {FILE * fp fopen(FILE_NAME, "w");if(fpNULL){printf("fopen error!\n");}const char* msg "hello zk\n";int c…