下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

软件设计:netty框架概述

作者:the.forgotten     来源: https://www.cnblogs.com/zhuge134/p/11062266.html点击数:795发布时间: 2020-04-15 15:10:30

标签: java操作系统XML

  Netty是由JBOSS提供的一个java开源框架,现为Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

  概述

  最近在学习netty的相关知识,也在看netty的源码,光看不练假把式,所以也正好利用自己学习的机会写几篇netty的分析文章,主要还是一些源码解析的文章,一方面有输出会促使自己在看源码,学习原理的过程中更系统,更深入,同时也能加强记忆,巩固对知识的理解。

  关于netty的简介和应用我就不做介绍了,在网络上都能搜索到相关的资料。

  netty是一个性能非常优秀的网络框架,采用reactor模式,使用非常高效的基于事件驱动的io线程模型,即经典的多路复用的io模式。关于io线程模型其实又是一个很大的话题,涉及到操作系统的底层原理,后面有时间我也打算深入学习一下这方面的知识,并写一些相关的分析文章。

  我的整体思路是这样的:首先,以netty提供给用户的常用的接口为切入点,一步步地深入netty内核进行分析,因为netty的模块众多,而且某一个层级往往有很多种平级的模块,这些不同的模块一般代表了不同的实现机制或不同的功能,如根据多路复用系统调用的不同就分为EpollEventLoop,NioEventloop,KQueueEventLoop等;根据不同的应用层协议把编解码器分为不同种类,如http,smtp,http2,XML等等。所以,我们只需要分析其中的一套,其他类型的在实际用到时在深入了解,这样既能整体上掌握框架,也能深入实现的细节。

  netty应用示例

  之前对spark-core的源码进行过一些讲解,分析了spark-core中的大部分模块,但是其中有一个很重要的模块却没有分析,那就是spark的rpc模块,spark的rpc模块是基于netty实现的,也是对netty的一个很典型的应用,所以这里我还是以spark中的rpc模块为示例,切入netty的源码分析。

  //初始化netty服务端

  privatevoidinit(StringhostToBind,intportToBind){

  //io模式,有两种选项NIO,EPOLL

  IOModeioMode=IOMode.valueOf(conf.ioMode());

  //创建bossGroup和workerGroup,即主线程组合子线程组

  EventLoopGroupbossGroup=

  NettyUtils.createEventLoop(ioMode,conf.serverThreads(),conf.getModuleName()+"-server");

  EventLoopGroupworkerGroup=bossGroup;

  //缓冲分配器,分为堆内存和直接内存

  PooledByteBufAllocatorallocator=NettyUtils.createPooledByteBufAllocator(

  conf.preferDirectBufs(),true/*allowCache*/,conf.serverThreads());

  //创建一个netty服务端引导对象,并设置相关参数

  bootstrap=newServerBootstrap()

  .group(bossGroup,workerGroup)

  .channel(NettyUtils.getServerChannelClass(ioMode))

  .option(ChannelOption.ALLOCATOR,allocator)

  .childOption(ChannelOption.ALLOCATOR,allocator);

  //内存使用的度量对象

  this.metrics=newNettyMemoryMetrics(

  allocator,conf.getModuleName()+"-server",conf);

  //排队的连接数

  if(conf.backLog()>0){

  bootstrap.option(ChannelOption.SO_BACKLOG,conf.backLog());

  }

  //socket接收缓冲区大小

  if(conf.receiveBuf()>0){

  bootstrap.childOption(ChannelOption.SO_RCVBUF,conf.receiveBuf());

  }

  //socket发送缓冲区大小

  if(conf.sendBuf()>0){

  bootstrap.childOption(ChannelOption.SO_SNDBUF,conf.sendBuf());

  }

  //子channel处理器

  bootstrap.childHandler(newChannelInitializer<SocketChannel>(){

  @Override

  protectedvoidinitChannel(SocketChannelch){

  RpcHandlerrpcHandler=appRpcHandler;

  for(TransportServerBootstrapbootstrap:bootstraps){

  rpcHandler=bootstrap.doBootstrap(ch,rpcHandler);

  }

  context.initializePipeline(ch,rpcHandler);

  }

  });

  InetSocketAddressaddress=hostToBind==null?

  newInetSocketAddress(portToBind):newInetSocketAddress(hostToBind,portToBind);

  //绑定到ip地址和端口

  channelFuture=bootstrap.bind(address);

  //同步等待绑定成功

  channelFuture.syncUninterruptibly();

  port=((InetSocketAddress)channelFuture.channel().localAddress()).getPort();

  logger.debug("Shuffleserverstartedonport:{}",port);

  }

  netty使用一个引导对象ServerBootstrap来引导服务端的启动,最后的bootstrap.bind(address)实际出发了一系列的初始化机制。

  总结

  本节,我主要是开了一个头,以spark中rpc服务端的初始化为例子切入netty的源码。

  也就是说,Netty是一个基于NIO的客户、服务器端编程框架,使用Netty可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。

赞(15)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程