I am writing an application which uses web services to connect a remote server.I have written a method to ping function to determine if the server is online or not(i.e. its providing the web services which can be accessed using host:port).I am executing a simple web service with a 2 sec timeout(available as an option in stub class before I make the call).Ideally the call should return within 2 seconds allowing me to ascertain whether the server is up or down.However in certain cases it takes far longer than 2 seconds.
Can anyone help me figure out why this is happening?Is there a way to ensure that the timeout value is honored ?
Thanks,
Fell
In Axis client stubs, there is an option for you to set the timeout. You can also use it. Note that the time-out is measured in milliseconds. check here
And if it is Axis2, you can use like this:
Stub s = new Stub();
ServiceClient sc = s.getServiceClient();
Options o = sc.getOptions();
o.setTimeOutInMilliSeconds(2000); //2 seconds
sc.setOptions(o);
s.setServiceClient(sc);
You can make your calls after setting the above stuff.
Don't use the default http sender, switch to commons http client based sender. Details are here - http://wiki.apache.org/ws/FrontPage/Axis/AxisCommonsHTTP - Same page has details on how to set various kinds of timeouts as well.
Related
I have a few servers that I make REST requests to from my program. They will all have the same response to a particular request.
I accept one ip as argument and make my requests to that server. If I wish to now accept a List<ip>, how do I elegantly switch to the next server in the list when one fails? Looping through the list on every network call seems silly.
Unfortunately I cannot make a REST call with the catch-repeat_to_next_server extracted to one function that accepts an HttpClient with the rest of the request because I'm using a 3rd part SDK to talk to the servers and every request is a chain of method calls.
I can't do this (pseudo-code):
def doRequest(HttpClient client)
for ip in list_of_ips:
try:
client.host = ip
return client.execute()
catch exp:
// move failed ip to end of list or something
throw "None of them worked"
HttpClient c
c.method = "GET /api/employees"
doRequest(c)
c.method = "GET /api/department/:id"
doRequest(c)
Are there any standard ways to solve this in clean way?
I'm using Java and Spring so I am constrained by static typing but may have some sort of Spring annotation magic that I can use that I am not aware of.
How you are making the REST call is not important.
Your psuedo code should be correct even if you need to make a million method calls per REST call.
for ip in ip_list
do_stuff_to_make_the_rest_call
perhaps_note_the_ip_that_was_used
indicate_success
break_out_of_for_loop
catch some_exception
perhaps_note_the_ip_that_failed
end for
if !success
do all_ip_failed_stuff.
procedure do_stuff_to_make_the_rest_call
make a million method calls to get one REST call attempt.
I have tried TSimpleServer, THsHaServer and TThreadedSelectorSever but none of them worked for my use case where I need to scale. My server needs to receive lots of data but right now when I use the servers listed above the receive rate is 600KB which is very low when compare to other servers which can receive 6MB using one socket. I am bound by thrift and I need to find a way to get through!
Basically I have a service written in C++ and JAVA (same service written in two different languages) and we are trying to see which one has high throughput). with the C++ service we dont use any thrift server. we created our own non blocking server which uses one thread to accept the requests and passes it on to threadpool where the methods gets executed but with the Java service I tried TSimpleServer, THsHaServer and TThreadedSelectorSever and the performance was not great and when I run the profiler the one that seems to hotspot is the following method
org.apache.thrift.server.TNonblockingServer$SelectAcceptThread.run() 456
I have no idea what is going on underneath the thrift source code.
Benchmark results: C++ service 35K/sec(requests per seconds) and Java 2500/sec (request per second) Again they are executing the same methods, same service written in two different languages.
My code for one of the server is as follows. I have tried others as well as mentioned above but no peformance gain
TTransportFactory tTransportFactory = new TFramedTransport.Factory();
TNonblockingServerTransport tNonblockingServerTransport = new TNonblockingServerSocket(7911);
PersistenceService.AsyncProcessor<?> processor = getAsyncProcessor(serviceName);
Factory protocolFactory = new TBinaryProtocol.Factory(true, true);
THsHaServer.Args serverArgs = new THsHaServer.Args(tNonblockingServerTransport);
serverArgs.processor(processor);
serverArgs.transportFactory(tTransportFactory);
serverArgs.protocolFactory(protocolFactory);
TNonblockingServer tNonblockingServer = new THsHaServer(serverArgs);
System.out.println("Starting persistence server on port 7911 ...");
tNonblockingServer.serve();
I'm looking for the best solution to solve this problem :
I have a client and a server.
The client sending request to the server using the call.invoke method.
The call for now is synchronous and waiting for the answer.
The time is taking to receive the replay from the server under load is around 1 sec(this is a lot of time).
at the client side we are generating requests around 50-100 request per second , the queue is exploding.
For now i just created a thread pool that will work asynchronous and will send the requests to the server per thread , but the request it self will be synchronous.
The meaning of that is that the thread pool should maintain ~100 threads if we do want that it will work fine.
I'm not sure this is the best solution.
I also was thinking to create somehow 1 thread that will send the requests and 1 thread that will catch the replays, but then i'm afraid that i will pass on the load to the server side.
Few things that are importent:
We cannot effect the code on the server side and we cannot control the time it takes to receive a replay.
while receiving the replay we just use this data to create another data structure and pass it on - so the time stamp is not relay importent.
we are using axis api.
any idea of how is it the best way to solve it? the thread pool of the 100 thread seems fine ? or there some other ways?
Thanks!
You can call axis service using non-blocking client way by registering the callback instance.
Client class:
ServiceClient sc = new ServiceClient();
Options opt= new Options();
//set the target EP
opt.setTo(new EndpointReference("http://localhost:8080/axis2/services/CountryService"));
opt.setAction("urn:getCountryDetails");
sc.setOptions(opt);
sc.sendReceiveNonBlocking(payload, callBack);
// inner class with axisCallback , overide all its methods. onMessage get called once result receive from backend
AxisCallback callBack = new AxisCallback() {
#Override
public void onMessage(MessageContext msgContext) {
System.out.println(msgContext.getEnvelope().getBody().getFirstElement());
//this method get called when you received the results from the backend
}
...
}
Reference for writing axis service : http://jayalalk.blogspot.com/2014/01/writing-axis2-services-and-deploying-in.html
I'm using Apache Axis to make a SOAP request to a service. I noticed that sometimes, it take a couple of seconds to get a response even though the service is a simple echo for now. So I'm wondering if establishing the connection is what takes the time, even though the server does HTTP/1.1 connection keep alive.
Should somehow reuse the client between requests or if it's ok to get a new one for every request?
This is my code. Should I keep locator and/or client around between requests or is it okay to forget it?
MyExampleServiceLocator locator = new MyExampleServiceLocator();
MyExampleServicePort client = locator.getMyExampleServicePort(url);
MyExampleRequest request = buildMyExampleRequest();
MyExampleResponse response = client.send(request); // This takes time sometimes
For complex services the cost of instantiating the locator may be high. Therefore you should always try to reuse it as much as possible. Locators are expected to be thread safe, so you can use them as singletons. Note however that in Axis 1.4 there is at least one thread safety issue regarding locators: AXIS-2498.
Creating a new stub (client) is less expensive, but reusing a stub is unproblematic. They are also expected to be thread safe (at least in Axis 1.4), except for scenarios that use the stub in a stateful way (e.g. HTTP sessions).
Axis' default HTTP transport only supports HTTP 1.0 and creates a new connection for every request.
I have a Java web service client running on Linux (using Axis 1.4) that invokes a series of web services operations performed against a Windows server. There are times that some transactional operations fail with this Exception:
java.net.SocketTimeoutException: Read timed out
However, the operation on the server is completed (even having no useful response on the client). Is this a bug of either the web service server/client? Or is expected to happen on a TCP socket?
This is the expected behavior, rather than a bug. The operation behind the web service doesn't know anything about your read timing out so continues processing the operation.
You could increase the timeout of the connection - if you are manually manipulating the socket itself, the socket.connect() method can take a timeout (in milliseconds). A zero should avoid your side timing out - see the API docs.
If the operation is going to take a long time in each case, you may want to look at making this asynchronous - a first request submits the operations, then a second request to get back the results, possibly with some polling to see when the results are ready.
If you think the operation should be completing in this time, have you access to the server to see why it is taking so long?
I had similar issue. We have JAX-WS soap webservice running on Jboss EAP6 (or JBOSS 7). The default http socket timeout is set to 60 seconds unless otherwise overridden in server or by the client. To fix this issue I changed our java client to something like this. I had to use 3 different combinations of propeties here
This combination seems to work as standalone java client or webservice client running as part of other application on other web server.
//Set timeout on the client
String edxWsUrl ="http://www.example.com/service?wsdl";
URL WsURL = new URL(edxWsUrl);
EdxWebServiceImplService edxService = new EdxWebServiceImplService(WsURL);
EdxWebServiceImpl edxServicePort = edxService.getEdxWebServiceImplPort();
//Set timeout on the client
BindingProvider edxWebserviceBindingProvider = (BindingProvider)edxServicePort;
BindingProvider edxWebserviceBindingProvider = (BindingProvider)edxServicePort;
edxWebserviceBindingProvider.getRequestContext().put("com.sun.xml.internal.ws.request.timeout", connectionTimeoutInMilliSeconds);
edxWebserviceBindingProvider.getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", connectionTimeoutInMilliSeconds);
edxWebserviceBindingProvider.getRequestContext().put("com.sun.xml.ws.request.timeout", connectionTimeoutInMilliSeconds);
edxWebserviceBindingProvider.getRequestContext().put("com.sun.xml.ws.connect.timeout", connectionTimeoutInMilliSeconds);
edxWebserviceBindingProvider.getRequestContext().put("javax.xml.ws.client.receiveTimeout", connectionTimeoutInMilliSeconds);
edxWebserviceBindingProvider.getRequestContext().put("javax.xml.ws.client.connectionTimeout", connectionTimeoutInMilliSeconds);