OpenSource - 分布式重试平台

文章目录

  • 概述
  • 重试方案对比
  • 设计思想
  • 流量管理平台预览
  • 场景应用
    • 强通知场景
      • 发送MQ场景
      • 回调场景
      • 异步场景

在这里插入图片描述


概述

在当前广泛流行的分布式系统中,确保系统数据的一致性和正确性是一项重大挑战。为了解决分布式事务问题,涌现了许多理论和业务实践,其中BASE理论是目前业界广泛接受的分布式一致性理论。

基于BASE理论,采用柔性事务并优先保障系统的可用性和数据的最终一致性已逐渐成为技术共识。 为了确保分布式服务的可用性和数据一致性,并防止由于网络抖动、连接超时等问题导致短时不可用的情况,根据"墨菲定律",在核心流程中增加重试和数据核对校验的动作成为提高系统鲁棒性常用的技术方案。

在此背景下EasyRetry应运而生。EasyRetry是一款基于BASE思想实现的分布式服务重试组件,旨在通过重试机制确保数据的最终一致性。它提供了控制台任务观测、可配置的重试策略、重试后执行回调以及丰富地告警配置等功能。

通过这些手段,可以对异常数据进行全面监测和回放,从而在确保系统高可用性的同时,大大提升数据的一致性。

在这里插入图片描述

通常的业务场景有:

  • 保障系统稳定性,减少网络抖动导致异常,增加重试能力
  • 保障服务容错性,对核心流程进行拆分,在业务低峰期进行数据核对
  • 保证信息的可达性,在服务间通知时增加重试

但由于正常业务场景较难触发重试流程,从而导致研发测试对重试场景和流量并不重视,始终处于重要但无序的"管理真空"

Easy-RETRY 是一个针对业务系统重试流量的治理平台,其自身具有高可用高性能高负载的特点,服务特性有:

  • 支持千万级别的重试流量分派
  • 支持流量容量扩容,自动识别并处理
  • 支持流量处理节点水平扩容
  • 高效利用系统资源支持高并发
  • 支持多种算法调度客户端执行
  • 打包上报,支持高并发业务场景
  • 加密通讯,保障信息安全

在这里插入图片描述


重试方案对比

在这里插入图片描述

设计思想

在这里插入图片描述

流量管理平台预览

地址: http://preview.easyretry.com/ 账号: admin 密码: admin

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


场景应用

为了小伙伴们能更快了解EasyRetry的使用场景和优势,以下新增了一些模拟案例仅供大家参考。 同时期待大家积极参与并分享自己在项目中使用EasyRetry的经验和案例,共同推动技术的发展和应用的实践。

这样可以让更多需要使用EasyRetry的小伙伴们找到适合自己的应用场景, 并充分利用EasyRetry的优势,以提升系统的可靠性和稳定性。

强通知场景

强通知性

在某些业务场景下,需要强制保证将通知、消息等数据发送到目标端接口,但由于网络的不确定性以及目标系统、应用、服务的不确定性,可能会造成通知消息的发送失败。

此类场景下可以使用LOCAL_REMOTE或者ONLY_REMOTE模式进行重试。


发送MQ场景

众所周知消息队列的异步、削峰、解耦优点, 在业务系统承担着十分重要的角色,如果保障消息的可达性就尤为重要了。

下面模拟一个常见的的下单流程。

在这里插入图片描述
订单中心下单完成后回抛出下单成功消息从而解耦了订单和其他业务系统的耦合关系,其他相关的业务系统只需要监听订单的下单成功的消息即可完成自己的业务逻辑。

但是若由于网络的不稳定、消息队列故障等等,可能导致消息未发送出去,这时候就需要增加重试流程来保障消息的强可达性

在这里插入图片描述
然后接入EasyRetry后将变的非常简单,您只需要简单的一个注解就保障强可达性

以下代码案例仅供参考

@Retryable(scene = "create-order-success", retryStrategy = RetryType.ONLY_REMOTE)
public void sendCreateOrderSuccessMessage(Message message) {......// 发送消息mqProducer.publish("主题", "key", message);
}

如果您不想使用注解的方式您可是使用手动模式

