Spring retry,guava retryingの統合-sisyphus java再試行

12454 ワード

Sisyphus
プロシージャプログラミングと注釈プログラミングをサポートするjava再試行フレームワーク.
とくせい
  • fluentプロセスプログラミング
  • をサポート
  • バイトコードに基づくエージェント再試行
  • 注釈の再試行に基づいて、注釈
  • をカスタマイズできる
  • シームレスアクセスspring
  • インタフェースと注釈の統一
  • spring-retryとguava-retryingにおける不足点
  • を解決する
    設計の目的
    spring-retryとgauva-retryingの優位性を統合した.
    いくつかの特性を調整して、実際の使用に有利にします.
    Nettyのようなインタフェースの考え方を採用し、インタフェースの一貫性と交換の柔軟性を保証します.
    Hibernate-Validatorの設計を参考にして、ユーザーが注釈をカスタマイズできるようにします.
    Spring-retryとguava-retryingの不足点
    レコードの更新
    レコードの更新
    オープンソースアドレス
    sisyphus
    クイックスタート
    導入
    
        com.github.houbb
        sisyphus-core
        0.0.6
    

    入門コード
    詳細については[RetryerTest]()を参照してください.
    public void helloTest() {
        Retryer.newInstance()
                .retry(new Callable() {
                    @Override
                    public String call() throws Exception {
                        System.out.println("called...");
                        throw new RuntimeException();
                    }
                });
    }

    コード解析
  • retry

  • callableの実装を指定します.
    ログを印刷し、プログラム異常をシミュレートします.
    ログ情報
    ログ情報
    called...
    called...
    called...

    その他の異常情報もあります.
    再試行トリガの条件、デフォルトはプログラムに異常が発生しました
    ここでの再試行間隔はデフォルトでは時間間隔がなく、合計3回試行されます.(初回プログラム自体の実行を含む)
    なぜsisyphusを選んだのか
    なぜsisyphusを選んだのか
    開発者として、私たちは一般的に有名なフレームワークを選択します.
    例えばguava-retrying spring-retry.
    あるいはいっそ自分で書きます.
    なぜguava-retrying/spring-retryではないのか
    JAva retryという文章では、一般的な実装方法と上記の2つのフレームワークを挙げ、その不足も述べています.
    guava-retryingのメリットとデメリット
    メリット
  • フレキシブル
  • を使用
  • fluent優雅な書き方
  • は、
  • の実装を十分に提供する.
    欠点
  • 注釈ベースのデフォルトの実装はありません
  • 再試行ポリシー設計は友好的ではありません
  • spring-retry
    メリット
  • 単純
  • を使用
    欠点
  • 再試行条件単一
  • 再試行待機ポリシー単一
  • 注釈をカスタマイズできません
  • どうして自分で書かないの?
    個人的な感覚.
    私は開発者として、普段は本当のことを言って、再試行を見ました.
    私はきっとサボってforループを書いて、何度もやり直して終わります.
    時間が許さないからです.
    もっとまめにすればspring-retry/guava-retryingを選択できます.もしあなたが彼らの長所と短所をよく知っているなら.
    創造を望むなら
    Sisyphusのすべての実装はインタフェースに基づいている.
    あなたは完全に自分の実現を実現することができて、すべてのものは基本的に完全に交換することができます.
    もちろん、いくつかの一般的なポリシーの実装では、プロジェクトの基本的なフレームワークには詳細なコメントがあり、参考にすることもできます.
    Sisyphusがもっとやったこと
    nettyのインスピレーション
    nettyの設計を参考にして,インタフェースの実現の一貫性を保証した.
    さらにsisyphusはさらに多く,インタフェースと注釈の一貫性を保証した.
    ブートクラスを使用して、使用時の利便性、後期の柔軟性を保証します.
    hibernate-validator
    hibernate-validatorの著者はjava注釈アプリケーションに対する数少ない素晴らしい開発者だと知っています.(あまり知られていませんが)
    カスタム注釈はこのフレームワークから学んだものです.
    スプリングと戦う
    Springは基本的に私たちのコードと影も形も離れないので、springを簡単に結合することができます.
    spring-retryを使うように.
    Sisyphusモジュールの概要
    モジュール分割
    Sisyphusはモジュールの区分時に使用者の便利さを考慮して、主にいくつかのモジュールがあります.
    sisyphus-api
    インタフェース定義モジュールは、最も基礎的な部分です.
    sisyphus-coreにデフォルトで依存されます.
    一般的に導入する必要はありませんが、それに基づいて自分の再試行フレームワークを実現したい場合は、試してみてください.
    sisyphus-core
    sisyphus-apiモジュールのデフォルト実装.
    さらに使いやすいFluentブートクラスを追加することで、宣言式の再試行コードを簡単に書くことができます.
    sisyphus-annotation
    Sisyphusの注釈実装モジュール.
    (1)バイトコードに基づいて実現されるエージェント再試行はspringに依存しなくてもよい.普段使いやすい
    (2)カスタム注釈とその実装を許可する.使用者は,自分の再試行注釈を記述することができる.
    sisyphus-spring
    Springはjava開発のリーダーとして機能します.もちろん応援します.
    spring-retryと同様にsisyphus-springを便利に使用できます.
    モジュール間の依存関係
    sisyphus-api
    sisyphus-core
    sisyphus-annotation
    sisyphus-spring
    sisyphus-test

    Sisyphus-apiはベースで、柔軟性が最も高い.
    Sisyphus-springは最も簡単で使いやすく、柔軟性が相対的に悪い.
    Sisyphus-testはテストとしてのみ使用され、外部から導入する必要はありません.
    Sisyphus構成の概要
    より便利な構成を満たすために、Retryerクラスは多くの構成可能な情報を提供します.
    デフォルト設定
    /**
     *       
     */
    public void defaultConfigTest() {
        Retryer.newInstance()
                .condition(RetryConditions.hasExceptionCause())
                .retryWaitContext(RetryWaiter.retryWait(NoRetryWait.class).context())
                .maxAttempt(3)
                .listen(RetryListens.noListen())
                .recover(Recovers.noRecover())
                .callable(new Callable() {
                    @Override
                    public String call() throws Exception {
                        System.out.println("called...");
                        throw new RuntimeException();
                    }
                }).retryCall();
    }

    次のコードと同等です.
    public void helloTest() {
        Retryer.newInstance()
                .callable(new Callable() {
                    @Override
                    public String call() throws Exception {
                        System.out.println("called...");
                        throw new RuntimeException();
                    }
                }).retryCall();
    }

    メソッドの説明
    condition
    トリガーされた条件を再試行し、複数の条件を指定できます.
    デフォルトでは、例外が放出されます.
    retryWaitContext
    待機中のポリシーを再試行し、複数を指定できます.
    デフォルトでは、待機は行われません.
    maxAttempt
    最初の実行を含む最大再試行回数を指定します.
    デフォルト:3回です.
    listen
    再試行のリスニング実装を指定します.デフォルトでは、リスニングは行われません.
    recover
    再試行が完了しても、再試行条件が満たされている場合は、リカバリのポリシーを指定できます.
    デフォルトではリカバリは行われません.
    callable
    再試行する方法.
    retryCall
    再試行実行をトリガーします.
    インタフェースの詳細
    インタフェースとその実装
    すべてのインタフェースで、対応するサブクラスインスタンスを直接表示できます.
    ユーザーのカスタマイズ
    代替の柔軟性に基づいて、ユーザーはインタフェースを実現し、自分のビジネスに合った実装を定義することができます.
    Sisyphus注記
    構成には柔軟性がありますが、開発者の使用には注釈ほど簡単ではありません.
    したがって,本フレームワークは注釈ベースの再試行も実現した.
    設計の仕様
    インタフェースと注釈の統一性を保証します.
    maven導入
    
        ${project.groupId}
        sisyphus-annotation
        ${project.version}
    

    注釈
    コア注記は主に2つあります.
    Retry
    再試行に関する構成を指定します.
    /**
     *     
     * 1.     ,        。
     * 2.        ,          ?      ,       。
     * 3.            。{@link com.github.houbb.sisyphus.api.core.Retry}   
     * @author binbin.hou
     * @since 0.0.3
     */
    @Documented
    @Inherited
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @RetryAble(DefaultRetryAbleHandler.class)
    public @interface Retry {
    
        /**
         *      
         * @return   
         * @since 0.0.5
         */
        Class extends com.github.houbb.sisyphus.api.core.Retry> retry() default DefaultRetry.class;
    
        /**
         *       
         * 1.               
         * @return   
         */
        int maxAttempt() default 3;
    
        /**
         *        
         * @return        
         */
        Class extends RetryCondition> condition() default ExceptionCauseRetryCondition.class;
    
        /**
         *    
         * 1.        
         * @return    
         */
        Class extends RetryListen> listen() default NoRetryListen.class;
    
        /**
         *     
         * 1.            
         * @return         
         */
        Class extends Recover> recover() default NoRecover.class;
    
        /**
         *     
         * 1.       ,     ,        ,
         * @return     
         */
        RetryWait[] waits() default {};
    
    }

    RetryWait
    再試行の待機ポリシーを指定します.
    package com.github.houbb.sisyphus.annotation.annotation;
    
    import com.github.houbb.sisyphus.annotation.annotation.metadata.RetryWaitAble;
    import com.github.houbb.sisyphus.annotation.handler.impl.DefaultRetryWaitAbleHandler;
    import com.github.houbb.sisyphus.core.constant.RetryWaitConst;
    import com.github.houbb.sisyphus.core.support.wait.NoRetryWait;
    
    import java.lang.annotation.*;
    
    /**
     *       
     * 1.         ,                。
     * 2.          ?
     *
     *    +         ,    。
     *
     * @author binbin.hou
     * @since 0.0.3
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    @Target(ElementType.ANNOTATION_TYPE)
    @RetryWaitAble(DefaultRetryWaitAbleHandler.class)
    public @interface RetryWait {
    
        /**
         *    
         * 1. fixed   ,         
         * 2.   
         * @return    
         */
        long value() default RetryWaitConst.VALUE_MILLS;
    
        /**
         *    
         * @return    
         */
        long min() default RetryWaitConst.MIN_MILLS;
    
        /**
         *    
         * @return    
         */
        long max() default RetryWaitConst.MAX_MILLS;
    
        /**
         *     
         * 1.     ,    {@link RetryWaitConst#INCREASE_MILLS_FACTOR}
         * 2.     。    {@link RetryWaitConst#MULTIPLY_FACTOR}
         * @return     
         */
        double factor() default Double.MIN_VALUE;
    
        /**
         *           class   
         * @return        class
         */
        Class extends com.github.houbb.sisyphus.api.support.wait.RetryWait> retryWait() default NoRetryWait.class;
    
    }

    注記の使用
    注釈を定義したら、必ず注釈の関連使用が必要です.
    注釈の使用については、主に2つの方法があります.
    Proxy+CGLIB
    エージェント・モードとバイト・コードに基づいて強化されます.
    プロジェクトでspringを使用していない場合は、この方法を直接使用すると便利です.
    Spring-AOP
    スプリングと直接統合できます.
    使い方はspring-retryと同じです.
    Sisyphusエージェントテンプレート
    目的
    ユーザがspringに依存せずに注釈をより便利に使用できるようにする.
    コードモード+バイトコード強化に基づいて実現する方法を提供する.
    使用例
    maven導入
    注記関連モジュールを導入します.
    
        ${project.groupId}
        sisyphus-annotation
        ${project.version}
    

    テスト方法の定義
    以下のテストコードは[spring-test]()モジュールを参照できます.
  • MenuServiceImpl.java
  • public class MenuServiceImpl {
    
        public void queryMenu(long id) {
            System.out.println("    ...");
            throw new RuntimeException();
        }
    
        @Retry
        public void queryMenuRetry(long id) {
            System.out.println("    ...");
            throw new RuntimeException();
        }
    
    }

    テスト
    RetryTemplateを使用したテスト
    注釈の再試行方法なし
    @Test(expected = RuntimeException.class)
    public void templateTest() {
        MenuServiceImpl menuService = RetryTemplate.getProxyObject(new MenuServiceImpl());
        menuService.queryMenu(1);
    }
  • ログ情報
  •     ...

    一度だけお願いしました.
    注釈のある方法
    @Test(expected = RuntimeException.class)
    public void templateRetryTest() {
        MenuServiceImpl menuService = RetryTemplate.getProxyObject(new MenuServiceImpl());
        menuService.queryMenuRetry(1);
    }
  • ログ情報
  •     ...
        ...
        ...

    その他
    もちろん、より多くの構成があり、自分で試してみることができます.
    スプリングと組み合わせて注釈を使用したい場合は、引き続き下を見てください.
    Sisyphus spring統合
    目的
    spring-retryフレームワークと同様に、springフレームワークを使用すると、本プロジェクトを統合するのは簡単です.
    注釈の方式とプロセス式のプログラミング、両者はできるだけ一致性を維持して、あなたは1つの方式から別の方式に変えたいのも比較的に簡単です.
    Spring-retryから本フレームに切り替えたいのも便利です.
    使用例
    maven導入
    
        ${project.groupId}
        sisyphus-spring
        ${project.version}
    

    springおよびAOP関連jarがデフォルトで導入されます.
    ビジネスコード
    sisyphus-testモジュールを参照してください.
    次に、非常に一般的なビジネス・メソッドをシミュレートします.@Retry標識方法を使用するには、再試行が必要です.
  • SpringService.java
  • public interface SpringService {
    
        /**
         *       
         * @return   
         */
        String query();
    
    }
  • SpringServiceImpl.java
  • import com.github.houbb.sisyphus.annotation.annotation.Retry;
    import com.github.houbb.sisyphus.test.service.SpringService;
    import org.springframework.stereotype.Service;
    
    /**
     * @author binbin.hou
     * @since 0.0.4
     */
    @Service
    public class SpringServiceImpl implements SpringService {
    
        @Override
        @Retry
        public String query() {
            System.out.println("spring service query...");
            throw new RuntimeException();
        }
    
    }

    再試行を開始
    注記に基づいて直接次のように構成すればよい.@EnableRetry IDを使用して再試行を開始する必要があります.
    @Configurable
    @ComponentScan(basePackages = "com.github.houbb.sisyphus.test.service")
    @EnableRetry
    public class SpringConfig {
    }

    テストコード
    import com.github.houbb.sisyphus.test.config.SpringConfig;
    import com.github.houbb.sisyphus.test.service.SpringService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4Cla***unner;
    
    /**
     * @author binbin.hou
     * @since 0.0.4
     */
    @ContextConfiguration(classes = SpringConfig.class)
    @RunWith(SpringJUnit4Cla***unner.class)
    public class SpringServiceTest {
    
        @Autowired
        private SpringService springService;
    
        @Test(expected = RuntimeException.class)
        public void queryTest() {
            springService.query();
        }
    
    }
  • ログ情報
  • spring service query...
    spring service query...
    spring service query...

    新しいプロパティの予定
    入参
    再試行コンテキストのパラメータ情報の追加
    構成の最適化
    より優れた構成体験を提供