1. 程式人生 > >java重試工具庫: 實現業務邏輯與重試邏輯的解耦

java重試工具庫: 實現業務邏輯與重試邏輯的解耦

對於開發過網路應用程式的程式設計師來說,重試並不陌生,由於網路的擁堵和波動,此刻不能訪問服務的請求,也許過一小段時間就可以正常訪問了。比如下面這段給某個手機號發SMS的虛擬碼:

  1. // 傳送SMS
  2. public boolean sendSMS(String phone, String content)
  3. {
  4. int retryTimes = 3;
  5. for(int i=0; i<=3; i++)
  6. {
  7. try
  8. {
  9. boolean result = doSomething(phone, content);
  10. // 傳送成功直接返回
  11. if(result == true)
  12. {
  13. return true
    ;
  14. }
  15. }
  16. catch(IOException e)
  17. {
  18. // 可能是網路問題導致IOException,所以我們繼續重試
  19. logger.error("send sms error", e);
  20. }
  21. catch(Exception e)
  22. {
  23. // 未知異常,與網路無關,有可能是程式碼出現問題,這個時候重試沒用,我們直接返回false
  24. logger.error("unknown exception", e);
  25. return false;
  26. }
  27. }
  28. return false;
  29. }
  30. // 給某人發簡訊
  31. private boolean doSomething(String phone, String content)
  32. {
  33. }

這段程式碼有什麼問題呢?看起來很醜,為了實現重試邏輯,各種if-else,各種try-catch。重試邏輯太簡單,只是控制了重試次數,並沒有控制2次重試之間的時間間隔。因為重試程式碼與業務程式碼耦合在一起,所以看起來很複雜。

試想如果我們要改變重試邏輯:比如我們希望每次重試過後,隨機等待一段時間後再重試;比如我們希望重試次數不超過10次,而且總共的重試時間不超過1分鐘;比如我們希望每次重試的時候,都給我們監控系統發一條訊息...隨著重試邏輯的不斷變化,上面程式碼會越來越複雜。而且重試邏輯,其實是各個模組是差別不大的。

最近遇到2個開源專案,都是將重試程式碼封裝成專門的工具,方便使用,比如guava-retrying和spring-retry。後面的文章,會介紹下如何使用guava-retrying。下面這段程式碼使用的是guava-retrying,明顯可以感到程式碼變簡單了。

  1. public boolean sendSMS(final String phone, final String content)
  2. {
  3. Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
  4. .retryIfResult(Predicates.equalTo(false)) // 返回false時重試
  5. .retryIfExceptionOfType(IOException.class) // 丟擲IOException時重試
  6. .withWaitStrategy(WaitStrategies.fixedWait(200, TimeUnit.MILLISECONDS)) // 200ms後重試
  7. .withStopStrategy(StopStrategies.stopAfterAttempt(3)) // 重試3次後停止
  8. .build();
  9. try {
  10. return retryer.call(new Callable<Boolean>() {
  11. @Override
  12. public Boolean call() throws Exception {
  13. return doSomething(phone, content);
  14. }
  15. });
  16. } catch (Exception e) {
  17. return false;
  18. }
  19. }


這2個專案github地址是:

https://github.com/rholder/guava-retrying

https://github.com/spring-projects/spring-retry

guava-retrying博文如下:

相關推薦

java工具: 實現業務邏輯邏輯

對於開發過網路應用程式的程式設計師來說,重試並不陌生,由於網路的擁堵和波動,此刻不能訪問服務的請求,也許過一小段時間就可以正常訪問了。比如下面這段給某個手機號發SMS的虛擬碼:// 傳送SMSpublic boolean sendSMS(String phone, String content){ int r

Java操作數據實現"增刪改查"

mysq 新的 rom 可用 erp catch next() value eight 本文主要講解JDBC操作數據庫 主要實現對MySql數據庫的"增刪改查" 綜合概述: JDBC的常用類和接口 一 DriverManager類 DriverManage類用

細說Java主流日誌工具

概述 在專案開發中,為了跟蹤程式碼的執行情況,常常要使用日誌來記錄資訊。 在Java世界,有很多的日誌工具庫來實現日誌功能,避免了我們重複造輪子。 我們先來逐一瞭解一下主流日誌工具。 java.util.logging (JUL) JDK1.4開始,通過java

java利用poi開源實現將資料集寫入Excel表格並儲存在本地

一,目前主流的關於讀寫excel表格的有poi 和jxl開源庫,這裡只是簡單的介紹如何poi將資料集寫進Excel表格,並存進本地。 二,官網下載poi的相關jar包,網址 http://poi.apache.org/download.html#POI-4.0.1 &nb

