JHipster micro-services unable to register properly to Eureka on AWS - spring-boot

I have a Spring Cloud application working well on AWS.
I decided to add JHipster generated micro-services (the JHipster gateway and UAA).
Both of these services register to an existing Eureka Server, like all the previous ones.
Things work fine on a local machine, or running in Docker containers deployed on a EC2 instance on AWS.
However, when deploying on different EC2 instances, the JHipster generated services are not registering correctly. The Eureka UI displays :
Application AMIs Availability Zones Status
HELLO-SERVICE ami-809f84e6 (2) eu-west-1b (1), eu-west-1a (1) UP (2) - i-02eg07053a672ea37 , i-083c2f2204d01f4ba
UAA n/a (2) (2) UP (2) - 97b39345fb59:uaa:9999 , ga6831e52701:uaa:9999
"HELLO-SERVICE" is a simple spring boot app. Eureka displays AWS information, and links it to a private ip/port which is working.
"UAA" is generated by Jhipster. Eureka is missing AWS information for this service, and links it to a 172.17.x.x.x address which is not working.
What bothers me is that both services share the same eureka configuration files :
eureka:
datacenter: cloud
instance:
preferIpAddress: true
client:
healthcheck:
enabled: true
registerWithEureka: true
fetchRegistry: true
region: eu-west-1
preferedSameZone: true
availabilityZones:
eu-west-1: eu-west-1a,eu-west-1b
serviceUrl:
eu-west-1a: http://[eurekainstance]:8761/eureka/
eu-west-1b: http://[eurekainstance]:8761/eureka/
Why would a JHipster generated app and a simple Spring Boot app behave differently while sharing the same configuration ?
I have run out of ideas, any help would be much appreciated!

I'll anwser my own question in case it's useful to someone.
The issue had nothing to do with JHipster or AWS, but with Docker.
Adding an EurekaInstanceConfigBean solved it:
public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inet) {
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inet);
AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka");
config.setDataCenterInfo(info);
info.getMetadata().put(AmazonInfo.MetaDataKey.localHostname.getName(), info.get(AmazonInfo.MetaDataKey.localIpv4));
config.setHostname(info.get(AmazonInfo.MetaDataKey.localHostname));
config.setIpAddress(info.get(AmazonInfo.MetaDataKey.localIpv4));
config.setNonSecurePort(port);
return config;
}
See the documentation for more information.

Related

Register on eureka server on a different machine

