Spring Cloud: use consul instead of eureka for service discovery with zuul - consul

I'm implementing a Gateway with Zuul. The router is supposed to discover some micro services in order to satisfy the rules described in my application.yml. By default, Zuul is going to leverage Eureka, and this what my application does when starting.
I can read that spring-cloud-consul can be used also: Supports Zuul, a dynamic router and filter via Spring Cloud Netflix. However, there is no clear example that shows how to substitute consul to eureka. I added my dependency to my pom.xml in order to boostrap consul:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
<version>1.0.0.RC1</version>
</dependency>
However, when my application starts, it continues trying to contact eureka (my eureka server is stopped): Can't get a response from http://localhost:8761/eureka/apps/MICROSERVICE-REST-API/xxxxxxx
I'm probably missing some configuration point in order to tell zuul or ribbon to use consul.
Any suggestion?
Thanks

Related

Spring Cloud Zuul-Gateway mapping with Config-Server

I'm developing a spring-microservice architecture with following modules (see the architecture diagram below):
Configuration-server
Eureka-Server
Zuul Api Gateway
User-api(Config-Server-Client, Eureka-Client)
Stats-api(Config-Server-Client, Eureka-Client)
Auth-Service (in-progress/out of context)
It's is more of a configuration approach rather than a bug. So far everything is running fine.
For most of the configurations of core-apis, I'm loading them from config-Server.
What should be the actual or recommended way if we use config-server with Api-Gateway?
Would it be good to map(load from) the configuration of Zuul-Gateway to my Config-Server as with other core apis like User-Api and Stats-Api.
And if I did so what should be the order of starting the applications?
Like:
1. Start the Config-Server
2. Eureka Server
3. Zuul Gateway
4. Core-Apis
Thanks :)
I have build a similar architecture for testing purpose. You can find in the link below:
https://github.com/rshtishi/payroll
The order I use to start the services is like below:
Configuration Server (Spring Cloud Config Server) is always the first start. Here are the configuration for all the services.
Eureka Server, is responsible for registering all services.
After starting the service above, you can start whatever you wish api-services or zuul gateway server. Zuul gateway server will access the api services through eureka. So it doesn't matter the order.

Spring Cloud Kubernetes FeignClient Error

I am using spring cloud kubernetes with spring boot and necessary RBAC requirements needed for the project.
<!-- kubernetes -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>
I have 2 microservices running in kubernetes
my-service
some-service
The my-service is running with spring boot 2.x and some-service is running with Spring boot 1.x. Both the services are exposed via the Kubernetes Service and with proper endpoints.
excerpt of application.yaml for my-service is as below.
some-service:
url: http://some-service:8080
serviceName: some-service
And the FeignClient used is as below.
//FeignClient(url = "${some-service.url}") // does not work either
#FeignClient(value = "${some-service.serviceName}")
#RequestMapping("/api")
public interface SomeServiceClient {
Also I have made spring.cloud.kubernetes.discovery.enabled=false
With this in place I expect that my-service should be able to talk to some-service via kubernetes service discovery But I get this error.
ERROR c.b.d.m.s.c.MatchCoordinator - error=FeignException: status 404 reading SomeServiceClient#get(Test
ion,Output) stacktrace=feign.FeignException: status 404 reading SomeServiceClient#get
I am unable to understand what am I doing wrong. Also I do not have the spring.application.name set for some-service since its a third party service.
Can someone please help. Also FYI that the services work properly with port-forwarding and if accessed via Ingress.
If you do not have a name set for some-service, and it's a 3rd party service, I think the better approach would be to call it via RestTemplate or something.
Feign client needs to have the service name configured and known, for it to call that particular service in the network using service discovery.
Well, I found that the discrepancy was at the some-service where the payload of was updated and my-service FeignClient was not updated. and hence caused the HTTP 404 Error. However it works now with the FeignClient properly and able to do a service discovery with the service name properly.

How to register non Spring Boot MicroService in Eureka discovery server

