网络io相关

基础概念

阻塞

请求资源得不到满足停下来等待

同步 异步

同步 : 多个线程不能同时进行,一个个来
异步: 多个线程可以同时开工

i/o

两个状态

  • 读入/写出数据的过程
  • 等待读入/写出数据的过程

阻塞io

用户线程运行在用户空间,数据没有到达用户空间,则用户线程被阻塞在io上等待数据或拷贝数据上。

  • 等待数据或拷贝数据??

非阻塞io

用户数据拷贝到用户空间以后,去通知用户线程去执行

同步阻塞io

等待数据或拷贝数据,线程都在阻塞
等待数据:线程采用死循环轮训
拷贝数据:线程阻塞

没有同步非阻塞io

io

  • 哪些地方用到:
    tomcat、redis、kafka、nginx、mysql、libuv、netty
  • 怎么实现
    只要运行在linux 基于linux
  • 学习路径
    io->网络通信io(socket) ->bio ->nio 多路复用 ->netty

io建立连接 与请求

分两种:

  1. 一种 建立连接没有请求
  2. 建立连接有请求

java的线程

调用内核的系统调用,当做一个轻量级进程,他们会以进程id来表示

操作系统层网络io处理对应的三步

在这里插入图片描述
fd:3
端口:8090

了解socket 中的阻塞

strace linux指令 追踪java线程
在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mp30lS0s-1631010805139)(en-resource://database/3213:0)]

tcp->socket

socket 得到一个fd->bind 绑定fd 到端口->listen监听fd->accept 返回clone线程fd->clone->recv 等待资源返回到fd
accept代表 客户端过来的请求是本机ip并且 是8090端口号,交给server 3处理

当有请求访问8090端口后
在这里插入图片描述
主线程克隆一个子线程将此客户端交给子线程处理 8281子线程返回
在这里插入图片描述
在这里插入图片描述
clone多个子线程

  1. .accept() 等待客户端请求 接收用户端连接 会阻塞
  2. inputStreamReader(in); 如果客户端不发送数据 会阻塞
    5是代表客户端请求
    在这里插入图片描述

操作系统内核升级

(学习计组原理)

网络通信io演变过程

bio 同步阻塞

会位每一个连接分配一个线程
在这里插入图片描述

主线程 clone一个线程,将此socket对应到此线程阻塞,每一个socket对应一个线程

优势

可以接收很多的连接

弊端
  1. 线程内存浪费
  2. cpu调度消耗
  • 根源
    阻塞(blocking) accept 、recv

同步非阻塞nio

注册特定的io事件,在发生特定事件时,系统再通知我们,核心对象selecter。注册事件发生时,从selector中获得selectionKey,找到相应的selectableChannel以获得以获得客户端数据。

  • 非阻塞指io事件本身不阻塞,获取io事件select()是阻塞的,这时候io操作还没有发生所以我们认为他不阻塞。
  • 本质是延迟io操作到真正发生io的时候。

核心

  1. channels
  2. buffers
  3. selectors
    非核心
  4. pipe
  5. filelock

channels

  • stream单向 channels双向
  • 不必关心数据源具体的物理结构。
  • 用于在字节缓冲区和位于通道另一侧的实体(文件或套接字)传输数据。
主要实现
  1. filechannel 文件读写
  2. datagramChannel(udp)
  3. socketChannel(tcp)
  4. serverSocketChannel(坚挺新进来的tcp连接)

buffer

selector

单线程处理多个channel

在这里插入图片描述
一次轮询返回一个fd

文件描述符FD 一切皆文件

一个用户线程fd
java:流

io多路复用技术

可以监视多个描述符,一旦某个描述符就绪,能够通知程序进行相应的操作。
多路复用主要有三种技术:select,poll,epoll
在这里插入图片描述

“复用”指的是复用同一个recv调用

多路复用器

用一次系统调用找到所有io状态 尽量少的recv
允许一个程序监控多个fd
返回一个状态

select poll

在这里插入图片描述

select

一次轮询返回多个fd
select 1024个fd数量限制

poll

没有 限制

优势

通过一次系统调用,把fds传递给内核,内核进行遍历,减少了系统调用次数

弊端

重复传递fd 解决:内核开辟空间存储传来的fd 和 返回区
每次select、poll 都要遍历全量fd 解决:中断 callback

epoll 非阻塞

在这里插入图片描述

利用多核
空间换时间

  1. 在Linux内核中构建了一个文件系统 mmap就绪队列,该文件系统采用红黑树来构建,红黑树在查询、新增、删除的效率极高,保障了在存在大量活跃连接的情况下的性能。
  2. 其次Epoll红黑树上采用事件异步唤醒,内核监听I/O,事件发生后内核搜索红黑树并将对应节点数据放入异步唤醒的事件队列中。这就避免了无差别的轮询,不会因为连接数增加而导致性能的快速下降
  3. 数据从用户空间到内核空间采用mmap存储I/O映射来加速。该方法是目前Linux进程间通信中传递最快,消耗最小,传递数据过程不涉及系统调用的方法。这点大大提升了存在大量FD时数据拷贝的消耗。
  4. 有返回区 请求数据
函数 3个

create(int)就绪队列大小
ctl()控制fd增删改查
int nready=wait(fd,事件,大小,time)多长时间取一次 返回多个准备好了

水平触发 边缘触发

水平触发 一次性读完
边缘触发 多次读取

epoll 6种做法
  1. 单线程处理accept 多线程出来recv/send
  2. 多线程处理accept 多线程处理 recv/send
  3. 多线程epoll-wait()不区分accept与、recv/send
    多进程 session独立 前后不关联
  4. 多进程epollwait()不区分 accept与recv/send nginx
linux 系统调用查看指令

man 2 系统调用
tail -f out 8211
netstat -natp

零拷贝 sendfile 系统调用

在这里插入图片描述

kafka mmap+sendfile

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值