在微服务架构中设计用于实时通信的 WebSocket 服务器
背景上下文
在许多情况下,Web 应用程序(前端)需要客户端(浏览器)和服务器(后端)之间的实时通信。此类用例的一些示例包括实时提要、实时协作编辑、实时数据可视化、实时聊天、通知、事件更新等。
假设每个用例都有一个微服务;上图将说明如何在客户端(前端)和每个单独的微服务(后端)之间建立 WebSocket 连接。
如上图,这不是一个优雅的设计,因为当微服务的数量增加时,会创建更多的 WebSocket 连接。因此,让我们看看 WebSocket 服务器如何帮助解决这个问题。
WebSocket 服务器设计
微服务架构中 WebSocket 服务器的高级图
在上面的设计中,WebSocket 服务器是唯一与 Web 应用程序(前端)建立 WebSocket 连接的微服务。对于其他微服务,与 Web 应用程序(前端)进行实时通信的主要方式有两种:
单向(后端到前端)
双向(在前端和后端之间)
构建 WebSocket 服务器
基于上述设计使用 Spring Boot、Stomp 和 Redis Pub/Sub 构建 WebSocket 服务器。
第一步:初始化 Spring Boot 项目
初始化一个 Spring Boot 项目。您至少需要 Spring Web、Redis 和 Websocket 依赖项。
第 2 步:配置 WebSocket 和 STOMP 消息传递
创建一个配置文件,WebsocketConfig.kt然后添加下面的配置。该配置为 Spring Boot 应用程序启用 WebSocket 功能。
启用 Spring Boot Websocket 的配置 (WebsocketConfig.kt)
API 端点为微服务(后端)向 Web 应用程序(前端)发送消息提供了一种方式。由于消息只需要单向流(后端 → WebSocket 服务器 → 前端),使用 API 将是微服务(后端 → Websocket 服务器)之间良好的通信方式。
用于向 WebSocket 服务器发送消息的 API 端点
第 4 步:配置 Redis Pub/Sub 以进行双向实时通信(可选)
注意:根据您的场景,如果您不需要 Web 应用程序(前端)和微服务(后端)之间的双向实时通信,则可以省略此步骤。
与使用发布-订阅消息模式相比,微服务(后端和 Websocket 服务器)之间通过 API 进行的通信对于实时通信来说并不是最佳的。因此,对于双向通信,可以使用发布-订阅消息模式。
有很多方法可以实现发布-订阅消息传递模式,但为了演示和简单起见,我们将使用 Redis Pub/Sub。
首先,使用 docker ( docker run — name redis-server -p 6379:6379 -d redis) 在本地运行 Redis 服务器,并将以下配置添加到 application.yml 文件中,以便 WebSocket 服务器连接到 Redis 服务器。
# application.yml
spring.redis:
主机: localhost
端口: 6379
接下来,创建一个配置文件 ,RedisConfig.kt并在下面添加配置。本质上,我们正在配置一个ReactiveRedisTemplate与 Redis 服务器通信并配置为将消息序列化和反序列化为字符串。
@Configurationclass RedisConfig { @Bean fun reactiveRedisTemplate(factory: LettuceConnectionFactory): ReactiveRedisTemplate<String, String> { val serializer = Jackson2JsonRedisSerializer(String::class.java) val builder = RedisSerializationContext.newSerializationContext<String, String>(StringRedisSerializer()) val context = builder.value(serializer).build() return ReactiveRedisTemplate(factory, context) }}
@Serviceclass RedisService( private val reactiveRedisTemplate: ReactiveRedisTemplate<String, String>, private val websocketTemplate: SimpMessagingTemplate) { fun publish(topic: String, message: String) { reactiveRedisTemplate.convertAndSend(topic, message).subscribe() } fun subscribe(channelTopic: String, destination: String) { reactiveRedisTemplate.listenTo(ChannelTopic.of(channelTopic)) .map(ReactiveSubscription.Message<String, String>::getMessage) .subscribe { message -> websocketTemplate.convertAndSend(destination, message) } } @PostConstruct fun subscribe() { subscribe("GREETING_CHANNEL_INBOUND", "/topic/greetings") }}
@Controllerclass WebsocketController(private val redisService: RedisService) { @MessageMapping("/greet") fun greetMessage(@Payload message: String) { redisService.publish("GREETING_CHANNEL_OUTBOUND", message) }}
这样,我们将 WebSocket 服务器设置为充当中间件(或代理),通过 WebSocket 与 Web 应用程序(前端)进行通信,并通过 Redis Pub/Sub 与微服务(后端)进行通信。
测试 WebSocket 连接
测试 #1:从后端向前端发送消息(通过 API)
启动 WebSocket 服务器,并ws://localhost:8080/stomp使用 WebSocket 调试器工具通过 STOMP 协议连接到 WebSocket 服务器。连接后,配置 WebSocket 调试器工具以订阅主题/topic/toast。
接下来,使用以下命令向 WebSocket 服务器发送 HTTP POST 请求:
curl -X POST -d '{"topic": "/topic/toast", "message": "测试 API 端点" }' -H 'Content-Type: application/json' localhost:8080/api/notification
WebSocket 调试器工具应具有如下所示的输出:
测试 #2:从后端向前端发送消息(通过 Pub/Sub)
启动 WebSocket 服务器,并ws://localhost:8080/stomp使用 WebSocket 调试器工具通过 STOMP 协议连接到 WebSocket 服务器。连接后,配置 WebSocket 调试器工具以订阅主题/topic/greetings。
使用 Redis CLI,使用命令将消息发布到通道主题GREETING_CHANNEL_INBOUND PUBLISH GREETING_CHANNEL_INBOUND “\"Test Message from Backend PubSub\"”。
请注意,\”由于 WebSocket 服务器配置为接收字符串消息,因此需要额外的内容。WebSocket 调试器工具应该会收到如下所示的消息
测试 #3:从前端向后端发送消息(通过 Pub/Sub)
启动 WebSocket 服务器,并ws://localhost:8080/stomp使用 WebSocket 调试器工具通过 STOMP 协议连接到 WebSocket 服务器。连接后,使用 Redis CLI,使用命令订阅频道主题GREETING_CHANNEL_OUTBOUND SUBSCRIBE GREETING_CHANNEL_OUTBOUND。使用 WebSocket 调试器工具向 STOMP 目的地发送消息/app/greet,您应该观察以下内容:
概括
总之,完成了微服务架构中 WebSocket 服务器的可能设计。拥有 WebSocket 服务器与微服务的“单一职责原则”非常一致,它管理与 Web 应用程序(前端)的所有 WebSocket 连接,并处理 Web 应用程序(前端)和其他微服务(后端)之间的实时通信.
用户评论
这款游戏真是不一般,还能学习到微服务和WebSocket技术,简直一举两得。
有16位网友表示赞同!
作为一个开发者,这个游戏的开发背景让我很感兴趣。
有11位网友表示赞同!
学到了好多关于服务器建设的新知识,非常实用。
有12位网友表示赞同!
喜欢这种能够边玩边学习的游戏,涨姿势!
有11位网友表示赞同!
游戏里的场景设计得很真实,特别有带入感。
有10位网友表示赞同!
操作简单易懂,即使新手也能轻松上手。
有18位网友表示赞同!
WebSocket技术让游戏中实时互动更加流畅了。
有11位网友表示赞同!
希望这个游戏能继续推出更多关于后端技术的教程。
有18位网友表示赞同!
游戏界面清新简洁,很符合现代审美。
有9位网友表示赞同!
通过这款游戏,我对微服务有了更深入的了解。
有10位网友表示赞同!
非常喜欢游戏里搭建服务器的环节,很有成就感。
有12位网友表示赞同!
和朋友们一起玩这个游戏,感觉团队协作更加紧密了。
有7位网友表示赞同!
学习过程中遇到了难题,社区里的解答让我收获颇丰。
有6位网友表示赞同!
这款游戏的教程很详细,新手也能快速入门。
有9位网友表示赞同!
希望游戏还能增加更多实际的开发案例。
有8位网友表示赞同!
游戏中涉及到的很多知识点我在其他地方都学到了,感觉非常充实。
有17位网友表示赞同!
这个游戏的互动性很强,和其他玩家交流学习很有趣。
有8位网友表示赞同!
喜欢这款游戏的氛围,让人在轻松的环境中学习。
有9位网友表示赞同!
希望游戏开发者能持续优化,让体验更加完美。
有17位网友表示赞同!