搜尋

首頁  >  問答  >  主體

java - 分布式环境下,定时任务或异步处理如何保持幂等性?

天蓬老师天蓬老师2802 天前802

全部回覆(9)我來回復

  • 黄舟

    黄舟2017-04-18 09:28:19

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

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

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

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

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

    回覆
    0
  • PHPz

    PHPz2017-04-18 09:28:19

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

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

    回覆
    0
  • 迷茫

    迷茫2017-04-18 09:28:19

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

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 09:28:19

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

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

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-18 09:28:19

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

    回覆
    0
  • 黄舟

    黄舟2017-04-18 09:28:19

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

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-18 09:28:19

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

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-18 09:28:19

    redis + token就可以的

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 09:28:19

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

    回覆
    0
  • 取消回覆