Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 收到响应时Netty ChannelFuture超时_Java_Spring_Netty_Future - Fatal编程技术网

Java 收到响应时Netty ChannelFuture超时

Java 收到响应时Netty ChannelFuture超时,java,spring,netty,future,Java,Spring,Netty,Future,我是netty的新手,我有一个用netty开发的tcp客户端应用程序。当我使用future从服务器获取异步响应时,会返回一些响应,但future并没有完成超时。TCPClient类,如下所示 public TcpClient { public boolean connect(Host host) { try { Bootstrap clientBootstrap = new Bootstrap() .grou

我是netty的新手,我有一个用netty开发的tcp客户端应用程序。当我使用future从服务器获取异步响应时,会返回一些响应,但future并没有完成超时。TCPClient类,如下所示

public TcpClient {
    public boolean connect(Host host) {
        try {
            Bootstrap clientBootstrap = new Bootstrap()
                    .group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE,true)
                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 50)
                    .remoteAddress(new InetSocketAddress(host.getIp(), host.getPort()))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) {
                            socketChannel.config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(2146));
                            FalconClientHandler falconClientHandler = new FalconClientHandler(host);
                            host.setFalconClientHandler(falconClientHandler);
                            socketChannel.pipeline().addLast(falconClientHandler);
                        }
                    });

            channelFuture = clientBootstrap.connect().sync(); //BAŞARI İLE BAĞLANDI

            channelFuture.channel().closeFuture().sync();

            return host.isActive();
        } catch (Exception e) {
            log.info("Connection timed out --> " + e);
            host.setActive(false);
            return false;
        } finally {
            host.setActive(false);
        }
    }

public synchronized ResponseFuture send(long transactionId,String message) {
    final Map<Long,ResponseFuture> responseFuture = new ConcurrentHashMap<>();
    responseFuture.put(transactionId,new ResponseFuture());
    if (!hostSelector.getUpHostList().isEmpty()) {
        int hostCount = hostSelector.getUpHostList().size();
        Host host;

        host = hostSelector.getUpHostList().get(index.incrementAndGet() % hostCount);
        if (host.isActive()) {
            int headerLength = Integer.parseInt(message.substring(8, 12));
            log.info("[{}] Host {} Tcp Request",message.substring(52, 52 + headerLength),host.getIp());
            channelFuture.addListener((GenericFutureListener<ChannelFuture>) future -> {
                log.info("[{}] Tcp request added to map",transactionId);
                channelFuture.channel().pipeline().get(FalconClientHandler.class).setResponseFuture(responseFuture);
                byte[] byteBuffer = message.getBytes();
                channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer(byteBuffer));
            });
        }
    } else {
        log.error("AYAKTA HOST YOK");
    }
    return responseFuture.get(transactionId);
}

}
    ResponseFuture responseFuture = falconClient.send(Long.valueOf(transactionId), finalMessage);
    try {
        Object obj = responseFuture.get(ddaTimeoutParam, TimeUnit.MILLISECONDS);
        if(obj!=null) {
            response = obj.toString();
            ddaDelta = System.currentTimeMillis()-ddaRequestStartTime;
        }
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        log.warn("[{}] DDA timeout. Timeout parameter: {}",transactionId,ddaTimeoutParam);
        responseFuture.cancel(true);
        response = "TIMEOUT";
        ddaDelta = System.currentTimeMillis()-ddaRequestStartTime;
    } 
Response future是一个基本的future实现类。提出并获得这样的方法

public class ResponseFuture implements Future<String> {

    private volatile State state = State.WAITING;
    ArrayBlockingQueue<String> blockingResponse = new ArrayBlockingQueue<String>(1);

    private enum State {
        WAITING,
        DONE
    }

    @Override
    public String get(long timeout, TimeUnit unit) throws InterruptedException,
            ExecutionException, TimeoutException {
        final String responseAfterWait = blockingResponse.poll(timeout, unit);
        if (responseAfterWait == null) {
            throw new TimeoutException();
        }
        return responseAfterWait;
    }

