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
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 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 am trying to get a simple microservice to register to the Eureka Server and then have Zuul proxy to the microservice. I got the microservice to register to the Eureka Server. However, whenever I bring the Zuul service up I see that it is not registering to the Eureka Server. Whenever I try to route to the microservice I get the below exception:
Load balancer does not have available server for client: microservice
I am not able to figure out where the issue is. Any help would be greatly appreciated
Below are my Spring Boot classes for each of these components.
Microservice Components
MicroserviceApplication.java
#SpringBootApplication(scanBasePackages = { "some.package.controller", "some.package.service" })
#EnableEurekaClient
#EnableJpaRepositories("some.package.repository")
#EntityScan("some.package.entity")
public class MicroserviceApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceApplication.class, args);
}
}
bootstrap.yml
server:
port: 8090
info:
component: Core Services
spring:
application:
name: microservice
application.yml
eureka:
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 2
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
healthcheck:
enabled: true
lease:
duration: 5
#some other logging and jpa properties below
Eureka Server Components
EurekaServerApplication.java
#SpringBootApplication
#EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
bootstrap.yml
spring:
application:
name: discovery-server
application.yml
server:
port: 8761
info:
component: Discovery Server
eureka:
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
instance:
hostname: localhost
server:
waitTimeInMsWhenSyncEmpty: 0
API Gateway Components
ZuulGatewayApplication.java
#SpringBootApplication
#EnableZuulProxy
public class ZuulGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
#Bean
public ZuulGatewayPreFilter gatewayPreFilter() {
return new ZuulGatewayPreFilter();
}
}
bootstrap.yml
spring:
application:
name: api-gateway
application.yml
server:
port: 8888
info:
component: API Gateway
eureka:
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 2
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
zuul:
routes:
microservice:
path: /microservice/**
serviceId: microservice
Adding #EnableEurekaClient solved this issue. The Zuul application is now discoverable in the Eureka server and is able to route requests.
I had the correct annotation on my Zuul application #EnableZuulClient but still got that error.
The problem was that I started all the applications (Eureka, Zuul and the third application) at the same time instead of doing this one by one. So they all needed time to register. After some time, the error was gone and I could reach my service through Zuul client.
Wrong spring.application.name might be the reason for this error other than
adding #EnableEurekaClient to the Zuul application class.
I'm trying to get the failover behavior of the Eureka Client working and am receiving the below exception. Eureka server1 is shutdown and I want it to failover to Eureka server2. The application realizes server 1 is down and tries to use the failover, but gets to this place in the code and throws an exception because the backup registry isn't defined.
2016-07-08T14:25:41.369Z WARN 0 [main] com.netflix.discovery.DiscoveryClient: Using default backup registry implementation which does not do anything.
2016-07-08T14:25:41.370Z WARN 0 [main] com.netflix.discovery.DiscoveryClient: Cannot fetch applications from apps although backup registry was specified
java.lang.UnsupportedOperationException: Backup registry not implemented.
at com.netflix.discovery.NotImplementedRegistryImpl.fetchRegistry(NotImplementedRegistryImpl.java:15)
at com.netflix.discovery.DiscoveryClient.fetchRegistryFromBackup(DiscoveryClient.java:1811)
My bootstrap.yml
eureka:
client:
fetchRegistry: true
service-url:
defaultZone: https://server1/eureka/,https://server2/eureka/
This the line in the Eureka Client the failure is occurring.
private void fetchRegistryFromBackup() {
try {
#SuppressWarnings("deprecation")
BackupRegistry backupRegistryInstance = newBackupRegistryInstance();
if (null == backupRegistryInstance) { // backward compatibility with the old protected method, in case it is being used.
backupRegistryInstance = backupRegistryProvider.get();
}
if (null != backupRegistryInstance) {
You may try the following configuration:
eureka:
client:
register-with-eureka: true
fetch-registry: true
availability-zones:
us-east-1: us-east-1a,us-east-1b
region: us-east-1
service-url:
us-east-1a: http://<server1>/eureka/
us-east-1b: http://<server2>/eureka/