由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面。

附上自己的github项目地址 https://github.com/247292980/spring-boot

附上汇总博文地址 https://www.cnblogs.com/ydymz/p/9391653.html

以整合功能

spring-boot,FusionChart,thymeleaf,vue,ShardingJdbc,mybatis-generator,微信分享授权,drools,spring-security,spring-jpa,webjars,Aspect,drools-drt,rabbitmq,zookeeper,mongodb,mysql存储过程,前端的延迟加载,netty,postgresql,树的遍历

这次再次说下netty,为什么在学netty呢?因为面试一家大公司的时候,被问倒了,,,所以只好耐下心来看原理了。

目前看了两本netty的书(市面上就两本 orz)第一感觉就是netty的书怎么说呢,就是demo集合,某程度还是挺好看懂的,但是过时啊。

不过参考之前写drools的痛苦经验,国内大部分环境应该也是用过时的netty,不信你去技术群里问下新版netty的特性,大家一定会劝你去踩坑...

而这篇文章也不介绍新特性,只是对netty的原理研究。说实话就是丢图,,,

二 模型

说到netty一定要知道他的基本模型。

1.先说下之前的bio-同步阻塞io

显然有点网络基础的人都写过类似的代码。优缺点很明显

缺点:性能瓶颈。每个链接一个线程,怎么保证线程的即时回收和可靠回收是一大技术问题。而该模型在遇到大量线程的时候(超过某个阈值,例如java默认的线程上限或者linux的默认线程上限之类的)性能指数性下降啊。

优点:简单。所以我才说有点网络基础的人都写过类似的代码,,,除非直接起手springboot的

2.后面就是nio-同步非阻塞io

acceptor收到所有的连接请求

acceptor上注册了selector,

服务器构建对应的Channel,并在其上注册Selector

selector分配请求到不同的channel,进行相应的读写处理。

ps.写完发现可能有点难理解,具体代码项目里面有。

其实就是selector分配请求,channel处理请求并能通过selector得到client,等处理完成后直接返回client,不走selector。

优点:一个线程处理全部连接,不阻塞后面的连接。性能大提升!

缺点:模型复杂,代码复杂(至少我觉得不看一下代码,很难说清);处理半包问题

ps.半包问题

我们知道TCP/IP在发送消息的时候,可能会拆包。这就导致接收端无法知道什么时候收到的数据是一个完整的数据。

例如:发送端分别发送了ABC,DEF,GHI三条信息,发送时被拆成了AB,CDRFG,H,I这四个包进行发送,接受端如何将其进行还原呢?在BIO模型中,当读不到数据后会阻塞,而NIO中不会!所以需要自行进行处理!说到底就是自定义网络协议,额其实这个有点基础的都写过,我也不细说了。

3.所以为了解决这问题,netty就使用了Reactor模型-bio的变种

具体来说这是reactor的单线程模型,可以看出和bio基本没什么差别,就是把channel的数据处理提到handler,并且统一在reactor注册了,而不用去acceptor,channel分别注册在两个地方,统一处理了。

但是这玩意有个问题就是,一个client多次请求,handler中的处理特别慢,那么后续的请求就会被积压。

4.Reactor多线程模型

reactor将接受发送分离,client发送的请求丢到线程池中,所以后续请求不会被阻塞。

但是当用户进一步增加的时候,Reactor会出现瓶颈!因为Reactor既要处理IO操作请求,又要响应连接请求!为了分担Reactor的负担,所以引入了主从Reactor模型!

上面的这一句话是书上原话,其实我是不太赞成的,因为说到底就是一个线程的事,所以没可能是性能瓶颈,而在我看来netty使用主从reactor的主要原因是代码可读性和易于理解。

5.Reactor主从模型

简单明了

client发送请求

acceptor就是个死循环监听

mainreactor分配acceptor监听到的请求到channel

channel通过subreactor将请求发到handler处理,然后直接返回给client

ps.注意的是mainreactor一定是单线程,多线程可能导致为client分配channel的时候,一个线程分配了一个,浪费资源;也存在一个client的请求去了两线程,而其中一个处理很久,另一个则早早完成,而此时client的等待时间是取最大等待时间的,那么早早完成的还不如一起在另一个处理很久的线程里面;

主从模型最精彩的地方在于,主reactor和从reactor的分离,可以让住reactor有更多的花样,如验权授权等,更加便于大数据手机分析

三 术语

bootstrap: Netty 通过设置 bootstrap(引导)类的开始,该类提供了一个应用程序网络层配置的容器

Channel: 是一个客户端用来进行连接的 Channel,记录了client信息,用于io操作的交互

ChannelHandler: 数据处理的容器

ChannelPipeline:提供了一个容器给 ChannelHandler 链并提供了一个API 用于管理沿着链入站和出站事件的流动

EventLoop: EventLoop 用于处理 Channel 的 I/O 操作。一个单一的 EventLoop通常会处理多个 Channel 事件

EventLoopGroup:可以含有多于一个的 EventLoop 和 提供了一种迭代用于检索清单中的下一个

ChannelFuture: ChannelFuture是netty的一个回调不管是否成功返回

ChannelFutureListener:ChannelFuture通过addListener 注册。当操作完成时,可以被通知(不管成功与否)

ps.ChannelFutureListener加上了之后就可以说是实现异步。

四 channel

通常来说, 所有的 netty 的 I/O 操作都是从 Channel 开始的. 一个 channel 类似于一个 stream.

Stream 和 Channel 对比

