成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

spring retry, guava retrying 的整合-sisyphus java 重試框

宋華 / 3634人閱讀

摘要:特性支持過(guò)程式編程基于字節(jié)碼的代理重試基于注解的重試,允許自定義注解無(wú)縫接入接口與注解的統(tǒng)一解決與中的不足之處設(shè)計(jì)目的綜合了和的優(yōu)勢(shì)?;谧止?jié)碼實(shí)現(xiàn)的代理重試,可以不依賴。提供基于代碼模式字節(jié)碼增強(qiáng)實(shí)現(xiàn)的方式。

Sisyphus

支持過(guò)程式編程和注解編程的 java 重試框架。

特性

支持 fluent 過(guò)程式編程

基于字節(jié)碼的代理重試

基于注解的重試,允許自定義注解

無(wú)縫接入 spring

接口與注解的統(tǒng)一

解決 spring-retry 與 guava-retrying 中的不足之處

設(shè)計(jì)目的

綜合了 spring-retry 和 gauva-retrying 的優(yōu)勢(shì)。

調(diào)整一些特性,使其更利于實(shí)際使用。

采用 Netty 類(lèi)似的接口思想,保證接口的一致性,和替換的靈活性。

借鑒 Hibernate-Validator 的設(shè)計(jì),允許用戶自定義注解。

spring-retry 與 guava-retrying 中的不足之處
更新記錄
更新記錄
開(kāi)源地址
sisyphus
快速開(kāi)始 引入

    com.github.houbb
    sisyphus-core
    0.0.6
入門(mén)代碼

詳情參見(jiàn) [RetryerTest]()

public void helloTest() {
    Retryer.newInstance()
            .retry(new Callable() {
                @Override
                public String call() throws Exception {
                    System.out.println("called...");
                    throw new RuntimeException();
                }
            });
}
代碼分析

retry

指定一個(gè) callable 的實(shí)現(xiàn)。

我們打印一條日志,并且模擬一個(gè)程序異常。

日志信息

日志信息

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

和一些其他異常信息。

重試觸發(fā)的條件,默認(rèn)是程序發(fā)生了異常

這里的重試間隔默認(rèn)為沒(méi)有時(shí)間間隔,一共嘗試3次。(包括第一次程序本身執(zhí)行)

為什么選擇 sisyphus 為什么選擇 sisyphus

作為開(kāi)發(fā)者,我們一般都會(huì)選擇比較著名的框架。

比如 guava-retrying spring-retry。

或者干脆自己寫(xiě)一個(gè)。

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

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

guava-retrying 優(yōu)缺點(diǎn) 優(yōu)點(diǎn)

使用靈活

fluent 優(yōu)雅寫(xiě)法

提供足夠多的實(shí)現(xiàn)

缺點(diǎn)

沒(méi)有默認(rèn)基于注解的實(shí)現(xiàn)

重試策略設(shè)計(jì)并不友好

spring-retry 優(yōu)點(diǎn)

使用簡(jiǎn)單

缺點(diǎn)

重試條件單一

重試等待策略單一

無(wú)法自定義注解

為什么不自己寫(xiě)一個(gè) 個(gè)人感受

我作為一名開(kāi)發(fā),平時(shí)說(shuō)實(shí)在的,看到重試。

我肯定會(huì)偷懶寫(xiě)一個(gè) for 循環(huán),重試幾次就結(jié)束了。

因?yàn)闀r(shí)間不允許。

如果你更勤快一點(diǎn),就可以選擇 spring-retry/guava-retrying。如果你熟悉他們的優(yōu)缺點(diǎn)的話。

如果你渴望創(chuàng)造

sisyphus 所有的實(shí)現(xiàn)都是基于接口的。

你完全可以實(shí)現(xiàn)自己的實(shí)現(xiàn),所有的東西基本完全可以被替換。

當(dāng)然一些常見(jiàn)的策略實(shí)現(xiàn),項(xiàng)目的基本框架都有詳盡的注釋?zhuān)?dāng)做參考也可以有一點(diǎn)幫助。

sisyphus 做的更多的事情 netty 的靈感

參考了 netty 的設(shè)計(jì),保證接口實(shí)現(xiàn)的一致性。

而且 sisyphus 還做了更多,還保證了接口和注解之間的一致性。

使用引導(dǎo)類(lèi),保證使用時(shí)的便利性,后期拓展的靈活性。

hibernate-validator

hibernate-validator 的作者是我知道為數(shù)不多的對(duì)于 java 注解應(yīng)用很棒的開(kāi)發(fā)者。(雖然所知甚少)

自定義注解就是從這個(gè)框架中學(xué)來(lái)的。

與 spring 為伍

spring 基本與我們的代碼形影不離,所以你可以很簡(jiǎn)單的結(jié)合 spring.

就像你使用 spring-retry 一樣。

sisyphus 模塊簡(jiǎn)介 模塊劃分

sisyphus 在模塊劃分的時(shí)候考慮到使用者的方便,主要有幾個(gè)模塊:

sisyphus-api

接口定義模塊,是最基礎(chǔ)的部分。

會(huì)被 sisyphus-core 默認(rèn)依賴。

一般不需要引入,如果你想根據(jù)它實(shí)現(xiàn)自己的重試框架,不妨一試。

sisyphus-core

對(duì)于 sisyphus-api 模塊的默認(rèn)實(shí)現(xiàn)。

并且添加易于使用的 Fluent 引導(dǎo)類(lèi),可以很方便的寫(xiě)出聲明式的重試代碼。

sisyphus-annotation

sisyphus 的注解實(shí)現(xiàn)模塊。

(1)基于字節(jié)碼實(shí)現(xiàn)的代理重試,可以不依賴 spring。平時(shí)使用也更加靈活

(2)允許自定義注解及其實(shí)現(xiàn)。使用者可以編寫(xiě)屬于自己的重試注解。

sisyphus-spring

spring 做為 java 開(kāi)發(fā)的引導(dǎo)者。自然是要支持的。

你可以和使用 spring-retry 一樣方便的使用 sisyphus-spring。

模塊間的依賴關(guān)系
sisyphus-api
sisyphus-core
sisyphus-annotation
sisyphus-spring
sisyphus-test

sisyphus-api 是基礎(chǔ)的,靈活性最高。

sisyphus-spring 是最簡(jiǎn)單易用的,靈活性相對(duì)較差。

sisyphus-test 僅僅用作測(cè)試,不用外部引入。

sisyphus 配置概覽

為了滿足更加方便的配置,Retryer 類(lèi)提供了許多可以配置的信息。

默認(rèn)配置
/**
 * 默認(rèn)配置測(cè)試
 */
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();
}

和下面的代碼是等價(jià)的:

public void helloTest() {
    Retryer.newInstance()
            .callable(new Callable() {
                @Override
                public String call() throws Exception {
                    System.out.println("called...");
                    throw new RuntimeException();
                }
            }).retryCall();
}
方法說(shuō)明 condition

重試觸發(fā)的條件,可以指定多個(gè)條件。

默認(rèn)為拋出異常。

retryWaitContext

重試等待的策略,可以指定多個(gè)。

默認(rèn)為不做任何等待。

maxAttempt

指定最大重試次數(shù),包括第一次執(zhí)行。

默認(rèn)值:3 次。

listen

指定重試的監(jiān)聽(tīng)實(shí)現(xiàn),默認(rèn)為不做監(jiān)聽(tīng)。

recover

當(dāng)重試完成之后,依然滿足重試條件,則可以指定恢復(fù)的策略。

默認(rèn)不做恢復(fù)。

callable

待重試執(zhí)行的方法。

retryCall

觸發(fā)重試執(zhí)行。

接口的詳細(xì)介紹 接口及其實(shí)現(xiàn)

所有的接口,都可以直接查看對(duì)應(yīng)的子類(lèi)實(shí)例。

用戶自定義

基于替換的靈活性,用戶可以實(shí)現(xiàn)接口,定義更符合自己業(yè)務(wù)的實(shí)現(xiàn)。

sisyphus 注解

配置具有很高的靈活性,但是對(duì)于開(kāi)發(fā)人員的使用,就沒(méi)有注解那樣簡(jiǎn)單靈活。

所以本框架也實(shí)現(xiàn)了基于注解的重試。

設(shè)計(jì)的規(guī)范

保證接口和注解二者的統(tǒng)一性。

maven 引入

    ${project.groupId}
    sisyphus-annotation
    ${project.version}
注解

核心注解主要有兩個(gè)。

Retry

用于指定重試的相關(guān)配置。

