[英]Using Tomcat HTTP and Netty UDP in same Spring Boot Application
我正在编写一个需要能够侦听 UDP 数据报并公开一些 HTTP 端点的应用程序。
我正在使用 Spring Boot,Web Starter 用于 HTTP 部分,Netty 用于 UDP。
要设置 UDP,我使用以下代码:
@Configuration
class NettyConfig(
@Value("\${netty.port}")
val port: Int,
@Value("\${netty.epoll}")
val epoll: Boolean
) {
val log = LoggerFactory.getLogger(NettyConfig::class.java)!!
@Bean
fun executor() = Executors.newFixedThreadPool(threads)!!
@Bean
fun bootstrap(handlerService: HandlerService): Bootstrap {
val master: EventLoopGroup
val clazz: Class<out Channel>
log.info("Starting Netty Server. EPoll enable: $epoll")
if (epoll) {
master = EpollEventLoopGroup(1)
clazz = EpollDatagramChannel::class.java
} else {
master = NioEventLoopGroup(1)
clazz = NioDatagramChannel::class.java
}
val bootstrap = Bootstrap()
.group(master)
.channel(clazz)
.option(ChannelOption.SO_SNDBUF, 1048576)
.option(ChannelOption.SO_RCVBUF, 1048576)
.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator(2048, 2048, 64 * 2048))
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.option(ChannelOption.SO_BROADCAST, true)
.handler(object: ChannelInitializer<DatagramChannel>() {
override fun initChannel(ch: DatagramChannel) {
ch.pipeline().addLast(
LineBasedFrameDecoder(1048576),
handler(handlerService))
}
})
val channel = bootstrap.bind(port).sync().channel()
log.info("Started Netty Server. Listening on {}", port)
channel.closeFuture().sync()
log.info("Stopped Netty Server.")
return bootstrap
}
...
而一个HTTP部分由Spring Starter Web管理,由Tomcat实现。
我想要实现的目标:
两个部分都在工作,但不是一起工作。 通过反复试验,我遇到了以下问题:如果我注释掉这一行(即不启动 Netty):
val channel = bootstrap.bind(port).sync().channel()
HTTP 部分有效(和 UDP obv。不)。 如果我把它留在原地——一切都会开始,但是,任何对 8080 端口的请求都会给出一个连接被拒绝的错误。
根据我的理解,应该没有问题,因为两台服务器都在不同的端口(5432 与 8080)上侦听,这就是我在日志消息中得到的内容。 因此,两台服务器之间存在一些我不知道的重要交互。
我该如何解决它,以便两台服务器将在同一个 JVM/Spring Boot 应用程序中一起运行?
我怀疑您的应用程序由于bootstrap
@Bean
方法中的channel.closeFuture().sync()
而未完成启动。 由于启动未完成,Tomcat 没有机会启动,因此它无法接受任何传入连接。
与其阻止 bean 的创建,不如使用 destroy 方法调用channel.closeFuture().sync()
作为应用程序上下文关闭处理的一部分。 为此,您可以实现DisposibleBean
或使用@PreDestroy
注释方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.