集群方案如下:
- 采用Redis的订阅与发布,由于Websocket无法被序列化,不能进行缓存,所以不能直接将websocket消息缓存到Redis中。
- 采用单纯的RabbitMQ,利用fanout\topic进行消息订阅,将Websocket消息结果发送到消息队列中,在进行转发接收。参考代码
- 采用RabbitMQ+MQTT消息协议,可以在RabbitMQ官网上看到
- 采用RabbitMQ+STOMP消息协议,可以在RabbitMQ官网上看到【推荐使用】
- 还能够利用负载均衡的源地址哈希法,将ip通过一定的hash算法转发到一台固定的服务器(这个的话,对代码几乎没有改动,不过缺点也比较大)
接下来介绍如何使用RabbitMQ+STOMP,代码如下
maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--websocket 相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
配置文件
spring:
rabbitmq:
host: 192.168.66.10
port: 5672
username: guest
password: guest
RabbitMQ配置类
@Configuration
public class RabbitConfig {
@Bean
public Queue helloQueue() {
return new Queue("hello");
}
}
Websocket配置类
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
/**
* 配置简单的消息代理
*/
config.enableSimpleBroker("/topic","/all");
/**
* 客户端发送过来的消息,需要以"/app"为前缀,再经过Broker转发给响应的Controller
*/
config.setApplicationDestinationPrefixes("/app");
}
@Override
public