最近工作上接触Spring Cloud Gateway比较多,在高并发请求下遇到了不少坑,其中一些就是和SCG底层使用的reactor-netty框架相关,其中的细节我以后有时间再详谈,这篇文章主要介绍如何给Spring Boot Embedded的Netty server 添加自定义的channel handler。
Channel 是Netty框架一个非常重要的概念,Netty内所有请求和应答都要经过channel的传输,channel handler的作用就是把多种多样的行为添加到Channel的传输pipeline中,达到一些定制化的效果,比如协议的解析等等。
SCG底层开启了一个Netty Server 去接受来自client的request,这个Netty Server其实就是一个Spring boot embedded Netty server,我们要去给这个netty server添加 channel handler需要新建一个类去实现WebServerFactoryCustomizer接口:
@Component
public class NettyWebServerFactoryPortCustomizer implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {
@Override
public void customize(NettyReactiveWebServerFactory factory) {
factory.setPort(30001);
factory.addServerCustomizers(new Customizer());
}
}
这个接口必须得实现customize函数,大家可以在这个函数内实现一系列自定义的行为,
比如改变server的端口号,给server添加ssl等等,我们的目的是给nettyserver 添加channelhandler, 那就需要调用NettyReactiveWebServerFactory的addServerCustomizers,该函数的入参是任何实现NettyServerCustomizer的类型。
在🌰中,我自定义了一个类型去实现NettyServerCustomizer接口:
public class Customizer implements NettyServerCustomizer {
@Override
public HttpServer apply(HttpServer httpServer) {
return httpServer.tcpConfiguration(tcpServer ->tcpServer.bootstrap(serverBootstrap ->
serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) throws Exception {
channel.pipeline().addFirst("customHttpserver",new CustomHttpServerHandler());
}
})
));
}
}
可以看到该类实现了nettyserver用于添加channel handler的方法channel.pipeline().addFirst
在我的🌰中,我创建了一个CustomHttpServerHandler类型的handler添加到channel的pipeline中,于是每一个request的inbound的都会经过我这个handler的处理。
我们可以通过以上手段给spring embedded的netty server 添加更多灵活的属性,包括适配多种协议或者多种字符解析方法等等。