Pooling data from server using RMI and springs - java

I am new to RMI and springs and need a little help with a feature we are implementing.
We are creating chat software with java and want to use RMI with springs.
I can setup a client server interaction fairly easily using RMIServerExporter, interfaces, etc.
The problem I can get my head around is that the client needs to pool data from the server. We need to get keep checking for new messages.
We can't push data from the server for other reasons.
How do I go about setting up RMI with springs so that the client pools data from the server. I have looked up callbacks but this involved pushing from the server!?
Is there away to do this. Let me know if you need to me explain this further

RMI is just a transport protocol used for client-server communication. On client side, once your RmiProxyFactoryBean has been properly defined and initialized in Spring container, where, when and how to use this service bean is totally up to developer. For a server pooling implementation, we usually use ScheduledThreadPoolExecutor to schedule the RMI call in a given time interval, for example:
public class ChatClient {
// Defined and wired as RmiProxyFactoryBean in applicationContext.xml
private ChatService chatService;
private ScheduledExecutorService scheduleTaskService;
... ...
// At some point during chat application running life cyle:
scheduleTaskService = Executors.newScheduledThreadPool(5);
// This schedule pooling task to run every 2 minutes:
scheduleTaskService.scheduleAtFixedRate(new Runnable() {
public void run() {
// Pooling server using RMI call:
chatService.poolingData();
}
}, 0, 2, TimeUnit.MINUTES);
... ...
}
For a more enterprise solution, we usually use Quartz, check out this blog post as a live example.

Related

Spring AMQP #RabbitListener is not ready to receive messages on #ApplicationReadyEvent. Queues/Bindings declared too slow?

