高并发网络编程

高并发网络编程

网络七层模型

为了使不同计算机厂家的计算机能够互互相通信,以便在更大的范围内建立计算机网络,有必要建立一个估计规范的网络体系结构标准。
在这里插入图片描述

各层的主要功能

低三层,
物理层:使原始的数据比特流能在物理介质上传输。
数据链路层:通过校验、确认和反馈重要手段、形成稳定的数据链路
网络层:进行路由选择和流量控制(ip协议)

传输层:提供可靠的端口到端口的数据传输服务(TCP/UDP协议)

高三层,
会话层:负责建立、管理和终止进程之间的会话和数据交互。
表示层:负责数据格式转换、数据加密、压缩与解压等。
应用层:为用户的应用进程提供网络服务。

传输控制协议TCP

传输控制协议(TCP)是internet 一个重要的传输层协议。TCP提供面向连接、可靠、有序、字节流传输服务。应用程序在使用TCP之前。必须先建立TCP连接。

在这里插入图片描述

TCP握手机制

确认网络是否通畅
客户端:你好,能听见吗?
服务端:你好,我能听见。
客户端:好的,明天来我家吃饭。
在这里插入图片描述

四次挥手
客户端:我说完了,我准备挂电话了。
服务端:好的,你可以挂电话了。
服务端:拜拜
客户端:拜拜

服务端挂断
客户端挂断

用户数据报协议UDP
用户数据报协议UDP是internet传输协议。
提供无连接、不可靠、数据报尽力传输服务。

Socket编程

Internet中应用最广泛发网络应用编程接口,实现与3种低层协议接口:
数据报类型套接字SOCK_DGRAM(面向UDP接口)
流式套接字SOCK_STREAM(面向TCP接口)
原始套接字SOCK_RAW(面向网络层协议接口IP、ICMP)

主要Socket API及调用过程。
创建套接字-端点绑定-发送数据-接受数据-释放套接字

BIO网络编程

Http协议-请求数据包解析

第一部分: 请求行,请求类型,资源路径以及HTTP版本。
第二部分:请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器使用的附加信息
第三部分:空行,请求头部后面的空行是必须的请求头部和数据主体之间必须有换行
第四部分:请求数据也叫主体,可以添加任意的数据。

http协议-响应数据包解析

第一部分:状态行。HTTP版本、状态码、状态消息。
第二部分:相应报头部分,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加消息
第三部分:空行,头部后面的空行必须的头部和数据主体之间必须有换行。
第四部分:响应正文。可以添加任意的数据。

http 协议-响应状态码

