Background
I'm well into building a central appointment booking system for various service providers. This is being built on Java EE 6 on GlassFish 3.1.1, making use of JSF 2, EJB 3.1 and other JEE6 standards. Each service provider has their own appointment booking facility running on their own server that is connected to the Internet, but currently they don't have any interface to allow their patients to make their own appointments.
My system will synchronously book appointments on service providers' systems (in response to user requests) via an API I have defined which involves streaming XML over HTTP. These appointment booking requests are synchronous because service providers will continue to book appointments directly in their system the old fashioned way (over the phone/counter) and, for whatever reasons, their system reserves the right to reject such requests (to prevent double bookings and for other reasons). So, their systems retain the status of being the source of truth.
For obvious reasons (mainly security), API connections are established by the service providers' systems. This means requests are being sent by the server (my system) and responses by the client (their system).
Problem
I need some suggestions regarding how I can build a server-push XML over HTTP API using Java EE 6 on GlassFish 3.1.1. A number of less than ideal options come to mind. One of them involves a singleton bean that contains a map of my appointment IDs to their appointment booking responses. In this scenario, my system polls the map for a limited time (up to 10 seconds, for example) until it finds a matching response, then returns the response which is then handled eventually in the JSF UI. Meanwhile, the API servlet (or perhaps JAX-RS web service) polls the singleton bean for requests, converts them to XML and streams them to the service provider's output stream.
I'm sure there must be a number of better ways of doing this not involving thread-per-connection, blocking, polling, etc.
Ideas?
Update
I was leaning towards Atmosphere/Jersey, but now I realize that blocking I/O is quite scalable under NPTL, so I'm flexible in that regard.
Here's how I did it:
Start with a singleton EJB containing:
A Map<Long, BlockingDeque<OutboundApiMessage>>, where the key is the API client ID;
A Map<Long, Exchanger<AppointmentExchange>>, where the key is the web-side appointment ID and AppointmentExchange contains that ID and the API client side appointment ID.
I set bean managed concurrency control on the singleton EJB, defined some methods to enqueue, dequeue and requeue (the latter in case server push of the OutboundApiMessage failed and needed to be added to the front of the queue where it would be the next item to be dequeued), wired it to the JAX-RS web services (one for upstream, one for downstream).
The singleton EJB has a method to synchronously book an appointment. It enqueues a message to be picked up by the client, creates an Exchanger containing a new AppointmentExchange instance then blocks waiting for the exchange. When an answer comes back on the inbound web service, that web service notifies the singleton EJB via another method which performs the exchange via the Exchanger.
It all works quite well now. Of course, there is a bit more to it than that, but that's the gist of it.
Related
Background:
I've a local application that process the user input for 3 second (approximately) and then return an answer (output) to the user.
(I don't want to go into details about my application in purpose of not complicate the question and keep it a pure architectural question)
My Goal:
I want to make my application a service in the cloud and expose API
(for the upcoming website and for clients that will connect the service without install the software locally)
Possible Solutions:
Deploy WCF on the cloud and use my application there, so clients can invoke the service and use my application on the cloud. (RPC style)
Use a Web-API that will insert the request into queue and then a worker role will dequeue requests and post the results to a DB, so the client will send one request for creating a request in the queue, and another request for getting the result (which the Web-API will get from the DB).
The Problems:
If I go with the WCF solution (#1) I cant handle great loads of requests, maybe 10-20 simultaneously.
If I go with the WebAPI-Queue-WorkerRole solution (#2) sometimes the client will need to request the results multiple times its can be a problem.
If I go with the WebAPI-Queue-WorkerRole solution (#2) the process isn't sync, the client will not get the result once the process of his request is done, he need to request the result.
Questions:
In the WebAPI-Queue-WorkerRole solution (#2), can I somehow alert the client once his request has processed and done ? so I can save the client multiple request (for the result).
Asking multiple times for the result isn't old stuff ? I remmemeber that 10 - 15 years ago its was accepted but now ? I know that VirusTotal API use this kind of design.
There is a better solution ? one that will handle great loads and will be sync or async (returning result to the client once it done) ?
Thank you.
If you're using Azure, why not simply fire up more servers and use load balancing to handle more load? In that way, as your load increases, you have more servers to handle the requests.
Microsoft recently made available the Azure Service Fabric, which gives you a lot of control over spinning up and shutting down these services.
In developing backend components, I need to decide how these components will interact and communicate with each other. In particular, I need to decide whether it is better to use (RESTful, micro) web services versus a message broker (e.g. RabbitMQ). Are there certain criteria to help decide between using web services for each component versus messaging?
Eranda covered some of this in his answer, but I think three of the key drivers are:
Are you modeling a Request-Response type interaction?
Can your interaction be asynchronous?
How much knowledge does the sender of the information need to have about the recipients?
It is possible to do Request-Response type interactions with an asynchronous messaging infrastructure but it adds significantly to the complexity, so generally Request-Response type interactions (i.e. does the sender need some data returned from the recipient) are more easily modeled as RPC/REST interactions.
If your interaction can be asynchronous then it is possible to implement this using a REST interaction but it may scale better if you use a fire and forget messaging type interaction.
An asynchronous messaging interaction will also be much more appropriate if the provider of the information doesn't care who is consuming the information. An information provider could be publishing information and new consumers of that information could be added to the system later without having to change the provider.
Web server and message broker have their own use cases. Web server used to host web services and the message broker are use to exchange messages between two points. If you need to deploy a web service then you have to use a web server, where you can process that message and send back a response. Now let's think that you need to have publisher/subscriber pattern or/and reliable messaging between any two nodes, between two servers, between client and server, or server and client, that's where the message broker comes into the picture where you can use a message broker in the middle of two nodes to achieve it. Using message broker gives you the reliability but you have to pay it with the performance. So the components you should use depends on your use case though there are multiple options available.
Problem
We have a client-server application, server side is Glassfish 3.1.2. This app has many users, as well as many modules (e.g. View Transactions, View Banks etc). There are some long running processes invoked by client which run on server. Currently we have not found a nice solution to show the user what is going on on the server side. We want the users to get updated messages from server with given frequency. What would you suggest to use?
What we have done/tried
We (independently) used an approach with Singleton bean and a Map of client IDs similar to this, and it works of course. But then on the server side every method doSomething(Object... vars) must be converted to doSomething(Object... vars, String clientID) or whatever ID is type of. The client pulls data from server say once per second. I would like to avoid adding facades between server and client.
I was thinking about JAX-WS or JAX-RS, but I'm not familiar with these technologies deeply and not sure about what they can do.
Sockets
I should note that on the server side we have only Stateless beans (there is a reason for that), that is why I did not mention the use of Stateful bean (which is very good candidate I think).
Regards, Oleg
WebSocket could be a suitable choice, it allows the server to send unsolicited data to clients with no strong coupling, you just have to store a client id to map client connections to running tasks and be able to push updates to the right connection.
The client id/socket connection mapping can be maintained in a singleton bean using an in-memory structure, i.e. a hash map, or a permanent datastore for scalability purposes or in case you need a robust solution.
Some useful links to better understand WebSocket technology are this and this.
I've got a Grails app (version 2.2.4) with a controller method that "logs" all requests to an external web service (JSON over HTTP - one way message, response is not needed). I want to decouple the controller method from calling the web service directly/synchronously and provide a simple "queue" which can store the calls if the web service is unavailable and then send them through once the service is back up again.
This sounds like a good fit for some sort of JMS solution but I've not got any experience with using JMS (so learning curve could be an issue). Should I be using one of the available messaging plugins or is that overkill for my simple requirements? I don't want a separate messaging app, it has to be embedded in my webapp and I'd prefer something small and simple vs more complicated and robust (so advice on which plugin would be welcome).
The alternative is to implement an async service myself and queue the "messages" in the database (reading them via a Quartz job) or with something like java.util.concurrent.ConcurrentLinkedQueue?
EDIT: Another approach could be to use log4j with a custom appender set up as a AsyncAppender.
The alternative is to implement an async service myself and queue the "messages" in the database (reading them via a Quartz job)
I went ahead and tried this approach. It was very straight forward and was only a "screen" length of code in the end. I tested it with a failing web service end point as well as an app restart (crash) and it handled both. I used a single service class to both persist the messages (Grails domain class) and to flush the queue (triggered by Quartz scheduler) which reads the DB and fires off the web service calls, removing the DB entity when web service returns 200 status code.
I have an application running in a Java EE App Server and it needs to call a web service of a partner company.
Using wsimport.exe from my JDK (1.6) I have generated the client classes. I instantiate the service and get the port in order to call the web service.
I noticed that the first call to the web service is slow, and I am led to believe this is because it is validating the WSDL. Subsequent calls are fast.
I could keep the WSDL locally, and apparently that will speed up the first call.
In order to optimise my app, I was thinking I could create a pool of the clients. This has the added advantage that I have some throttling in the app - lets say I have a pool of 5 clients, then at most I will be using memory for 5 clients. If the load increased suddenly on my server, I don't have to worry that an unlimited number of clients would cause an out of memory error. I am assuming, based on past experience, that the web service clients use a lot of memory...
Would you bother with a pool?
How would you get over the first call to the web service being slow?
What is the best way to create that pool, so that I have to do the least amount of programming (i.e. I'd like to use a library / API / whatever, so that I don't have to reinvent the wheel and code some hairy bugs).
The Apache Commons Pool might be exactly what I am after.
It is configurable and seems to have thought of everything.
A colleague of mine suggested that you can use the #WebServiceRef annotation on a field in an EJB. The idea is that the server would inject a reference to a client, from which one can create a port for each thread that calls the EJB.
I assume that injected references come from a pool, although the specification doesn't appear to talk about this. The Javadoc for the annotation explicitly mentions that:
"the injected references are not thread safe"
AKKA with a master/slave setup as shown in the link could work well, albeit a little more complex than the Apache Commons Pool listed in another answer. AKKA also uses an execution pool, with its own threads, which isn't strictly allowed in the Java EE world, although I'd argue that because a well tested framework is in charge of the threads, there is no danger, and it shouldn't interfere with the app servers control of threads anyway as the number of threads being handled by AKKA is minimal.