we have a larger multi service java spring app that declares about 100 exchanges and queues in RabbitMQ on startup. Some are declared explicitly via Beans, but most of them are declared implicitly via #RabbitListener Annotations.
#Component
#RabbitListener(
bindings = #QueueBinding(key = {"example.routingkey"},
exchange = #Exchange(value = "example.exchange", type = ExchangeTypes.TOPIC),
value = #Queue(name = "example_queue", autoDelete = "true", exclusive = "true")))
public class ExampleListener{
#RabbitHandler
public void handleRequest(final ExampleRequest request) {
System.out.println("got request!");
}
There are quite a lot of these listeners in the whole application.
The services of the application sometimes talk to each other via RabbitMq, so take a example Publisher that publishes a message to the Example Exchange that the above ExampleListener is bound to.
If that publish happens too early in the application lifecycle (but AFTER all the Spring Lifecycle Events are through, so after ApplicationReadyEvent, ContextStartedEvent), the binding of the Example Queue to the Example Exchange has not yet happend and the very first publish and reply chain will fail. In other words, the above Example Listener would not print "got request".
We "fixed" this problem by simply waiting 3 seconds before we start sending any RabbitMq messages to give it time to declare all queues,exchanges and bindings but this seems like a very suboptimal solution.
Does anyone else have some advice on how to fix this problem? It is quite hard to recreate as I would guess that it only occurs with a large amount of queues/exchanges/bindings that RabbitMq can not create fast enough. Forcing Spring to synchronize this creation process and wait for a confirmation by RabbitMq would probably fix this but as I see it, there is no built in way to do this.
Are you using multiple connection factories?
Or are you setting usePublisherConnection on the RabbitTemplate? (which is recommended, especially for a complex application like yours).
Normally, a single connection is used and all users of it will block until the admin has declared all the elements (it is run as a connection listener).
If the template is using a different connection factory, it will not block because a different connection is used.
If that is the case, and you are using the CachingConnectionFactory, you can call createConnection().close() on the consumer connection factory during initialization, before sending any messages. That call will block until all the declarations are done.

#async vs message queue difference

I have a spring boot project, deploying in two servers and using nginx. One method in the project will do:
set some key-values in redis
insert something in db
After 1, I want to do 2 in async way.
One solution is to let doDB() be a springboot #async method:
Class A {
public void ***() {
doRedis() // 1.set some key-values in redis
doDB() // 2.insert something in db
}
}
Class B {
#async
doDB()
}
Another solution is to send message to MQ:
Class A {
public void ***() {
doRedis() // 1.set some key-values in redis
sendMessage()
}
}
Class B {
onMessage(){
doDB()
}
}
If Class A and B are both in the spring boot project, just deploying this project in two servers. I think using #async is enough, there is no need to use MQ to achieve the async way because there is no difference between server one to do Class B doDB() and server two to do Class B doDB(). If class B is in another project, then using MQ is good because it's decoupling for project one doing redis work and project two doing db work.
Is it right? Thanks!
Basically, you are right, if it is going to be in the same application within the same server, no need for MQ because async is already has a queue. But there are some key points you should be decided on even if in the same application
if you care about ordering message queue is more meaningful, you can use async in this case too but you have to configure the thread pool to use only one thread to process async
if you care about losing messages and if some bad things happen before processing messages, you should use an MQ that saves messages to the disk or somewhere to process the rest of the messages later on
if your application gets a lot of requests and you did not carefully set threads in the async thread pool, you could get overflow errors or other problems with using machine resources
Choose within capabilities within your application, do not over-engineer from day one, you spin up from what you have and what you already tested

Java TCPIP EJB Threads

I am developing a TCPIP application where the client will send information to a specified port and the server will listen to that port. I would like to achieve the following:
Reconnect to the the client/port to see whether it is active after a specified time period.
I have the below code implemented:
#Stateless
#Local
public Listener implements ConnectionListener {
public void listen() throws Exception {
ServerSocket serverSocket = new ServerSocket(somePort);
Socket socket = serverSocket.accept();
while(!socket.isClosed()) {
}
}
}
public interface ConnectionListener {
public void listen() throws Exception;
}
How can this be achived with EJB technology? I know the while loop is wrong but what can be included. I have two approaches:
Wait for a time period to reconnect
Thread
However, I do not wish to use the Thread appraoch.
I know in EJB there are things such as an EJBTimer. What would be the best way to implement this and how could this be implemented in the code. Could you help how I could change the while loop to do what I want it to do?
Also, the client has no API to call on this application. How can this instance be triggered on start up of the Application Server so that messages are listened to. Usually, this could be achieved through a Servlet but I don't think this will work. Any ideas?
This kind of functionality is at the "edge" of the types of things you would do in EJB. typically, EJBs do not directly do network type activity, especially long term listening.
what you really want is an EJB singleton. this is kind of like a standalone instance which can do more advanced things like custom concurrency/threading and (relevant to you) start a custom socket listener.

JMS - ActiveMQ - Servlet(Remote Server (Apache-ActiveMQ)) and Console Java Program

I have to send a message from a JAVA console program to a servlet on APACHE Tomcat 7.0.42 Server and using ActiveMQ 5.8.0 and send the acknowledgement message back to the program and continue the same thing until server goes offline.
I am completely new to JMS, i only know servlets,jsp,listeners,i.e. no frameworks.
I have: Eclipse-Kepler and JDK1.7 and was not able to configure ActiveMQ on Apache.
I read quite many blogs but nothing seems to work
Please, guide me how to go about the problem.
Thanks you.
If you are using a servlet-container only (Tomcat), you can create an unmanaged thread like this:
#WebListener
public class MyServletContextListener implements ServletContextListener {
public void contextInitialized(final ServletContextEvent sce) {
final java.util.Timer timer = new Timer();
// Executes repeatedly (delay = 4000, period = 5000)
timer.schedule(new ReplyTask(), 4000, 5000);
sce.getServletContext().setAttribute("replyTaskTimer", timer);
}
public void contextDestroyed(final ServletContextEvent sce) {
final java.util.Timer timer =
(Timer) sce.getServletContext().getAttribute("replyTaskTimer");
timer.cancel();
}
}
In the ReplyTask just read the incoming queue, and send something on an outgoing queue (I suggest using two different queues to ping and pong). You must cancel the timer, that thread will otherwise survive undeployments and redeployments.
Note: If you were using an application server (JBoss for example), you could do that using a Message driven bean (MDB). More elegant and concise, and the threading is managed by the application server. The extra benefit of using an application server like JBoss is the integrated HornetQ JMS provider.

concurrent request to jersey rest service

I am developing a very simple REST web service with Eclipse, Tomcat7 and Jersey implementation, with a connection to MySQL.
Looking to the jersey documentation i know that every request create a new object of the root resource class. But i dont know if every request is independet, for example if one request have to wait a long time, the server will accept more request normaly?
The problem is :
I have 2 main classes, 1 class implements Jersey with annotations(Proxy.java), and other class that connects to a BD(Notificator.java), there is only one instance of this class (Singleton) in order to use only 1 Connection object. The classes who implements Jersey use this class. So, if one of the request is blocked , i dont know if the others will run because they are using the same (Notificator.java) instance.
The relation is N instances of(Proxy.java) uses the only one (Notificator.java) witch have one Connection to a MySQL.
Jersey is developed on top of servlets. There is a new thread for each of the incoming request. Your code is creating a bottleneck for all the threads as there is a contention for single available connection object. If you have multiple requests then only one request will be using that connection and others have to wait. If the wait is not too long then there is no problem. But if wait is more than the HTTP REQUEST TIMEOUT then your other requests may end up as TIMED OUT.
I understand that you may be having single connection bottleneck due to some business requriement/ complication. So in all such cases where we cannot process all the requests simulataneously and there can be variety of reasons for it, then we should create our web services as Asynchronous. Asynchronous web services work on the model of SUBMIT REQUEST-> REQUEST ACCEPTED(will be processed asynchronously) and JOB URL returned for polling-> CLIENT POLLS till the JOB IS NOT COMPLETED.
Hope it helps!
Try database connection pooling, more on this here:
http://en.wikipedia.org/wiki/Connection_pool
How to establish a connection pool in JDBC?

Categories