不工作 - CXF电路断路器功能的编程方法

问题描述 投票:0回答:1

根据文档 - 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>

包含堆栈跟踪的日志(available here)。

经过大量的调试后,我开始明白连接失败的计数器永远不会超过阈值限制,因为数据的状态(包括计数器)特定于每个WebClient对象,为每个调用实例化。我假设如果在多次失败的调用中使用了相同的WebClient实例,那么计数器就会更新并最终打开电路。有关详细信息,请查找attached screenshot

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

cxf circuit-breaker
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

© www.soinside.com 2019 - 2024. All rights reserved.