    public void set(String msg) {
        if (state == State.DONE) {
            return;
        }

        try {
            blockingResponse.put(msg);
            state = State.DONE;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


    My Handler class for receive server response message like following;


public class FalconClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    private ChannelHandlerContext ctx;

    private Map<Long,ResponseFuture> responseFuture;

    public synchronized void setResponseFuture(Map<Long,ResponseFuture> responseFuture) {
        log.info("{} ResponseFuture setted",responseFuture.keySet());
        this.responseFuture = responseFuture;
    }

    @Override
    public void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf in) {
        String input = in.toString(CharsetUtil.UTF_8);
        String transactionKey = input.substring(52, 66).trim();
        if(responseFuture.get(Long.valueOf(transactionKey))!=null)
            responseFuture.get(Long.valueOf(transactionKey)).set(input);
        else
            log.info("[{}] Tcp Response map is empty",transactionKey);
        }
}
公共类响应未来实现未来{
私有易失性状态State=State.WAITING;
ArrayBlockingQueue blockingResponse=新的ArrayBlockingQueue(1);
私有枚举状态{
等待,
完成
}
@凌驾
公共字符串get(长超时,时间单位)抛出InterruptedException,
ExecutionException,TimeoutException{
最终字符串responseAfterWait=blockingResponse.poll(超时,单位);
if(responseAfterWait==null){
抛出新的TimeoutException();
}
返回responseAfterWait;
}
公共无效集(字符串消息){
if(state==state.DONE){
返回;
}
试一试{
blockingResponse.put(味精);
state=state.DONE;
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
接收服务器响应消息的我的处理程序类,如下所示;
公共类FalconClientHandler扩展了SimpleChannelInboundHandler{
专用通道HandlerContext ctx;
私有地图响应未来;
公共同步的void setResponseFuture(映射responseFuture){
log.info(“{}ResponseFuture setted”,ResponseFuture.keySet());
this.responseFuture=responseFuture;
}
@凌驾
public void channelRead0(ChannelHandlerContext ChannelHandlerContext,ByteBuf in){
字符串输入=in.toString(CharsetUtil.UTF_8);
String transactionKey=input.substring(52,66).trim();
if(responseFuture.get(Long.valueOf(transactionKey))!=null)
responseFuture.get(Long.valueOf(transactionKey)).set(input);
其他的
log.info(“[{}]Tcp响应映射为空”,transactionKey);
}
}

当我在高负载(如每秒30个事务)下运行此代码时,tcp响应从netty服务器返回,但未来的get方法收到超时。这种情况不会发生在每个请求上,例如%20请求在40个tps中30个tps%50请求失败时失败。负载下会发生什么

您的代码是不可复制的,因此很难在这方面提供帮助。一个关键点是,由EventLoopGroup处理的任何内容,线程都不应该阻止。另外,由于我无法运行您的代码对其进行测试,您是否也查看了
send(longtransactionid,String message)
在另一个请求已挂起的情况下调用它时,根据行
.setResponseFuture(responseFuture)如何反应,似乎它只能同时处理1个请求感谢响应问题与未来承诺相关,因此当此行responseFuture.get(Long.valueOf(transactionKey)).set(input)时在responseFuture.get和inputs之前工作会混合每个事务id。我如何一次只提供一个请求?您的代码不可复制,因此很难在这方面提供帮助。一个关键点是,由EventLoopGroup处理的任何内容,线程都不应该阻止。另外,由于我无法运行您的代码对其进行测试,您是否也查看了
send(longtransactionid,String message)
在另一个请求已挂起的情况下调用它时,根据行
.setResponseFuture(responseFuture)如何反应,似乎它只能同时处理1个请求感谢响应问题与未来承诺相关,所以当此行responseFuture.get(Long.valueOf(transactionKey)).set(input)在responseFuture.get之前工作时,输入和每个事务id混合在一起。如何一次只处理1个请求?