netty答题
1,介绍一下netty
netty封装了Java原生的nio,是一个异步和数据驱动的网络编程框架,
与tcp:
- netty -> Java Runtime Socket (io、nio、nio2) -> OS Socket -> TCP (当然也可以是UDP、SCTP);
- 既然连操作系统层的Socket都必须做三次握手(仅对TCP而言),Netty当然无法跳过,只不过它对用户屏蔽了三次握手(当然还有四次挥手)的部分细节。
异步:read和write方法均是异步方法,用户进程发起一个IO操作然后,立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知(回到函数,channelactive和channelRead
bio:在bio是阻塞的通信模式。一个用户连接占用一条线程,服务器通过一个Acceptor线程负责监听客户端请求和为每个客户端创建一个新的线程进行链路处理。典型的一请求一应答模式。当连接没有数据,也会阻塞在那里不释放cpu,若客户端数量增多,频繁地创建和销毁线程会给服务器打开很大的压力。(内存(每条线程栈上的基本数据类型,对象引用,方法栈,程序计数器)和cpu上下文切换(cpu寄存器需要把线程重新装入
nio:netty使用的是封装Java的nio模型,Java API 这是一个繁琐和不容易保证的用法,所以我们一般都使用netty完成nio模型的编程,在netty的多路复用nio模型,工作模式是一个工作线程对应多条连接,用一个轮询器selector不断轮询连接,若连接上有io事件,则可以获得io线程的资源,当连接没有了io请求,线程不用被阻塞,selector会轮询到其他有io请求的连接,这样线程可以被重定向到其他任务上。
启动过程:服务端监听线程和IO线程分离,创建服务端的时候实例化了2个EventLoopGroup,bossGroup和workGroup,1个EventLoopGroup实际就是一个EventLoop线程组,
bossGroup线程组实际就是Acceptor线程池,负责处理客户端的TCP连接请求,如果系统只有一个服务端端口需要监听,则建议bossGroup线程组线程数设置为1。服务端Channel创建完成之后,bossGroup将会把channel绑定在一个可用的event loop上(没有的时候创建),相当于注册到eventloop的多路复用器Selector上,用于接收客户端的TCP连接,关系是1:1:1
如果监听到客户端连接,则创建客户端SocketChannel连接,重新注册到workerGroup的IO线程上。EventLoopGroup从中选择一个I/O线程负责网络消息的读写。选择IO线程之后,将SocketChannel注册到多路复用器上,监听后面的io操作。一个workgroup最多
开cpu数量*2的线程,workgroup:selector:连接 = 1 : n :m
线程安全:Netty采用了串行化设计理念,从消息的读取、编码以及后续Handler的执行,始终都由IO线程NioEventLoop负责,也就是一个客户端连接始终绑定在他一开始注册的NioEvenLoop,这就意味着整个流程不会进行线程上下文的切换,客户端连接不会在两个两个io线程切换,造成可见性问题(工作线程到主内存拷贝的时候有可见性问题,可以引出jmm),所以数据也不会面临被并发修改的风险

复杂和时间不可控业务:在添加 pipeline 中的 handler 时候,添加一个线程池, handler 中的代码不用做任何修改,当selector轮询到它的时候,从上下文中发现有线程池,就用线程池执行耗时任务,不占用当前线程,当耗时任务执行完毕再执行 write 方法的时候,会将任务的结果写入outbound 等待轮询
channel相关:
- 每个Channel会绑定一个ChannelPipeline,每个ChannelPipeline会持有一个Channel
- 每个ChannelHandler对应一个ChannelHandlerContext,ChannelPipeline持有ChannelHandlerContext链表,也就相当于持有ChannelHandler链表
- ChannelHandlerContext作为上下文,持有ChannelPipeline和它对应ChannelHandler的引用,持有ChannelPipeline相当于间接持有Channel,同时持有它上/下一个ChannelHandlerContext的引用
- inbound按照顺序,outbound逆序,inbound事件------channel注册事件,读事件,outbound事件-----bind事件write事件
SimpleChannelInbouundHandler<Object>比channelInboundHandlerAdapter多了添加泛型和自动清空缓冲区


参考
io模型最明白:https://my.oschina.net/zhangph89/blog/967490
比较全面:http://www.infoq.com/cn/articles/netty-threading-model
netty答题的更多相关文章
- hbase之createTable完整的netty实现执行流程
hbase的客户端代码并不想hive一样用java编写,shell调用,而是使用ruby编写. 在admin.rb文件中方法create,其中接受两个参数,其中第二个参数类型为变长参数. 而在crea ...
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
- 谈谈如何使用Netty开发实现高性能的RPC服务器
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...
- 基于netty http协议栈的轻量级流程控制组件的实现
今儿个是冬至,所谓“冬大过年”,公司也应景五点钟就放大伙儿回家吃饺子喝羊肉汤了,而我本着极高的职业素养依然坚持留在公司(实则因为没饺子吃没羊肉汤喝,只能呆公司吃食堂……).趁着这一个多小时的时间,想跟 ...
- 从netty-example分析Netty组件续
上文我们从netty-example的Discard服务器端示例分析了netty的组件,今天我们从另一个简单的示例Echo客户端分析一下上个示例中没有出现的netty组件. 1. 服务端的连接处理,读 ...
- 源码分析netty服务器创建过程vs java nio服务器创建
1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...
- 从netty-example分析Netty组件
分析netty从源码开始 准备工作: 1.下载源代码:https://github.com/netty/netty.git 我下载的版本为4.1 2. eclipse导入maven工程. netty提 ...
- Netty实现高性能RPC服务器优化篇之消息序列化
在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...
- Netty构建分布式消息队列(AvatarMQ)设计指南之架构篇
目前业界流行的分布式消息队列系统(或者可以叫做消息中间件)种类繁多,比如,基于Erlang的RabbitMQ.基于Java的ActiveMQ/Apache Kafka.基于C/C++的ZeroMQ等等 ...
随机推荐
- MVC5 学习笔记 controller
主要参考书籍<ASP.NET MVC5 高级编程(第5版) > 作者:Jon Galloway等 1. MVC 表示 模型-视图-控制器.MVC是一种用于开发应用程序的模式,具备良好的架构 ...
- 浅析postgresql数据库事务及行锁特征
开源数据库领域,postgresql以其优越的性能.功能及良好的稳定性排名首位可谓当之无愧,尤其是对高并发的支持可谓匠心独具.而优越的性能和稳定性,究其根本无非是良好的基础架构,本文将对其性能和稳定性 ...
- 015PHP文件处理——文件处理flock 文件锁定 pathinfo realpath tmpfile tempname
<?php /**文件处理flock 文件锁定 pathinfo realpath tmpfile tempname */ /*$arr=pathinfo('ab.txt');//获取文件路径的 ...
- learning docker steps(2) ----- docker contailner 初次体验
参考:https://docs.docker-cn.com/get-started/part2/ Dockerfile的内容如下所示: # 将官方 Python 运行时用作父镜像 FROM pytho ...
- 通过Viewpager 来实现微信界面左右滑动。
package com.lixu.huadong; import java.util.ArrayList; import android.os.Bundle; import android.suppo ...
- ECharts报表的使用
知道你们懒得手打网址,给你们贴上:http://echarts.baidu.com/echarts2/ 1.下载并解压之后,找到echarts-2.2.7\build\dist\echarts-all ...
- 1.5 C++ new和delete操作符
参考:http://www.weixueyuan.net/view/6331.html 在C语言中,动态分配和释放内存的函数是malloc.calloc和free,而在C++语言中,new.new[] ...
- iOS调用第三方地图App进行导航方法
前言 App内根据手机上装载的地图App将其显示在弹出的选择框,选择对应地图跳转进入地图导航.需要用到- (BOOL)canOpenURL:(NSURL *)url NS_AVAILABLE_IOS( ...
- oracle主从表主外键对应关系
一.首先让我们来了解下什么是主外键? 1.主键:唯一标识数据表中的某一行 1) 一个表中只能有一个主键.如果在其他字段上建立主键,则原来的主键就会取消.在ACCESS中,虽然主键不是必需的,但最好为每 ...
- 解压Ubuntu的initrd.img的方法
Ubuntu的initrd.img可以在/boot中找到,通常文件名后面还跟有很长的一串版本号. 为了保险起见,不直接操作原文件,而是把它复制到自己的家目(home)录中.如果你是用root帐号登录的 ...