/**
 * 重試注解
 * 1. 實(shí)際需要,只允許放在方法上。
 * 2. 如果放在接口上,是否所有的子類(lèi)都生效?為了簡(jiǎn)單明確,不提供這種實(shí)現(xiàn)。
 * 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 {

    /**
     * 重試類(lèi)實(shí)現(xiàn)
     * @return 重試
     * @since 0.0.5
     */
    Class retry() default DefaultRetry.class;

    /**
     * 最大嘗試次數(shù)
     * 1. 包含方法第一次正常執(zhí)行的次數(shù)
     * @return 次數(shù)
     */
    int maxAttempt() default 3;

    /**
     * 重試觸發(fā)的場(chǎng)景
     * @return 重試觸發(fā)的場(chǎng)景
     */
    Class condition() default ExceptionCauseRetryCondition.class;

    /**
     * 監(jiān)聽(tīng)器
     * 1. 默認(rèn)不進(jìn)行監(jiān)聽(tīng)
     * @return 監(jiān)聽(tīng)器
     */
    Class listen() default NoRetryListen.class;

    /**
     * 恢復(fù)操作
     * 1. 默認(rèn)不進(jìn)行任何恢復(fù)操作
     * @return 恢復(fù)操作對(duì)應(yīng)的類(lèi)
     */
    Class recover() default NoRecover.class;

    /**
     * 等待策略
     * 1. 支持指定多個(gè),如果不指定,則不進(jìn)行任何等待,
     * @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. 為了對(duì)應(yīng)重試策略,所有的內(nèi)置注解應(yīng)該實(shí)現(xiàn)當(dāng)前的注解。
 * 2. 是否允許自定義注解?
 *
 * 當(dāng)注解+對(duì)象同時(shí)出現(xiàn)的時(shí)候,視為組合。
 *
 * @author binbin.hou
 * @since 0.0.3
 */
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Target(ElementType.ANNOTATION_TYPE)
@RetryWaitAble(DefaultRetryWaitAbleHandler.class)
public @interface RetryWait {

    /**
     * 默認(rèn)值
     * 1. fixed 模式,則對(duì)應(yīng)固定等待時(shí)間
     * 2. 遞增
     * @return 默認(rèn)值
     */
    long value() default RetryWaitConst.VALUE_MILLS;

    /**
     * 最小值
     * @return 最小值
     */
    long min() default RetryWaitConst.MIN_MILLS;

    /**
     * 最大值
     * @return 最大值
     */
    long max() default RetryWaitConst.MAX_MILLS;

    /**
     * 影響因數(shù)
     * 1. 遞增重試,默認(rèn)為 {@link RetryWaitConst#INCREASE_MILLS_FACTOR}
     * 2. 指數(shù)模式。默認(rèn)為 {@link RetryWaitConst#MULTIPLY_FACTOR}
     * @return 影響因數(shù)
     */
    double factor() default Double.MIN_VALUE;

    /**
     * 指定重試的等待時(shí)間 class 信息
     * @return 重試等待時(shí)間 class
     */
    Class retryWait() default NoRetryWait.class;

}
注解的使用

定義好了注解,肯定要有注解的相關(guān)使用。

關(guān)于注解的使用,主要有兩種方式。

Proxy+CGLIB

基于代理模式和字節(jié)碼增強(qiáng)。

如果是項(xiàng)目中沒(méi)有使用 spring,直接使用這種方式比較方便。

Spring-AOP

可以和 spring 直接整合。

使用方式和 spring-retry 是一樣的。

sisyphus 代理模板 目的

為了便于用戶更加方便地使用注解,同時(shí)又不依賴 spring。

提供基于代碼模式+字節(jié)碼增強(qiáng)實(shí)現(xiàn)的方式。

使用案例 maven 引入

引入注解相關(guān)模塊。


    ${project.groupId}
    sisyphus-annotation
    ${project.version}
定義測(cè)試方法

以下測(cè)試代碼可以參考 [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();
    }

}
測(cè)試

使用 RetryTemplate 進(jìn)行測(cè)試

無(wú)重試注解的方法
@Test(expected = RuntimeException.class)
public void templateTest() {
    MenuServiceImpl menuService = RetryTemplate.getProxyObject(new MenuServiceImpl());
    menuService.queryMenu(1);
}

日志信息

查詢菜單...

只請(qǐng)求了一次。

有注解的方法
@Test(expected = RuntimeException.class)
public void templateRetryTest() {
    MenuServiceImpl menuService = RetryTemplate.getProxyObject(new MenuServiceImpl());
    menuService.queryMenuRetry(1);
}

日志信息

查詢菜單...
查詢菜單...
查詢菜單...
其他

當(dāng)然還有更多的配置,可以自行嘗試。

如果你想結(jié)合 spring 使用注解,請(qǐng)繼續(xù)往下看。

sisyphus spring 整合 目的

類(lèi)似于 spring-retry 框架,如果你使用 spring 框架,那么整合本項(xiàng)目將會(huì)非常簡(jiǎn)單。

注解的方式和過(guò)程式編程,二者盡可能的保持一致性,你想從一種方式變?yōu)榱硪环N也比較簡(jiǎn)單。

想從 spring-retry 切換到本框架也很方便。

使用示例 maven 引入

    ${project.groupId}
    sisyphus-spring
    ${project.version}