public void createOrder(Order order) {// 其他逻辑// 发送消息try {mqProducer.publish("主题", "key", order);} catch (Exception e) {// 发送出现异常EasyRetryTemplate retryTemplate = RetryTaskTemplateBuilder.newBuilder().withExecutorMethod(RetrySendMqMessageExecutorMethod.class).withParam(order).withScene(RetrySendMqMessageExecutorMethod.SCENE).build();retryTemplate.executeRetry();}
}
@ExecutorMethodRegister(scene = RetrySendMqMessageExecutorMethod.SCENE, async = true, forceReport = true)
public class RetrySendMqMessageExecutorMethod implements ExecutorMethod {public static final String SCENE = "retrySendMqMessageExecutorMethod";@Overridepublic Object doExecute(Object objs) {Object[] params = (Object[]) objs;// 发送消息mqProducer.publish("主题", "key", params[0]);return null;}
}    

回调场景

这里引用一个使用EasyRetry的小伙伴重试框架-Easy-Retry接入之路,他们线上真实的使用场景。

他们一个paas平台, 其中功能模块有“事件中心”,“审核中心”,“支付中心”等相关的一些组件。他们都有一个类似的东西,当我发起事件的时候,需要将事件通知到其他的应用, 比如

  • 【审核中心】当我审核的时候需要将审核结果返回给其他应用,
  • 【支付中心】当我支付完成后也会将结果推送给其他应用。

然而,我们的其他应用可能会有不可用的状态, 可能会导致回调通知的时候会报错, 所以不难想象到我们需要做一个重试机制来保障回调的可达性

下面是一个支付中心的调用过程

在这里插入图片描述

用户在商品中心下单然后通过支付中心唤起收银台进行付款,第三方支付平台回调支付中心,支付平台回调商品中心完成业务流程;

但是若回调失败了就会导致商品中心和 支付中心数据不一致,这肯定不是我们所期望的。

所以需要新增一个重试机制来保障数据的最终一致性。

以下代码案例仅供参考

@Retryable(scene = "callbackProductCenter", retryStrategy = RetryType.ONLY_REMOTE)
public void callbackProductCenter(CallbackDTO callback) {......// 回调商品中心String responseStr = restTemplate.postForObject("第三方接口", "参数", String.class);
}

如果您不想使用注解的方式您可是使用手动模式

public void callbackProductCenter(CallbackDTO callback) {// 其他逻辑try {// 回调商品中心String responseStr = restTemplate.postForObject("第三方接口", "参数", String.class);} catch (Exception e) {// 发送出现异常EasyRetryTemplate retryTemplate = RetryTaskTemplateBuilder.newBuilder().withExecutorMethod(RetrySendMqMessageExecutorMethod.class).withParam(order).withScene(RetrySendMqMessageExecutorMethod.SCENE).build();retryTemplate.executeRetry();}
}
@ExecutorMethodRegister(scene = CallbackProductCenterExecutorMethod.SCENE, async = true, forceReport = true)
public class CallbackProductCenterExecutorMethod implements ExecutorMethod {public static final String SCENE = "callbackProductCenterExecutorMethod";@Overridepublic Object doExecute(Object objs) {Object[] params = (Object[]) objs;// 回调商品中心String responseStr = restTemplate.postForObject("第三方接口", "参数", String.class);return null;}
}    

异步场景

在一些核心的接口上,我们总是想不断的提高接口的性能,我们知道提高接口性能的方式常用的就是异步、缓存、并行等,

这里我们说说异步,比如下面一个场景
在这里插入图片描述

下单完成后会有一些非核心的流程,主要特点实时性要求不高、耗时比较高的操作等;

一般会把这些流程进行异步化操作、进程异步化: 比如可以通过发送MQ消息, 如果保存MQ的可达性可以参考发送MQ场景⬆️⬆️⬆️

线程异步化: 开启一个异步线程进行异步处理, 但是出现异常就会导致数据丢失,因此需要增加重试保证数据的一致性, 可以使用LOCAL_REMOTE先本地重试,如果本地重试仍未解决就上报服务端

以下代码案例仅供参考

@Retryable(scene = "sendEmail", retryStrategy = RetryType.LOCAL_REMOTE)
public void sendEmail(EmailDTO email) {......// 发送下单确认邮件String responseStr = restTemplate.postForObject("邮箱地址", email, String.class);
}

在这里插入图片描述

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

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

相关文章

Android Studio 屏幕适配

Android开发屏幕适配流程 首先studio中没有ScreenMatch这个插件的,下去现在这个插件 点击File->settings->Plugins->(搜索ScreenMatch插件),点击下载,应用重启Studio即可,如下图 在values下 创建dimens.xml&#xff0c…

IO进程线程day7(2023.8.4)

一、Xmind整理: 二、课上练习: 练习1:创建两个线程:其中一个线程拷贝前半部分,另一个线程拷贝后半部分。 只允许开一份资源,且用互斥锁方式实现。 提示:找临界区--->找临界资源。 #includ…

面试热题(最长回文子串)

给你一个字符串 s,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串 输入:s "babad" 输出:"bab" 最长回文子串以前的博客已经讲过KMP算法以及比较不常见的Manacher算法…

Gartner发布《2023年全球RPA魔力象限》:90%RPA厂商,将提供生成式AI自动化

8月3日,全球著名咨询调查机构Gartner发布了《2023年全球RPA魔力象限》,通过产品能力、技术创新、市场影响力等维度,对全球16家卓越RPA厂商进行了深度评估。 弘玑Cyclone(Cyclone Robotics)、来也(Laiye&am…

教资学习笔记总结

科目一 科目二 第一章 教育基础知识和基本原理 第一节 教育的认识 1.教育的概念 教育的词源:教育一词最早出现于《孟子尽心上》:“得天下英才而教育之”许慎在《说文解字》中最早解释教育:“教,上所施,下所效也”…

opencv35-形态学操作-腐蚀cv2.erode()

形态学,即数学形态学(Mathematical Morphology),是图像处理过程中一个非常重要的研 究方向。形态学主要从图像内提取分量信息,该分量信息通常对于表达和描绘图像的形状具有 重要意义,通常是图像理解时所使用…

Docker实战-操作Docker容器实战(二)

导语   上篇分享中,我们介绍了关于如何创建容器、如何启动容器、如何停止容器。这篇我们来分享一下如何操作容器。 如何进入容器 可以通过使用-d参数启动容器后会进入后台运行,用户无法查看容器中的信息,无法对容器中的信息进行操作。 这个时候如果我们需要进入容器对容器…

聊聊比亚迪的DM-i技术

比亚迪的DM-i技术是一种混合动力技术,结合了燃油发动机和电动技术,旨在提高汽车的燃油经济性和环境友好性。 DM-i技术的核心是搭载了一台高效的燃油发动机和一组电动机,通过电子控制系统实现两者的协同工作。在日常行驶中,汽车首先…

SpringBoot项目-个人博客系统的实现【下】

10.实现强制要求登陆 当用户访问 博客列表页和 博客详情页时, 如果用户当前尚未登陆, 就自动跳转到登陆页面 1.添加拦截器 public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletRespon…

kubernetes基于helm部署gitlab-runner

kubernetes基于helm部署gitlab-runner 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab-runner。 先决条件: 已运行的 Kubernetes 集群已运行的 gitlab 实例 项目地址:https://gitlab.com/gitlab-org/charts/gitlab-runner 官方文档&#xff…

深度学习——注意力机制、自注意力机制

什么是注意力机制? 1.注意力机制的概念: 我们在听到一句话的时候,会不自觉的捕获关键信息,这种能力叫做注意力。 比如:“我吃了100个包子” 有的人会注意“我”,有的人会注意“100个”。 那么对于机器来说…

【LeetCode-简单】剑指 Offer 52. 两个链表的第一个公共节点

题目 输入两个链表,找出它们的第一个公共节点。 如下面的两个链表: 在节点 c1 开始相交。 输入:intersectVal 8, listA [4,1,8,4,5], listB [5,0,1,8,4,5], skipA 2, skipB 3 输出:Reference of the node with value 8 输…