1、新增功能探针联动处置、心跳在线检测
2、syslog-consumer模块拆分 syslog-consumer-rule模块实现日志数据消费、解析、泛化入库。
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
package com.netty;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Syslog 服务器主类,支持 TCP 和 UDP 协议
|
||||
*/
|
||||
public class SyslogServerBoth {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SyslogServer.class);
|
||||
|
||||
private final int tcpPort;
|
||||
private final int udpPort;
|
||||
|
||||
// 共享的EventLoopGroup以优化资源使用
|
||||
private EventLoopGroup bossGroup;
|
||||
private EventLoopGroup workerGroup;
|
||||
private EventLoopGroup udpGroup;
|
||||
|
||||
private ChannelFuture tcpChannelFuture;
|
||||
private ChannelFuture udpChannelFuture;
|
||||
|
||||
private final ExecutorService serverExecutor = Executors.newFixedThreadPool(2);
|
||||
|
||||
public SyslogServerBoth(int tcpPort, int udpPort) {
|
||||
this.tcpPort = tcpPort;
|
||||
this.udpPort = udpPort;
|
||||
}
|
||||
|
||||
public void start() throws InterruptedException {
|
||||
logger.info("Starting Syslog server with TCP port {} and UDP port {}", tcpPort, udpPort);
|
||||
|
||||
// 创建共享的EventLoopGroup
|
||||
bossGroup = new NioEventLoopGroup(1);
|
||||
workerGroup = new NioEventLoopGroup();
|
||||
udpGroup = new NioEventLoopGroup();
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
|
||||
try {
|
||||
// 启动UDP服务器(使用独立的线程)
|
||||
serverExecutor.submit(() -> {
|
||||
try {
|
||||
startUdpServer();
|
||||
latch.countDown();
|
||||
} catch (Exception e) {
|
||||
logger.error("UDP server failed to start", e);
|
||||
latch.countDown();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
// 启动TCP服务器(使用独立的线程)
|
||||
serverExecutor.submit(() -> {
|
||||
try {
|
||||
startTcpServer();
|
||||
latch.countDown();
|
||||
} catch (Exception e) {
|
||||
logger.error("TCP server failed to start", e);
|
||||
latch.countDown();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
// 等待两个服务器都启动完成
|
||||
latch.await();
|
||||
logger.info("Both TCP and UDP Syslog servers are running");
|
||||
|
||||
// 注册关闭钩子
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
|
||||
|
||||
// 保持主线程运行
|
||||
Thread.currentThread().join();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to start servers", e);
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void startTcpServer() throws InterruptedException {
|
||||
ServerBootstrap b = new ServerBootstrap();
|
||||
b.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new SyslogTcpChannelInitializer())
|
||||
.option(ChannelOption.SO_BACKLOG, 128)
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true);
|
||||
|
||||
tcpChannelFuture = b.bind(tcpPort).sync();
|
||||
logger.info("TCP Syslog server started on port {}", tcpPort);
|
||||
|
||||
// 添加关闭监听器
|
||||
tcpChannelFuture.channel().closeFuture().addListener(future -> {
|
||||
if (future.isSuccess()) {
|
||||
logger.info("TCP server channel closed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startUdpServer() throws InterruptedException {
|
||||
Bootstrap b = new Bootstrap();
|
||||
b.group(udpGroup)
|
||||
.channel(NioDatagramChannel.class)
|
||||
.handler(new SyslogUdpChannelInitializer())
|
||||
.option(ChannelOption.SO_BROADCAST, true);
|
||||
|
||||
udpChannelFuture = b.bind(udpPort).sync();
|
||||
logger.info("UDP Syslog server started on port {}", udpPort);
|
||||
|
||||
// 添加关闭监听器
|
||||
udpChannelFuture.channel().closeFuture().addListener(future -> {
|
||||
if (future.isSuccess()) {
|
||||
logger.info("UDP server channel closed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 优雅关闭服务器
|
||||
*/
|
||||
public void shutdown() {
|
||||
logger.info("Shutting down Syslog servers...");
|
||||
|
||||
try {
|
||||
// 关闭TCP服务器
|
||||
if (tcpChannelFuture != null) {
|
||||
tcpChannelFuture.channel().close().sync();
|
||||
}
|
||||
|
||||
// 关闭UDP服务器
|
||||
if (udpChannelFuture != null) {
|
||||
udpChannelFuture.channel().close().sync();
|
||||
}
|
||||
|
||||
// 关闭EventLoopGroup
|
||||
if (bossGroup != null) {
|
||||
bossGroup.shutdownGracefully().sync();
|
||||
}
|
||||
if (workerGroup != null) {
|
||||
workerGroup.shutdownGracefully().sync();
|
||||
}
|
||||
if (udpGroup != null) {
|
||||
udpGroup.shutdownGracefully().sync();
|
||||
}
|
||||
|
||||
// 关闭线程池
|
||||
serverExecutor.shutdown();
|
||||
|
||||
logger.info("Syslog servers shutdown complete");
|
||||
} catch (Exception e) {
|
||||
logger.error("Error during shutdown", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查服务器是否在运行
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return (tcpChannelFuture != null && tcpChannelFuture.channel().isActive()) ||
|
||||
(udpChannelFuture != null && udpChannelFuture.channel().isActive());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int tcpPort = 514;
|
||||
int udpPort = 514;
|
||||
|
||||
// 解析命令行参数
|
||||
if (args.length >= 1) {
|
||||
tcpPort = Integer.parseInt(args[0]);
|
||||
}
|
||||
if (args.length >= 2) {
|
||||
udpPort = Integer.parseInt(args[1]);
|
||||
}
|
||||
|
||||
// 如果两个端口相同,UDP端口自动+1避免冲突
|
||||
if (tcpPort == udpPort) {
|
||||
udpPort = tcpPort + 1;
|
||||
logger.warn("TCP and UDP ports cannot be the same. UDP port changed to {}", udpPort);
|
||||
}
|
||||
|
||||
SyslogServerBoth server = new SyslogServerBoth(tcpPort, udpPort);
|
||||
|
||||
// 注册全局异常处理器
|
||||
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
|
||||
logger.error("Uncaught exception in thread {}", t.getName(), e);
|
||||
});
|
||||
|
||||
server.start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user