netty在服务器端设置超时时间

本文讲述了作者在使用Netty设置服务器端超时时间时遇到的问题及解决过程。通过一段ChannelInitializer的代码示例展示了如何设置超时,并解释了Netty中读写超时的具体含义,指出触发超时的条件与预期不符,从而帮助读者理解Netty的超时机制。

设置很简单,直接官网上抄就行,然后把它放在第一位或者尽量靠前吧

public class MyChannelInitializer extends ChannelInitializer<Channel> {
      @Override
     public void initChannel(Channel channel) {
         channel.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 30, 0));
         channel.pipeline().addLast("myHandler", new MyHandler());
     }
 }

 // Handler should handle the IdleStateEvent triggered by IdleStateHandler.
 public class MyHandler extends ChannelDuplexHandler {
      @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
         if (evt instanceof IdleStateEvent) {
             IdleStateEvent e = (IdleStateEvent) evt;
             if (e.state() == IdleState.READER_IDLE) {
                 ctx.close();
             } else if (e.state() == IdleState.WRITER_IDLE) {
                 ctx.writeAndFlush(new PingMessage());
             }
         }
     }
 }

 ServerBootstrap bootstrap = ...;
 ...
 bootstrap.childHandler(new MyChannelInitializer());

那么,我为什么还要写这篇博客呢?说多了都是泪,我花了近6小时的时间去验证这个请求超时设置是否成功。下面来听听我的翻车史。

我写这个服务器的是用来启动web项目的,类似tomcat的功能。源码可以在https://blog.csdn.net/fsgsggd/article/details/107817314 的项目地址上看到。

这是我的ChannelInitializer,超时时间处理,http请求信息的解码,自定义对http请求的处理。

package com.tczs.springmvc.netty;

import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.timeout.IdleStateHandler;

@Sharable
public class SunChannelInitializer extends ChannelInitializer<SocketChannel>{
	 
	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		pipeline.addLast(new IdleStateHandler(5,5, 0));
		pipeline.addLast(new TimeOutHandler());
		pipeline.addLast(new HttpServerCodec());
		pipeline.addLast(new HttpObjectAggregator(512 * 1024));
		pipeline.addLast(new HttpExecuteHandler());
	}

}

我打算postman来请求这个接口:

 @RequestMapping(url="/findByParam")
    public List<TestData.Person> findByParam(@Param("id")Integer id,@Param("name")String name,@Param("mobile")String mobile) throws UnknownHostException, IOException{
        System.out.println("name-----"+name);

        	Socket s = new Socket("news.baidu.com", 450);

        return testService.findByParam(id, name, mobile);
    }

可以看到这个接口肯定要花费很长时间,而且接口肯定报错了。那么为什么我上面设置的5秒超时时间不起作用呢?这就是我耗费6小时去验证的原因了。

首先,上面的设置是没有问题的。那么为什么没起作用,那就是我想的触发超时时间条件和它的触发超时时间条件是完全不在一个水平线上的。

我想的是从http连接开始到返回数据的这段时间,超过了设置的超时时间则触发。但它的不是。

看图:

它的读超时时间是连接开始到处理第一个入站handler的 channelRead0 方法,如果时间超过,则是读超时。

它的写超时时间是入站消息处理完的时间到写入第一个出站handler的 write 方法,如果时间超过,则是读超时。

想通了,再回首看这篇文章,写的是什么玩意啊,还要你说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

3wtczs93点抗母

钱癌晚期

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值