脚本宝典收集整理的这篇文章主要介绍了spring websocket集群,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
做项目使用websocket网上的方案很多,但是如果是产品或者平台,采用的是微服务架构,而每个微服务都可能有异步消息处理,想采用websocket,对于前端处理就会产生一个问题,那就是前端vue是SPA应用,它与后台建立一个websocket连接,如果每个微服务都建立一个连接,前端代码岂不是非常复杂。 从下图可以看到前端应用只需要跟消息微服务建立websocket连接即可,后台业务逻辑处理,调用消息服务提供的dubbo接口,再通过消息服务将响应结果推送给前端应用,整个流程就完整了。
接下只需要考虑消息微服务的集群了。1 sPRing websocket 代码参考websocket-springboot-starter websocket-demo
@Slf4j
@component
@ServerEndpoint("/busi/{source}/{identifier}")
public class WebSocketEndpoint extends AbstractWebSocketEndpoint {
private static WebSocketManager webSocketManager;
@Autowired
public void setWebSocketManager(WebSocketManager webSocketManager) {
WebSocketEndpoint.webSocketManager = webSocketManager;
}
@OnOPEn
public void onOpen(Session session,@PathParam("source") String source, @PathParam(value="identifier")String identifier ){
LOG.info("用户连接成功,连接来源为{},连接用户为:{}",source, identifier);
connect(session, source, identifier);
}
@OnMessage
public void onMessage(String message,Session session, @PathParam(value="identifier")String identifier ){
log.info("接受到的消息是{}",message);
recieveMessage(message, session,identifier );
}
@OnClose
public void onClose(Session session, @PathParam(value="identifier")String identifier ){
log.info("用户断开连接");
disconnect(session, identifier);
}
@OnError
public void onError(Session session,Throwable t, @PathParam("identifier") String identifier){
log.info("发生异常F1a;, identifier = " + identifier);
log.error(t.getMessage() , t);
disconnect(session, identifier);
}
@override
public WebSocketManager getWebSocketManager() {
return WebSocketEndpoint.webSocketManager ;
}
}
这里重点关注的是applicationContext
的赋值
@configuration
public class MemoryWebSocketManagerConfig implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Bean(WebSocketManager.WEBSOCKET_MANAGER_NAME)
public WebSocketManager webSocketManager() {
return new MemoryWebsocketManager(this.applicationContext);
}
}
@Slf4j
@RestController
@RequestMapping("imBusi")
public class ImBusiController {
@Autowired
private WebSocketManager webSocketManager;
@GetMapping("call/{id}")
public String call(@PathVARiable("id") String id){
WebSocketConn webSocketConn = webSocketManager.get(id);
WebsocketUtil.sendText(webSocketConn.getSession(), "hi," +id);
return "ok";
}
}
@Data
public class WebSocketConn {
/**
* 连接集合
*/
private Session session;
/**
* 连接终端的来源
*/
private WebSocketSource source;
/**
* 会话的唯一标识
*/
private String id;
}
2 gateway websocket spring gateway自身就带了WebsocketRoutingFilter
,网上有sockjs方案,但我的工程并不需要做什么
uri
只需要调整下增加ws
协议前缀就可以了,gateway本身不用做什么
{
"id": "im-server",
"predicates": [{
"args": {
"pattern": "/api/im/**"
},
"name": "Path"
}],
"filters": [{
"name": "StripPrefix",
"args": {
"_genkey_0": "2"
}
}],
"uri": "lb:ws://im-server"
}
3 jmeter验证 看到别人写的jmx脚本,自己不亲自动手写,感觉还是差很多,连jmeter的菜单都熟练。掌握jmeter并不是为了做测试,而是会让你更有全局思维。 jmeter之websocket压测 这个方案比较简单JMeterWebSocketSamplers-1.2.8.jar放到/lib/ext
目录下
int size_full_thread = ${size_full_thread};
String phonenum_prefix = "${phonenum_prefix}";
String thead = String.valueOf(${__threadNum});
int size_thead = thead.length();
String pading_thead = "";
for(i = 0; i< size_full_thread - size_thead; ++i) {
pading_thead = "0" + pading_thead;
}
thead = pading_thead + thead;
String username = phonenum_prefix + thead;
vars.put("username", username);
log.info("###############################username#############################:" + username);
3 jprofiler性能监控 3.1 单例 从jprofiler中可以看到MemoryWebsocketManager
、ImBusiController
、MemoryWebSocketManagerConfig
均是单例
jcmd 19060 GC.run
,多例的实例从内存中回收掉了,但单例还存在。 线程安全问题:
@ServerEndpoint
中websocket
即是多例;但是单例模式下,因实例变量共享一个实例变量,故而存在线程安全的问题。spring默认都是单例模式,线程安全如何保障的呢? 如何看待Spring下单例模式与线程安全的矛盾,spring单例模式下肯定有线程安全的问题,只要涉及成员变量都存在这个问题。对我们接触的Controller层,如果只有读,那么也不会有线程安全的问题。 高并发的情况下,多线程由tomcat或者netty等容器管理,多线程可以访问同一个实例对象,进入到方法区,因为方法的局部变量又是线程安全的,故而不用担心此问题,只有没有设置共有的成员属性即可。 3.2 多例 从上图可以看到WebSocketEndpoint
、WebSocketConn
这些是多例,websocket是线程安全,采用的是多例模式。以上是脚本宝典为你收集整理的spring websocket集群全部内容,希望文章能够帮你解决spring websocket集群所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。