SpringCloudGateway+Nacos注册与转发Netty+WebSocket

发布于:2025-02-11 ⋅ 阅读:(36) ⋅ 点赞:(0)

背景

项目中有个拍卖服务是长连接的,需要加入到注册中心中方便统一的管理,并且方便动态扩容。

问题

Nacos没有对长连接的服务注册的支持,需要手动实现把服务注册上线下线,感知服务状态。并需要支持域名转发WebSocket的请求。

实现

  • 自动注册,下线服务
@Async
    public void start() {
        log.info("=================Netty服务开启==================");
        try {
            //ServerBootstrap 是一个启动类
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            // 设置主从线程组
            // ... 业务
            // 注册到nacos
            nettyNacosService.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;
    }

网站公告

今日签到

点亮在社区的每一天
去签到