I have a Spring Boot web application implementing the API Gateway pattern in which the embedded Tomcat instance receives requests and forwards them to a number of microservices (also Spring Boot applications). I'm using Spring Remoting with AMQP to establish communication and some of the calls to these services may take a while to complete (the most expensive one takes, say, 1-2 seconds).
I've successfully configured listener concurrency on these microservices and everything is working smooth, but now I'm wondering what the default behaviour of the client is. Are calls to those microservices made synchronously or asynchronously? And, in case they are synchronous by default, how can I make them asynchronous so that these calls don't block the "Tomcat" thread in which they're being made (making it available to process other requests while waiting for the response from the services)?
The 1.6 release introduces a new AsyncRabbitTemplate. When calling the sendAndReceive() (and convertSendAndReceive()) methods, a ListenableFuture is returned with which you can register a callback to receive the reply.
Related
If my reactive endpoint needs to call an external, non-reactive endpoint which does blocking stuff, is my reactive endpoint still reactive?
I have 2 services running that levergaes Spring Boot MVC and Spring Webflux.
Service A
Spring Webflux
Service B
Spring MVC
Now my Service A which is reactive calling the Service B endpoint which is blocking. Will my service A be affected and be non-reactive?
If yes? How to tackle such scenario such that my reactive endpoint stays reactive?
If Service A is written as a reactive services using webflux it will always stay reactive, no matter who else it is calling.
Im going to assume we are talking http/https now using for instance webclient.
The thing about reactive is if service B is very slow to respond, your service A, will not have the calling thread wait for the response, instead service A's thread will go and do other stuff while it is waiting for the response from service b, and when the response comes back any thread can pick up the response and continue.
A reactive service isn't reactive if it only calls other reactive services. It's always reactive. As in it reacts to events.
There are some caveats. For instance if you are talking to a database, here the database driver needs to be a specific driver that is following the R2DBC specification.
You see the traditional JDBC specification for how to write database drivers was designed to be inherently blocking. If you followed the spec and wrote a driver the driver would automatically have to be blocking. You had no choice.
So spring created a new spec (R2DBC) that is not inherently blocking, so you need a driver that is compliant to that spec. Otherwise your service will be affected by blocking behavior.
But the answer to your question is.
No, if we are talking http from one service to another.
Is it possible for a RestTemplate to consume an endpoint which is reactive based (Spring WebFlux)? I understand that the main idea of reactive programming is to avoid blocking and make better use of threads (eliminate thread per connection model) so what happens if my Client is non reactive?
Will I still be able to call the service even if it is in a blocking
manner?
To achieve full reactiveness (non blocking) both Client and Server
must be reactive?
Yes, that is not relevant to the clients of Reactive applications. The reason is that this is a regular HTTP call.
Each may be fully reactive on its own. Having said that, if you use WebFlux in both Client and Server you will have a system that is as a whole reactive. But there is nothing forcing you to do this. You can have only one of the services as a Reactive application. It comes down to your needs and context.
I exploit spring-cloud. As far as I understand, when client of Eureka gets a list of services from Eureka server, it uses the Ribbon for load balancing.
Does the client use Hystrix to get the list of services from Eureka through the circuit breakers?
There is a Gateway Service called Netflix Zuul(You can also call it as edge Service).Client connect to gateway service which in turn queries Eureka Server to get appropriate Micro Service details.
Hystrix basically uses fault tolerance mechanism which can be used in any Micro Service. Its advantage is that, if any API goes down ,it gracefully handles the errors in the Application.
As shankarsh15 says, Hystrix actually provides resilience (e.g. fallbacks) when errors and/or timeouts occur in API calls.
I believe it's actually ribbon-loadbalance (LoadBalancerContext.java -> getServerFromLoadBalancer()) that determines which client to call.
And this ultimately works in a similar way to doing discoveryClient.getInstances("service-name") (aka gets a list of service instances, then uses round robin to pick a service to use)
I'm exposing functionality to access user details via a rest call.
From reading this post: Is Spring Boot MVC controller multithreaded? spring boot rest services are multithreaded. Does this mean using Akka to multi-thread web services does not serve any use?
Using Java Akka will not offer any multi-threaded advantages but will offer:
If a rest call fails with error (e.g 404) Akka can be used to restart the rest call or kill the thread, so stopping the service.
If the a certain rest call is taking much of time to complete Akka can be used to kill the call after a duration of time.
Akka can be used to throttle requests to rest client, useful if service allows max requests in period of time.
Are my assertions correct? If I'm not concerned with these points above, should I still use Akka or use the functionality to access the user details and not wrap the it with Akka? Could Java futures be also used for these points?
Currently I'm doing the integration work of one project. In this project, we need to expose a restful api with java framework Wink. Since we have several other components to integrate, we put a message queue(activemq) between the api layer and other service parts.But this time the api layer will communicate to the lower level in an asynchronous way. In my understanding, the restful api should run in a synchronous way. For example, in the api layer, if one thread received a request, the response will get returned in the same thread. So there is a internal mismatch between these 2 communication styles. My question is how can we integrate these 2 parts to make the api layer work without sacrificing the features in message queue like reliability and performance?
Any suggestions will be apprciated here.
Thanks
Asynchronous callback is possible in REST communication, see this JERSEY framework example:
https://jersey.java.net/documentation/latest/async.html
But yes the latency should be controlled as your client would be waiting for server to respond, and would be good if client calls it in AJAX way.
Simplest way would be to fork a new process through "executor service", which sends a message in a channel to lower level api and listens back for response in another channel(MQ communication). And on process completion return a response, which then the higher API will push back to client.