我们可以在同一个 Channel 中执行读和写操作, 然而同一个 Stream 仅仅支持读或写.

Channel 可以异步地读写, 而 Stream 是阻塞的同步读写.

Channel 总是从 Buffer 中读取数据, 或将数据写入到 Buffer 中.

Channel 类型有:

FileChannel, 文件操作

DatagramChannel, UDP 操作

SocketChannel, TCP 操作

ServerSocketChannel, TCP 操作, 使用在服务器端.

五 Buffer

与 Channel 进行交互时, 我们就需要使用到 Buffer, 即数据从 Buffer读取到 Channel 中, 并且从 Channel 中写入到 Buffer 中.

Buffer 其实就是一块内存区域,  并提供了一些操作方法让我们能够方便地进行数据的读写.

Buffer 类型有:

ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,LongBuffer,ShortBuffer(就是基本类型啊)

六 Selector

Selector 允许一个单一的线程来操作多个 Channel. 如果我们的应用程序中使用了多个 Channel, 那么使用 Selector 很方便的实现这样的目的, 但是因为在一个线程中使用了多个 Channel, 因此也会造成了每个 Channel 传输效率的降低.

为了使用 Selector, 我们首先需要将 Channel 注册到 Selector 中, 随后调用 Selector 的 select()方法, 这个方法会阻塞, 直到注册在 Selector 中的 Channel 发送可读写事件. 当这个方法返回后, 当前的这个线程就可以处理 Channel 的事件了.

七 Bootstrap

Bootstrap 是 Netty 提供的一个便利的工厂类, 我们可以通过它来完成 Netty 的客户端或服务器端的 Netty 初始化.

八 ChannelPipeline

一个 Channel 包含了一个 ChannelPipeline, 而 ChannelPipeline 中又维护了一个由 ChannelHandlerContext 组成的双向链表

java使用netty的模型总结的更多相关文章

  1. eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结

    eventloop的基本概念可以参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html Eventloop指的是独立于主线程的一条线程,专门 ...

  2. Java后端进阶-网络编程(Netty线程模型)

    前言 我们在使用Netty进行服务端开发的时候,一般来说会定义两个NioEventLoopGroup线程池,一个"bossGroup"线程池去负责处理客户端连接,一个"w ...

  3. I/O模型之四:Java 浅析I/O模型(BIO、NIO、AIO、Reactor、Proactor)

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  4. Netty系列之Netty线程模型

    Reference: http://www.infoq.com/cn/articles/netty-threading-model 1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 ...

  5. 彻底搞懂 netty 线程模型

    编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等.本文就netty线程模型展开 ...

  6. 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型

    一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...

  7. Netty线程模型

    一.Reactor模型 1.单线程模型 Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接: 2)作为NI ...

  8. Java对象的内存模型(一)

    前言 新人一枚,刚刚入门编程不久,各方面都在学习当中,博文有什么错误的地方,希望我们可以多多交流! 最近,在开发App后台过程中,需要将项目部署到云服务器上.而云服务器的内存大小却只有1G.要如何做到 ...

  9. Java虚拟机:内存模型详解

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...

随机推荐

  1. 以太坊系列之十八: 百行go代码构建p2p聊天室

    百行go代码构建p2p聊天室 百行go代码构建p2p聊天室 1. 上手使用 2. whisper 原理 3. 源码解读 3.1 参数说明 3.1 连接主节点 3.2 我的标识 3.2 配置我的节点 3 ...

  2. 多线程《八》线程queue

    一 线程queue queue is especially useful in threaded programming when information must be exchanged safe ...

  3. Jmeter_使用IE代理录制脚本

    因为项目登录的密码需要RSA加密,选用了jmeter作为压测工具: 就自己本次项目,顺便学习Jmeter,做一个简单的记录,本文主要介绍使用IE代理录制脚本: 自己也尝试过使用Badboy录制,还是喜 ...

  4. CKEditor富⽂本编辑器

    在运营后台,运营⼈员需要录⼊商品并编辑商品的详情信息,⽽商品的详情信息不是普通的⽂本, 可以是包含了HTML语法格式的字符串.为了快速简单的让⽤户能够在⻚⾯中编辑带格式的⽂本,我们引⼊富⽂本编辑器.富 ...

  5. 题解 P2863 【[USACO06JAN]牛的舞会The Cow Prom】

    题目链接 赤裸裸的板子,就加一个特判就行.直接上代码 #include<stdio.h> #include<algorithm> #include<iostream> ...

  6. VS2017+DLib_19.17详细配置教程

      最近学校布置了一个关于图像融合的作业,于是想利用Learn OpenCV 网站上的Face Morph 教程来设计一个人脸融合的Gif图,但是程序中需要用到DLib库,光是配置这个库就花费了我半天 ...

  7. Python3之shutil模块

    一. 简介 shutil 是高级的文件,文件夹,压缩包处理模块. 二. 使用 shutil.copyfileobj(fsrc, fdst[, length])将文件内容拷贝到另一个文件中 import ...

  8. zabbix 3.0 快速安装文档

    下载地址:http://www.zabbix.com/download.php 官方文档:https://www.zabbix.com/documentation/3.0/manual/install ...

  9. JS中Math函数的常用方法

    Math 是数学函数,但又属于对象数据类型 typeof Math => ‘object’ console.dir(Math) 查看Math的所有函数方法. 1,Math.abs() 获取绝对值 ...

  10. tomcat更改web文件路径

    由于代码太长,记不住!只能自己做个小笔记了!! <Context path="/" docBase="/opt/appl/merch.bak" debug ...