java使用Apache工具實現ftp檔案傳輸

本文主要介紹如何使用Apache工具集commons-net提供的ftp工具實現向ftp伺服器上傳和下載檔案。 一、準備 需要引用commons-net-3.5.jar包。 使用ma

java並發工具學習 01 進程線程基礎

ava 多處理器 科技 進程通訊 存在 空間 會有 過時 主線程 在並發程序設計中,有兩個基本的單位:進程和線程。並發程序設計主要是針對線程而言,當然,進程也是非常重要的。操作系統包含很多進程與線程。即使在單核系統中(systems that only have a sin

[Win32]一個調器的實現(五)調符號

獨立 普通 mic proc 相關信息 預處理 arc const 負責 一個調試器應該可以跟蹤被調試程序執行到了什麽地方,顯示下一條將要執行的語句,顯示各個變量的值,設置斷點,進行單步執行等等,這些功能都需要一個基礎設施的支持,那就是調試符號。 什麽是調試符號

Java單元測試工具:JUnit4(二)——JUnit使用詳

(二)JUnit使用注意點及測試失敗的兩種情況         看了慕課網的JUnit視訊教程: http://www.imooc.com/learn/356,總結筆記。       &nbs

netty自定義訊息實現心跳檢測

其實客戶端心跳傳送用到的是IdleStateHandler,詳細看程式碼你就會明白為什麼。 //處理空閒狀態事件的處理器 pipeline.addLast(new IdleStateHandler(6,7,8, TimeUnit.SECONDS)); 在IdleSt

Java多執行緒的實現(程序執行緒的概念、Java繼承Thread類實現多執行緒、Java實現Runnable介面實現多執行緒、ThreadRunnable的區別、實現Callable介面實現多執行緒)

1 程序與執行緒 1.1 程序與執行緒的概念 什麼是程序?   程序: 作業系統中一個程式的執行週期。(比如我們想要在電腦上登入QQ,從雙擊qq按鈕---->關閉qq這個過程就是一個程序)   多程序: 同一時刻跑多個程式。   在DOS(磁碟作業系統時

Java語言開發工具包JDK的安裝配置

Java語言開發工具包JDK的安裝與配置 說明:此JDK的安裝與配置流程是在Windows10作業系統下進行的,其他作業系統可能會有所不同,請根據不同作業系統選擇配置流程進行操作。 以安裝在D盤為例(軟體儘量都安裝在D盤) 安裝 版本:JDK1.8,即JDK8.0 雙

MYSQL數據配置文件權限詳

net index 域名解析 eap iso 記錄 expire 隊列 sin “1” MYSQL配置文件常用參數說明:bind-address:MYSQL實例啟動後綁定的IPport : MYSQL實例啟動後監聽的端口socket: 本地SOCKET方式登錄MYSQL時S

運算符優先級 以及 && (邏輯) 和||(邏輯或)的優先級:

對象創建 content ins 條件 邏輯或 style -a ID class 運算符優先級(從高到低列出) 運算符 描述 . [] () 字段訪問、數組下標、函數調用以及表達式分組 ++ -- - ~ ! delete new typeof void 一

“全棧2019”Java第四十九章:過載重寫對比詳

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第四十九章:過載與重寫對比詳解 下一章 “全棧2019”Java第五十章:繼承與構造方法詳解

“全棧2019”Java第五十二章:繼承初始化詳

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第五十二章:繼承與初始化詳解 下一章 “全棧2019”Java第五十三章:向上轉型和向下轉型

邏輯優先順序高於邏輯

a||b&&c這個出來的效果可以看做是這樣的a||(b&&c),&&優先結合b和c,b和c兩個發生作用,而沒有去和a發生作用,a是和b&&

Java核心類-IO-對象流(實現序列化反序列化)

.get throws 反序 code row cts new java cep 使用對象流來完成序列化和反序列化操作:   ObjectOutputStream:通過writeObject()方法做序列化操作的   ObjectInputStream:通過readObje

h2數據用於實例的模塊

定時 h2數據庫 運行模式 htm new 連接 cal http 本地 H2說明(參考http://www.importnew.com/17924.html)H2有3種運行方式 (1)嵌入式,數據庫為單個文件。 啟動實例的的時候,自動開啟數據庫,數據

JAVA中使用MD5加密工具實現對數據的加密處理

歸納 ssa utf int 控制 nic this com nod 1.MD5工具類 package com.ssm.util; import java.security.MessageDigest; public class MD5Util { //將字

java定向輸出流實現程序日誌

java重定向public class RedirectOutputStream { public static void main(String[] args) {try {PrintStream out = System.out; //保存原輸出流PrintSt