I have two micro services A and B with eureka enable .Am using feign in B to call A service it's working fine .And am trying to make retry works with below ribbon properties
feignclient
#FeignClient(name = "https://test",
path = test, fallback = FeignClientFallback.class)
public interface FeignClient
{
#RequestMapping(value = "getname", method = RequestMethod.GET)
public Testdata find(#RequestParam(value = "id", required = true) String id)
}
service B
#Autowired
FeignClient feignClient;
#RequestMapping(value = "/testdata", method = RequestMethod.GET)
public Testdata gettestdata() throws Exception
{
Testdata testdata = feignClient.find("apple");
return testdata;
}
ribbon properities
spring
cloud:
loadbalancer:
retry:
enabled: true
ribbon.MaxAutoRetries: 3
ribbon.MaxAutoRetriesNextServer: 2
ribbon.OkToRetryOnAllOperations: true
feign:
hystrix:
enabled: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 45000
circuitBreaker:
enabled: true
sleepWindowInMilliseconds: 5000
requestVolumeThreshold: 20
spring cloud dependency are
spring-cloud-dependencies-Dalston.SR1
spring retry ,spring-cloud-starter-feign,spring-cloud-starter-ribbon
when service A is down and am trying to call A service from B but retry is not working and its directly invoking fallback is any configuration am missing to make work?
without fall back am getting error like below
com.netflix.client.ClientException: Load balancer does not have available server for client: test
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at rx.Observable.unsafeSubscribe(Observable.java:10211) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) ~[rxjava-1.1.10.jar:1.1.10]
at rx.Observable.unsafeSubscribe(Observable.java:10211) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276) ~[rxjava-1.1.10.jar:1.1.10]
at rx.Subscriber.setProducer(Subscriber.java:209) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) ~[rxjava-1.1.10.jar:1.1.10]
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.10.jar:1.1.10]
at rx.Observable.subscribe(Observable.java:10307) ~[rxjava-1.1.10.jar:1.1.10]
at rx.Observable.subscribe(Observable.java:10274) ~[rxjava-1.1.10.jar:1.1.10]
at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:445) ~[rxjava-1.1.10.jar:1.1.10]
at rx.observables.BlockingObservable.single(BlockingObservable.java:342) ~[rxjava-1.1.10.jar:1.1.10]
at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:117) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97) ~[feign-core-9.5.0.jar:?]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) ~[feign-core-9.5.0.jar:?]
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:108) ~[feign-hystrix-9.5.0.jar:?]
i assume when its execute with loadbalancerfeignclient
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest,
requestConfig).toResponse();
}
catch (ClientException e) {
IOException io = findIOException(e);
if (io != null) {
throw io;
}
throw new RuntimeException(e);
but am always getting client exception ,its not getting retry so created a bean as primary to retry still its not working
#Bean
#Primary
RetryHandler retryhandler() {
// TODO Auto-generated method stub
return new RequestSpecificRetryHandler(true, true);
}
Any help is appreciated and trying to understand y its not working......
Related
We have an application that has faced such error after successfully doing bunch of transactions from db and we realized the jdbc connection pool is full of idle connections that won't be closed and keep piling up.
Here is the error log from springboot app:
2021-08-12T00:50:28,078 INFO [org.apache.cxf.binding.soap.interceptor.Soap12FaultOutInterceptor:66] (http-nio-8080-exec-83) eventId=w:ef9c7df4-fae6-11eb-b2fa-000d3a434359, tenantId=, pe=, user=, app=, pid=, message=class org.apache.cxf.binding.soap.interceptor.Soap12FaultOutInterceptor$Soap12FaultOutInterceptorInternalmultipart/related; type="application/xop+xml"; boundary="uuid:c21d3fc7-b321-4895-a608-1e4e58824a90"; start="<root.message#cxf.apache.org>"; start-info="application/soap+xml"
2021-08-12 00:51:28 org.hibernate.engine.jdbc.spi.SqlExceptionHelper:137 [WARN] SQL Error: 0, SQLState: null
2021-08-12 00:51:28 org.hibernate.engine.jdbc.spi.SqlExceptionHelper:142 [ERROR] Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.
2021-08-12T00:51:28,074 WARN [org.apache.cxf.phase.PhaseInterceptorChain:475] (http-nio-8080-exec-84) eventId=w:e29c0214-fae6-11eb-8a27-000d3a434359, tenantId=, pe=, user=, app=, pid=, message=Interceptor for {urn:ihe:iti:xds-b:2007}HIEDirectXDRService#{urn:ihe:iti:xds-b:2007}DocumentRepository_ProvideAndRegisterDocumentSet-b has thrown exception, unwinding now
org.springframework.orm.hibernate5.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [n/a]; SQL state [null]; error code [0]; Unable to acquire JDBC Connection; nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:252) ~[spring-orm-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.orm.hibernate5.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:102) ~[spring-orm-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
......
Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:107) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:134) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
......
Caused by: com.atomikos.jdbc.AtomikosSQLException: Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.
at com.atomikos.jdbc.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:29) ~[transactions-jdbc-4.0.6.jar!/:?]
at com.atomikos.jdbc.AbstractDataSourceBean.throwAtomikosSQLException(AbstractDataSourceBean.java:76) ~[transactions-jdbc-4.0.6.jar!/:?]
at com.atomikos.jdbc.AbstractDataSourceBean.throwAtomikosSQLException(AbstractDataSourceBean.java:71) ~[transactions-jdbc-4.0.6.jar!/:?]
at com.atomikos.jdbc.AbstractDataSourceBean.getConnection(AbstractDataSourceBean.java:351) ~[transactions-jdbc-4.0.6.jar!/:?]
at com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean.getConnection(AtomikosNonXADataSourceBean.java:189) ~[transactions-jdbc-4.0.6.jar!/:?]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38) ~[hibernate-core-5.4.18.Final.jar!/:5.4.18.Final]
......
We tried to increase maxpoolsize and borrowConnectionTimeout but haven't resolved the issue successfully. The app uses atomikos as transaction manager and we are trying to find how to close the idle connections after several minutes without any activities and keep the total number of connections down, fewer idle connections hanging out means more active connections can be going hopefully. We use XA transaction with atomikos. Please kindly advise how we could achieve the goal to keep idle connection down and close or flush the idle connection after certain time without active transaction to allow more active connections to start wtihout running out of the connection pool. Thanks. BTW, we use atomikos 4.0.6.
The application.yml looks like:
app:
datasource:
transaction:
transaction_timeout: 600
postgres:
dialect: org.hibernate.dialect.PostgreSQL82Dialect
driverClassName: org.postgresql.Driver
tac:
borrow_conn_timeout: 30
max_idle_time: 300
min_pool_size: 5
max_pool_size: 20
show_sql: false
max_lifetime: 1800
test_query: 'select 1'
hibernate:
connection:
release_mode: after_transaction
current_session_context_class: jta
spring:
profiles:
active: PostgreSql
jpa:
hibernate:
use-new-id-generator-mappings: false
properties:
hibernate:
id:
new_generator_mappings: false
jta:
atomikos:
connectionfactory:
ignore-session-transacted-flag: false
max-pool-size: 50
min-pool-size: 5
datasource:
max-pool-size: 50
min-pool-size: 5
properties:
service: com.atomikos.icatch.standalone.UserTransactionServiceFactory
enabled: true
Here is the DatabaseTransactionConfiguration:
#Configuration
public class DatabaseTransactionConfiguration {
#Value("${app.datasource.transaction.transaction_timeout}")
Integer transactionTimeout = 300;
#Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
final UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(transactionTimeout);
return userTransactionImp;
}
#Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
public TransactionManager atomikosTransactionManager() throws Throwable {
final UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setTransactionTimeout(transactionTimeout);
userTransactionManager.setStartupTransactionService(false);
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
#Bean(name = { "transactionManager", "jtaTransactionManager" })
#DependsOn({ "userTransaction", "atomikosTransactionManager" })
public PlatformTransactionManager transactionManager() throws Throwable {
final UserTransaction userTransaction = userTransaction();
final TransactionManager atomikosTransactionManager = atomikosTransactionManager();
return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
}
}
Here is the DataSourceConfigurationTAC.java:
#Configuration
#EnableTransactionManagement
public class DataSourceConfigurationTAC {
#Value("${app.datasource.postgres.driverClassName}")
String postgresDriverClass;
#Value("${app.datasource.oracle.dialect}")
String oracleDialect;
#Value("${app.datasource.postgres.dialect}")
String postgresDialect;
#Value("${app.datasource.danc.borrow_conn_timeout}")
Integer borrowConnectionTimeout;
#Value("${app.datasource.danc.max_idle_time}")
Integer maxIdleTime;
#Value("${app.datasource.danc.min_pool_size}")
Integer minPoolSize;
#Value("${app.datasource.danc.max_pool_size}")
Integer maxPoolSize;
/**
* Maximum amount of seconds that a connection is kept in the pool before
* it is destroyed automatically. Optional, defaults to 0 (no limit).
*/
#Value("${app.datasource.tac.max_lifetime:0}")
Integer maxLifetime;
/**
* SQL query or statement used to validate a connection before returning it. Optional.
*/
#Value("${app.datasource.tac.test_query:#null}")
String testQuery;
#Bean(name = "dataSource")
#Primary
public DataSource tacDataSource() throws SQLException {
AtomikosNonXADataSourceBean bean = new AtomikosNonXADataSourceBean();
bean.setUniqueResourceName(dataSourceName);
bean.setDriverClassName(OdxcEnvironment.isPostgreSql() ? postgresDriverClass : oracleDriverClass);
bean.setBorrowConnectionTimeout(borrowConnectionTimeout);
bean.setMaxIdleTime(maxIdleTime);
bean.setMinPoolSize(minPoolSize);
bean.setMaxPoolSize(maxPoolSize);
bean.setMaxLifetime(maxLifetime);
bean.setTestQuery(testQuery);
return bean;
}
#Bean(name = { "sessionFactory" })
#Primary
public LocalSessionFactoryBean customerEntityManager(
#Autowired #Qualifier("jtaTransactionManager") PlatformTransactionManager transactionManager,
#Autowired #Qualifier("dataSource") DataSource tacDataSource) throws Throwable {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(tacDataSource);
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", postgresDialect);
hibernateProperties.setProperty("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
hibernateProperties.setProperty("javax.persistence.transactionType", "JTA");
hibernateProperties.setProperty("hibernate.transaction.coordinator_class", "jta");
hibernateProperties.setProperty("hibernate.jdbc.use_streams_for_binary", Boolean.FALSE.toString());
hibernateProperties.setProperty("hibernate.id.new_generator_mappings", Boolean.FALSE.toString());
hibernateProperties.setProperty("hibernate.show_sql", Boolean.FALSE.toString());
hibernateProperties.setProperty("hibernate.format_sql", Boolean.FALSE.toString());
hibernateProperties.setProperty("hibernate.use_sql_comments", Boolean.FALSE.toString());
hibernateProperties.setProperty("hibernate.default_batch_fetch_size", "16");
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", Boolean.TRUE.toString());
hibernateProperties.setProperty("hibernate.cache.region.factory_class",
"org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");
hibernateProperties.setProperty("hibernate.cache.region_prefix", "connnectivity_springboot");
hibernateProperties.setProperty("hibernate.cache.use_query_cache", Boolean.TRUE.toString());
hibernateProperties.setProperty("hibernate.generate_statistics", Boolean.FALSE.toString());
sessionFactoryBean.setHibernateProperties(hibernateProperties);
sessionFactoryBean.setJtaTransactionManager(transactionManager);
return sessionFactoryBean;
}
}
I have a Spring Cloud Gateway (eureka client) app that uses Spring Cloud Load Balancer (Spring Cloud version: Hoxton.SR6) and I have an instance of a spring boot app (spring boot 2.3 with enabled graceful shutdown, (eureka client).
When I shutdown a spring boot service and perform a request through the gateway then the gateway throws 500 error (connection refused), instead of 503. 503 appears after a 1-2 minutes.
Can anyone clarify if it is an expected behavior?
It seems that the problem comes from eureka-client (1.9.21 version in my case)
AtomicReference<Applications> localRegionApps isn't frequently updated
Thanks!
UPDATE:
I decided to check deeper this 500 error. The result is that my system (ubuntu) gives this error if the port is not used:
curl -v localhost:9722
Rebuilt URL to: localhost:9722/
Trying 127.0.0.1...
TCP_NODELAY set
connect to 127.0.0.1 port 9722 failed: Connection refused
Failed to connect to localhost port 9722: Connection refused
Closing connection 0
So I put in my application.yml:
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:9722/
Then when my request is routed to my_route and none of apps uses 9722 then I get an error:
io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: localhost/127.0.0.1:9722
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/internal/mail/internal/health-check" [ExceptionHandlingWebHandler]
Stack trace:
Caused by: java.net.ConnectException: finishConnect(..) failed: Connection refused
at io.netty.channel.unix.Errors.throwConnectException(Errors.java:124)
at io.netty.channel.unix.Socket.finishConnect(Socket.java:251)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.doFinishConnect(AbstractEpollChannel.java:672)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.finishConnect(AbstractEpollChannel.java:649)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.epollOutReady(AbstractEpollChannel.java:529)
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:465)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
It seems to be an unexpected exception, since it isn't possible to handle it using a circuit breaker or any gateway filter.
Is it possible to handle this error correctly? I would like to return 503 in this case
One of the easiest ways to map particular exception to particular HTTP status code is providing a custom bean of type org.springframework.boot.web.reactive.error.ErrorAttributes. Here is an example:
#Bean
public ErrorAttributes errorAttributes() {
return new CustomErrorAttributes(httpStatusExceptionTypeMapper);
}
public class CustomErrorAttributes extends DefaultErrorAttributes {
#Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> attributes = super.getErrorAttributes(request, options);
Throwable error = getError(request);
MergedAnnotation<ResponseStatus> responseStatusAnnotation = MergedAnnotations
.from(error.getClass(), MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(ResponseStatus.class);
HttpStatus errorStatus = determineHttpStatus(error, responseStatusAnnotation);
attributes.put("status", errorStatus.value());
return attributes;
}
private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation<ResponseStatus> responseStatusAnnotation) {
if (error instanceof ResponseStatusException) {
return ((ResponseStatusException) error).getStatus();
}
return responseStatusAnnotation.getValue("code", HttpStatus.class).orElseGet(() -> {
if (error instanceof java.net.ConnectException) {
return HttpStatus.SERVICE_UNAVAILABLE;
}
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}
}
hava a try to define your custom ErrorWebExceptionHandler.
see:
org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler
org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler
You should use Cloud Circuit Breaker.
For that:
Declare corresponding starter in your pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
Declare circuit breaker in application.yaml
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:9722/
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
Declare the endpoint which will be called in the case of failure (a connection error, for example)
#RequestMapping("/inCaseOfFailureUseThis")
public Mono<ResponseEntity<String>> inCaseOfFailureUseThis() {
return Mono.just(ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("body for service failure case"));
}
I'm using Spring Cloud gateway and trying to use the circuit breaker. In the gateway I have added a fallback(failover-service) method for the service(cricketer-service) in the gateway(cricketer-gateway).
The failover service works fine individually. Failover service is named as cricketer-failover-service in application.properties.
Gateway config
#Configuration
public class RoutesConfig {
#Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/cricketers*")
.filters(f -> f.circuitBreaker(c -> c.setName("cricketerFb")
.setFallbackUri("forward:/cricketer-failover")
.setRouteId("cricketer-failover")
))
.uri("lb://cricketer-service")
.id("cricketer-service"))
.route(r -> r.path("/cricketer-failover*")
.uri("lb://cricketer-failover-service")
.id("cricketer-failover-service"))
.build();
}
When I turn the service off and then hit the endpoint, I receive an exception
2020-08-30 14:17:28.670 ERROR 14766 --- [or-http-epoll-3] com.netflix.hystrix.AbstractCommand : Unrecoverable Error for HystrixCommand so will throw HystrixRuntimeException and not apply fallback.
java.lang.Exception: Throwable caught while executing.
at com.netflix.hystrix.AbstractCommand.getExceptionFromThrowable(AbstractCommand.java:1976) ~[hystrix-core-1.5.18.jar:1.5.18]
Stacktrace - https://gist.github.com/nirmalks/4adb8b64955625df6b5a22469f106bfe
Code - https://github.com/nirmalks/cricketer-microservice/tree/hystrix-fallback-err
I have deployed an EJB in Jboss As 7.0.
Following is what the deployment logs says about the JNDI binding of EJB.
19:21:43,269 INFO
[org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor]
(MSC service thread 1-1) JNDI bindings for session bean named
ManageEmployeeBean in deployment unit deployment "EJBTest1.jar" are as
follows:
java:global/EJBTest1/ManageEmployeeBean!com.test.ejb.businessimpl.ManageEmployeeBeanRemote
java:app/EJBTest1/ManageEmployeeBean!com.test.ejb.businessimpl.ManageEmployeeBeanRemote
java:module/ManageEmployeeBean!com.test.ejb.businessimpl.ManageEmployeeBeanRemote
java:jboss/exported/EJBTest1/ManageEmployeeBean!com.test.ejb.businessimpl.ManageEmployeeBeanRemote
java:global/EJBTest1/ManageEmployeeBean
java:app/EJBTest1/ManageEmployeeBean java:module/ManageEmployeeBean
This is how my client class looks like.
package com.test.ejb.test;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.test.ejb.bean.Employee;
import com.test.ejb.businessimpl.ManageEmployeeBean;
import com.test.ejb.businessimpl.ManageEmployeeBeanRemote;
public class Client {
private static InitialContext initialContext;
public static void main(String[] args){
try {
getInitialContext();
System.out.println("CTX:"+initialContext);
} catch (NamingException e) {
e.printStackTrace();
}
try {
System.out.println("Looking up EJB !!");
ManageEmployeeBeanRemote remote =
(ManageEmployeeBeanRemote)initialContext.lookup("/EJBTest1/ManageEmployeeBean!com.test.ejb.businessimpl.ManageEmployeeBeanRemote");
System.out.println("setting employee..............");
Employee employee = new Employee();
employee.setFirstName("Renjith");
employee.setLastName("Ravi");
System.out.println("Adding employee");
remote.addEmployee(employee);
} catch (NamingException e) {
e.printStackTrace();
}
}
public static InitialContext getInitialContext() throws NamingException {
if (initialContext == null) {
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
prop.put(Context.PROVIDER_URL, "remote://localhost:4447");
prop.put(Context.SECURITY_PRINCIPAL, "renjith");
prop.put(Context.SECURITY_CREDENTIALS, "user");
initialContext = new InitialContext(prop);
}
return initialContext;
}
}
Client is not able to find the service when I run it.
CTX:javax.naming.InitialContext#40964823
Looking up EJB !!
javax.naming.CommunicationException: Could not obtain connection to any of these urls: remote://localhost:4447 and discovery failed with error: javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out] [Root exception is javax.naming.CommunicationException: Failed to connect to server remote:1099 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server remote:1099 [Root exception is java.net.UnknownHostException: remote: Name or service not known]]]
at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1416)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:596)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:589)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at com.test.ejb.test.Client.main(Client.java:29)
Caused by: javax.naming.CommunicationException: Failed to connect to server remote:1099 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server remote:1099 [Root exception is java.net.UnknownHostException: remote: Name or service not known]]
at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:269)
at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1387)
... 4 more
Caused by: javax.naming.ServiceUnavailableException: Failed to connect to server remote:1099 [Root exception is java.net.UnknownHostException: remote: Name or service not known]
at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:243)
... 5 more
Caused by: java.net.UnknownHostException: remote: Name or service not known
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:901)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1293)
at java.net.InetAddress.getAllByName0(InetAddress.java:1246)
at java.net.InetAddress.getAllByName(InetAddress.java:1162)
at java.net.InetAddress.getAllByName(InetAddress.java:1098)
at java.net.InetAddress.getByName(InetAddress.java:1048)
at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:76)
at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:239)
... 5 more
Can anyone tell me what am i missing here?
I saw lots of threads on similar topic in stackoverflow, but none of them helped me!!
You are attempting to use the EJB Remote client from JBoss AS 5 (or earlier).
You need to use the JBoss AS 7 EJB Remote client and configure it as per the documentation at AS7 JNDI Reference under the Remote JNDI heading.
I am using Java 8, Hibernate 5.1 and eclipse its working fine when using java code but when I setting proxy in java code or passing as VM argument in eclipse to connect AWS Cloud then hibernate connection get failed.
Java code which I setting proxy.
System.setProperty("java.net.useSystemProxies", "true");
System.setProperty("http.proxyHost", "comproxy.net");
System.setProperty("http.proxyPort", "80");
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1");
System.setProperty("http.proxyUser", "tm_user");
System.setProperty("http.proxyPassword", "password#135");
or VM argument
-Djava.net.useSystemProxies=true
-Dhttp.proxyHost=comproxy.is
-Dhttp.proxyPort=80
-Dhttp.nonProxyHosts=localhost
-Dhttp.proxyUser=tm_user
-Dhttp.proxyPassword=pwd#135
Exception
INFO: HHH000115: Hibernate connection pool size: 10 (min=1)
Exception in thread "main" org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:244)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:208)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
at com.singtel.mi.database.MIQueueDaoImpl.getSessionFactory(MIQueueDaoImpl.java:67)
at com.singtel.mi.database.MIQueueDaoImpl.openCurrentSession(MIQueueDaoImpl.java:44)
at com.singtel.mi.service.MessageInboxService.findAllCampaign(MessageInboxService.java:66)
at com.singtel.mi.service.APICallService.postJSONDatatoAWS(APICallService.java:25)
at com.singtel.mi.service.TestMessageInbox.main(TestMessageInbox.java:8)
Caused by: org.hibernate.exception.JDBCConnectionException: Error calling Driver#connect
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator$1$1.convert(BasicConnectionCreator.java:105)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:123)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:41)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:58)
at org.hibernate.engine.jdbc.connections.internal.PooledConnections.addConnections(PooledConnections.java:106)
at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:40)
at org.hibernate.engine.jdbc.connections.internal.PooledConnections.<init>(PooledConnections.java:19)
at org.hibernate.engine.jdbc.connections.internal.PooledConnections$Builder.build(PooledConnections.java:138)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:110)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:74)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:217)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
... 17 more
Caused by: java.sql.SQLException: Io exception: The Network Adapter could not establish the connection
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:124)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:161)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:273)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:318)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:343)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:147)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:31)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:545)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38)
... 32 more
Its failing because of proxy setting or -Djava.net.useSystemProxies=true or because of cloud?
public class HibernateUtil {
private final static SessionFactory sessionFactory;
//private static final SessionFactory sessionFactory = buildSessionFactory();
static{
try {
sessionFactory = new Configuration().configure("/com/singtel/mi/utils/hibernate.cfg.xml").buildSessionFactory();
} catch (Exception e) {
System.err.println("Seesion Factory Creation Failed---> "+e);
throw new ExceptionInInitializerError();
}
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
I am not able to get root cause for this.