We've three Spring Boot applications:
Eureka Service
Config Server
Simple Web Service making use of Eureka and Config Server
I've set up the services so that we use a Eureka First Discovery, i.e. the simple web application finds out about the config server from the eureka service.
When started separately (either locally or by starting them as individual docker images) everything is ok, i.e. start config server after discovery service is running, and the Simple web service is started once the config server is running.
When docker-compose is used to start the services, they obviously start at the same time and essentially race to get up and running. This isn't an issue as we've added failFast: true and retry values to the simple web service and also have the docker container restarting so that the simple web service will eventually restart at a time when the discovery service and config server are both running but this doesn't feel optimal.
The unexpected behaviour we noticed was the following:
The simple web service reattempts a number of times to connect to the discovery service. This is sensible and expected
At the same time the simple web service attempts to contact the config server. Because it cannot contact the discovery service, it retries to connect to a config server on localhost, e.g. logs show retries going to http://localhost:8888. This wasn't expected.
The simple web service will eventually successfully connect to the discovery service but the logs show it stills tries to establish communication to the config server by going to http://localhost:8888. Again, this wasn't ideal.
Three questions/observations:
Is it a sensible strategy for the config client to fall back to trying localhost:8888 when it has been configured to use discovery to find the config server?
When the eureka connections is established, should the retry mechanism not now switch to trying the config server endpoint as indicated by Eureka? Essentially putting in higher/longer retry intervals and periods for the config server connection is pointless in this case as it's never going to connect to it if it's looking at localhost so we're better just failing fast.
Are there any properties that can override this behaviour?
I've created a sample github repo that demonstrates this behaviour:
https://github.com/KramKroc/eurekafirstdiscovery/tree/master
Related
We use Consul by HashiCorp for configuration management in our spring boot application. Sometimes consul agent is occasionally unavailable when our app starts. It is inconvenient that the app fails if consul isn’t available for configuration.
I read about Consul Retry https://cloud.spring.io/spring-cloud-static/spring-cloud-consul/1.2.3.RELEASE/single/spring-cloud-consul.html#spring-cloud-consul-retry
Although it is a good solution for retrying, is there any solution in which the application retries indefinitely until it connects with consul?
We deploy this app on tomcat. Is there a better solution than consul-retry for reconnection? Should we try reloading app on tomcat whenever it fails ?
Can anyone tell me the best practice for reconnection in this scenario?
I've started building a microservice application with the netflix stack, and have been successful in registering clients with the eureka discovery server.
I want to have two instances of each client service,
and i'm wondering what happens if one instance of a client goes down. Does loadbalancing handle such situations ? If yes, then isn't eureka also acting as a failover system ?
I have a development environment in windows where I can access the spring build in both IP Address and Hostname(PC-Name) for my Eureka Config Server / Client. When I move it to the RedHat environment it does not recognize the URL if it is a hostname.
My main goal is to change the eureka client status page to point to the hysterix monitor for the eureka client's hysterix stream. The value of ${spring.cloud.client.hostname} resolves to the hostname. I was wondering what is the way to make it the current IP of the eureka client?
To be exact here is an example of what I want am trying to do.
eureka:
instance:
preferIPAddress: true
statusPageUrlPath: http://${spring.cloud.client.hostname}:${eureka.cloud.config.port}/hystrix/monitor?stream=http%3A%2F%2F${spring.cloud.client.hostname}%3A${server.port}%2Factuator%2Fhystrix.stream
It just so happen that the client and the server are both in the same machine so I am contented in using the client hostname for both the Eureka Config Server path and the Eureka Client hystrix stream.
Note that I already set the preferIPAddress to true but the generated hostname is still the value of "/etc/hostname". I saw some solution that explicitly specifies the IP Address in the Eureka Client Instance. But I prefer to make it dynamic so that the same code can run smoothly on either Development and Deploy environment.
What can I do so that the hostname can also be recognized the same as the ip address?
The answer has dawn upon me just now. I just changed the following to this.
${spring.cloud.client.hostname}
↓↓↓↓↓↓↓↓↓↓↓↓
${spring.cloud.client.ip-address}
I was thrown to a wrong conclusion because other sites would tell me to use this configuration ${spring.cloud.client.ipAddress} which does not work.
Probably there was a change in Finchley / Spring boot 2.0 version. If anyone can give me a link to a documentation or discussion describing the configuration change, it would be helpful.
I was able to register the single nodejs app instance using the netflix sidecar app successfully. Both nodejs and sidecar bridge app are running in Cloud foundry.
Result:
SAMPLE-NODEJS n/a (1) (1) UP (1)
When i scale the nodeJS app to 3 instances, could not see the scaled instances in Eureka service registry. It still shows 1 instance.
Can some one help me to do this....
I want to register all the instances of Nodejs app with Eureka service registry with Sidecar bridge app.
Pls.. help.
Regards
Purandhar
Sidecar, like the eureka java client is built to register only one application with the eureka server at a time. It is not a eureka proxy for multiple applications. I built a proof of concept proxy that will do what you want.
This happens because it's not your node application, which is registering to eureka, but your sidecar, which still runs in one instance.
simple solution
you scale your sidecars with your node apps. This is quite straight forward, in particular when using container based deployment. You just can craft a docker container starting both, a node instance and a sidecar.
load balancing
you can extend your sidecar application to load balance traffic to your sidecars. Then your node apps will still be shown as a single instance, but still have load balancing to scaled node instances
In my project we have a requirement to run two instances of spring cloud config server so if one instance goes down, other will take care the config server responsibilities.
Currently, you would need to put config server behind a load balancer. It is stateless, so that wouldn't hurt. There is an open issue to configure multiple config server url's in the client, so it could do failover there.
If you are running multiple instances of the config server, you can have them all register themselves in Eureka, and maybe do a lookup to the config server with it's application name via Eureka in all the other microservices. This way, Zuul (and Ribbon) will take care of the load balancing.
Edit:
I guess spencergibb is right. It's best to use a load balancer, for eg: ELB, if you're going to deploy on AWS.
Consider multiple spring-cloud-config-uris for high availability