状況は次のとおりです。
私は Axis2 1.6.2 を使用し、2 つの Web サービス用に( wsdl2javaを使用して) スタブを生成しました。それらをWS#1およびWS#2と呼びましょう。
BasePoolableObjectFactory (org.apache.commons.pool.BasePoolableObjectFactory) を拡張する StubPoolableFactory を実装することで、スタブのプーリング メカニズムを使用します。
これを実現するために、スタブはシングルトンとして作成されたアダプタによって「ラップ」されます。Adapter のスケルトンは次のようになります。
/** The Adapter class */
public class PdfServiceAdapter extends PoolableStubAdapter<PdfServiceStub> {
/** The Singleton. */
private static PdfServiceAdapter pdfServiceAdapter;
/**
* Gets the PdfService adapter instance.
*
* @return the PdfService adapter
*/
public synchronized static PdfServiceAdapter getPdfServiceAdapter() {
if (null == pdfServiceAdapter) {
pdfServiceAdapter = new PdfServiceAdapter();
pdfServiceAdapter.initiateStubPool();
}
return pdfServiceAdapter;
}
public void doSomething() throws AdapterException {
try {
stub = getStub();
} catch (final Exception e) {
throw new AdapterPreparationException(e);
}
try {
//call some actual Stub method here...
} catch (final Exception e) {
stopWatch.stop("PdfService.doSomething.FAILURE");
throw new AdapterExecutionException(e);
} finally {
final ServiceClient client = stub._getServiceClient();
if (client != null) {
try {
client.cleanupTransport();
client.cleanup();
} catch (final AxisFault e) {
log.warn("Something went wrong while cleaning up service client: ", e);
}
}
releaseStub(stub);
}
}
@Override
protected int getMaxActive() {
return Integer.parseInt(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_MAX_ACTIVE"));
}
@Override
protected boolean getLifo() {
return Boolean.parseBoolean(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_LIFO_FLAG"));
}
@Override
protected int getMaxIdle() {
return Integer.parseInt(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_MAX_IDLE"));
}
@Override
protected long getMaxWait() {
return Integer.parseInt(ESignatureConfig.getInstance().getConfig().getString(
"AXIS_STUB_POOL_EREQUEST_COMMUNICATION_MAX_WAIT"));
}
@Override
protected String getEndPointURL() {
return ESignatureConfig.getInstance().getConfig().getString("PDF_SERVICE_ENDPONT");
}
@Override
protected Stub getInstance() throws Exception {
return new PdfServiceStub(AxisConfigurationContextFactory.getInstance().getConfigurationContext());
}
}
スタブのインスタンスを要求するとわかるように、軸構成がスタブに渡されます。この Axis 構成はファクトリから返されます。これは Singleton であり、キャッシュされた HTTP client を持つ MultiThreadedHttpConnectionManager に基づいています。
さて、問題はどこにありますか:
- Web サービスを長時間呼び出した後、 WS#1を呼び出して WS #2の直後に呼び出すと、WS#2 を呼び出すときに Connection Reset エラーが発生することがあります。この接続がリセットされた後、すぐに WS#1 と WS#2 をもう一度呼び出しても問題ありません。
- また、アプリケーションのストレス テストを行っても問題はありません。アイドル状態にして、「back 2 back」 WS#1および WS#2 を呼び出した場合にのみ、常に WS#2 呼び出しで接続のリセットが発生します。
これは私の実装と関係があると思いますか? おそらく、Singleton Axis 構成またはキャッシュされた HTTP クライアントが状況によっては、このリセットの原因になるのでしょうか?