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?
Related
I am using spring boot to make a mock of one of our more complicated services. While all of the standard cases are easily done there is one that is causing me some troubles. It is theoretically possible for the application I am mocking to crash and close the connection without sending a response.
I tried several things to achieve this in spring boot without actually having my mock to crash. This includes throwing exceptions that go into an exception handler and from there do not properly response, however so far that either has generated an error response by spring or somehow resolved to an empty response.
Is there an option to have a method in a #Conroller to cause a closed connection without any response?
Closing the connection is the responsibility of HTTP specification and protocol. You cannot enforce it programmatically. Connection negotitation is happening between HTTP Client and HTTP Server.
Although you can try interrupting current Thread or setting header Connection: close, but you should not be messing around with that part of the processing of a Connection and Request. Your HTTP server can start behaving unexpectedly.
Try a different approach. If you need to simulate a closed connection you can programmatically allocate a new instance of HTTP server, send a request to it, put request processing on hold and kill an instance is a separate thread. I'm sure you'll find a better way for this, just get to the root of the problem from a different angle.
You can create method like this:
#ResponseBody
#RequestMapping("/your-url")
public String test() {
return null;
}
you can also change #Controller to #RestController and remove the #ResponseBody
I have a REST service defined in Spring Boot, which exposes a synchronous REST API, to be invoked by a user from a Web based UI. The service is expected to provide a real time response.
The service talks to an external endpoint in an asynchronous fashion. That is:
- A single one - way outbound message for the request
- A single one - way inbound message for the response
How can I combine the two messages to provide an impression of a synchronous behavior? I am thinking of a few approaches like:
The Rest Service posts a request to the endpoint. Once the endpoint responds, the response is added to a ConcurrentHashMap. The Rest Service queries the HashMap every few milliseconds and once it finds the right response it exits with a valid HTTP reason code.
It is akin to polling and I am thinking if we can avoid that.
The Rest Service posts a request to the endpoint. Once the endpoint responds, the waiting thread in the Rest Service is notified. However the waiting thread should conclude only if the right response is received (i.e. matching correlation Ids etc.)
Is this possible?
I realize that this is similar to a JMS Queue Request Response scenario, where each JMS queue request opens up a listener on the response queue with a message selector criteria.
However in this case I have to implement this using HTTP.
Any thoughts on this are welcome. I am fully convinced I am missing something very basic, but am not sure what.
Thanks a lot!
How to implement one-way operation in Web Services (using Java or Spring annotations)?
I have tried to add one way as given below
#WebService
public interface DanduServices {
#Oneway
public void saveDanduInformation(#WebParam(name = "serv") ServDTO Serv, #WebParam(name = "dandu") DanduDTO danduDto);
but it is still request-response not asynchronus or one way.
Could anyone suggest to make a operation one-way in service endpoint and let other operations behave as per request-response?
You need to think in terms of the protocol as well though. In HTTP when you send a request you wait for a response, if no response comes back after an amount of time then you will receive a time-out error. So when you talk about one-way (you should rather say async request maybe) you really need to specify exactly what you mean. Do you want to have confirmation that your message was received i.e. have the server respond back with an OK status code and go off and complete it's task but you not wait for the task to be completed? Then you would need to spawn another thread. Spring has AOP for this the same way it has for transactions with #Transactional. Instead you annotated your method with #Async and return a Future<Something>. You'll also need #EnableAsync in your config. Refer to this article for an example Hot To Do #Async
If you don't even care about if the server received your request you don't want to use TCP/HTTP but instead UDP which is used in VOIP (phone over internet) for instance and is quicker, but it will depend on your client.
Create a javax.ws.rs-ap.jar client and send the request to the server:
javax.ws.rs.client.Client client = ClientBuilder.newBuilder().build();
I have writtten the above code to call multiple api(get user by id, get all users and deleteUser).
My question is here.
I am creating a new Client for each api cal.
Just wanted to know i can create a single instance of Client and make multiple calls ?
Yes, a Client can be reused as long as it's lifecycle is managed properly. This means when a client instance is created, it should be closed properly as well using the close() method, once it's purpose is served. Refer to the Client API documentation.
Note that multiple client instances would be needed if each client has a different client configuration.
I am using jersey client to send POST requests to a third party webservice. Since creating jersey clients is expensive, I am doing this inside the constructor of a service client class which is Spring managed. My thinking is that when my server starts up, Spring will create my service client bean, which in turn will cause the constructor to be invoked and so my jersey client will be created once. As long as the server is up, this jersey client will be responsible for sending out the requests and no further client initializations are required. However, I will be creating a new webresource for each call as creating jersey webresources is much cheaper.
package com.mypackage;
//Bunch of imports
class MyWebserviceClient {
//jersey client member variable
private Client jClient;
public MyWebserviceClient(){
//Create jersey client
jClient = Client.create();
//Other stuff
}
public void sendRequest(){
WebResource wr = jClient.resource(someUrl);
//Use the webresource to make webservice call
}
}
MyWebserviceClient is spring managed as such in the Spring config xml:
<bean id="myClient" class="com.mypackage,MyWebserviceClient"></bean>
The bean myClient will then be injected into the appropriate place where the service call needs to be made.
My questions
1) If my application is dealing with thousands of requests per hour is it efficient enough to handle all the requests with just one jersey client.
2) Do I need some kind of jersey client pool so that a large number of requests are taken care of more efficiently. If so, is there a way to do it?
3) I would like to know in general how multiple requests coming in from the end users are handled on the server side. Each request is a separate thread of execution on the server and all of them have access to the same jersey client object. If the jersey client object is busy with one such request, are the other requests from different end users going to wait till a response is received for the ongoing request?
4) Any better alternative to the one I am using.
Your thinking is right on track.
1 - Yes, and it is recommended to reuse a client instance:
from https://jersey.java.net/documentation/1.18/client-api.html#d4e623:
Client instances are expensive resources. It is recommended a configured instance is reused for the creation of Web resources. The creation of Web resources, the building of requests and receiving of responses are guaranteed to be thread safe. Thus a Client instance and WebResource instances may be shared between multiple threads.
2 - No need, the client itself can handle the requests. In the case of asynchronous requests, it internally uses a thread pool that is configurable.
3 - The Jersey client is thread safe, so threads will not block each other
4 - You can also consider providing the client as a dependency to MyWebserviceClient, and possibly reuse the same client between multiple classes