根据文档 - 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。
我想就我的理解是否正确得到第二个意见。
答案 0 :(得分:1)
您已同时打开问题https://issues.apache.org/jira/browse/CXF-7663,因此我在此分享Colm的回复:
如果您想使用断路器功能,则需要使用 所有调用都使用相同的Webclient实例 - 它不起作用 如果您要为每个呼叫创建一个新的WebClient。这是一个测试,显示 它是如何工作的: