Load Balancing Web Services with WebSEAL
I came across this bit of information from an old email from several years ago, and wanted to capture it here for future reference.
In case you're thinking of using a WebSEAL server as a proxy for a web service based application (SOAP or REST), there are some details you need to be aware of in how you tune your servers for a successful implementation.
The advantage to using a WebSEAL server for proxying web service traffic is that you can enforce authorization based on the client ip address (typically a client web application). This isn't as strong of security as performing authenitcation and authorization using WS-Security or SAML, but if these options aren't available, WebSEAL can increase the security by only allowing certain ip addresses to access the application using POPs (Protected Object Policies).
What you have to be aware of is the fact that the client opening the connection to the WebSEAL server is typically another application. This creates a problem if the application attempts to cache open connections (using a connection pool) using HTTP KeepAlive. By defaut, WebSEAL will allow KeepAlive requests to stay open for a maximum of 5 seconds (persistent-con-timeout setting in the [server] stanza). If the client application is running on WebSphere using either IBM JAX-RPC or JAX-WS implementation, the application server will also cache open connections for 5 seconds.
The problem is that WebSEAL starts counting 5 seconds when the last packet is sent to the client, while the client application server starts counting when the last packet is received, which may be a few miliseconds after the WebSEAL starts counting. The result is that when WebSphere takes a connection from the connection pool WebSEAL may have already closed the connection, and the result is that the client application is thrown a WebServiceFault exception. This race condition is small, and unlikely, but when you are dealing with a client application which is calling a backend web service thousands or millions of times a day, the condition will occur.
There is no way to turn off this feature within WebSphere and the work-around in WebSphere is to enable the JVM parameter: com.ibm.websphere.webservices.http.requestResendEnabled=true
This parameter instructs WebSphere to re-attempt the request from the client application upon failure. The problem with this approach is that WebSphere will attempt to re-use an already open connection, which has the same possible race condition.
The fix is to increase the persistent-con-timeout parameter in the WebSEAL configuration. If you do this you will also need to increase the setting for all backend applications as well to avoid the same condition there.
In case you're thinking of using a WebSEAL server as a proxy for a web service based application (SOAP or REST), there are some details you need to be aware of in how you tune your servers for a successful implementation.
The advantage to using a WebSEAL server for proxying web service traffic is that you can enforce authorization based on the client ip address (typically a client web application). This isn't as strong of security as performing authenitcation and authorization using WS-Security or SAML, but if these options aren't available, WebSEAL can increase the security by only allowing certain ip addresses to access the application using POPs (Protected Object Policies).
What you have to be aware of is the fact that the client opening the connection to the WebSEAL server is typically another application. This creates a problem if the application attempts to cache open connections (using a connection pool) using HTTP KeepAlive. By defaut, WebSEAL will allow KeepAlive requests to stay open for a maximum of 5 seconds (persistent-con-timeout setting in the [server] stanza). If the client application is running on WebSphere using either IBM JAX-RPC or JAX-WS implementation, the application server will also cache open connections for 5 seconds.
The problem is that WebSEAL starts counting 5 seconds when the last packet is sent to the client, while the client application server starts counting when the last packet is received, which may be a few miliseconds after the WebSEAL starts counting. The result is that when WebSphere takes a connection from the connection pool WebSEAL may have already closed the connection, and the result is that the client application is thrown a WebServiceFault exception. This race condition is small, and unlikely, but when you are dealing with a client application which is calling a backend web service thousands or millions of times a day, the condition will occur.
There is no way to turn off this feature within WebSphere and the work-around in WebSphere is to enable the JVM parameter: com.ibm.websphere.webservices.http.requestResendEnabled=true
This parameter instructs WebSphere to re-attempt the request from the client application upon failure. The problem with this approach is that WebSphere will attempt to re-use an already open connection, which has the same possible race condition.
The fix is to increase the persistent-con-timeout parameter in the WebSEAL configuration. If you do this you will also need to increase the setting for all backend applications as well to avoid the same condition there.
Comments