ModCluster configuration to discard request when load is full - java

I have a Java application which exposes REST.
I have a master and 2 slaves. (jboss7.1.1)
Apache-modcluster takes care of load balancing.
I have queues maintained in my application which gets filled up at times, when there are no consumers. Hence I get OutOfMemory and the slave node goes down.
Is there any configuration in apache modcluster to check the load and block incoming requests, inspite of just routing?
Or any different suggestion?

As far as I am aware you can only route requests based on load (using a LoadMetric), not block them
I would suggest you should design you API to return a different response code (509 or 503 perhaps) when your queues are full and the jboss node is unable to service the request, you can then instruct the API consumers to try again after a timeout if they encounter one of these responses
It is possible to 'rate-limit' apache using something like mod_security (see: https://johnleach.co.uk/words/1073/rate-limiting-with-apache-and-mod-security), however I think that controlling this from within your application code would be better

Related

How to avoid Response error: 429 Too Many Requests

One Spring boot application sends many calls in parallel to another and in one time i faced with 29 Too Many Requests
How can avoid it?
You should stop spamming your server and rethink your architecture. The 429 status is not an error. It is more a hint to stop spamming:
The 429 status code indicates that the user has sent too many
requests in a given amount of time ("rate limiting").
https://www.rfc-editor.org/rfc/rfc6585#page-3
You need K8s with clustering of your micro service and to think how you want
to scale your pods horizontally.
On top of that you need to use a load balancer and maybe to use the ribbon + Hysterix + Feign client out of the stack of spring cloud solution.
And you also have too check that you don't receive too many auto-retry technical requests of your underlying HTTP client.
Your application sends many calls in parallel to another, I unable to get what is another?,
If another is db call then you can increase connection size in db then you wouldn't be get in future.
or else if another is API call then you should go with batch statement it will helpful instead of parallel call.
This is standard use case for Pub-Sub pattern. Use any message queue like, SQS, Kafka etc.
First spring boot instance should push messages to this queue. Another spring application (or any application) should poll messages at the rate suitable for it self.
Messages will be hold in the queue until app2 picks it up.

Is there a way to Queue REST call with Spring?

I am working on a project that is making a REST call to another Service to save DATA on the DB. The Data is very important so we can't afford losing anything.
If there is a problem in the network this message will be lost, which can't happen. I already searched about Spring Retry and I saw that it is designed to handle temporary network glitches, which is not what I need.
I need a method to put the REST calls in some kind of Queue (Like Active MQ) and preserve the order (this is very important because I receive Save, Delete and Update REST calls.)
Any ideas? Thanks.
If a standalone installation of ActiveMQ is not desirable, you can use an embedded in-memory broker.
http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html
Not sure if you can configure the in-memory broker to use KahaDB. Of course the scope of persistence will be limited to your application process i.e. messages in the queue will not be available if the application is restarted . This is probably the most important reason why in-memory or vanilla code based approaches are no good.
If you must reinvent the wheel, then have a look at this topic, which talks about using Executors and BlockingQueue to implement your own pseudo-MQ.
Producer/Consumer threads using a Queue.
On a side note, retry mechanism is not something provided by the MQ broker. It is the client that implements it. Be it ActiveMQs bundled client library or other Messaging libraries such as Camel.
You can also retrospect your current tech-stack to see if any of the existing components have JMS capabilities. For example: Oracle database bundles an MQ called Oracle AQ
Have your service keep its own internal queue of jobs, and only move onto the next REST call until the previous one returns a success code.
There are many better ways to do this but the limitation will come down to what your company will let you do.

How to execute a very heavy process exposed as REST services from wildfly?

I have a process that processes an input file, uses 100% of the processor (uses 16 cores), and 8 GB of RAM. I currently run it directly from the console. But I need to call this process from a REST service. The service must be asynchronous, and there will be another service to consult the output of the first service called. The input files must be queued, because it can only be processed one at a time.
I use RestEasy on Wildfly.
My query is:
What architecture do you suggest to call this process?
I have these possible solutions.
Call from my EJB to JAR with Runtime. And have a queue of files in a database.
Transform my JAR into a Demon, which is constantly monitoring a directory. And they will be storing the files there. And that the demon took one by one the files according to the date of arrival.
Copy the classes in my EAR project, and call them as a simple EJB, and let wildfly manage the resources. This would also imply having a file queue in a database.
Do you have any other suggestions?
Instead of writing a queue use a JMS implementation or Kafka. Cloud solutions exist from Google and AWS. Have your REST endpoint publish to the queue and your "daemon" receive from it.
From there it's easy to pull these apart into microservice architecture
Technically the solution is simple: have a rest endpoint call another Stateless EJB with #Asynchronous annotation. If you want to track the status, use some kind of Job entity, that you create (synchronously) when you receive the request, then start the async job with this Job entity as param and update it from your async task.
There is however a more conceptual problem: why do you need to invoke such long running op on your web server? With requirement like this it is going to be very difficult to scale your app, handle failover(what happens if your server crashes during processing)..
If you need to do IO or computation heavy task like this in java env, have a look at batch processing - jberet or spring batch will do the job. That way you can process your file in chunks, paralelize the compution and spread the load more evenly. If you are doing some video processing or similiar task, consider using a dedicated machines with some kind of job queue(celery, kafka...) for that, and just let your server handle the rest layer and job monitoring.

Clustered event driven Java application - Should I use Websockets or polling?

I'm creating a monitor application that monitors the activities of a user. There are four elements in my system:
EventCatcher: The EventCatcher is responsible for catching all the events that happen in a subsystem and pushes the data to the EventHandler. Based from observation, there is an average of 10 events per second that is being pushed to the EventHandler. Some events are UserLogin, UserLogout.
EventHandler: The EventHandler is a singleton class that handles all the incoming events from the EventCatcher. It also keeps track of all the logged in users in the system. So, whenever the EventHandler receives a UserLogin event, the User object is extracted from the event and is stored in a HashMap. When a UserLogout event is received, that User object will be remove from the HashMap. This class also maintains a Set of all active Websocket sessions because everytime an event has occurred, I would want to inform all the open sessions that a particular event happened.
Websocket Endpoint: This is just a simple Java class annotated with #ServerEndpoint.
Clients: The system I will be building is for internal (company) use only. At production, at most, there will only be around 5 - 10 clients. All the clients will be receiving the same information every time an event has occurred.
So right now I am trying to convince my supervisor that Websockets is the way to go, however, my supervisor finds it really unnecessary because a simple polling solution would do the trick.
His points are:
We don't really need up-to-date information by the millisecond. We can poll every second.
If I was to maintain a list of open WebSocket sessions, how would that work in a clustered environment (we use a load balancer)
If I plan to send information to the client every time an event (UserLogin, UserLogout) has occurred, I should be able to just send small updates to all WebSocket sessions - meaning, I can't be sending a whole JSON dump of everything. So that means, for every WebSocket instance, I would have to maintain another Set of Users and properly maintain it to mirror the Set contained in the EventHandler.
What my supervisor suggests is that I lose the WebSocket and just convert it to a simple Servlet and let the clients poll every second to receive the entire JSON dump.
In this scenario, should I stick with WebSockets? Or should I just poll?
The main advantage, as far as I've read, of Websockets vs. polling is that by using Websockets, you will have a persistent connection from client to server. HTTP is not really meant for real-time data.
Also, polling requires sending an HTTP request every time and every request comes with HTTP headers. If an HTTP request header contains 800 bytes, then that's 48kb sent per minute per client. With a WebSocket, this isn't problem.
But then again, we won't really have a lot of active clients. We're not concerned about third parties sniffing our requests because this system is for company use only - internal use! And I believe my supervisor wants something simple and reliable.
I am fine with either way. I just want to be sure whether I'm using the right tool for the job.
Additional question: If WebSockets is the way to go, is there any reason why I should consider polling?
The entire purpose of WebSocket is to efficiently support continuing connections between client and server.
I’m not clear on how you are implementing your app. If this is a web app running in a Servlet environment leveraging WebSocket support in the web server, be aware that you need to use recent versions of the Servlet container. For example, with Tomcat you must use either version 8 or the latest updates to version 7.
And of course the web browser must have support for WebSocket.
Be aware that WebSocket is still a new technology that has been changing and evolving in both the specs and the implementations.
Atmosphere
You may want to consider using the Atmosphere framework. Atmosphere supports multiple techniques of Push including WebSocket & Comet.
The Vaadin web-app framework leverages Atmosphere to provide automatic support for Push in your app. By default, WebSocket is automatically attempted first. If WebSocket is not available, Vaadin+Atmosphere falls back automatically to the other techniques including polling.

Whats the best way to process an asynchronous queue continuously in Java?

I'm having a hard time figuring out how to architect the final piece of my system. Currently I'm running a Tomcat server that has a servlet that responds to client requests. Each request in turn adds a processing message to an asynchronous queue (I'll probably be using JMS via Spring or more likely Amazon SQS).
The sequence of events is this:
Sending side:
1. Take a client request
2. Add some data into a DB related to this request with a unique ID
3. Add a message object representing this request to the message queue
Receiving side:
1. Pull a new message object from the queue
2. Unwrap the object and grab some information from a web site based on information contained in the msg object.
3. Send an email alert
4. update my DB row (same unique ID) with the information that operation was completed for this request.
I'm having a hard figuring out how to properly deal with the receiving side. On one hand I can probably create a simple java program that I kick off from the command line that picks each item in the queue and processes it. Is that safe? Does it make more sense to have that program running as another thread inside the Tomcat container? I will not want to do this serially, meaning the receiving end should be able to process several objects at a time -- using multiple threads. I want this to be always running, 24 hours a day.
What are some options for building the receiving side?
"On one hand I can probably create a simple java program that I kick off from the command line that picks each item in the queue and processes it. Is that safe?"
What's unsafe about it? It works great.
"Does it make more sense to have that program running as another thread inside the Tomcat container?"
Only if Tomcat has a lot of free time to handle background processing. Often, this is the case -- you have free time to do this kind of processing.
However, threads aren't optimal. Threads share common I/O resources, and your background thread may slow down the front-end.
Better is to have a JMS queue between the "port 80" front-end, and a separate backend process. The back-end process starts, connects to the queue, fetches and executes the requests. The backend process can (if necessary) be multi-threaded.
If you are using JMS, why are you placing the tasks into a DB?
You can use a durable Queue in JMS. This would keep tasks, even if the JMS broker dies, until they have been acknowledged. You can have redundant brokers so that if one broker dies, the second automatically takes over. This could be more reliable than using a single DB.
If you are already using Spring, check out DefaultMessageListenerContainer. It allows you to create a POJO message driven bean. This can be used from within an existing application container (your WAR file) or as a separate process.
I've done this sort of thing by hosting the receiver in an app server, weblogic in my case, but tomcat works fine, too. Don't poll the queue, use an event-based model. This could be hand-coded or it could be a message-driven web service. If the database update is idempotent, you could update the database and send the email, then issue the commit on the queue. It's not a problem to have several threads that all read from the same queue.
I've use various JMS solutions, including tibco, activemq (before apache subsumed it) and joram. Joram was the more reliable opensource solution, but that may have changed now that it's part of apache.

Categories

Resources