更好的 java 重試框架 sisyphus 入門簡介

老馬嘯西風發表於2021-10-27

What is Sisyphus

sisyphus 綜合了 spring-retry 和 gauva-retrying 的優勢,使用起來也非常靈活。

為什麼選擇這個名字

我覺得重試做的事情和西西弗斯很相似。

一遍遍的重複,可能徒勞無功,但是樂此不疲。

人一定要想象西西弗斯的快樂。——加繆

其他原因

以前看了 java retry 的相關框架,
雖然覺得其中有很多不足之處。但是沒有任何重複造輪子的衝動,覺得是徒勞無功的。

當然這段時間也看了 Netty 的介面設計,和 Hibernate-Validator 的介面設計,覺得非常的巧妙。

覺得把這些東西結合,可以寫出一個還不錯的框架,就寫了起來。

至少,sisyphus 是快樂的。

關於版本

這次的框架版本採用了比較保守的方式,使用 0.0.X

原因有兩個:

(1)我認為前期出於實驗階段。程式碼並不成熟,自測也不充分。所以不適合用於生產。

(2)這樣可以快速迭代,而不至於為了追求更好導致版本特性遲遲無法迭代。

版本特性

我用了 5 個版本,實現了主要的特性:

(1)基於 fluent 介面宣告式呼叫

(2)基於 annotation 的代理實現

(3)spring 的整合實現

(4)自定義註解的實現

未完成的工作

  • 更方便的工具類。
  • 使用文件
  • 測試程式碼

感受

想法是很容易產生的,但是想把它變成一個穩定的框架需要很長的時間錘鍊。

為什麼選擇 sisyphus

作為開發者,我們一般都會選擇比較著名的框架。

比如 guava-retrying spring-retry。

或者乾脆自己寫一個。

為什麼不是 guava-retrying/spring-retry

java retry 這篇文章中我列舉了常見的實現方式
以及上述的兩種框架,也講述了其中的不足。

guava-retrying 優缺點

優點

  • 使用靈活
  • fluent 優雅寫法
  • 提供足夠多的實現

缺點

  • 沒有預設基於註解的實現
  • 重試策略設計並不友好

spring-retry

優點

  • 使用簡單

缺點

  • 重試條件單一
  • 重試等待策略單一
  • 無法自定義註解

為什麼不自己寫一個

個人感受

我作為一名開發,平時說實在的,看到重試。

我肯定會偷懶寫一個 for 迴圈,重試幾次就結束了。

因為時間不允許。

如果你更勤快一點,就可以選擇 spring-retry/guava-retrying。如果你熟悉他們的優缺點的話。

如果你渴望創造

sisyphus 所有的實現都是基於介面的。

你完全可以實現自己的實現,所有的東西基本完全可以被替換。

當然一些常見的策略實現,專案的基本框架都有詳盡的註釋,當做參考也可以有一點幫助。

sisyphus 做的更多的事情

netty 的靈感

參考了 netty 的設計,保證介面實現的一致性。

而且 sisyphus 還做了更多,還保證了介面和註解之間的一致性。

使用引導類,保證使用時的便利性,後期擴充的靈活性。

hibernate-validator

hibernate-validator 的作者是我知道為數不多的對於 java 註解應用很棒的開發者。(雖然所知甚少)

自定義註解就是從這個框架中學來的。

與 spring 為伍

spring 基本與我們的程式碼形影不離,所以你可以很簡單的結合 spring.

就像你使用 spring-retry 一樣。

快速開始

需要

jdk1.7+

maven 3.x+

maven 引入

sisyphus 使用 maven 管理 jar,

<plugin>
    <groupId>com.github.houbb</groupId>
    <artifactId>sisyphus-core</artifactId>
    <version>0.0.6</version>
</plugin>

編碼

作為入門案例,我們首先介紹些簡單靈活的宣告式程式設計

public void helloTest() {
    Retryer.<String>newInstance()
            .callable(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    System.out.println("called...");
                    throw new RuntimeException();
                }
            }).retryCall();
}

程式碼簡介

Retryer.<String>newInstance() 建立引導類的例項,String 是 callable 也就是待重試方法的返回值型別。

callable() 指定待重試的方法實現。

retryCall() 觸發重試呼叫。

日誌資訊

called...
called...
called...

以及一些異常資訊。

等價配置

上面的配置其實有很多預設值,如下:

/**
 * 預設配置測試
 */
@Test(expected = RuntimeException.class)
public void defaultConfigTest() {
    Retryer.<String>newInstance()
            .maxAttempt(3)
            .listen(RetryListens.noListen())
            .recover(Recovers.noRecover())
            .condition(RetryConditions.hasExceptionCause())
            .retryWaitContext(RetryWaiter.<String>retryWait(NoRetryWait.class).context())
            .callable(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    System.out.println("called...");
                    throw new RuntimeException();
                }
            }).retryCall();
}

這些預設值都是可以配置的。

比如什麼時候觸發重試?重試幾次?多久觸發一次重試?這些都會在下面的章節進行詳細講解。

小結

本文簡單介紹了重試框架的設計緣由,及其使用入門。

java 重試框架 sisyphus 開源地址

希望本文對你有所幫助,如果喜歡,歡迎點贊收藏轉發一波。

我是老馬,期待與你的下次重逢。

在這裡插入圖片描述

相關文章