I recently replaced Hystrix with resilience4j with spring cloud. Most of the unit test are working fine but now I am getting 504 gateway timeout after 1 second. Is there anyway, I can configure the timeout in the properties? So far, I have added
#Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.circuitBreakerConfig(CircuitBreakerConfig.custom()
.minimumNumberOfCalls(5).failureRateThreshold(20)
.build())
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(10))
.build())
.build());
}
And also set the properties in application.yml file
spring:
cloud:
config:
enabled: false
gateway:
httpclient:
response-timeout: 6s
connect-timeout: 6000
Is there any other timeout, I need to configure?
Is there any workaround to configure the timeoutDuration in TimeLimiterConfig? Right now, timeoutDuration is picking up the default value of 1 second. Thats I am getting a 504.
Related
I have the following health management endpoints in my application.yml file
management:
endpoints:
health:
sensitive: false
web:
base-path: /
and I have an interceptor with the following code
class TestInterceptor {
TestInterceptor() {
matchAll()
}
boolean before() {
if (request.forwardURI?.endsWith('.json')) {
// ... some code
return false
}
true
}
}
this is working great. The application is working on 8080.
But as soon as I change the port of management endpoints (so that health check is served on a different port), the following code
management:
server:
port: 8989
endpoints:
health:
sensitive: false
web:
base-path: /
Ref# https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/production-ready-monitoring.html
then the application is throwing a cast exception when accessing the request object in the interceptor
org.springframework.web.util.NestedServletException: Request
processing failed; nested exception is
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot
cast object 'Request(GET
//localhost:8989/testApp/health)#68117e64' with class
'org.springframework.web.context.request.ServletRequestAttributes' to
class 'org.grails.web.servlet.mvc.GrailsWebRequest'
any suggestion to fix the issue.
(Grails 4.0.12, Groovy 2.5.14 and Java 11)
Upgrade to Grails 5. The above functionality working fine with that.
I want to stop the consumers in rabbitmq of creating a queue from spring cloud stream bindings while hitting endpoint /prepare-for-shutdown. Please find below the configuration,
Added dependency in pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
Application.yml:
spring:
cloud:
stream:
bindings:
produceChannel:
binder: rabbit
content-type: application/json
destination: internal-exchange
consumeChannel:
binder: rabbit
content-type: application/json
destination: internal-exchange
group: small-queue
rabbit:
bindings:
consumeChannel:
consumer:
autoBindDlq: true
durableSubscription: true
requeueRejected: false
republishToDlq: true
bindingRoutingKey: admin
produceChannel:
producer:
routingKeyExpression: '"admin"'
sample.java
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel;
public interface Sample{
#Input("consumeChannel")
SubscribableChannel consumeChannel();
#Output("produceChannel")
SubscribableChannel produceChannel();
}
The integration with RabbitMQ has been achieved using Spring Cloud's #StreamLinster and #EnableBinding abstractions as shown below:
#EnableBinding(Sample.class)
#StreamListener("consumeChannel")
public void sampleMessage(String message) {
// code
}
Looking forward to stop a consumer of a RabbitMQ queue programmatically.
Thanks in Advance
I analyzed the issue why am getting empty values by invoking the actuator endpoint '/actuator/bindings'
When hitting actuator binding endpoint, it invokes the method gatherInputBindings()in BindingsEndpoint.class.
In BindingsEndpoint.java, fetching the binding values from inputBindingLifecycle
(Collection<Binding<?>>) new DirectFieldAccessor(inputBindingLifecycle).getPropertyValue("inputBindings");
In below methods, setting empty bindings list to inputBindings
In InputBindingLifecycle.java,
void doStartWithBindable(Bindable bindable) {
this.inputBindings = bindable.createAndBindInputs(bindingService);
}
In Bindable.java,
default Collection<Binding<Object>> createAndBindInputs(BindingService adapter) {
return Collections.<Binding<Object>>emptyList();
}
Pls suggest me to fix these issues whether need to change any dependency or any code configuration
I implemented ratelimit with redis in my spring cloud api gateway. Here is part of application.yml:
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
discovery:
locator:
enabled: true
routes:
- id: test-rest-service
uri: lb://test-rest-service
predicates:
- Path=/test/**
filters:
- RewritePath=/test/(?<path>.*), /$\{path}
- name: RequestRateLimiter
args:
key-resolver: "#{#userRemoteAddressResolver}"
redis-rate-limiter.replenishRate: 2
redis-rate-limiter.burstCapacity: 3
I called a GET API via postman and checked response header.
X-RateLimit-Remaining -1
X-RateLimit-Burst-Capacity 3
X-RateLimit-Replenish-Rate 2
The rate limit is not working. Why am I getting negative value for X-RateLimit-Remaining? What does it mean? How do I fix it?
This happened to me because there was no Redis instance launched. You have two options:
1) Download and run a Redis instance using docker:
docker run --name redis -d redis
2) You can use in testing an Embedded Redis Server as it is explained in the following article by adding the maven dependency:
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.7.2</version>
<scope>test</scope>
</dependency>
And including the following snippet:
#TestConfiguration
public class TestRedisConfiguration {
private RedisServer redisServer;
public TestRedisConfiguration() {
this.redisServer = new RedisServer(6379);
}
#PostConstruct
public void postConstruct() {
redisServer.start();
}
#PreDestroy
public void preDestroy() {
redisServer.stop();
}
}
I faced the same issue recently. In my case, there was an older version of Redis installed which caused X-RateLimit-Remaining to be set to -1 constantly.
redis-cli shutdown
I have a spring-boot app which uses Declarative Feign Client
#ComponentScan
#EnableFeignClients
#EnableCircuitBreaker
#EnableDiscoveryClient
#EnableZuulProxy
#FeignClient(name = "${service-registry-name}", fallbackFactory = MyFallbackFactory.class, configuration = CommonFeignConfiguration.class)
public interface MyClient {
#RequestMapping(method = RequestMethod.GET, path = "/test/reference/data")
HttpEntity<String> getAllData();}
I have following application.yml
feign:
okhttp:
enabled: true
feign:
hystrix:
enabled: true
hystrix:
command:
MyClient#getAllData():
execution:
isolation:
thread:
timeoutInMilliseconds: 30000
hystrix:
command:
default:
execution:
timeout:
enabled: false
logging:
level:
project:
user:
MyClient: DEBUG
feign:
client:
config:
feign-name:
requestInterceptors: com.test.MyRequestHeaderProcessor
This spring-boot app works perfectly fine and when I debug the I could see that the timeout value of 30000 is properly applied.
The trouble starts when I use this code NOT as a standalone spring boot app but as a dependency jar into another project.
At this time, the timeout is always 1000, which is the default. I managed to override this as well. But despite of that, i get HystrixRunTimeException, Timeout with null.
I have feign.hystrix.enabled=true.
If I use feign.hystrix.enabled=false, I can see that my request doesnt time out but then the Fallback mechanism fails to work.
But, when I add URL attribute in FeignClient it works fine and does NOT timeout.I cannot rely on the URL attribute as this is coming from the cloud foundry service URL which can change.
Add below properties in Application.yml file.
feign:
client:
config:
default:
connectTimeout: 80000000
readTimeout: 80000000
I have a simple spring cloud application with side car here is the code:
#SpringBootApplication
#EnableSidecar
public class SidecarApp {
public static void main(String[] args) {
SpringApplication.run(SidecarApp.class, args);
}
}
The side car call to another service via zuul and I am trying to configure the hystrix timeout without success! here is my configurations:
server:
port: 9085
spring:
application:
name: cue
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 100
hystrix.command.default.execution.isolation.thread.interruptOnTimeout: true
hystrix.command.default.execution.timeout.enabled: true
sidecar:
port: 8085
health-uri: http://localhost:8085/health.json
in these configurations I expect that if the call to the other service will take more than 100 miliseconds the hystrix will return immediately, but this is not happened(the service hystrix call take 10 seconds)
Am I misconfiguring something?
Note:
The call to the other service is: http://localhost:9085/cma/myinfo1 so the call arrives to the sidecar and cma is the Eureka name of the remote service and it calls the function myinfo1 in the service cma...
First, I think your yaml file is incorrect,you should use standard format.
You can disable hystrix's timeout check:
hystrix:
command:
default:
execution:
timeout:
enabled: false
Or change Zuul's Hystrix isolation strategy to THREAD:
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD
thread:
timeoutInMilliseconds: 10000