《 Netty权威指南(第2版)》 学习感悟
《 Netty权威指南(第2版)》 学习感悟
1:Netty是什么?
Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序dsf。
也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。
“快速”和“简单”并不意味着会让你的最终应用产生维护性或性能上的问题。Netty 是一个吸收了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
Netty具有如下优势:
- 处理大容量数据流更简单
- 处理协议编码和单元测试更简单
- I/O超时和idle状态检测
- 应用程序的关闭更简单,更安全
- 更可靠的OutOfMemoryError预防
传输方式为:
- 基于BIO和NIO的UDP传输
- 本地传输(又名 in-VM传输)
- HTTP通道,可绕过防火墙
2:Netty可以做什么?
netty是一套在java NIO的基础上封装的便于用户开发网络应用程序的api. 应用场景很多,诸如阿里的消息队列(RocketMQ),分布式rpc(Dubbo)通信层都使用到了netty(dubbo可以用服务发现自由选择通信层). 主要优点个人总结如下:
1. netty是非阻塞事件驱动框架, 并结合线程组(group)的概念,可以很好的支持高并发,慢连接的场景。
2. 编程接口非常容易,并且也较好的解决了TCP粘包/拆包的问题.netty提供了自己的ByteBuf和channel,相比于jdk的ByteBuffer和channel来说更简便灵活操作, 并提供了pipeline的概念,并针对每个contextHandler都可以由用户定义, 方便直接.
3. 有一些web框架已经开始直接使用netty做为底层通信服务,诸如play. 这样play就不用依赖于容器去进行部署,在没有nginx做反向代理的情况下也能支持高并发.编解码器可以随意扩展,今天是个web,明天就可以是一个ftp或email服务器,个人觉得比较灵活。
《 Netty权威指南(第2版)》试读章节是服务端创建,其对原生NIO类库的使用复杂性进行了讲解,对Netty服务端穿件的时序图和步骤进行了详细说明,对Netty源码对服务端创建进行剖析,最后对新的客户端接入进行了源码层面的分析和讲解。通过本章节的学习,读者可以掌握Netty服务端创建并且可以在实际中使用,编写出高效的代码。
Netty服务端创建时序图:
Netty服务端创建程序:
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpContentDecompressor; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import org.apache.log4j.PropertyConfigurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import com.innoplay.httpserver.config.ConfigInfo; import com.innoplay.httpserver.config.ConfigProperties; import com.innoplay.service.context.ApplicationContextUtil; /** * server main entrance, netty tcp server listen on configInfo.listenPort * */ public class HttpServer { /** * init load config information */ private static ConfigInfo configInfo; private static final Logger logger = LoggerFactory .getLogger(HttpServer.class); private static ServerBootstrap bootstrap; /** * start server method * * @param args * @throws IOException */ private void start() throws Exception { EventLoopGroup group = new NioEventLoopGroup(configInfo.getThreadNum()); try { bootstrap = new ServerBootstrap(); bootstrap .group(group) .channel(NioServerSocketChannel.class) .localAddress( new InetSocketAddress(configInfo.getListenPort())) .childHandler(new ChannelInitializer<SocketChannel>() { /* * (non-Javadoc) * * @see * io.netty.channel.ChannelInitializer#initChannel(io * .netty.channel.Channel) */ @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new HttpServerCodec()); ch.pipeline().addLast(new HttpContentDecompressor()); ch.pipeline().addLast(new HttpObjectAggregator(Integer.MAX_VALUE));//定义 ch.pipeline().addLast(new HttpServerHandler()); } }); ChannelFuture f = bootstrap.bind().sync(); logger.info(HttpServer.class.getName() + " started and listen on " + f.channel().localAddress()); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } } /** * main entrance * * @param args */ public static void main(String[] args) { try { //program argument setting/windows/linux //conf.path=E:\Workspace\server\trunk\innoplay-httpserver\target\conf if(args != null) { for(String s : args) { if(s.startsWith("--conf.path")) { System.setProperty(ConfigProperties.CONFIGPATH, s.replace("--conf.path=", "")); PropertyConfigurator.configure(System.getProperty(ConfigProperties.CONFIGPATH) + File.separator + "log4j.properties"); logger.info("System has received conf.path: {}", s); } } } else { logger.error("please setting the --conf.path=XXXX, system exited!"); System.exit(-1); } configInfo = ConfigProperties.loadProperties(); // ApplicationContext context = new FileSystemXmlApplicationContext(System.getProperty(ConfigProperties.CONFIGPATH) + File.separator +"applicationContext.xml"); ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml"); ApplicationContextUtil.setContext(context); HttpServer server = new HttpServer(); server.start(); } catch (Exception e) { logger.error("Server occur an error!", e.getCause()); e.printStackTrace(); } } public static void close() { if (bootstrap != null) { try { bootstrap.group().shutdownGracefully().sync(); } catch (InterruptedException e) { logger.error("Server close occur an error!", e.getCause()); e.printStackTrace(); } } } }
相信这本书对学习Netty的爱好者有很好的帮助,对编写出高效的代码有很好的帮助。
相关推荐
fengshantao 2020-10-29
arctan0 2020-10-14
爱传文档 2020-07-28
gzx0 2020-07-05
fengshantao 2020-07-04
fengshantao 2020-07-02
jannal 2020-06-21
arctan0 2020-06-19
arctan0 2020-06-16
gzx0 2020-06-14
fengshantao 2020-06-13
gzx0 2020-06-12
arctan0 2020-06-11
fengshantao 2020-06-11
mbcsdn 2020-05-19
arctan0 2020-05-16
爱传文档 2020-05-08
爱传文档 2020-05-04