Implementing a WebSocket Load‑Balancing Library for Microservice Architectures
This article introduces a Spring‑Boot library that uses a configuration annotation to enable WebSocket load‑balancing across microservice instances, detailing its usage, abstract design, connection management, message routing, and extensibility for various long‑connection protocols.
WebSocket is widely used, but in a microservice architecture a single instance may not receive messages sent by another instance, leading to communication gaps.
For example, when service A has two instances A1 and A2, a client connected to A1 will miss messages broadcast by A2.
The simplest solution is to forward messages from A2 to A1, which then delivers them to the client.
Based on this idea, the author created a library that solves the problem with a single configuration annotation.
Usage
First, add the annotation to the Spring Boot main class:
@EnableWebSocketLoadBalanceConcept
@EnableDiscoveryClient
@SpringBootApplication
public class AServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AServiceApplication.class, args);
}
}Then inject WebSocketLoadBalanceConcept where messages need to be sent:
@RestController
@RequestMapping("/ws")
public class WsController {
@Autowired
private WebSocketLoadBalanceConcept concept;
@RequestMapping("/send")
public void send(@RequestParam String msg) {
concept.send(msg);
}
}This makes cross‑instance message sending straightforward.
Abstract Design
The problem is abstracted as a "long‑connection cluster solution" applicable to WebSocket, TCP, or any other persistent connection.
A top‑level Connection interface is defined, with concrete implementations such as WebSocketConnection and TCPConnection . Even short‑lived protocols like HTTP can be wrapped in a HTTPConnection for uniform handling.
Connection Subscriber
An interface ConnectionSubscriber represents a service instance subscribing to messages from other instances. A default implementation uses the native protocol, while custom subscribers (e.g., MQConnectionSubscriber , HTTPConnectionSubscriber ) can be provided.
Service Instance Discovery
The ConnectionServerManager interface manages instance information. By leveraging Spring Cloud discovery (Eureka, Nacos, etc.), the library obtains all instances via DiscoveryClient#getInstances() , excludes the current one, and establishes bidirectional connections.
Heartbeat detection and automatic reconnection ensure resilience in unstable networks.
Connection Management
Connections are classified into real client connections and forwarding connections, then managed centrally. A ConnectionFactory adapts any concrete connection to the generic Connection type.
Each connection is equipped with a MessageEncoder and MessageDecoder . Because different connection types require different encoding, a MessageCodecAdapter abstracts these variations.
Message Sending and Selection
When a message is sent, it is forwarded to selected connections. The library provides a ConnectionSelector to determine the target set, similar to Ribbon’s IRule for server selection.
Selectors can filter by metadata such as user ID or path. The library includes ready‑made selectors:
UserSelector with UserMessage for sending to a specific user.
PathSelector with PathMessage for topic‑based routing.
Metadata is stored in the Connection object, while message headers carry routing information.
Extensibility
Developers can implement custom Connection types (e.g., Redis, MQTT) and corresponding selectors to fit unique scenarios.
Overall, the library abstracts the core concepts—connection, message, subscriber, selector—allowing flexible, scalable, and maintainable long‑connection communication across microservice clusters.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.