WS-Trust, WS-SecureConversation performance issues / Client Caching
I'm having some problems with performance of (or at least confusion around) WS-Trust and WS-SecureConversation. I have a set of around 10 web services that are all used by a web based frontend. My problem is that I'm unable to get good response times from the services without making huge memory sacrifices. I'll explain what I've tried:
The services were all initial secured with WS-Trust and we would create a ws clients from the UI as needed. So, a user would click a button on the web page which generated a request which in turn would create 2 or 3 ws clients and make calls, then return some result back to the UI. This was painfully slow and very CPU intensive.
So, we tried enabling WS-SecureConversation in an attempt to make things better. This had the effect of making things even slower since the ws-client had such a small lifetime (a single request from the UI).
Next we attempted to cache the clients. We implemented a thread local cache of ws clients, so each thread would get a set of clients. We turned on automatic WS-SecureConversation renewal and set the SC Session lifetime to 10 minutes. This made the UI much faster. The first time you clicked something in the UI it might take some time, but after that the response was nearly instant. The only problem now is that we get heap space errors and crashes. If the server was busy, tomcat would create around 30-40 threads, each thread had 10 ws clients, so you end up with 300-400 ws clients each wutg SecureConversation sessions open. This is further complicated by the fact that the SC sessions are not renewed unless a request is made when the session is about to expire. If you attempt to renew after the session is expired, you get an exception, but the memory consumed on the server side from having a SecureConversations session open is not released. (This was with metro 2.0.1. Perhaps this is fixed?)
So, we decided to disable SC automatic renewal and implement our own form of renewal. When we create the ws clients, we put them in a cache with an expiration time. After that expiration time, a new client will be created on the next request instead of returning the cached client. We have a separate thread that periodically goes through all ws clients and calls Close() on the expired ones. We have some occasional strange behavior with this approach, but it more or less works.
I keep thinking there has to be a better way. Am I doing something wrong? Is there anyone else who calls WS-Trust protected services from a web UI?
We've recently updated to Metro 2.2, but that was after we had all this implemented. We were previously on 2.0.1. If anything I described should have been fixed in 2.2, please let me know.