Could someone help me on this,
i have created simple webservices and it has a queue that keeps xml files send from a client, so whenever webservice client call a method on webserbice , webserbice load this xml to its queue, now i want to have a thread running on webserbice which monitors this queue if there items on the queue take other actions.
But my problem is , webservice only invoke if client calls one of the methods in ws interface. so but i need this thread to be running on webserbice. so could someone tell me is there are a way to do this
You have to run your web service (server) inside a web application, which means that you probably have a web.xml somewhere. You can create a servlet, and initialize (starting) the processing thread on its init method, stopping it on the destroy method of the servlet. Be aware, thought, that by using this model you may lose unprocessed messages if the web application is stopped. You should perhaps be looking at JMS or something like WebSphere MQ, they both can act as messaging systems - you receive the message, queue it in a different queue, and then when the processing application is ready, it pulls the next message, processes it, and informs the calling process back.
Related
How to continuously pull messages from service bus queue. Like in aws we have :
spring-cloud-starter-aws-messaging
and a : Link to explain more
How to do similar thing in azure?
Same you can do in Azure as well.
You can create queues using the Azure portal, PowerShell, CLI, or Resource Manager templates. Then, send and receive messages using clients written in C#, Java, Python, and JavaScript.
Receive messages from a queue
Add a method named receiveMessages to receive messages from the queue.
This method creates a ServiceBusProcessorClient for the queue by
specifying a handler for processing messages and another one for
handling errors. Then, it starts the processor, waits for few seconds,
prints the messages that are received, and then stops and closes the
processor
For more information you can refer this MS Document for Create a console project and Configure your application to use Service Bus
I plan to create a webservice (in Tomcat) that works with a certain file on the system and make some system calls. The challenge am having is to make sure only 1 request can be processed at a given time and the previous request needs to be pre-empted. I currently have a singleton class that works on the request. And requesting threads somehow wait until the running thread is done. But what is the general design pattern for such problems?
Any ideas how this can be achieved?
Thanks,
V
Since there may be too many requests calling to this service, the synchronous approach may not be achieved. There also may be a chance that some clients waiting so that it is time-out. Then I prefer the asynchronous as
The Service-A receives the request and put it to queue-A or DB table-A, together with generating the ref-id.
The Service-A returns the ref-id to the client for further monitoring.
There is a back-end process monitoring the queue-A or DB table-A and perform the request one-by-one.
After finish, put the result to another queue-B or DB table-B.
The client keep monitoring periodically via another Service-B by using the ref-id, if the request is done.
I hope this may help to achieve your requirement.
Regard,
Charlee Ch.
I would place the queues mentioned by Charlee in the ServletContext. It is initialized when your WebApplication is started.
You can initialize and destroy these queues an the backend process in an implementation of ServletContextListener. Store them with setAttribute on the ServletContext.
Now you're able to access these queues via ServletContext in your Servlet.
I need to be able to achieve two threading tasks in a container and need to understand the best practices for doing this. Here are the two classes of task I need to accomplish:
During a web services call, I need to start a thread that continues processing after the response has been sent. No message is required back to the original sender when processing is complete.
A web services call may need to spawn multiple threads that need to run in parallel to each other. The response to the original request should be blocked until all the workers have completed. Elements of the response will be drawn from pieces of each of the thread's results.
Of course, I could create my own instance of a java.util.concurrent.Executor and use it, but I suspect containers might be smart enough to provide one that they manage.
FWIW - I'm using WebSphere 6.1 on JDK 1.5.0 (I know, ancient...but it is what it is). I am running web services developed using Apache CXF, so I'm in the servlet container, but configured with Spring.
For 1) you might want to look at Asynchronous Beans. Alternatively use a Message Driven Bean which picks up and actions a message you send to a Queue. There's the Quartz stuff from Spring you might want to look at too. I think with Servlet 3 (no chance on WAS 6.1!) you might get the async support without the Async Work Manager or JMS approach, but until then I don't know a better way than these patterns.
For 2) generally blocking the request is a risky business (what if you hit the timeout). However, you're in the servlet container so you're ok using something from java.util.concurrent e.g. ExecutorService as you mentioned. Alternatively use messaging to send the work off somewhere else and block until it completes.
Generally, I wouldn't start threads from inside a container because there is the chance that j2ee full compliance is turned on and your app would die. Under full compliance threads are not allowed to be created. What you want to do is set up a JMS queue that you submit your "work to be done" to. You can then have an MDB listening to the queue which performs that actual operation that your thread would have done.
Could someone help me on this,
I have created simple web services using axis2 , apache and tomcat. This web service has a queue that keeps xml files sent from a client, so whenever a client calls a method on the webservice, the webservice loads this xml to its queue. Now I want to have a thread running in the webservice which monitors this queue, and if there are items in the queue takes some action.
But my problem is that the webservice is invoked only if a client calls one of the methods on its interface. But I need this thread to be running on webserbice. Could someone tell me is there are is a way to do this?
When a client invokes a method on the webservice, it does not consider previous method invocations. This means that it does not keep track of data in the queue, for each invocation it creates new queue.
If you need background threads in a web application you must manage them inside a ContextListener registered in web.xml. You are then notified when your web application is started and stopped.
Sounds like the perfect use case for JMS/message driven beans. Spring JMS provides these facilities without having to use a full-blown J2EE container, so tomcat will fit here. Active MQ can provide the messaging engine.
Essentially, your web service would put a message on a queue and a message driven bean (or message driven pojo) would read them off the queue and process. Using JMS would have the advantage that you'd be able to reconfigure the message driven bean to sit on a separate host if you're load on the server grows. It'll also mean you'll be able to move to different app servers with ease as JMS is a standardised solution.
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.