背景
项目中有个拍卖服务是长连接的,需要加入到注册中心中方便统一的管理,并且方便动态扩容。
问题
Nacos没有对长连接的服务注册的支持,需要手动实现把服务注册上线下线,感知服务状态。并需要支持域名转发WebSocket的请求。
实现
- 自动注册,下线服务
@Asyncpublic void start() {log.info("=================Netty服务开启==================");try {//ServerBootstrap 是一个启动类ServerBootstrap serverBootstrap = new ServerBootstrap();// 设置主从线程组// ... 业务// 注册到nacosnettyNacosService.registerNamingService();bindFuture = serverBootstrap.bind(nettyNacosService.getNettPort()).sync();log.info("netty监听端口:{},后台服务器启动.....", nettyNacosService.getNettPort());} catch (Exception e) {log.error("netty服务器启动异常:{}", e.getMessage());}}public void destroy() {// 将NacosNetty注销服务nettyNacosService.deregisterInstance();log.info("=================Netty服务关闭==================");if (bindFuture != null) {bindFuture.channel().closeFuture();}bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}// 注册伪代码:/*** 将Netty服务注册进Nacos*/
public void registerNamingService() {try {Properties properties = getNacosProperties();NamingService namingService = NamingFactory.createNamingService(properties);Instance nettyInstance = getNettyInstance();namingService.registerInstance(nettyInstance.getServiceName(),getGroup(),nettyInstance);} catch (Exception e) {throw new RuntimeException(e);}}private Properties getNacosProperties() {Properties properties = new Properties();properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacosDiscoveryProperties.getServerAddr());properties.setProperty(PropertyKeyConst.NAMESPACE, nacosDiscoveryProperties.getNamespace());properties.setProperty(PropertyKeyConst.USERNAME, nacosDiscoveryProperties.getUsername());properties.setProperty(PropertyKeyConst.PASSWORD, nacosDiscoveryProperties.getPassword());return properties;}/*** 将NacosNetty注销服务*/public void deregisterInstance() {try {Properties properties = getNacosProperties();NamingService namingService = NamingFactory.createNamingService(properties);Instance nettyInstance = getNettyInstance();namingService.deregisterInstance(nettyInstance.getServiceName(),getGroup(),nettyInstance);} catch (Exception e) {throw new RuntimeException(e);}}
- gateway增加路由
{"id": "web-socket","order": 3,"predicates": [{"args": {"pattern": "/ws/**"},"name": "Path"}],"filters":[{"name":"StripPrefix","args":{"parts":"1"}}],"uri": "lb:ws://web-socket"
}
- nginx配置
这里支持长连接的配置跟http稍微有点不同。
主要看这个配置:$http_upgrade
map $http_upgrade $connection_upgrade {default upgrade;'' close;
}location /ws {proxy_pass https://abc.com/web-socket # 这里改为对应的域名proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $connection_upgrade;}