Scaling Containers
Several containers of the same application share the load, but not every part of TX Text Control .NET Server can move freely between them. The Document Viewer and your document processing endpoints can answer from any container, while an editing session in the Document Editor lives in exactly one of them. Whoever sets up the load balancer in front of the containers needs to know which requests must stay together.
What Each Part Needs From the Load Balancer
| Part | State between requests | Distribution |
|---|---|---|
| Document Viewer | None. Each request of the viewer carries the document data. | Any instance |
Your endpoints with ServerTextControl and MailMerge | Only what your own code keeps | Any instance, unless your code keeps state in memory |
| Document Editor | The document of a session lives in a worker process of one backend, and the connection in one application instance | Sticky sessions: all connections of an editor go to the same instance |
Behind a load balancer without affinity, the page with the viewer can come from one instance while another instance answers all requests of the viewer, including a search.
Why the Document Editor Needs Sticky Sessions
An editor keeps a WebSocket connection open for as long as it's used. The instance that accepts the connection passes it to its backend, which holds the document in a worker process. Without affinity, the editor still loads, because each connection stays on the instance that accepted it. The problems start later:
- Reconnects. When a connection drops, for example because a proxy restarts, the editor reconnects to its session with its connection ID. Only the backend of the instance that holds the session knows the ID, so a reconnect that reaches another instance fails and the unsaved changes are lost, as Reconnecting Fails Behind a Load Balancer describes. With sticky sessions, the editor reconnects to its instance and keeps the document.
- Server code for a session.
WebSocketHandler.GetInstancefinds the handler of a connection only in the application instance that holds the connection. A controller that saves or changes the document of an editor this way, as in Reach a Session on the Server, must receive its requests on the same instance.
Configure sticky sessions, also called session affinity, at the load balancer, so that all requests and WebSocket connections of a browser go to the same instance. Host the Connection describes the affinity settings of Azure App Service and YARP, and The Life of an Editing Session how the editor reconnects.
Choose a Layout
Instances With Their Own Backend
Each container runs the image from Dockerfile with its application and its backend. The load balancer distributes browsers across the containers with sticky sessions. This layout needs no further configuration, and each container scales application and backend together.
Separate Backend Containers
When the backend runs in containers of its own, as described in Multiple Processes, a second hop needs attention. UseTXWebSocketMiddleware resolves the name of the backend once, when the application starts, and connects every editor of this application instance to that one address. It doesn't distribute connections across several backends.
- One backend per application instance. Pair each application instance with a backend of its own. The sticky sessions of the load balancer then keep an editor on both.
- Several backends behind one address. A reconnect only succeeds if it reaches the backend that holds the session, so the component in front of the backends must keep each application instance on the same backend, for example with affinity by client IP address.
Separate Document Processing
A document processing service needs no sticky sessions and can scale on its own. For many concurrent users, Text Control recommends running it apart from the application instances and the backend, as Container Scaling describes with the sizing of each workload.
When Containers Stop or Are Replaced
- Stopping an instance ends its editing sessions. When the application shuts down, it stops its backend and the worker processes with the documents of all open editors. Unsaved changes are lost, so save documents regularly; the blog article Best Practices: Reliable Auto-Save in TX Text Control Using the WebSocketHandler and Background Services saves them on the server.
- A replaced backend container can have a new address. Application instances resolved the name of the backend when they started. Restart them after the backend container was recreated.
- Scaling in removes sessions as well. Each instance that a platform removes takes its open editing sessions with it.
Licensing
Each running instance of your application, such as a container that a platform starts when the load grows, needs its own runtime license. For deployments whose number of instances changes automatically, Text Control offers an unlimited runtime license. See Runtime Licenses and OEM / Unlimited Runtime.
Next Steps
- Kubernetes: run and scale the containers in a cluster.
- Multiple Processes: the backend in its own container.
- Document Editor Architecture: editing sessions, reconnects and sizing.
- Performance and Scalability: tune the instances for load.