在netty客户端中与2位主机一起工作时,我遇到了困难。我想做的是,在2台主机之间建立连接,将其作为一个主机和一个备份。如果通过TCP发送消息时我的主连接被禁用,则将消息发送到备份主机。例如;
我有2位主持人。其中一个是10.50.60.30,另一个是10.50.60.57。我的主要主机是10.50.60.30,备份是10.50.60.57。当我发现60.30有问题时,我希望降低到60.57。但是它仍然试图发送到损坏的主主机。
我猜想,在channelActive()函数中初始化静态ctx变量时,该问题发生在FalconClientHandler.class中。我是否应该使用存储所有连接的ChannelHandlerContext列表。顺便说一句,没有任何异常发生。关于逻辑
public static boolean connect(Host host) {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap clientBootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 50)
.remoteAddress(new InetSocketAddress(host.getIp(), host.getPort()))
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel socketChannel) {
//socketChannel.pipeline().addLast("idleStateHandler", new IdleStateHandler(250, 0, 0, TimeUnit.MILLISECONDS));
socketChannel.config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(2146));
socketChannel.pipeline().addLast(new FalconClientHandler(host));
}
});
ChannelFuture channelFuture = clientBootstrap.connect().sync(); //BAŞARI İLE BAĞLANDI
channelFuture.channel().closeFuture().sync();
return host.isActive();
} catch (Exception e) {
LOGGER.info("Connection timed out --> " + e);
host.setActive(false);
return false;
} finally {
//group.shutdownGracefully().sync();
host.setActive(false);
}
}
我可以找到FalconClientHandler内部发生故障的服务器。所以我可以在此功能中更改主机。
private void sendMessageToServer() throws Exception {
if (!LB.getUpHostList().isEmpty()) {
TCPRequestMessage message = jobQueue.take();
host = LB.getUpHostList().get(0);
if (host.isActive()) {
String rbtran = message.getRBTRAN();
LOGGER.debug(host.getIp() + " - GÖNDERME KUYRUĞUNDAN ÇIKARTILDI -> " + rbtran);
FalconClientHandler.sendMessage(rbtran);
} else {
jobQueue.put(message);
}
}
}
public class FalconClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
private Host host;
private static ChannelHandlerContext ctx;
public FalconClientHandler(Host host) {
this.host = host;
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println(cause.getLocalizedMessage());
host.setActive(false);
ctx.close();
//do more exception handling
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
System.out.println("Connected!" + ctx.channel().remoteAddress());
ctx.fireChannelActive();
this.ctx = ctx;
}
public synchronized static void sendMessage(String message) {
System.err.println(ctx.channel().isActive());
System.err.println(ctx.channel().remoteAddress());
//if connection is broken, switch to another ctx
byte[] byteBuffer = message.getBytes();
ctx.channel().writeAndFlush(Unpooled.copiedBuffer(byteBuffer));
LOGGER.debug("MESAJ FALCONA GÖNDERİLDİ " + message);
}
@Override
public void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf in) throws InterruptedException {
String input = in.toString(CharsetUtil.UTF_8);
LOGGER.debug(host.getIp() + " MESAJ -> " + input);
if (input.length() > 0 && !input.equalsIgnoreCase(FALCONSTART) && !input.equalsIgnoreCase(FALCONSTOP)) {
if (input.contains(FALCONSTART))
input = input.replace(FALCONSTART, "");
if (input.contains(FALCONREADY))
input = input.replace(FALCONREADY, "");
int headerLength = Integer.parseInt(input.substring(8, 12));
String transactionKey = input.substring(52, 52 + headerLength).trim();
FalconClient.addResponseMessageToMap(transactionKey, input);
FalconClient.requestQueue.take();
}
switch (input) {
case FALCONSTART: //FALCON BAŞLADI 100000051
addStatusHistoryToStack(FALCONSTART, this.host.getStatusHistory()); //Bir önceki durumu kaydet.
this.host.setActive(true);
break;
case FALCONSTOP: //FALCON DURDU 100000050
addStatusHistoryToStack(FALCONSTOP, this.host.getStatusHistory());
this.host.setActive(false);
break;
}
}
}
谢谢