I am running Eureka with multiple instances of multiple Feign clients all load balanced with Ribbon. I have a situation whereby I need to target a request to a particular Feign client instance. Is it possible to set the instance by say instance Id and guarantee the call will be made to that instance?
Related
I want to implement a resilient microservices architecture using Feign Client,Ribbon and Eureka so I encountered an issue. When a microservices target is down I want to redirect to another instance of microservices without the user seeing it. For example, I have 4 instances of microservices B and one instance A :
The Browser client call A then A call B1 but B1 is down => A redirect automatically to B2, B2 is KO then A call B3 and B3 is up then it returns a response to A. A returns response to the browser client.
How I could implement it, please.
Thanks in advance.
Basically, Ribbon should already find instances that are alive for you - firstly, Eureka stores and updates information on which instances are alive and, secondly, Ribbon runs health-check requests to the instances. If that is not working correctly for you, you can try customising the polling intervals for Ribbon. If you want a failed request to be repeated against a different instance, you can use Spring Cloud Netflix Ribbon with Spring Retry (see documentation).
Having said that, since Spring Cloud Ribbon is now in maintenance mode and will not be making it into the 2020.0.0 release train, I would definitely not encourage adding it at this point. The available alternative is Spring Cloud LoadBalancer. It supports retrieving the instances that are alive from Service Discovery (either with or without caching and health-checks. It does not support retries at this point, but there's an issue for it in the project backlog.
I want to use the gRPC streaming mechanism for the clients to get notified when the system has changed.
E.g. The db stores users. Clients can add and delete users via gRPC unary calls. There are also streaming methods such that the clients can get notified when other client has added or deleted a user.
In case that I have several intances of my gRPC service (e.g. in k8s) how can Client1 that has a durable connection to instance1 gets notified when a client2 that makes a unary delete call to an instance 3?
You need a way to publish events between all instances. One way is to use your database. Or use a messaging solution that supports publish/subscribe. A lightweight solution could be redis.
For an application that has multiple feign clients connecting all to the same external component we want one shared circuit breaker.
How can this be achieved with spring-cloud-starter-openfeign?
Detailed explanation:
When the providing service is down all 3 clients should stop sending. As all requests should fail. Is it possible that all 3 clients share the same circuitbreaker?
I think you can create FeignClient(not circuit breaker) for providing service(feign in this service).Consuming service inject ‘providing service's FeignClient’, this client can request providing service.
guides spring-cloud-feign and
circuit-breaker
Actually I would like to understand correct approach for managing requests among several microservices, one of them is Zuul:
I have Zuul-app, which is proxy before my microservice. Zuul started on port 7777 and declares API like /api/service1/get or /api/service2/get. On every service I have echo-endpoint which is available localhost:7777/api/service1/get and work well.
But those echo-endpoints are available directly from corresponding services. Thus I can make request from Postman, let's say, to service1/get/ and service2/get
As far as I understand anybody can call those services through Zuul or directly from those services. So what is difference and what is real value of Zuul for such case (instead of Zuul can authorize users, let's say as proxy microservice)
So what is correct approach for using Zuul for microservices ?
Your question looks like you are asking two things. What is the purpose and how to use it. Going to answer the first one.
Its purpose is to be the service in front of all the other services you have. Like front door to your system.
Rest of the services should be hidden of outside world, behind proxy service.
The purpose is to route all the services from one place, so with netflix-zuul you are able to intercept the request, manipulate, authenticate, route...
You can integrate service discovery (netflix-eureka) so your services will be registered there, and you don't need to deal with urls of your services, you can access them by path you defined and registered service ids.
You can integrate load balancing (netflix-ribbon) across your system.
You can control the interactions between your services by adding latency tolerance and fault tolerance logic (netflix-hystrix). So you can provide fallback options when error occurs..
And so on...
I have an orchestrator service which keeps track of the instances that are running and what request they are currently dealing with. If a new instance is required, I make a REST call to increase the instances and wait for the new instance to connect to the orchestrator. It's one request per instance.
The orchestrator tracks whether an instance is doing anything and knows which instances can be stopped, however there is nothing in the API that allows me to reduce the number of instances stopping a particular instance, which is what I am trying to achieve.
Is there anything I can do to manipulate the platform into deterministically stopping the instances that I want to stop? Perhaps by having long running HTTP requests to the instances I require and killing the request when it's no longer required, then making the API call to reduce the number of instances?
Part of the issue here is that I don't know the specifics of the current behavior...
Assuming you're talking about CloudFoundry/Instant Runtime applications, all of the instances of an applications are running behind a load balancer which uses round-robin to distribute requests across the instances (unless you have session affinity cookie set up). Differentiating between each instances for incoming requests or manual scaling is not recommended and it's an anti-pattern. You can not control which instance the scale down task will choose.
If you really want that level of control with each instance, maybe you should deploy them as separate applications. MyApp1, MyApp2, MyApp3, etc. All of your applications can have the same route (myapp.mybluemix.net). Each of the applications can now distinguish themselves by their name (VCAP_APPLICATION) allowing you terminate them.