1XX (临时响应)
表示临时响应并需要请求者继续执行操作的状态代码
2XX (成功)
表示成功处理了请求的状态代码
3XX (重定向)
表示要完成请求,需要进一步的操作。通常,这些状态代码用来重定向。
4XX (请求错误)
这些状态代码表示请求可能出错了,妨碍了服务器的处理
5XX (服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。

BIO -阻塞IO的含义

阻塞(blocking) IO: 资源不可用时,IO请求一直阻塞,直到反馈结果。
非阻塞(non-blocking)IO: 资源不可用时,IO请求离开返回,返回数据标识资源不可用。

同步(synchronous)IO:应用阻塞在发送或者接受数据的状态,直到数据成功传输或返回失败。
异步(asynchronous)IO:应用发送或者接受数据后立即返回,实际处理是异步执行的。

JAVA NIO

三个核心组件
Buffer 缓冲区
Channel 通道
Sellector 选择器

Buffer缓冲区

缓冲区本质上是一个可用写数据的内存块(类似数组),然后可以再次读取。此内存块包含在NIO Buffer对象中,该对象提供了一组方法,可以更轻松地使用内存块。
相比较直接对数组的操作,Buffer API更加容易操作和管理。

使用Buffer进行数据写入与读取,需要进行如下四个步骤:
1.将数据写入缓冲区
2.调用buffer.flip(),转换为读取模式
3.缓冲区读取数据
4.调用buffer.clear()或者buffer.compact()清楚缓冲区

Buffer工作原理

Buffer 三个重要属性
Capacity 容量:作为一个内存块,Buffer具有一定的固定大小,也称‘容量’。
Position 位置:写入模式时表示数据的位置。读取模式时代表读取数据的位置。
Limit限制:写入模式,限制等于buffer的容量。读取模式下,limit等于写入的数据量。

在这里插入图片描述

ByteBuffer内存类型

ByteBuffer 为性能关键型代码提供了直接内存(direct堆外)和非直接内存(heap堆)两种实现。
堆外内存获取的方式:ByteBuffer directByteBuffer = ByteBuffer.allocateDirct(noBytes);

好处:
1.进行网络IO或者文件IO时比heapBuffer少一次拷贝。(file/socket—OS memory—居民heap)GC会移动对象内存,在写file或socket的过程中,JVM的实现中,会先把数据复制到堆外,再进行写入。
2.GC范围之外,降低GC压力,但实现了自动管理。DirectByteBuffer中有一个Cleaner对象(PhantomReference),Cleaner被GC前会执行clean方法,触发DirectByteBuffer中定义的Ceallocator

建议:
1.性能确实可观的时候才去使用;分配给大型、长寿命:(网络传输,文件读写场景)
2.通过虚拟机参数MaxDirectMemorySize限制大小,防止耗尽整个机器的内存;

Channel通道

SocketChannel

SocketChanne用于建立TCP网络连接,类似java.net.Socket 有两种创建SoketChannel形式:
1.客户端主动发起和服务器的连接。
2.服务端获取的新连接。
!](https://img-blog.csdnimg.cn/20191106125847309.png)

Write 写: write()在尚未写入任何内容时就可能返回了。需要在循环中调用write().
Read 读:read()方法可能直接返回而根本不读取任何数,根据返回的int值判读读取了多少字节。

ServiceSocketChannel

可以监听新建的TCP连接通道,类型ServerSocket.
在这里插入图片描述
serverSocketChannel.accept();如果该通道处于非阻塞模式,那么如果没有挂起的连接,该方法将立即返回null。必须监测返回的SocketChannel是否为null。

Selector选择器

是一个javaNIO组件,可以检查一个或者多个NIO通道,并确定哪些通道已经准备好进行读取或写入。实现单个线程可以管理多个通道,从而管理多个网络连接。

一个线程使用Selector监听多个channeld的不同事件。
四个事件分别对应selectionKey四个常量。
1.Connect连接(SelectionKey.OP_CONNECT)
2.Accept准备就绪(OP_ACCEPT)
3.Read读取(OP_READ)
4.Write写入(OP_WRITE)
在这里插入图片描述

实现一个线程处理多个通道的核心概念理解:事件驱动机制。
非阻塞的网络通道下,开发者通过Selector注册对于通道感兴趣的事件类型,线程通过监听事件来触发相应的代码执行(拓展:更低层是操作系统的多路复用机制)

Netty

是一个高性能,高可扩展性的异步事件驱动的网络应用程序框架,它极大地简化了TCP和UDP客户端和服务器开发等网络编程。

Netty重要的四个内容:
1.Reactor线程模型:一种高性能的多线程程序设计思路
2.Netty中自己定义Channel概念:增强版的通道概念
3.ChannelPipeline责任链设计模式:事件处理机制
4.内存管理:增强的ByteBuf缓冲区

Netty线程模型

为了让NiO处理更好的利用多线程特性,Netty实现了Reactor线程模型
Reactor模型中有四个核心概念
1.Resources 资源(请求/任务)
2.Synchronous Event Demultiplexer 同步事件复用器
3.Dispatcher 分配器
4.Request Handler 请求处理器

EventLoopGroup 初始化过程

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

责任链模式

责任链模式(Chain of Responsibility Pattern) 为请求创建了一个处理对象的链。

发起请求和具体处理请求的过程进行解耦:责任链上的处理者负责处理请求,客户只需要将请求发送到责任链上即可,无线关系请求的处理细节和请求的传递。

实现责任链模式4个要素:处理器抽象类、具体的处理器实现类、保存处理器信息、处理执行

Pipleline管道

保存了通道所有处理器信息。
创建新channel时会自动创建一个专有的pipeline
入站事件和出战操作会调用pipleline上的处理器

入站事件:通常指I/O线程生成了入站数据。
(通俗理解:从socket底层自己往上冒上来的事件都是入站)
比如EventLoop收到selector的OP_READ事件,入站处理器调用socketChannel.read(ByteBuffer)接受到数据后,这将导致通道的ChannnelPipleline中包含的下一个中的channelRead方法调用。

出战事件:通常是指I/o线程执行实际的输出操作。
(通俗理解:想主动往socket底层操作的事件都是出站)
比如bind方法用意是请求server socket 绑定到给定socketAddress,这将导致通道的 ChannelPipeline 中包含的下一个出战处理器中的bind方法被调用。

Pipleline中的handler是什么

ChannelHandler:用于处理I/O事件或者拦截I/O操作,并转发到ChannelPiple中的下一个处理器。
这个顶级接口定义功能很弱,实际使用时会去实现下面两个大子接口:
处理入站I/O事件的ChannelInboundHandler ,处理出战I/o操作的ChannelOutboundHandler

适配器类:为了开发方便,避免所有handler去实现一遍接口方法,Netty提供了简单的实现类:
ChannelInboundHandlerAdapter 处理入站I/O事件
ChannelOutboundHandlerAdapter 处理出站I/O操作
ChannelDuplexHandler来支持同时处理入站和出站事件

ChannelHanderContext :实际存储在Pipline中的对象并非ChannelHandler,而是上下文对象。
将handler,包裹在上下文对象中,通过上下文对象与它所属的ChannelPipleline交互,向上或向下传递事件或者修改pipeline都时通过上下文对象。

ChannelPipeline是线程安全的,ChannelHandler可以在任何时候添加或者删除。
例如,你可以在即将交互敏感信息时插入加密处理程序,并在交换后删除她。一般操作,初始化的时候增加进去,较少删除。

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值