I am wondering how Quarkus is handling simultaneous requests to for example a REST API with json-rest.
Example:
REST API is called by lots of clients simultaneously
REST API call calls other APIs
REST API processes the response of the other called APIs and returns the processed response
Questions:
Are the requests queued and processed one by one?
Are requests rejected if the API is busy?
Is handling parallelism offloaded to the infrastructure using tools like Istio?
Can someone please point me to some documentation about that or give an explanation? Thank you.
Quarkus uses Vert.x under the hood which implements an event loop. This means that it can handle thousands of the requests because its threads are not blocked.
You may read more about it in the Vert.x's documentation: https://vertx.io/docs/vertx-core/java/
Related
I come across many blog that say using rabbitmq improve the performance of microservices due to asynchronous nature of rabbitmq.
I don't understand in that case how the the http response is send to end user I am elaborating my question below more clearly.
user send a http request to microservice1(which is user facing service)
microservice1 send it to rabbitmq because it need some service from microservice2
microservice2 receive the request process it and send the response to rabbitmq
microservice1 receive the response from rabbitmq
NOW how this response is send to browser?
Does microservice1 waits untill it receive the response from rabbitmq?
If yes then how it become aynchronous??
It's a good question. To answer, you have to imagine the server running one thread at a time. Making a request to a microservice via RestTemplate is a blocking request. The user clicks a button on the web page, which triggers your spring-boot method in microservice1. In that method, you make a request to microservice2, and the microservice1 does a blocking wait for the response.
That thread is busy waiting for microservice2 to complete the request. Threads are not expensive, but on a very busy server, they can be a limiting factor.
RabbitMQ allows microservice1 to queue up a message to microservice2, and then release the thread. Your receive message will be trigger by the system (spring-boot / RabbitMQ) when microservice2 processes the message and provides a response. That thread in the thread pool can be used to process other users' requests in the meantime. When the RabbitMQ response comes, the thread pool uses an unused thread to process the remainder of the request.
Effectively, you're making the server running microservice1 have more threads available more of the time. It only becomes a problem when the server is under heavy load.
Good question , lets discuss one by one
Synchronous behavior:
Client send HTTP or any request and waits for the response HTTP.
Asynchronous behavior:
Client sends the request, There's another thread that is waiting on the socket for the response. Once response arrives, the original sender is notified (usually, using a callback like structure).
Now we can talk about blocking vs nonblocking call
When you are using spring rest then each call will initiate new thread and waiting for response and block your network , while nonblocking call all call going via single thread and pushback will return response without blocking network.
Now come to your question
Using rabbitmq improve the performance of microservices due to
asynchronous nature of rabbitmq.
No , performance is depends on your TPS hit and rabbitmq not going to improve performance .
Messaging give you two different type of messaging model
Synchronous messaging
Asynchronous messaging
Using Messaging you will get loose coupling and fault tolerance .
If your application need blocking call like response is needed else cannot move use Rest
If you can work without getting response go ahaead with non blocking
If you want to design your app loose couple go with messaging.
In short above all are architecture style how you want to architect your application , performance depends on scalability .
You can combine your app with rest and messaging and non-blocking with messaging.
In your scenario microservice 1 could be rest blocking call give call other api using rest template or web client and or messaging queue and once get response will return rest json call to your web app.
I would take another look at your architecture. In general, with microservices - especially user-facing ones that must be essentially synchronous, it's an anti-pattern to have ServiceA have to make a call to ServiceB (which may, in turn, call ServiceC and so on...) to return a response. That condition indicates those services are tightly coupled which makes them fragile. For example: if ServiceB goes down or is overloaded in your example, ServiceA also goes offline due to no fault of its own. So, probably one or more of the following should occur:
Deploy the related services behind a facade that encloses the entire domain - let the client interact synchronously with the facade and let the facade handle talking to multiple services behind the scenes.
Use MQTT or AMQP to publish data as it gets added/changed in ServiceB and have ServiceA subscribe to pick up what it needs so that it can fulfill the user request without explicitly calling another service
Consider merging ServiceA and ServiceB into a single service that can handle requests without having to make external calls
You can also send the HTTP request from the client to the service, set the application-state to waiting or similar, and have the consuming application subscribe to a eventSuccess or eventFail integration message from the bus. The main point of this idea is that you let daisy-chained services (which, again, I don't like) take their turns and whichever service "finishes" the job publishes an integration event to let anyone who's listening know. You can even do things like pass webhook URI's with the initial request to have services call the app back directly on completion (or use SignalR, or gRPC, or...)
The way we use RabbitMQ is to integrate services in real-time so that each service always has the info it needs to be responsive all by itself. To use your example, in our world ServiceB publishes events when data changes. ServiceA only cares about, and subscribes to a small subset of those events (and typically only a field or two of the event data), but it knows within seconds (usually less) when B has changed and it has all the information it needs to respond to requests. Each service literally has no idea what other services exist, it just knows events that it cares about (and that conform to a contract) arrive from time-to-time and it needs to pay attention to them.
You could also use events and make the whole flow async. In this scenario microservice1 creates an event representing the user request and then return a requested created response immediately to the user. You can then notify the user later when the request is finished processing.
I recommend the book Designing Event-Driven Systems written by Ben Stopford.
I asked a similar question to Chris Richardson (www.microservices.io). The result was:
Option 1
You use something like websockets, so the microservice1 can send the response, when it's done.
Option 2
microservice1 responds immediately (OK - request accepted). The client pulls from the server repeatedly until the state changed. Important is that microservice1 stores some state about the request (ie. initial state "accepted", so the client can show the spinner) which is modified, when you finally receive the response (ie. update state to "complete").
We are designing an API for an application where the clients (external) can
interact with it synchronously to say:
a) request a plan
b) cancel a plan etc
However once the plan is made, the decision as to whether a plan is
approved or disapproved is done asynchronously. The application itself
can send other notifications to the clients asynchronously. This part has
been implemented using spring's stomp over websocket framework. This
work perfectly fine.
Now, coming to the synchronous part of the API, the plan is to provide
a RESTful interface for the interaction. If this is done this way, the
clients will have to build two different client API's, one using http
for making RESTful calls and another using a stomp client to consume notifications.
Should we rather make it accessible via one interface?
I am not convinced of using Stomp for synchronous calls since I think the REST framework
will address the use case well. However I am concerned about the need for the clients to do both, although it is for different functionality.
Will it be okay to support both? Is this a good design practice. Can someone please advice?
HTTP based clients could a) send requests ('simple polling), in long intervalls to limit bandwidth usage, or b) use HTTP long polling (blocking) to immediately return control to the client code when the server sends for a response
I've only just learnt about Akka and actors and am unsure whether to use them for my following use case in a Play framework application.
What I want to do is have a user make a web request, which then needs to make somewhere between 20-50 Yelp API calls (in parallel), get those responses, do some processing and combine them into a single result.
What I want to know is whether using Akka actors will improve the scalability and decrease the response time to the user. Will using actors give me any benefit over just making the WS calls in my controller code (using a future for each).
I think I am having trouble understanding what benefit using actors might give me in this scenario as opposed to just a bunch of asynch web requests.
Actors themselves are just a means to achieve and manage parallelism. The gain that you get with for example spinning up one actor per async request that you're issuing is supervision hierarchies. For example, a master Actor can decide to kill respond with a failure message transparently already if one of the requests fails, or only after a number of them has failed etc. You can issue restarts (retries of these requests) etc. Without Actors you'd have to implement all this supervision logic yourself – which gets quite repetitive after a while.
To answer your question about scalability and response times: sadly "it depends" on your exact access patterns, but in general yes because you can fine-tune them way better than just one asynchronous http client as well as implement retries more easily.
If you want to check out how to collect responses from many async requests using Actors refer to this answer on stack overflow on "Waiting on multiple Akka messages".
Hope this helps.
Currently I am using Jersey 1.0 and about to switch to 2.0. For REST requests the may last over a second or two I use the following pattern:
Client calls GET or PUT
Server returns a polling URL to the client
The client polls the URL until it gets a redirect to the completed resource
Pretty standard and straightforward. However, I noticed that Jersey 2.0 has an AsyncResponse capability. But it looks like this is done with no changes on the wire. In other words, the client still blocks for the result while the server is asynchronously processing the request.
So what good is this? Should I be using it instead of my current asynchronous approach for calls >1 second? Or is it really just to keep the connections freed on the server for calls that would be only a few hundred milliseconds?
I want my server to be as scalable as possible but the approach I use now can be tedious for the client. AsyncResponse seems super simple but I'm not sure how it would work for something like a heroku service where you want very short connection times.
AsyncResponse presumably gives you more scalability within the web app server for standard standard requests in terms of thread pooling resources, but I don't think it changes anything about the client experience which will continue to block on read on their connection. Therefore, if you already implemented a polling solution from your client side, this won't add much of any value to you imho.
I have this question, i am just throwing it out there. I am implementing a small logging feature for my spring based REST API server for logging all requests coming in.
I am expecting 1000s of users to use this API so with a blocking i/o logger, it's going to slow down everything. I have two approaches to solve the problem:
1. Have a async logger using an in-memory arrylist. then use the spring scheduler to flush this out to a log file periodically.
2. Use JMS and send the logs to the queue. Let the queue handle the logging asynchronously.
Has anyone done this before with spring. Though i am for option 2, are there better ways of doing this? Need some expert advice. Thanks everyone !
More info - I think synchronous logging will be a bottle neck because this REST API is consumed by a front end RoR app. So one session of the user will definitely result in 100s of API calls occuring very frequently. I am logging the actual request along with the JSON sent in the POSTs.
Has anyone done this before with spring.
Not so strangely, yes - Asynchronous Logging Using Spring
The article mentions that if you don't want any log events to be lost, JMS would be the way to go - otherwise sticking to Async makes sense for high volume logging.
If you really want to build your own logger, I suggest you to take a look at akka, it is much easier than JMS to set up.
You can use it locally (use of all CPU cores of your local machine), or even with remote agents.