欢迎微信搜索并关注“小猴子的技术笔记”公众号 私信我 领取丰富的视频学习资料!
对于之前学习Netty一直都是处于理论阶段,并没有太多的生产经验。搜寻一些实战项目也发现大多是弹幕或者聊天。为了检验学习效果,就编写了一套弹幕系统放在公网上,通过实际访问来解决和学习Netty。
弹幕系统使用的是SpringBoot-2.4.3、Thymeleaf、Netty、WebSocket目前已经放到公有云上近一个月之久,抗住了不同级别的攻击,可以用于实际的生产之中。
项目地址:“http://barrage.houry.top”
开源地址:“https://gitee.com/MonkeyBroth...”。欢迎大家Start
关于弹幕系统的打造我这里总结几个点,希望大家在应用其他领域的时候也能够注意到。
首先:我们在创建“EventLoopGroup”的时候需要自定义我们的线程工厂。之所以要自定义我们的线程工厂就是因为,如果将来系统发生异常了,我希望在日志中能够看到是哪个线程池发生的异常!“EventLoopGroup”的构造参数是支持我们传入自定义的线程工厂的。
就像下面这样,我为boss和worker线程池分别指定了名字。
EventLoopGroup boss = new NioEventLoopGroup(1,new NettyThreadFactory("netty-boss"));
EventLoopGroup worker = new NioEventLoopGroup(2, new NettyThreadFactory("netty-worker"));
另外,我们还需要配置一下我们的“logback.xml”中打印日志长度的配置,如果使用默认值的话,那么就会出现像下面这样的情况:日志信息残缺不全。
其次,我们知道Websocket和我们的Netty服务是长链接,所以一定要做心跳检测。也许有些人会疑惑,我不做心跳检测也能够检测到连接的断开和连接啊?是的,确实是能够检测到的。不过更过的时候我们的心跳检测一个是为了释放资源,一个是为了杜绝恶意连接占用资源!
就好比这样的一个例子:网络上有人是可以通过程序扫描服务器IP和端口的,然后恶意建立Socket连接并且不传输任何信息。长久持续的建立连接,服务器的文件描述符终究会被耗尽。有其他真正的业务再上来的时候就没有办法在进行连接了,也就是说:服务器变相瘫痪了!这在生产中是一个很严重的问题,因此一定要使用心跳检测来判断用户的连接是否还在存活,如果不存活就直接剔除,释放资源。
我下面给出了一个简单的心跳检测的例子,也是我云服务器上目前在跑的一个代码。我这里就是判断了如果10秒之内没有任何的数据传输进来,我就给他关闭调相应的channel通道。
pipeline.addLast("idleStateHandler", new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS));
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
switch (event.state()) {
case READER_IDLE:
log.info("[没有接收到:{}的信息心跳信息,将断开连接回收资源]", ctx.toString());
ctx.channel().close();
break;
case WRITER_IDLE:
log.info("写空闲");
break;
case ALL_IDLE:
log.info("读写空闲");
break;
default:
log.info("非法状态");
throw new IllegalStateException("非法状态!");
}
}
}
然后在生产上一段时间之后,就可以发现:互联网还是不安全啊!我的服务经常被扫描,然后恶意建立连接。如果没有心跳检测机制的话,那么系统估计早就瘫痪了。
既然加了心跳检测,那么一旦有连接上来,前端就需要有定时任务来进行数据的发送了。至于发送的时间间隔和发送的内容,可以根据自己的需求来定义。
与之对应的就是我们在Netty读的时候需要对数据类型做一个判断,如果是心跳信息那么就直接过滤掉。
需要注意的点就这么多了,大家可以去下载源码进行研究,也可以和我一起探究,。也希望你从中学到东西之后分享给大家。
欢迎微信搜索并关注“小猴子的技术笔记”公众号 私信我 领取丰富的视频学习资料!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。