【发布时间】:2021-02-25 07:25:47
【问题描述】:
我正在编写一个需要能够侦听 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实现。
我想要达到的目标:
- 应用程序在给定端口(例如 5432)上侦听 UDP 事件
- 应用程序在 8080 端口上侦听 HTTP 请求
- 应用程序实现它自己的 HTTP API
- 应用程序通过 HTTP 公开执行器端点以管理/监控它
这两个部分都在工作,但不能一起工作。通过反复试验,我遇到了以下问题: 如果我注释掉这一行(即不启动 Netty):
val channel = bootstrap.bind(port).sync().channel()
HTTP 部分有效(而 UDP obv. 无效)。如果我把它留在原地 - 一切都开始了,但是,任何对 8080 端口的请求都会给出连接被拒绝的错误。
据我了解,应该没有问题,因为两台服务器都在侦听不同的端口(5432 与 8080),这就是我在日志消息中得到的信息。所以两台服务器之间存在一些重要的交互,我不知道。
如何解决,让两台服务器在同一个 JVM/Spring Boot App 中一起运行?
【问题讨论】:
标签: java spring-boot netty