最近在阅读netty(3.2.7)源码的时候,看到服务器端接受客户端连接代码的时候嗅到了一丝不和谐的气味,具体代码见:
org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink类里面的BOSS线程:
public void run() { final Thread currentThread = Thread.currentThread(); channel.shutdownLock.lock(); try { for (;;) { try { if (selector.select(1000) > 0) { selector.selectedKeys().clear(); } SocketChannel acceptedSocket = channel.socket.accept(); if (acceptedSocket != null) { registerAcceptedChannel(acceptedSocket, currentThread); } } catch (SocketTimeoutException e) { // Thrown every second to get ClosedChannelException // raised. } catch (CancelledKeyException e) { // Raised by accept() when the server socket was closed. } catch (ClosedSelectorException e) { // Raised by accept() when the server socket was closed. } catch (ClosedChannelException e) { // Closed as requested. break; } catch (Throwable e) { logger.warn( "Failed to accept a connection.", e); try { Thread.sleep(1000); } catch (InterruptedException e1) { // Ignore } } } } finally { channel.shutdownLock.unlock(); closeSelector(); } }
1、selector.selectedKeys().clear();不管当前有多少个SelectionKey被触发,都一律清除掉,然后
2、SocketChannel acceptedSocket = channel.socket.accept();只接受一个链接。
曾今阅读别人对于NETTY的性能测试的时候貌似有说到在客户端高并发请求访问会出现丢包现象
今天看到这段代码怀疑就是这段代码的问题,稍微修改代码成如下来验证:
public void run() { final Thread currentThread = Thread.currentThread(); channel.shutdownLock.lock(); try { for (;;) { try { /** * 由于Runnable没有简单的sleep,所以我这里使用很土的方式让线程暂停30秒再去执行selector操作。 * 测试如果服务器启动后,30秒内有三个客户端连接请求过来,服务器端会处理几次. */ Long currentTime = System.currentTimeMillis(); while(true){ if(System.currentTimeMillis() - currentTime>30000){ break; } } if (selector.select(1000) > 0) { selector.selectedKeys().clear(); } SocketChannel acceptedSocket = channel.socket.accept(); if (acceptedSocket != null) { registerAcceptedChannel(acceptedSocket, currentThread); } } catch (SocketTimeoutException e) { // Thrown every second to get ClosedChannelException // raised. } catch (CancelledKeyException e) { // Raised by accept() when the server socket was closed. } catch (ClosedSelectorException e) { // Raised by accept() when the server socket was closed. } catch (ClosedChannelException e) { // Closed as requested. break; } catch (Throwable e) { logger.warn( "Failed to accept a connection.", e); try { Thread.sleep(1000); } catch (InterruptedException e1) { // Ignore } } } } finally { channel.shutdownLock.unlock(); closeSelector(); } }
可以直接使用netty中的例子DiscardServer和DiscardClient来做试验。开启一个DiscardServer后,然后在30秒内直接连续启动四个DiscardClient,等30秒后发现服务器端只接受并分配了一个链接.
-------------------------------------------------------------------分割线----------------------------------------------------------------------------------------
然后我去下了最稳定发布版本的netty源码,最新的稳定版截止到本文撰写时间为(3.6.5版),在这个版本中服务器端的Boss类的代码被抽出来形成了NioServerBoss.其中的代码为:
protected void process(Selector selector) { Set<SelectionKey> selectedKeys = selector.selectedKeys(); if (selectedKeys.isEmpty()) { return; } for (Iterator<SelectionKey> i = selectedKeys.iterator(); i.hasNext();) { SelectionKey k = i.next(); i.remove(); NioServerSocketChannel channel = (NioServerSocketChannel) k.attachment(); try { // accept connections in a for loop until no new connection is ready for (;;) { SocketChannel acceptedSocket = channel.socket.accept(); if (acceptedSocket == null) { break; } registerAcceptedChannel(channel, acceptedSocket, thread); } } catch (CancelledKeyException e) { // Raised by accept() when the server socket was closed. k.cancel(); channel.close(); } catch (SocketTimeoutException e) { // Thrown every second to get ClosedChannelException // raised. } catch (ClosedChannelException e) { // Closed as requested. } catch (Throwable t) { if (logger.isWarnEnabled()) { logger.warn( "Failed to accept a connection.", t); } try { Thread.sleep(1000); } catch (InterruptedException e1) { // Ignore } } } }
在这个版本会根据SelectionKey的个数来来接受客户端的请求,这个版本我未做过性能测试,应该可以解决客户端高并发下的丢包现象.
PS:最新更新到4.0的版本的netty代码又发生了翻天覆地的变化,还是直接去阅读4.0的代码到时候.
相关推荐
通过netty编写文件传输的客户端与服务端,以及协议说明, 通用的netty传输协议 通过该协议进行文件传输 文件传输客户端与服务端 可以根据文件的最后更新时间来增量传输文件 源码开放,通过eclipse或者idea导入代码...
netty-3.2.7.final JAR包,netty-3.2.7.final JAR包,netty-3.2.7.final JAR包
Netty是Java平台上的一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。尽管Netty本身是用Java编写的,但通过跨语言交互,C#也可以利用Netty进行网络通信。 在描述中...
Netty是一个异步事件驱动的网络应用程序框架,它为高性能、高可用性的网络服务器和客户端提供了一种简单易用的方式。本实践将详细介绍如何在Android环境中使用Netty进行客户端和服务端的通信。 首先,我们需要理解...
JAVA版基于netty的物联网高并发智能网关 JAVA版基于netty的物联网高并发智能网关 JAVA版基于netty的物联网高并发智能网关 JAVA版基于netty的物联网高并发智能网关 JAVA版基于netty的物联网高并发智能网关 JAVA...
JBoss Netty是一个高性能、异步事件驱动的网络应用程序框架,它为快速开发可维护的高性能协议服务器和客户端提供了丰富的API。本篇文章将深入探讨如何利用JBoss Netty创建高效的Web Service客户端和服务端。 首先,...
Java异步NIO框架Netty实现高性能高并发无标题笔记 1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨 节点...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,专为 Java 平台设计,用于快速开发可维护的高性能协议服务器和客户端。在高并发场景下,Netty 展现出强大的性能优势,使得它在分布式系统、微服务、云计算等...
netty-3.2.7.Final 源码包,包含pom文件,eclipse或者myeclipse导入就可用,方便学习源码和进行二次开发。
Netty是Java领域的一个高性能、异步事件驱动的网络应用框架,它简化了创建高并发、高性能的TCP和UDP服务的过程。Netty的核心特性包括非阻塞I/O、零拷贝、高效内存管理和灵活的线程模型。在Java服务端,开发者可以...
基于Netty实现的MQTT客户端_netty-mqtt-client
spring boot demo,整合netty5实现高并发websocket,并引入slf4g+lombok,采用maven形式; 直接导入运行,有测试页面也有实现代码及详细注释,src/main/webapps/TestNettyWebSocket.html里第十行改成 ws://localhost...
Netty是一个高性能、异步事件驱动的网络应用框架,它为Java开发人员提供了构建高性能、高可用性的网络服务器和客户端的API。这个框架广泛应用于分布式系统、消息中间件、游戏服务器等领域,因其高效和易用性而备受...
基于Java + Netty 实现的高并发高可用MQTT服务broker #### 技术体系 1. 使用 netty 实现通信及协议解析 2. 使用 nutzboot 提供依赖注入及属性配置 3. 使用 redis 实现消息缓存,集群 4. 使用 kafka 实现消息转发(可...
同过netty实现HTTP服务器(或者客户端) 。务器提供诸如HTML文件和其他内容之类的资源,或代表客户端执行其他功能,向客户端返回响应消息。 响应包含有关请求的完成状态信息,并且还可以在其消息正文中包含所请求的...
springboot整合netty,分客户端和服务端两个项目,springboot整合netty,分客户端和服务端两个项目,springboot整合netty,分客户端和服务端两个项目,springboot整合netty,分客户端和服务端两个项目
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。整合Spring Boot与Netty,可以利用Spring的便捷性和Netty的高效性来构建实时通信系统,例如基于Socket的服务...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本“Netty-高并发编程-视频教程张龙-90讲完整视频”中,讲师张龙深入浅出地讲解了Netty在处理高并发场景下...