Netty概述

Stella981
• 阅读 683

1.Netty概念

  • 异步事件驱动框架,用于快速开发高性能服务端和客户端
  • 封装了JDK底层BIO和NIO模型,提供高度可用的API
  • 自带编解码器解决拆包粘包问题,用户只用关心业务逻辑
  • 精心设计的reactor线程模型支持高并发海量连接
  • 自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手
  • 各大开源项目选择Netty作为底层通信框架

2.Netty使用场景

  • 高性能领域
  • 多线程并发领域
  • 异步通信领域

3.IO通信

(1)BIO通信

  • 一个线程负责连接:一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端的请求连接之后,为每个客户端创建一个新的线程进行链路处理,处理完成之后通过输出流应答给客户端,此时线程销毁。
  • 一请求一应答通信模型。
  • 缺陷:缺乏弹性伸缩能力。当客户端的并发访问量增加以后,服务端的线程个数和客户端的并发访问数呈1:1的正比关系,由于线程是java虚拟机非常宝贵的系统资源,当线程数膨胀之后,系统的性能将急剧下降,随着并发访问量的逐渐增大,系统将会发生线程堆栈溢出,创建新线程失败等问题,最终导致进程宕机或者僵死,不能对外提供服务。
  • 当有N个客户端接入的时候,服务端用一个Acceptor线程监听,它在服务端创建N个线程来对客户端的请求进行处理(客户端的个数=服务端创建的线程个数)

(2)伪异步IO通信

  • 线程池负责连接:当有新的客户端接入时,将客户端的socket封装成一个task投递到后端的线程池中进行处理。
  • M请求N应答:JDK的线程池维护一个消息队列和N个活跃的线程,对消息队列中的任务进行相关的处理。当有M个客户端接入的时候,服务端将会创建一个具有N个线程的线程池来对客户端的请求进行处理。
  • 线程池阻塞:由于线程池可以设置消息队列的大小和最大线程数,因此它的资源占用是可控的,无论多少个客户端并发访问,都不会导致资源的耗尽和宕机。不足之处就是当有大量的客户端接入时,随着并发访问量的不断增加,异步IO通信可能会造成线程池阻塞。
  • 伪异步IO通信模型与BIO通信模型最大的区别:伪异步IO不再针对每一个客户端创建一个独立的线程,而是由一个线程池统一处理所有客户端的接入。

(3)NIO通信(重点)

  • 缓冲区Buffer:它是一个对象,包含一些要写入或读出的数据,在NIO类库中加入Buffer对象体现了新库与原IO的一个重要区别,在面向流的IO中可以将数据直接写入或者将数据直接读到Stream对象中,在NIO库中所有数据都是用缓冲区处理的,在读取数据时,它直接读到缓冲区中;在写入数据时,也是写入到缓冲区中。任何时候访问NIO中的数据都是通过缓冲区进行操作。
  • 通道Channel:它是一个通道,像是自来水管,网络数据通过Channel读取和写入,通道与流的不同之处在于通道是双向的,流只是在一个方向上移动,一个流必须是InputStream或者OutputStream的子类, 而通道可以用于读写或者二者同时进行。
  • 多路复用器Selector:它是javaNIO编程的基础,它提供了选择已经就绪的任务的能力,Selector会不断地轮询出Channel,如果某个Channel上发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以获取就绪Channel的集合进行后续的IO操作,由于JDK使用了epoll代替了传统select的实现,所以它没有最大连接数的限制,可以接入成千上万的客户端,在IO通信领域是一个巨大的进步。

(4)AIO通信

  • 连接注册读写事件和回调函数
  • 读写方法异步
  • 主动通知程序AIO异步通道提供了两种方式获取操作结果。(1)通过Java.util.concurrent.Future类来表示异步操作的结果; (2)在执行异步操作的时候传入一个Java.nio.channels. CompletionHandler接口的实现类作为操作完成的回调。 AIO的异步套接字通道是真正的异步非阻塞IO,对应于UNIX网络编程中的事件驱动IO(AIO),它不需要通过多路复用器(Selector)对注册的通道进行轮询操作即可实现异步读写,从而简化了NIO的编程模型。

 

(5)四种IO对比

Netty概述

4.NIO与Netty

(1)原生NIO的缺陷

  • 类库和API繁杂
  • 入门门槛高
  • 工作量和难度大
  • JDK NIO存在Bug

(2)Netty的优势

  • API简单
  • 入门门槛低
  • 性能高
  • 成熟稳定

5.WebSocket

(1)WebSocket概念

  • H5协议规范
  • 握手机制:客户端和服务器可以建立一个类似TCP的连接,从而方便客户端和服务器之间的通信。在WebSocket出现之前,Web交互基于http之间的短连接或者长连接。
  • 解决客户端与服务端实时通信而产生的技术。WebSocket协议本质上是基于TCP的协议,是先通过http https协议发起一条特殊的http请求,进行握手后创建一个用于交换数据的TCP连接,此后服务端和客户端通过此TCP连接进行实时通信。注意,当WebSocket的客户端与服务器端进行通信以后,此时就不再需要之前进行握手请求的http协议的参与了。

(2)WebSocket优点

  • 节省通信开销。以前的WebServer实现推送技术或者即时通讯用的都是轮询,在特定的时间间隔比如1s,由浏览器自动发起请求,将服务器的消息主动拉回来,在这种情况下,我们需要不断地向服务器发送请求,然而http的request的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源。
  • 服务器主动传送数据给客户端。WebSocket可以使服务器和客户端在给定的时间范围内任意时刻相互推送信息,浏览器和服务器只需要做一个握手的动作,在建立连接之后,服务器可以主动传送数据给客户端,客户端也可以随时向服务器发送数据,此外服务器和客户端直接交换的标头信息也是非常小的。
  • 实时通信。WebSocket不仅限以Adjax方式进行通信,因为Adjax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息,从而实现实时通信。

(3)WebSocket建立连接

  • 客户端发起握手请求
  • 服务端响应请求
  • 连接建立

 

(4)WebSocket生命周期

  • 打开事件:@OnOpen 此事件发生在端点上建立新连接时并且在任何其他事件发生之前

  • 消息事件:@OnMessage 此事件接收WebSocket对话中另一端发送的消息。

  • 错误事件:@OnError 此事件在WebSocket连接或者端点发生错误时产生

  • 关闭事件:@OnClose 此事件表示WebSocket端点的连接目前部分地关闭,它可以由参与连接的任意一个端点发出

(5)WebSocket关闭连接

  • 服务器关闭底层TCP连接
  • 客户端发起TCP Close
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这