I have a microservice architecture in developement mode with an API Gateway running on localhost:8080, some services on localhost:8081...8084 and an eureka server on localhost:8761.
The services register with eureka and everything works fine on my local machine.
I'm trying to deploy the services to azure as single containers. So each service will end up with a unique url.
How can I tell my eureka clients (api gateway and services) where the eureka server is running?
No matter what I try, it will always try to find the eureka server at localhost:8761. These are my settings for the API gateway:
eureka:
instance:
instance-id: ${spring.application.name}:${random.uuid}
client:
service-url:
default-zone: ${EUREKA_HOST:http://localhost:8761}/eureka/
I always end up with this error:
How can I get the services to connect to a eureka server that runs on something like https://example.azurewebsites.net:8761 ? The variable EUREKA_HOST has the correct value since I can use it at other places without problem.

Fargate service discovery for eureka clients

We are planning to host our eureka discovery server in the same vpn as our fargate services. What configuration we have to provide in our client container configuration to enable them to seamlessly connect with our discovery server. The discovery server is not hosted on fargate , it is on separate EC2 machine.
You need to point the clients to the Eureka server including the following configuration on the client's application.yml:
spring:
application:
name: <client-name>
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
The EUREKA_URI environment variable need to be set on containers with the Eureka address. The additional localhost URL allows apps run without containers on dev workstations along with a local copy of Eureka (just another boot app).

Configuring Netflix Eureka with Spring Boot Microservices on AWS EC2 (Route 53 + VPC)

We are trying to deploy a set microservices (written in Spring Boot 2) to AWS and we want to enable service discovery using Eureka.
The Eureka server is running on Tomcat 9 on a Linux EC2 instance. The Eureka dashboard is reachable, but clients will not register. Clients register successfully on localhost, however.
Due to resource constraints, we are unable to use EIPs for the microservices. We are using Route 53 in conjunction with a Virtual Private Cloud for routing.
I found some mentions of this setup being mostly compatible, but no instructions:
Register VPC Eureka node in Route53 instead of EIP
Service Discovery - Microservices on AWS
Here are our Eureka server properties:
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
# below are prod environment variables
eureka.us-east-1.availabilityZones=us-east-1a
eureka.serviceUrl.us-east-1a=https://eureka.mydomain.com/
eureka.shouldUseDns=true
eureka.eurekaServer.domainName=eureka.mydomain.com/
eureka.eurekaServer.port=8081
eureka.eurekaServer.context=svc
eureka.datacenter=cloud
Here are our Eureka client properties:
eureka.us-east-1.availabilityZones=us-east-1a
eureka.serviceUrl.us-east-1a=https://eureka.mydomain.com/
eureka.shouldUseDns=true
eureka.eurekaServer.domainName=eureka.mydomain.com/
eureka.eurekaServer.port=8081
eureka.eurekaServer.context=svc
eureka.datacenter=cloud
Any help with our situation would be very much appreciated! Please let me know if you need more information.
It seems you are running Eureka on the port 8081. Eureka server usually runs on port 8761.
Have you created Route 53 endpoints (TXT Records) Ref: https://github.com/Netflix/eureka/wiki/Deploying-Eureka-Servers-in-EC2
Eureka Clients need to have below configuration:
https://cloud.spring.io/spring-cloud-netflix/multi/multi__service_discovery_eureka_clients.html
`
#Bean
#Autowired
#Profile("!default")
public EurekaInstanceConfigBean eurekaInstanceConfig(InetUtils inetUtils) {
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka");
config.setHostname(info.get(AmazonInfo.MetaDataKey.publicHostname));
config.setIpAddress(info.get(AmazonInfo.MetaDataKey.publicIpv4));
config.setNonSecurePort(appPort);
config.setDataCenterInfo(info);
return config;
}
`
Hope this helps.

Does Eureka and Ribbon work for non spring boot application?

I am rewriting a Spring MVC system.
The system is something like this in simple:
[Gateway<->Backend Services<->Databases], where Gateway is a controller simply for authentication and forwarding the requests to Backend services.
The Backend services will be refactored to micro-services. I will use Eureka service to do registration for each of them. So eventually the architecture will be: [Gateway <-> Eureka <-> Backend micro-services <-> Databases]. The Gateway will lookup the registries from Eureka server and call the micro services.
However, the Gateway is not a spring boot application(and will NOT be rewritten as Spring boot), thus I don't believe Spring's eureka features (#EnableEurekaClient , DiscoveryClient, ect.) can be adopted easily as the examples do. Actually I tried adding the eureka client annotation to Gateway's controller, which caused my application collapsed.
Moreover, Ribbon is needed in the Gateway for client side loading balancing. But the same concern is as above.
//Update on 1st Nov.
I have set up an Eureka server and a client, both of which are written in spring boot. I am using these two application for my Spring MVC testing. The server and client are running well.
Server's configuration application.properties is as below
server.port=8761
spring.application.name=service-itself
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false
logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
client's is as below: application.yml
spring:
application:
name: say-hello
server:
port: 8090
eureka:
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
When accessing the Eureka dashboard localhost:8761, I can see that client has been registered.
For my Spring MVC gateway, as it is not a Spring boot project, so I copied the example to my project simply for testing whether it can connect to the Eureka server and retrieve the registered the instance of "say-hello" client. Unfortunately, it cannot do so with saying "Cannot get an instance of example service to talk to from eureka" which is printed at line 76 in the example class.
Here is the eureka-client.properties placed in gateway's classpath. I can confirmed that the Client class is reading the config file.
eureka.name=gatewayEurekaClient
eureka.vipAddress=say-hello
eureka.port=8761
eureka.preferSameZone=true
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://localhost:8761/eureka
eureka.serviceUrl.defaultZone=http://localhost:8761/eureka
Moreover, this is the debug information when new DiscoveryClient(applicationInfoManager, clientConfig); is being executed
instanceInfo InstanceInfo (id=234)
actionType null
appGroupName "UNKNOWN" (id=246)
appName "GATEWAYEUREKACLIENT" (id=247)
asgName null
countryId 1
dataCenterInfo PropertiesInstanceConfig$1 (id=248)
healthCheckExplicitUrl null
healthCheckRelativeUrl "/healthcheck" (id=253)
healthCheckSecureExplicitUrl null
healthCheckUrl "http://A156N7AB89AXNZQ:8761/healthcheck" (id=254)
homePageUrl "http://A156N7AB89AXNZQ:8761/" (id=255)
hostName "A156N7AB89AXNZQ" (id=256)
instanceId "A156N7AB89AXNZQ" (id=256)
ipAddr "10.209.66.64" (id=257)
isCoordinatingDiscoveryServer Boolean (id=258)
isInstanceInfoDirty false
isSecurePortEnabled false
isUnsecurePortEnabled true
lastDirtyTimestamp Long (id=260)
lastUpdatedTimestamp Long (id=263)
leaseInfo LeaseInfo (id=264)
metadata ConcurrentHashMap<K,V> (id=266)
overriddenstatus InstanceInfo$InstanceStatus (id=267)
port 8761
secureHealthCheckUrl null
securePort 443
secureVipAddress null
secureVipAddressUnresolved null
sid "na" (id=270)
status InstanceInfo$InstanceStatus (id=271)
statusPageExplicitUrl null
statusPageRelativeUrl "/Status" (id=272)
statusPageUrl "http://A156N7AB89AXNZQ:8761/Status" (id=273)
version "unknown" (id=274)
vipAddress "say-hello" (id=275)
vipAddressUnresolved "say-hello" (id=275)
I am running out of idea. Can anyone please give a hand on this problem?
Ribbon (https://github.com/Netflix/ribbon) and Eureka (https://github.com/Netflix/eureka) can work without Spring (and that is the way they were developed in the first place) but you will need to put a bit more effort into configuring everything to your needs.
Support for Ribbon and Eureka in Spring is part of the Spring Cloud project (and mvn group id), not Spring Boot. I don't think boot is mandatory. Ribbon and Eureka themselves are provided by Netflix.
For ribbon, you need to define your own #LoadBalanced RestTemplate #Bean anyway. #EnableDiscoveryClient should work as long as the dependencies have spring cloud eureka and your class is a #Configuration class.
Short answer is - why not try a quick test? :).

Enable eureka.client.healthcheck

I'm following http://cloud.spring.io/spring-cloud-netflix/spring-cloud-netflix.html to build distributed system with Spring Cloud.
All works as expected apart from Eureka Client Healthcheck.
I have
eureka:
client:
healthcheck:
enabled: true
And pointing my service to nonexisten config_server, this results in
http://myservice:8080/health
{
status: "DOWN"
}
But Eureka server still showing this instance as UP and keep sending traffic to it.
What am I missing?
spring-boot: 1.2.8.RELEASE
spring-cloud-netflix : 1.0.4.RELEASE
You have to explicitly set eureka.client.healthcheck.enabled=true to link the Spring Boot health indicator to the Eureka registration. Source code reference: here.
Ok, I think I found it.
According to https://jmnarloch.wordpress.com/2015/09/02/spring-cloud-fixing-eureka-application-status/ this feature will only be available on Spring Cloud 1.1.
To make it work with 1.0.4 I need to implement my own HealthCheckHandler.
Thanks #xtreme-biker for bringing up Spring Cloud version issue.

Resources