There comes a point in time when one server is just not enough. You need to scale your service across multiple back-ends. Enter Windows Network Load Balancing (a.k.a. NLB). By using NLB, TCP connection initiations can be serviced by different machines.
This has an obvious impact on in-memory sessions. If you are using a protocol such as WS-Reliable Messaging (which will reestablish connections during the course of a session) or WS-Secure Conversation (which uses a session-negotiated security token), then you want to make sure subsequent connection requests go to the same back-end server. Similarly, when using a transport such as HTTP (which can in worst case scenarios use a new connection for each request-reply), if you are depending on an in-memory session then you will also need to ensure consecutive connection establishments arrive at the same server. Many load-balancer have an “affinity” setting that you can set to enable this behavior. Alternatively you can write a “state-less” service (from the in-memory perspective), where any app state is stored outside of your process. If you take this approach then you should avoid using WCF Sessions (which may store infrastructure state in-process).
Nicholas gave a nice overview of our Transport quotas. We have a few knobs on the TcpTransportBindingElement specifically targeted for NLB-type scenarios. They are associated with our client-side connection pooling. Nicholas highlights the final object model for these quotas, and I’ll go into a little detail about how these quotas will effect your use of NLB with our TCP transport.
- IdleTimeout: Controls the amount of time that a TCP connection can remain idle in our connection pool. This is useful for scenarios where you don’t mind connections being reused when you are under load, but when the load dissipates you wish to reclaim your connection. The default value of IdleTimeout is 2 minutes.
- LeaseTimeout: Controls the overall lifetime of a TCP connection. The lower you set this value, the more likely you will be re-load balanced when you create a new channel. Note that if this timeout expires we won’t just fault an existing connection. We will however close that connection when you Close() the active channel. This setting works well in conjunction with IdleTimeout. For example, if you are cycling through channels, and you are never really “idle”, you can still ensure periodic connection recycling through LeaseTimeout. The default value of LeaseTimeout is 5 minutes.
For HTTP we inherit our connection pooling settings from System.Net, so you can tweak their idle settings in order to control connection recycling frequency over HTTP.