會(huì)默認(rèn)引入 spring 以及 AOP 相關(guān) jar。

業(yè)務(wù)代碼

你可以參考 sisyphus-test 模塊。

下面模擬非常常見(jiàn)的一些業(yè)務(wù)方法。

使用 @Retry 標(biāo)識(shí)方法需要進(jìn)行重試。

SpringService.java

public interface SpringService {

    /**
     * 查詢示例代碼
     * @return 結(jié)果
     */
    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();
    }

}
開(kāi)啟重試

基于注解直接如下配置即可。

使用 @EnableRetry 標(biāo)識(shí)需要開(kāi)啟重試。

@Configurable
@ComponentScan(basePackages = "com.github.houbb.sisyphus.test.service")
@EnableRetry
public class SpringConfig {
}
測(cè)試代碼
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.SpringJUnit4ClassRunner;

/**
 * @author binbin.hou
 * @since 0.0.4
 */
@ContextConfiguration(classes = SpringConfig.class)
@RunWith(SpringJUnit4ClassRunner.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...
新特性預(yù)定 入?yún)?/b>

重試上下文添加入?yún)⑿畔?/p> 配置優(yōu)化

提供更加優(yōu)異的配置體驗(yàn)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77855.html

相關(guān)文章

  • java retry(重試) spring retry, guava retrying 詳解

    摘要:支持重試版本思考小明我手頭還有其他任務(wù),這個(gè)也挺簡(jiǎn)單的。與其他類(lèi)似的字節(jié)碼編輯器不同,提供了兩個(gè)級(jí)別的源級(jí)和字節(jié)碼級(jí)。另一方面,字節(jié)碼級(jí)允許用戶直接編輯類(lèi)文件作為其他編輯器。提供與其他字節(jié)碼框架類(lèi)似的功能,但主要關(guān)注性能。 系列說(shuō)明 java retry 的一步步實(shí)現(xiàn)機(jī)制。 java-retry 源碼地址 情景導(dǎo)入 簡(jiǎn)單的需求 產(chǎn)品經(jīng)理:實(shí)現(xiàn)一個(gè)按條件,查詢用戶信息的服務(wù)。 小明:好的...

    LucasTwilight 評(píng)論0 收藏0
  • Spring 指南(spring-retry

    摘要:包含一些狀態(tài)來(lái)決定是重試還是中止,但是這個(gè)狀態(tài)位于堆棧上,不需要將它存儲(chǔ)在全局的任何位置,因此我們將此稱(chēng)為無(wú)狀態(tài)重試。將拋出原始異常,除非在有狀態(tài)的情況下,當(dāng)沒(méi)有可用的恢復(fù),在這種情況下,它將拋出。 spring-retry 該項(xiàng)目為Spring應(yīng)用程序提供聲明式重試支持,它用于Spring Batch、Spring Integration、Apache Hadoop的Spring(以...

    xiaotianyi 評(píng)論0 收藏0
  • spring-cloud-feign源碼深度解析

    摘要:內(nèi)部使用了的動(dòng)態(tài)代理為目標(biāo)接口生成了一個(gè)動(dòng)態(tài)代理類(lèi),這里會(huì)生成一個(gè)動(dòng)態(tài)代理原理統(tǒng)一的方法攔截器,同時(shí)為接口的每個(gè)方法生成一個(gè)攔截器,并解析方法上的元數(shù)據(jù),生成一個(gè)請(qǐng)求模板。的核心源碼解析到此結(jié)束了,不知道是否對(duì)您有無(wú)幫助,可留言跟我交流。 Feign是一個(gè)聲明式的Web服務(wù)客戶端。這使得Web服務(wù)客戶端的寫(xiě)入更加方便 要使用Feign創(chuàng)建一個(gè)界面并對(duì)其進(jìn)行注釋。它具有可插拔注釋支持,包...

    vibiu 評(píng)論0 收藏0
  • ★推薦一款適用于SpringBoot項(xiàng)目輕量級(jí)HTTP客戶端框架

    摘要:請(qǐng)求重試攔截器錯(cuò)誤解碼器在發(fā)生請(qǐng)求錯(cuò)誤包括發(fā)生異?;蛘唔憫?yīng)數(shù)據(jù)不符合預(yù)期的時(shí)候,錯(cuò)誤解碼器可將相關(guān)信息解碼到自定義異常中。 在SpringBoot項(xiàng)目直接使用okhttp、httpClient或者RestTemplate發(fā)起HTTP請(qǐng)求,既繁瑣又不方便統(tǒng)一管理。因此,在這里推薦一個(gè)適...

    不知名網(wǎng)友 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<