java - 分布式环境下,定时任务或异步处理如何保持幂等性?
天蓬老师
天蓬老师 2017-04-18 09:26:19
0
9
796
天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回覆(9)
黄舟

冪等一般是指方法不改變業務狀態,因而能保證重複調用的效果和單次的效果一致.

看你的描述, 你的定時任務異步處理很可能會改變業務狀態(比如插入了數據).很可能你的方法應該本身就不是冪等的. 如果是這樣基本無解了.

我覺得你提問的實際想法可能是: 分佈式環境下, 如何保證定時任務和異步處理在發送重複請求時, 實際業務邏輯只執行一次?

如果是樣, 你可以使用使用一個集中式存儲(比如redis), 來保存調用端請求記錄, 服務端在接收到請求後, 用原子性的查詢和保存操作(比如redis的setnx命令) , 來保證只有一個請求會成功保存下來. 這樣就能達到實際業務只執行一次的效果了.

boolean setSuccess = redis.setnx(request.serializeToString(),"");//原子操作
if(setSuccess){
  doBusiness(); //执行业务
}else{
  doNothing(); //什么都不做
}
PHPzhong

個人並沒有這方面的經驗,不過公司裡的做法是用IP來做判斷,指定的IP才能去執行這個定時任務。

以下為個人空想,並無實務經驗:
搭建一個公共應用專門處理定時任務,然後提供訊息介面給具體應用呼叫。

迷茫

用事務來實現吧,分散式事務,或訊息佇列

洪涛
  1. 把操作本身變成冪等的,例如把+1操作改成=操作

  2. 給每個操作一個ID,每次執行都記錄,執行前先看這個ID的操作是否已經執行過

大家讲道理

可以考慮具備ack機制的訊息佇列,例如RabbitMQ等,既保證了一條任務只分配給一個worker,也保證了任務成功與否的完整性

黄舟

我們是透過zk調度來實現的,分散式環境中通一任務最多只能有一台機器執行,zk很好實現這種功能

巴扎黑

到目前為止所有答案都是錯的,包括那個被採納的。原因是,定時任務或非同步處理,與冪等性無關。

巴扎黑

redis + token就可以的

洪涛

用隊列,取了就沒了,只會執行一次,執行失敗在丟回隊列等下次

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板