当前位置: 首页 > 后端技术 > Java

浅谈分布式环境下的WebSocket消息共享

时间:2023-04-01 21:04:52 Java

浅谈分布式环境下的WebSocket消息共享技术分析我们在开发中会遇到需要即时通讯的场景。当然实现方式有很多,比如Socket、MQTT、Netty....等。使用哪一种取决于业务的需要,选择合理的方式来实现。今天简单聊的场景就是分布式环境下WebSocket消息共享的问题。在分布式环境中,业务方往往需要解决数据同步、共享等问题。这时,一幕出现了。后端有一个分布式服务。我需要这两种服务来接收WebSocket消息。如何实现?也就是说,服务器项目中有多个负载均衡实例,而且这些实例都在不同的实例上,这样当一个请求加载到A服务器实例时,socket会话是在A服务器线程上,而第二个请求加载到另一个服务器B的实例,此时服务器B没有服务器A的Session(即Socket的会话消息)。思考及解决思路1(失败)我们先想想,这个问题怎么解决?实现同步,根据上面的需求,我们可以直接定位到SocketSession无法共享的问题。只要能够共享session对象,就可以解决当前的问题。没错,小简也是这么想的,其实是错的,请往下看。我们首先想到在分布式下,我们的分布式锁和分布式状态信息可以通过Redis共享,所以我们可以直接通过Redis来共享SocketSession。思路确实是对的,但是Redis共享对象的使用是有条件的,必须实现Serializable接口才可以序列化。我们在查看源码的时候会发现SocketSession是不能序列化的,自然就不能使用Redis来共享Session对象了。为什么可以使用Redis共享HttpSession?/***@authorJanYork*@date2023/3/1411:36*/org.apache.catalina.session.StandardManagerorg.apache.catalina.session.HttpSession在PersistentManagerWEB中主要是通过以上两个manager实现序列化。Tomcat默认使用StandardManager。当Web应用程序关闭时,它会将所有HttpSession对象持久保存在内存中并将它们保存到文件系统中。默认存储文件为:/work/Catalina/<主机名>/<应用名>/sessions.serPersistentManager比StandardManager更灵活,只要某个设备提供org.apache.catalina的实现即可.Store接口的驱动类,PersistentManager可以将HttpSession对象保存到设备中。所以spring-session-redis通过将session序列化到redis中来解决分布式场景下的session共享,使用filter加decorator的方式解决分布式场景下https的session共享问题。注:此段引用程序员DD的文章。思路二既然对象不能共享,我们就可以共享消息。我们的目的是让其他实例也能接收到Socket消息。那么我们是1对n的消息模型,一对多的消息就简单了。哪些方法?首先我们马上会想到MQ,它是消息队列中间件。其次,我们还可以利用Redis的发布订阅功能。MQ使用MQ实现一对多的消息。我相信我不需要多说。MQ天然的广播、发布-订阅、点对点、路由消息模式可以轻松解决这个问题。RedisRedis的实现已经有大佬写过,请参考:分布式WebSocket场景下如何使用Redis解决Session共享问题:https://cloud.tencent.com/developer/article/195578??3文章是这样的总之(暗喜:又一篇,呵呵),下篇文章见。