JAX-RS: Failover
Starting from CXF 2.4.1, CXF JAX-RS clients can be configured for them to become failover-capable.
Core CXF Failover and Load Distribution features are supported.
Failover
Proxies and WebClients can be configured to failover to alternate addresses in case of connection-related failures.
Sequential and Random strategies are supported and implementers can build more sophisticated failover features by retrieving
alternate addresses from locators and other intermediaries.
Spring
xsi:schemaLocation="
http:
http:
http:
<bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<util:list id= "addressList" >
<value>http:
<value>http:
<value>http:
</util:list>
<bean id= "SequentialAddresses" class = "org.apache.cxf.clustering.SequentialStrategy" >
<property name= "alternateAddresses" >
<ref bean= "addressList" />
</property>
</bean>
<bean id= "RandomAddresses" class = "org.apache.cxf.clustering.RandomStrategy" >
<property name= "alternateAddresses" >
<ref bean= "addressList" />
</property>
</bean>
<jaxrs:features>
<clustering:failover>
<clustering:strategy>
<ref bean= "SequentialAddresses" />
</clustering:strategy>
</clustering:failover>
</jaxrs:features>
</jaxrs:client>
<jaxrs:features>
<clustering:failover>
<clustering:strategy>
<ref bean= "RandomAddresses" />
</clustering:strategy>
</clustering:failover>
</jaxrs:features>
</jaxrs:client>
<bean id= "myWebClient" class = "org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean"
factory-method= "createWebClient" >
<property name= "features" >
<ref bean= "failover1" />
</property>
</bean>
</beans>
|
Code
org.apache.cxf.jaxrs.features.clustering.FailoverFeature feature =
new org.apache.cxf.jaxrs.features.clustering.FailoverFeature();
List<String> alternateAddresses = new ArrayList<String>();
for (String s : address) {
alternateAddresses.add(s);
}
SequentialStrategy strategy = new SequentialStrategy();
strategy.setAlternateAddresses(alternateAddresses);
feature.setStrategy(strategy);
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
List<Feature> features = new ArrayList<Feature>();
features.add(feature);
bean.setFeatures(features);
bean.create(BookStore. class );
bean.createWebClient();
|
Circuit Breakers Failover
The recent addition to CXF failover features is the implementation based on circuit breakers, more precisely Apache Zest (https://zest.apache.org/) library. It is available starting from CXF 3.2.0.
The configuration is very similar to the regular failover strategy, the only difference is usage of clustering:circuit-breaker-failover element.
Spring
xsi:schemaLocation="
http:
http:
http:
<bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<util:list id= "addressList" >
<value>http:
<value>http:
<value>http:
</util:list>
<bean id= "SequentialAddresses" class = "org.apache.cxf.clustering.SequentialStrategy" >
<property name= "alternateAddresses" >
<ref bean= "addressList" />
</property>
</bean>
<bean id= "RandomAddresses" class = "org.apache.cxf.clustering.RandomStrategy" >
<property name= "alternateAddresses" >
<ref bean= "addressList" />
</property>
</bean>
<jaxrs:features>
<clustering:circuit-breaker-failover threshold= "1" timeout= "60000" >
<clustering:strategy>
<ref bean= "SequentialAddresses" />
</clustering:strategy>
</clustering:circuit-breaker-failover>
</jaxrs:features>
</jaxrs:client>
<jaxrs:features>
<clustering:circuit-breaker-failover threshold= "1" timeout= "60000" >
<clustering:strategy>
<ref bean= "RandomAddresses" />
</clustering:strategy>
</clustering:circuit-breaker-failover>
</jaxrs:features>
</jaxrs:client>
<bean id= "myWebClient" class = "org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean"
factory-method= "createWebClient" >
<property name= "features" >
<ref bean= "failover1" />
</property>
</bean>
</beans>
|
Circuit breakers have recommended themselves as a proven strategy to handle and monitor the failures related to external service calls, giving the external systems a time to recover by preventing endless retries or time-outing. For that reason, two configuration parameters could be tuned:
- threshold: the error threshold to open the circuit breaker
- timeout: the timeout to wait before trying the next invocation
Code
org.apache.cxf.jaxrs.features.clustering.CircuitBreakerFailoverFeature feature =
new org.apache.cxf.jaxrs.features.clustering.CircuitBreakerFailoverFeature( 1 , 60000 );
List<String> alternateAddresses = new ArrayList<String>();
for (String s : address) {
alternateAddresses.add(s);
}
SequentialStrategy strategy = new SequentialStrategy();
strategy.setAlternateAddresses(alternateAddresses);
feature.setStrategy(strategy);
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
List<Feature> features = new ArrayList<Feature>();
features.add(feature);
bean.setFeatures(features);
bean.create(BookStore. class );
bean.createWebClient();
|
Load Distribution
CXF Load Distribution feature is a failover feature which can iterate where alternate addresses not only in case of failures but also after a successful invocation has been done.
Example:
xsi:schemaLocation="
http:
http:
http:
<bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<util:list id= "addressList" >
<value>http:
<value>http:
<value>http:
</util:list>
<bean id= "SequentialAddresses" class = "org.apache.cxf.clustering.SequentialStrategy" >
<property name= "alternateAddresses" >
<ref bean= "addressList" />
</property>
</bean>
<jaxrs:features>
<clustering:loadDistributor>
<clustering:strategy>
<ref bean= "RandomAddresses" />
</clustering:strategy>
</clustering:loadDistributor>
</jaxrs:features>
</jaxrs:client>
|
the selector can be set from code like this:
org.apache.cxf.jaxrs.features.clustering.FailoverFeature feature =
new org.apache.cxf.jaxrs.features.clustering.FailoverFeature();
feature.setSelector( new org.apache.cxf.clustering.LoadDistributorTargetSelector());
|