Can I globally set the timeout of HTTP connections

2019-03-17 23:59发布

问题:

I have a program that uses javax.xml.ws.Service to call a remote service defined by a WSDL. This program runs on the Google App Engine which, by default, sets the HTTP connection timeout to 5 seconds{1}. I need to increase this timeout value since this service often takes a long time to respond, but since this request is not being made with URLConnection, I cannot figure out how to call URLConnection.setReadTimeout(int){2}, or otherwise change the timeout.

Is there any way to globally set the HTTP connection timeout on the App Engine? And, for purposes of sharing knowledge, how would one go about solving this sort of problem generally?

{1}: https://developers.google.com/appengine/docs/java/urlfetch/overview#Requests

{2}: http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URLConnection.html#setReadTimeout(int)

回答1:

You could try setting the sun.net.client.defaultConnectTimeout and sun.net.client.defaultReadTimeout system properties documented here, e.g.

System.setProperty("sun.net.client.defaultReadTimeout", "30000");
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");

EDIT

Sorry, just re-read and noticed this is on Google App Engine. I don't know for sure, but given the litigious relationship Google and Oracle have lately, I'm guessing GAE doesn't run the Oracle JVM. I'll leave this here in case someone else runs into a similar problem.



回答2:

Try this:

Port port = service.getPort(endPointInterface);  //or another "getPort(...)"
((BindingProvider) port).getRequestContext()
    .put(BindingProviderProperties.REQUEST_TIMEOUT, 30);


回答3:

See https://developers.google.com/appengine/docs/java/urlfetch/usingjavanet

You can do something like this to get a URLConnection:

    URL url = new URL("http://www.example.com/atom.xml");
    URLConnection tempConnection = url.openConnection();
    tempConnection.setReadTimeout(10);


回答4:

For App Engine with JAX-WS you have to set the request context (tested today with SDK 1.9.15). For normal machines you cannot go higher than 60s and would have to switch to the bigger machines (Bx) for better use a task queue.

For local testing you would normally use BindingProviderProperties.CONNECT_TIMEOUT and BindingProviderProperties.REQUEST_TIMEOUT, but they are not on the App Engine JRE White List and your code inspection might constantly warn you about that. The equivalent strings can be used though:

com.sun.xml.internal.ws.connect.timeout
com.sun.xml.internal.ws.connect.timeout

For deployment to App Engine:

com.sun.xml.ws.connect.timeout
com.sun.xml.ws.request.timeout

A full example how to apply that to auto-generated code from JAX-WS 2.x, values have to be provided in milliseconds:

@WebEndpoint(name = "Your.RandomServicePort")
public YourServiceInterface getYourRandomServicePort() {
    YourRandomServiceInterface port = super.getPort(YOURRANDOMSERVICE_QNAME_PORT, YourRandomServiceInterface.class);
    Map<String, Object> requestContext = ((BindingProvider)port).getRequestContext();
    requestContext.put("com.sun.xml.ws.connect.timeout", 10000);
    requestContext.put("com.sun.xml.ws.request.timeout", 10000);
    return port;
}