Microservices - What is the exact difference between service discovery and Service Gateway? - microservices

I read the articles like : What is the difference between an API-Gateway and an Edge Service?, but still not clear on what's the exact difference between the service discovery (say Eureka) and Service Gateway (Zuul) ? Any pointers?

The Services gateway (a.k.a. API gateway) is receiving requests from the clients. It is the (single) service that the clients see. But it doesn't know by itself how to do what the clients want so it must forward the request to another service. It inspects the URL and extracts the name of the service that will actually serve the request, the backend service. That backend service may be located on a different machine. It may have a dynamic address or port, that may change from time to time, from different reasons (nodes fail, new nodes are added to the network etc).
So, the gateway doesn't know where to forward the request. This is the job of the Service-discovery service (Eureka). Eureka knows on which node is located and at which address and port every service is listening for requests. The gateway is asking Eureka where it can find the backend service (by sending it only its name). After Eureka is responding, the gateway is forwarding the request to that address.

The differences is more understandable if you focus in responsabilities of both Zuul and Eureka. As you can see below each one has specific tasks. Thats the main differences.

API Gateway
In Api Gateway we have to register services with its URL and matching patterns
like this:
id: order-service
uri: http://localhost:9003/
predicates:
- Path=/order/**
But the problem here is we can have multiple instances on different ports. Like this
uri: http://localhost:9003/
uri: http://localhost:9004/
uri: http://localhost:9005/
In this case, a gateway will fail to route to other instances.
Service Discovery
In case of service discovery, we will have to register client services to service discovery (which is another service). Like this
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
Now all clients will register to service discovery automatically so even if there are multiple instances service register will take care of it.

Service Gateway operates at Network layer 7 (HTTP) and Service discovery operates at Network Layer 4 to be precise.
Zuul works at Layer 7 and Eureka works at Layer 4
Please refer to Kong Gateway which provides a uniform solution

Related

What is the use of Eureka Server in Microservices architecture

I am using "Spring Cloud Gateway" in my microservices application
Ex:
spring.cloud.gateway.routes[0].id=mydemoservice
spring.cloud.gateway.routes[0].uri=http://localhost:8100/
spring.cloud.gateway.routes[0].predicates[0]=Path=/mydemoservice/**
In this case if the request is coming from client like : http://localhost:8100/mydemoservice/api/getdetails
in this case "Spring Cloud Gateway" will route the request to respective service.
But why is Eureka Server required here ? I am not really understanding Eureka Server use here can some please explain.
Best I could find is this medium article which depicts the problems and solutions Eureka provides.
https://medium.com/javarevisited/how-to-use-spring-cloud-gateway-to-dynamically-discover-microservices-194c0c3869c6
This comes to shine when you deploy services with horizontal auto scalability (such as kubernetes). At certain moments, based on the equation you configure (recourse usage, client connections, etc.) the orchestration can and will scale your services (e.g. mydemoservice). It can scale your service instance up to:
the configured max number of instances
until the service usage limit is reached
either way, all of them will have different IP addresses.
Eureka is a discovery/registry service which provides to your gateway information of which cluster/load balancer (IP address) will it pass the request based on Round Robins and such algorithms. The gateway needs to configure all of the services but it will use aliases provided by the Eureka server depicted as such:
https://github.com/rubykv/code-examples/blob/master/gateway/src/main/resources/application.yml
In this example, we see the gateways are configured for services: subject, student, and eureka.
Eureka has a dashboard:
https://miro.medium.com/max/1400/1*KgT1_hnuXvX6xldyiJJuaQ.png
and will display all eureka clients. To display a service as a eureka client one must implement:
https://github.com/rubykv/code-examples/blob/master/student/pom.xml (netflix eureka and open feign)
annotate application with #EnableFeignClients https://github.com/rubykv/code-examples/blob/master/student/src/main/java/com/example/demo/StudentApplication.java
There are lots of tutorials and articles on medium, I hope this helps for your further investigation.

what is the difference between netflix zuul server and netflix eureka server?

i have created two java spring-boot micro services they are
1) producer
2) consumer
and i have used spring eureka server for service registration and discovery . it worked fine . then what is the use of Netflix Zuul.
Let's suppose you have 20 services to which user can interact to, and of course we are not going to expose each and every services publicly because that will be madness (because all services will have different ports and context), so the best approach will be to use an API gateway which will act as single entry point access to our application (developed in micro service pattern) and that is where Zuul comes into picture. Zuul act as a reverse proxy to all your micro-services running behind it and is capable of following
Authentication
Dynamic Routing
Service Migration
Load Shedding
Security
Static Response handling
Active/Active traffic management
You can go through documentation here
If you have enough experience in the domain, you could look at zuul as an API gateway like Apigee. It is very feature rich and touches up on a lot of different concerns like routing, monitoring and most importantly, security. And eureka as a service discovery platform that allows you to load balance (in Linux terms the nginx or haproxy) and fail over between your service instances.
Typically the backend services that perform the server side business operations (i.e. core) are not exposed publicly due to many reasons. They are shielded by some Gateway layer that also serves as reverse-proxy. Netflix Zuul serves as this gateway layer which easily gives you the capabilities as mentioned by #Apollo and here

How to get the service endpoint registered behind the Application name in Eureka Server?

I have some web services registered at Spring Boot Eureka Server. Is there any way I can check the endpoints registered at Eureka Server, with respect to all the application?
e.g: Eureka server
Service1 means Request will be routed to service endpoint: localhost:9080/service1
Service2 means Request will be routed to service endpoint: localhost:9088/service2
Service3 means Request will be routed to service endpoint: localhost:9085/service3
You can check the Eureka dashboard at http://host-name:8761 (Change the port if you're using a different one).
Secondly, Eureka doesn't route any request. It is just a service registry and keeps the records of the Microservices and its instances. You need an API Gateway (ZUUL) or similar to do the routing along with client side load balancers (ribbon, etc.).
You can configure the zuul endpoints in the application.yml (or properties) file like below to access your service endpoints.
zuul:
ignoredServices: "*"
routes:
service1:
path: /service1/**
service2:
path: /service2/**
If you want to access the service1, then your endpoint will be something like http://localhost:8765/service1/{custom-path}
Note: 8765 is the default zuul port. Change it accordingly.

When to configure zuul routes

I am new to spring cloud and going through some examples and material available online to make myself comfortable. However, while reading about ZUUL, some sites configured the routes in ZUUL's application.yml and some other sites mentioned that the requests will be forwarded to the respective microservice and no need to explicitly configure the routes. I was bit confused. For ex, in the below scenario what is the approach, to configure routes or to let zuul route automatically?
Let's say i have few micro services running and all of them along with ZUUL are registered to Eureka.
I have a front end which is running on a different port on the same server and needs to interact with the above micro services.
I also have few other applications (Running entirely on different servers) which need to interact with the above micro services for fetching the data.
TIA..
Did you use Zuul (which know microservices address through Eureka) to forward request between your micro-services ? if it's the case, you are using Server-Side Load Balancing pattern.
If you use a discovery service (Eureka in your case), i think the best approach it's to use Client-Side load balancing pattern for all inter-services requests (inside your system). (you can use Ribbon or RestTemplate for that).
You can use Zuul as a unified front door to your system, which allows a browser, mobile app or other user interface to consume services from multiple hosts without managing cross-origin resource sharing (CORS) and authentication for each one.
For example : a client (mobile app) request for all picture comments. The client dont need to know the Comments-service address. Only proxy address needed and Zuul will forward the request to the right service. You can do this in application.yml/.properties by
zuul.routes.comments.path=/comments/**
zuul.routes.comments.service-id=comments
The request will be GET www.myproxy.mycompany.com/comments. Dont forget the service name in your application.yml/.properties is very important (spring.application.name). It's the service-id in Zuul routes (which the same identifier in Eureka).
For some reason, your system need to request external services (as you mentionned in the 3th note). In this case, your external services are not a discovery client, Zuul can't look for the service-id from Eureka. you use routes as
zuul.routes.currencyprovider.path=/currencies/**
zuul.routes.currencyprovider.url=https://currencies.net/
with this route, all /currencies/** requests from your services THROUGH Zuul will be done.
with this approach you have one door for all your system. This is API Gateway pattern.
Sometimes your system need to aggregate multiple results from different services to response to client request. You can do this in Proxy (Zuul in your case).

Route Existing Services via ZUUL without adding routing rule

I am trying to route existing services via Spring cloud Netflix Zuul.
I have an existing service available at below url,
http://localhost:3080/query-service/getquery/1
Out of the box, with zuul I can route to the service as below,
localhost:9000/queryservice-id/queryservice/getquery/1, with "queryservice-id" as the service-id of the service when it is registered in Service Registry. The zuul port is 9000.
I do not want to change the context path and service path information when accessing the service via ZUUL.
With ZUUL, I want to access the service as below,
http://localhost:9000/query-service/getquery/1
I do want to prefix with the "serviceId". This is because I do not want to impact any existing clients of the service. Only the host and port changes, without serviceId.
I was able to accomplish it as below with ZUUL Configuration,
zuul:
routes:
query-service:
path: /query-service/**
serviceId: query-service
stripPrefix: false
With the above configuration, I am able to only use the zuul host and port, the other service specific information remains as before. Seems like stripPrefix is helping in routing without the serviceId.
But, I have a lot of services and will be adding more services too.
For every such service, I do not want to be adding a rule like that to ZUUL configuration which will mean rebuilding and recycling the ZUUL Service.
I feel there should be a simpler and better way to accomplish this, without a big effort, because the change I want to do is common to all services
Is there a way to making this change common for alll the services I want
to be routed via ZUUL.
Thanks,
As checked with the Spring Cloud Netflix team this is recommended approach.
https://github.com/spring-cloud/spring-cloud-netflix/issues/1549

Resources