【已解决】钉钉审批流回调瞬间返回两次通知

news/2024/11/18 1:46:54/

【已解决】钉钉审批流回调瞬间返回两次通知

  • 一、产生原因
  • 二、解决方案
    • (一)理论方案参考啊
    • (二)代码方案参考
  • 三、参考链接

一、产生原因

钉钉审批流回调应该只发一次通知给开发者。但实际情况是,钉钉有时会瞬间返回两次回调通知,间距非常短。这主要是钉钉审批流的回调机制引起的。

钉钉审批流的回调机制如下:

  • 主回调,当审批结果(通过/不通过等)最终确定后,会发出主回调通知。
  • 定时回调,钉钉系统将在一定时间内(几秒到几分钟不等)进行第二次回调。

设置定时回调是为了防止主回调因为网络异常而丢失。

但是有时候,主回调和定时回调间隔时间非常短,所以开发方会收到两次回调通知,通知内容基本相同。

二、解决方案

(一)理论方案参考啊

  1. 去重处理:在接收到回调通知时,可以记录每个回调的唯一标识(如回调数据的唯一标识),并将其保存在一个集合中。在处理每个回调之前,检查该回调是否已经被处理过,如果是,则忽略该回调。这样可以避免重复处理同一个回调通知。
  2. 时间窗口处理:在接收到回调通知后,可以记录当前时间戳,并与最后一次处理的时间戳进行比较。如果两次回调通知之间的时间间隔非常短(比如在毫秒级别),则可以认为是同一个回调通知的重复。在这种情况下,可以忽略第二次回调通知。
  3. 幂等性设计:幂等性是指对同一个操作的多次执行所产生的影响是一致的。在回调接口的实现中,可以设计为幂等操作,即多次接收到相同的回调通知不会产生不一致的结果。可以通过在回调处理逻辑中引入唯一标识或使用数据库事务来保证幂等性。
  4. 队列处理:将接收到的回调通知放入一个队列中,然后使用单独的线程或进程来处理队列中的回调通知。这样可以确保每个回调通知按顺序进行处理,并避免同时处理多个重复的回调通知。

(二)代码方案参考

以下代码选用的是第一个理论方案——去重处理。

public class DDServiceImpl implements DDService {//保存十分钟内已处理的回调事件private Map<String, Long> eventList = new HashMap<>();@Overridepublic Map<String, String> dingdingEventHandle(String msgSignature, String timeStamp, String nonce, JSONObject json) {// 处理回调消息,得到回调事件decryptMsg...// 检查回调事件是否已经处理过,如果是,则忽略该回调if (isCallbackProcessed(decryptMsg)) {return successMap;}// 业务处理代码...// 将回调事件和当前时间戳添加到已处理集合中long currentTime = System.currentTimeMillis();eventList.put(decryptMsg, currentTime);}/*** 检查该回调事件在十分钟内是否处理过,应对钉钉瞬间重复回调** @param decryptMsg 回调事件* @return 是否处理过*/private boolean isCallbackProcessed(String decryptMsg) {// 清理超过十分钟的回调事件long currentTime = System.currentTimeMillis();long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(10);eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);return eventList.containsKey(decryptMsg);}
}

三、参考链接

  1. https://developer.aliyun.com/ask/536536

http://www.ppmy.cn/news/1094277.html

相关文章

【CUDA OUT OF MEMORY】【Pytorch】计算图与CUDA OOM

计算图与CUDA OOM 在实践过程中多次碰到了CUDA OOM的问题&#xff0c;有时候这个问题是很好解决的&#xff0c;有时候DEBUG一整天还是头皮发麻。 最近实践对由于计算图积累导致CUDA OOM有一点新的看法&#xff0c;写下来记录一下。包括对计算图的一些看法和一个由于计算图引发…

解决DCNv2不能使用高版本pytorch编译的问题

可变形卷积网络GitHub - CharlesShang/DCNv2: Deformable Convolutional Networks v2 with Pytorch代码已经出来好几年了&#xff0c;虽然声称"Now the master branch is for pytorch 1.x"&#xff0c;实际上由于pytorch自1.11版开始发生了很大变化&#xff0c;原来基…

设计模式8:代理模式-动态代理

上一篇&#xff1a;设计模式8&#xff1a;代理模式-静态代理 目录 如何理解“动态”这两个字&#xff1f;动态代理简单的代码实例一个InvocationHandler代理多个接口有动态代理&#xff0c;为什么还要用Cglib代理&#xff1f; 如何理解“动态”这两个字&#xff1f; “动态”…

数学建模圈养湖羊的空间利用率

数学建模圈养湖羊的空间利用率 问题&#xff1a;规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&#xff1b;与此同时&#xff0c;也要尽量减少空间闲置所造成的资源浪费…

使用Apache Doris自动同步整个 MySQL/Oracle 数据库进行数据分析

Flink-Doris-Connector 1.4.0 允许用户一步将包含数千个表的整个数据库&#xff08;MySQL或Oracle &#xff09;摄取到Apache Doris&#xff08;一种实时分析数据库&#xff09;中。 通过内置的Flink CDC&#xff0c;连接器可以直接将上游源的表模式和数据同步到Apache Doris&…

vue深拷贝的几种实现方式

1、通过递归方式实现深拷贝 比较全面的深拷贝&#xff0c;缺点是较为繁琐 function deepClone(obj) {var target {};for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) {if (typeof obj[key] object) {target[key] deepClone(obj[key]);} else {…

【PHP】手术麻醉系统源码

手术麻醉信息管理系统覆盖了与麻醉相关的各个临床工作环节&#xff0c;可详细记录病人从进入手术室、手术中、到手术结束的全部数据&#xff0c;包括各类仪器的监测数据、麻药、用药、事件、输氧、插管、拔管、输液、出液、输血、呼吸、电子病例、检验信息、检查结果、医嘱、病…

有哪些开源通用流程引擎

有哪些开源通用流程引擎 Activiti&#xff1a;Camunda&#xff1a;Flowable&#xff1a;jBPM&#xff1a;Bonita&#xff1a; 以下是一些常见的开源通用流程引擎&#xff1a; Activiti&#xff1a; Activiti 是一个轻量级的、基于 Java 的 BPM&#xff08;Business Process M…