0

根据文档 - https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Failover#JAX-RSFailover-Code.1,我尝试运行以下代码以及相关配置,但是断路器一旦超过连接故障的阈值计数,机制就不会打开。由于电路保持关闭,调用尝试仍被接受,这与预期行为背道而驰。

public class CustomerRestClient {

private CustomerRestClientFactory customerRestClientFactory;

public List<Customer> filterByFirstName(String firstName) {
    List<Customer> filteredCustomers = new ArrayList<>();
    CircuitBreakerFailoverFeature cbFailoverFeature = new CircuitBreakerFailoverFeature(4, 180000L);
    SequentialStrategy strategy = new SequentialStrategy();
    cbFailoverFeature.setStrategy(strategy);

    List<Feature> featureList = new ArrayList<Feature>();
    featureList.add(cbFailoverFeature);

    WebClient client = customerRestClientFactory.getClient(featureList).path("/");
    // Call service to get all customers
    List<Customer> customers = client.get(new GenericType<List<Customer>>() {});
    return filteredCustomers;
}

public void setCustomerRestClientFactory(CustomerRestClientFactory customerRestClientFactory) {
    this.customerRestClientFactory = customerRestClientFactory;
}

}

public class CustomerRestClientFactory implements InitializingBean {

private List providerList;  // Value is injected by Spring
private String serviceUrl;  // Value is injected by Spring

public WebClient getClient(List<? extends Feature> featureList) {
    if (featureList == null || featureList.isEmpty()) {
        throw new IllegalArgumentException("featureList is not initialized.");
    }
    JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
    bean.setAddress(serviceUrl);
    bean.setServiceClass(WebClient.class);
    bean.setProviders(providerList);
    bean.setFeatures(featureList);

    return bean.createWebClient();
}

}

<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">             
    <property name="dateFormat">
        <bean class="java.text.SimpleDateFormat"> <constructor-arg type="java.lang.String" value="yyyy-MM-dd'T'HH:mm:ss"/>
        </bean>
    </property>
    <property name="serializationInclusion">
        <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value> 
    </property>
</bean>
<bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
     <property name="mapper" ref="objectMapper"/>
</bean>
<util:list id="providerList">
    <ref bean="jsonProvider" />
    <bean name="exceptionHandler" class="com.mycompany.refapp.exception.AppExceptionHandler" />
</util:list>
<bean id="customerRestClientFactory" class="com.mycompany.refapp.client.CustomerRestClientFactory">
    <property name="providerList" ref="providerList" />
    <property name="serviceUrl" value="${customer.rest.service.url}" />
</bean>

包含堆栈跟踪的日志(在此处可用)。

经过大量调试,我了解到连接失败的计数器永远不会超过阈值限制,因为数据的状态(包括计数器)特定于每个 WebClient 对象,为每个调用实例化。我假设如果在多个失败的调用中使用相同的 WebClient 实例,那么计数器将被更新并最终打开电路。有关详细信息,请参阅随附的屏幕截图

我想就我的理解是否正确获得第二意见。

4

1 回答 1

1

您已经同时打开了问题https://issues.apache.org/jira/browse/CXF-7663,所以我在这里分享 Colm 的回复:

如果您想使用 Circuit-Breaker 功能,那么您需要对所有调用使用相同的 Webclient 实例 - 如果您为每次调用创建一个新的 WebClient,它将无法工作。这是一个显示其工作原理的测试:

https://github.com/coheigea/testcases/blob/218044e3126cff9339e27a69cd8d3c5f3fe308ea/apache/cxf/cxf-failover/src/test/java/org/apache/coheigea/cxf/failover/feature/FailoverTest.java#L90

于 2018-03-05T20:07:26.400 回答