How can I get specific diagnostic information on an IP address from Zuul? - netflix-eureka

I have Zuul and Eureka running, with a bunch of smaller services. Using Eureka, I can see all of the services and their associated host/IP address. Usually, I can boot up multiple instances of another service and Eureka will pick them up for Zuul to route to. I'm currently having an issue where I have three instances of a service registered in Eureka, but Zuul only routes to one of them. I don't know where to go to get diagnostic information from Zuul to understand why it isn't routing to the other two instances. I've tried simple things, like manually sending requests from the Zuul box to the service boxes to make sure they can communicate.
Does Zuul expose an endpoint to list hosts/IP addresses and their status? What are my diagnostic options?

You can try to list all your endpoints with the routes endpoint
So, if you running zuul on your localhost on port 8080 you can do a GET call to http://localhost:8080/routes and you will get something like
{
/stores/**: "http://localhost:8081"
}
Depending on the version you are using, you also need to set
management.security.enabled = false
in the application.properties
EDIT:
You can also use the logging mechanism.
Set the loglevel just of the LoadBalancerContext to debug in application.properties
#logging
logging.level.com.netflix.loadbalancer.LoadBalancerContext=DEBUG
It will log each call that is routed.

Related

Get Eureka instance metadata in browser

I have a Spring Boot (2.4) app (a generic service) and a Eureka discovery server running. The server doesn't register itself as an instance. I am able to navigate to the Eureka dashboard at the default location of localhost:8761 to get an overview of all the registered instances. I successfully see the service is registered in Eureka. However, this dashboard doesn't give any details about the instance except the name and the port number. I want to be able to see the instance meta data. Is this possible using the dashboard? O maybe there is some exposed URL by the Eureka server that I can call in a browser or postman? Or is there an URL available in the Eureka client (the service) that gives details about its Eureka metadata?
I read thet feign clients access something to be able to query the registry. Can I mimic this as human in a browser?
Go to localhost:8761/eureka/apps

Spring cloud - Server and client

I'm config an application using spring cloud eureka. I start my discovery app in the 8761 port and reaching the console in "http://localhost:8761".
So, I start my client application and it's appear in the "Application" page of eureka console.
First question:
My client is using "server.port=0" in properties config so the tomcat port is starting in random. How can I reaching my services in client? Example: I have a get request in "/api/stuff", is that possible to access this not using the random port? Suppose I don't know the port!
Second Question:
I can start any clients I want, they will start, assuming a random port and register in the cloud server discovery, I can see the log:
"Registering application FLY-CLIENT with eureka with status UP"
But they don't appear in "Application" page of eureka console, why they don't appear?
Thanks!
If you are using Spring RestTemplate to request the services registered in Eureka you need to make it #LoadBalanced, something like this should do the try:
#LoadBalanced
#Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
// usage
restTemplate.getForObject("http://your-service-name/api/stuff", StuffResponse.class);
As for the 2nd question, I'm a little confused, as you mentioned earlier in the question that your application appears on Eureka's dashboard. Is this behavior only happening for the "fly-client"?

Kubernetes - route static IP to multiple services (Google Cloud Platform)

I have a small application comprising three services:
A single page application (SPA) served from nginx
A simple nodejs HTTP API used by the SPA
An MQtt broker exposing ports 1883 and 9001
Ideally I'd like the all to be served from the same subdomain and static IP address and have been trying to configure this in Kubernetes on the Google Cloud Platform.
I've created deployments for each of the services, with the SPA exposing port 80, the API 3000 and the MQTT broker 1883/9001. I've then followed the instructions here to set up a static IP and a Service to route to the SPA, then created similar services for the API and the MQTT app. (I've initally adapted these from deployments and services generated from a docker-compose file and Kompose).
The SPA and API seem to work fine but the MQTT service does not. When I run kubetl get events I see:
Error creating load balancer (will retry): failed to ensure load balancer for service default/mqtt-broker: failed to create forwarding rule for load balancer (a5529f2a9bdaf11e8b35d42010a84005(default/mqtt-broker)): googleapi: Error 400: Invalid value for field 'resource.IPAddress': '35.190.221.113'. Specified IP address is in-use and would result in a conflict., invalid
So I'm wondering if I should be creating a single service to route to the three deployments but can't find any documentation or examples that explain how to do this for a non http service.
I guess I could put the mqtt service on a separate IP address but this seems to be hacking around the problem rather than solving it.
Thanks in advance for any advice.
I eventually found an almost identical use case to my own on this github repository.
In essence, they are creating the MQTT broker on a separate static IP and using Kubernetes API calls to expose the details to the front end, which they explain in the following comment at the top of the web.yaml file:
This needs a bit of trickery
as it needs to expose the LB ip address for the MQTT server. That
requires kubernetes API calls to look it up, and the ability to
store it somewhere (we put it in a secret). To be secure this is
done with a dedicated service account and an init container.
https://github.com/IBM/ny-power

spring cloud netflix service to service through zuul

In a spring-cloud-netflix setup (everything uses feign,ribbon,eureka,zuul), is there any simple/elegant/out-of-the-box way (i.e. discovery based on serviceId vs URL) for CompositeAB to communicate to ServiceA and ServiceB through Zuul? In all of the examples I've seen, CompositeAB discovers and calls ServiceA directly vs. via the Zuul route for ServiceA.
Put another way, if ServiceA registers itself in Eureka as service-a, is the automatically created Zuul proxy for service-a exposed in Eureka in any discoverable way?
For real world context, this relates to network topology and firewalls (there's no direct route between CompositeAB and ServiceA - everything needs to go through the gateway). Using URLs in CompositeAB isn't awful, but seems to defeat the purpose of having the registry present (ideally, Zuul would register the proxy for service-a as something like "zuul-service-a" in the registry). That said, i do get how this particular use case doesn't really fit Zuul's purpose as an edge gateway.
Finally, i think i know how to get my desired effect through code - just wanted to check that i wasn't reinventing any wheels first.
Make sure that your Zuul proxy is registering with Eureka and fetching the registry. Any service that registers with eureka will get a route.
You don't have to allow every service that registers with eureka to be accessible via the proxy either.
A sample application.yml for your Zuul proxy that only allows service-a and service-b:
eureka:
client:
fetchRegistry: true
zuul:
add-proxy-headers: true
ignored-services: "*"
routes:
service-a:
serviceId: service-a
service-b:
serviceId: service-b

Ribbon- Calling a specific uri of an application from urls obtained from Eureka

Lets consider the following situation.This example will only have urls containing localhost. I have a zuul proxy setup and lets say its running on port 8080. So
Zuul proxy-
localhost:8080
I have an eureka server setup running on port 81.
Eureka server-
localhost:8081.
I have an application lets call it by name-example which is a REST web service. Its running on 3 different ports 82,83 and 84. All 3 instances are registered with eureka server. I have a filter setup in zuul for the uri /example.
So i expect consumers to call the zuul proxy at locahost:8080/example.
Now, in the application example for the request mapping /example, there is a controller setup.
So what i want to do is basically have the consumers call localhost:8080/example and route that request to localhost:8082/example, localhost:8083/example, localhost:8084/example . I know how to load balance using ribbon and eureka and have all the appropriate properties set to achieve that.
zuul.routes.example.serviceid=example
ribbon.eureka.enabled=true.
What i want to do is have ribbon look up the list of url(s) from eureka server and then call localhost:8082/example rather localhost:8082.
Is this possible?
Thank you in advance.
You need to specify the path & serviceId
zuul:
routes:
examplepath:
path: /example/**
serviceId: name-example
stripPrefix: false
The serviceId is the name registered with Eureka. Hope you are specifying Eureka server details in you Zuul gateway.