I have recently installed a micro service infrastraucture based on Spring Boot + Spring Cloud.
My Spring Boot microservices register in my Eureka server and Zuul automaticaly redirects requests to them.
I have a Drupal content manager that exposes content through REST interface and I'd like it to take part in the discovery rave party. How can I have my drupal register it self in the Eureka server so Zuul redirects the corresponding calls to it?
As an ugly workaround I wonder if I can have automatic discovery and routing running in Zuul while manually configuring some REST paths to be redirected to the drupal server? (Using zuul.routes... property files)
I found that I can add manual zuul routes in bootstrap.yaml
I have tried adding it in the application yaml property files in configuration server but for some reason they are ignored when the Eureka discovery server is working.
Anyway, bootstrap.yaml works. Example:
zuul:
routes:
mta_api:
path: /mta_api/**
url: http://my-non-springboot-rest-service.com/
stripPrefix: false
You could add sidecar to your non-springboot application. This would allow Eureka support.
Source: Dead- http://cloud.spring.io/spring-cloud-static/Edgware.SR4/single/spring-cloud.html#_polyglot_support_with_sidecar
Current: https://cloud.spring.io/spring-cloud-static/Dalston.SR5/multi/multi__polyglot_support_with_sidecar.html

How to detect new REST calls dynamically as and when they are available?

I am creating an API gateway using Netflix Zuul and Netflix Eureka doing the part of service registration for service discovery for a microservices framework.
I am trying to support a use case where new micro-services may come up which expose REST calls, or existing micro-services may get upgraded to expose new REST calls with version as part of their URL etc. Eureka runs as a dedicated springboot application and Zuul runs as a dedicated application. The application.prop or application.yml file of Zuul is where i am putting config for zuul.routes for each micro-services
My zuul's application.yml looks something like this to support one microservice config.
zuul:
routes:
example:
path: /example/**
stripPrefix: false
serviceId: zuul-service
If i bring down zuul add another such snippet of config under zuul:routes:
and then bring up zuul again, i will start seeing the new endpoint. But i want that to happen dynamically. Like Eureka will dynamically detect any new micro-services that come up or go down. If zuul can get in sync with Eureka then all my rest endpoints can be exposed perfectly through my Zuul api gateway.
Any suggestions on what i may be missing or add any other open source third party to achieve this will be helpful.

Load Balancing micro services using Spring cloud Netflix OSS

I have a microservice built using Spring Boot and Netflix OSS. I have used Central config server, Eureka and Zuul. Because of scalability multiple instances of the services is running on different port. All the instances are registered in Eureka but requests are going to only last registered server.
How to load balance services. Should I use ribbon in Zuul to load balance? Please let me know how to achieve load balancing on same service running on multiple instances.
If there is a code change required a snippet then please post a code snippet as well.
Application Config
spring.application.name=book-service
server.port=0
eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
eureka.client.serviceUrl.defaultZone=http://discUser:discPassword#localhost:10082/eureka/
#eureka.instance.metadataMap.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}
eureka.instance.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}
eureka.instance.leaseRenewalIntervalInSeconds=5
eureka.instance.leaseExpirationDurationInSeconds=5
Eureka Config
spring.application.name=discovery
server.port=10082
eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://discUser:discPassword#localhost:10082/eureka/
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
spring.session.store-type=hash-map
ZUUL Config
spring.application.name=gateway
server.port=10080
eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
management.security.sessions=always
zuul.routes.book-service.path=/book-service/**
zuul.routes.book-service.sensitive-headers=Set-Cookie,Authorization
hystrix.command.book-service.execution.isolation.thread.timeoutInMilliseconds=600000
#zuul.routes.rating-service.path=/rating-service/**
#zuul.routes.rating-service.sensitive-headers=Set-Cookie,Authorization
#hystrix.command.rating-service.execution.isolation.thread.timeoutInMilliseconds=600000
zuul.routes.discovery.path=/discovery/**
zuul.routes.discovery.sensitive-headers=Set-Cookie,Authorization
zuul.routes.discovery.url=http://localhost:8082
hystrix.command.discovery.execution.isolation.thread.timeoutInMilliseconds=600000
logging.level.org.springframework.web.=debug
logging.level.org.springframework.security=debug
logging.level.org.springframework.cloud.netflix.zuul=debug
spring.session.store-type=hash-map
Registering application properly with Eureka will do the trick.
Below entries will uniquely register services with Eureka.
#eureka.instance.metadataMap.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}
eureka.instance.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}

Resources