极客大学架构师训练营 网络通信协议 非阻塞网络I/O NIO 数据库架构原理 第16课 听课总结
说明
讲师:李智慧
网络通信协议
Web 请求的一次网络通信历程
客户端 > 域名访问 > DNS 解析为 IP地址 >
- 获取静态资源 jpg, css, javascript, 通过CDN
- 获取动态资源,基于TCP访问到负载均衡服务器 (比如订单、商品详情等)
反向代理服务器 > 负载均衡服务 > 网关服务器 > 微服务服务器 > - 数据库服务器 (基于TCP协议访问 )
- 缓存服务器(基于TCP协议访问 )
OSI 七层模型和TCP/IP四层模型
- 链路层(Mac地址),互联网有很多种媒介,比如光纤,网线等,要定义好什么是0,什么是1. 比如大于多少电压是1。
- 网络互联层,根据Router路由选择找到目标服务器,根据迪杰斯特拉算法得到最短路径。
- 传输层,主要看监听的端口,socket。
- 应用层,把二进制返回给应用,应用需要反序列化为程序可识别的数据。HTTP协议。
- 应用层 HTTP
- 传承层 TCP/IP 协议
- 互联网 IP 数据
- 网络接口 Mac地址
每一层都包了一个头和数据,传到下一层。
解析的话,就是把头都脱掉,剩下的就是下一层的数据。
网络数据包格式
- HTTP协议头,方法(POST), path, 编码(utf-8)
- TCP 协议头,HTTP进程监听端口
- IP协议头,服务器IP
- 链路层协议头,服务器Mac地址
物理层
物理层负责数据的物理传输,计算机输入输出的只能是0 1 这样的二进制数据,但是在真正的通信线路里有光纤、电缆、无线各种设备。光信号和电信号,以及无线电磁信号在物理上是完全不同的,如何让这些不同的设备能够理解、处理相同的二进制数据,这就是物理层要解决的问题。
链路层
链路层就是将数据进行封装后交给物理层进行传输,主要是将数据封装成数据帧,以帧为单位通过物理层进行通信,有了帧,就可以在帧上进行数据校验,进行流量控制。
链路层会定义帧的大小,这个大小也被称为最大传输单元。像HTTP要在传输的数据上添加一个HTTP头一样,数据链路层也会将封装好的帧添加一个帧头,帧头里记录的一个重要信息就是发送者和接收者的 MAC地址。MAC地址是网卡的设备标识符,是唯一的,数据帧通过这个信息确保数据送达到正确的目标机器。
数据链路层负载均衡
负载均衡服务器直接改Mac地址,达到负载均衡。
网络层
网络层 IP 协议使得互联网应用根据 IP 地址就能访问到目标服务器,请求离开 App 后,到达运营服务商的交换机,交换机会根据这个 IP 地址进行路由转发,可能中间会经过很多个转发节点,最后数据到达目标服务器。
网络层的数据需要交给链路层进行处理,而链路层帧的大小定义了最大传输单元,网络层的 IP 数据包必须要小于最大传输单元才能进行网络传输,这个数据包也有一个 IP 头,主要包括的就是发送者和接收者的 IP 地址。
IP负载均衡
负载均衡服务器通过修改IP地址,到达内网的应用服务器。
传输层(TCP协议)
IP 协议不是一个可靠的通信协议,不会建立稳定的通信链路,并不会确保数据一定送达。要保证通信的稳定可靠,需要传输层协议 TCP。
TCP协议是一种面向连接的、可靠的、基于字节流的传输层协议。TCP作为一个比较基础的通讯协议,有很多重要的机制保证了 TCP 协议的可靠性和健壮性:
- 使用序号,对收到的 TCP 报文段进行排序和检测重复的数据。
- 无错传输,使用校验和检测报文段的错误。
- 使用确认和计时器来检测和纠正丢包或者延迟。
- 流量控制,避免主机分组发送得过快而使接收方来不及完全收下。
- 拥塞控制,发送方根据网络承载情况控制分组的发送量,以获得高性能同时避免拥塞崩溃。
- 丢失包的重传。
TCP 建立连接的3次握手过程
- App 先发送
SYN=1
,Seq=X
的报文,表示请求建立连接,X是一个随机数; - 服务器收到这个报文后,应答
SYN=1
,ACK=X+1
,Seq=Y
的报文,表示同意建立连接; - App 收到这个报文后,检查 ACK 的值为自己发送的
Seq 值 +1
,确认建立连接,并发送ACK = Y + 1
的报文给服务器;服务器收到这个报文后检查 ACK 值为自己发送的Seq值 + 1
,确认建立连接。至此,App 和服务器建立 TCP 连接,就可以进行数据传输。
TCP 关闭连接4次挥手
- 客户端向服务器发送一个 FIN,请求关闭数据传输。
- 当服务器收到客户端的 FIN 时,向客户端发送一个 ACK,其中 ACK 的值等于
FIN + SEQ
。 - 然后服务器向客户端发送一个 FIN,告诉客户端应用程序关闭。
- 当客户端收到服务器的 FIN 时,回复一个 ACK 给服务器。其中 ACK 的值等于
FIN + SEQ
。
注意:客户端和服务端都可以发起关闭连接。
应用层 HTTP 协议
而互联网应用需要在全球范围为用户提供服务,将全球的应用和全球的用户联系在一起,需要一个统一的应用层协议,这个协议就是HTTP协议。
HTTP请求的7种方法
- Get: 只读请求,请求处理过程不应该产生副作用,即web应用不应该因为get请求而发生任何状态改变。
- Head:和get方法一样,但是只返回响应头。
- Post:提交请求。
- Put:上传请求。
- Delete:删除URL标识的资源。
- Trace:回显服务器收到的请求,用以测试或者诊断。
- Options:请求服务器返回支持的所有HTTP请求方法,测试服务器是否正常。
HTTP 响应的5种状态
- 1XX 消息 – 请求已被服务器接收,继续处理。
- 2XX 成功 – 请求已成功被服务器接收、理解、并接受。
- 3XX 重定向 – 需要后续操作才能完成这一请求。
- 4XX 请求错误 – 请求含有词法错误或者无法被执行。
- 5XX 服务器错误 – 服务器在处理某个正确请求时发生错误。
HTTP 协议版本
HTTP 1.0
1996 年发布了 HTTP/1.0, 在HTTP/1.0中,客户端和服务端之间交换的每个请求 / 响应都会创建一个新的 TCP 连接,这意味着所有请求之前都需要进行 TCP 握手连接,因此所有请求都会产生延迟。
HTTP 1.1
HTTP/1.1 试图引入保持连接的概念来解决这些问题,它允许客户端复用 TCP 连接,从而分摊了建立初始连接和针对多个请求缓慢启动的成本。但任意时点上每个连接只能执行一次请求 / 响应交换。
随着网络的发展,网站所需资源(CSS、JavaScript和图像等)不断增长,浏览器在获取和呈现网页时需要越来越多的并发性。但由于HTTP/1.1 只允许客户端进行一次 HTTP 请求 / 响应交换,因此在网络层上获得并发能力的唯一方法是并行使用多个 TCP 连接。
HTTP/2
HTTP/2 引入了 HTTP ”流“ 的概念,允许将不同的 HTTP 并发地复用到同一个 TCP 连接上,使浏览器更高效地复用 TCP 连接。 HTTP/2解决了 TCP 连接的使用效率低的问题,现在可以通过同一个连接同时传输多个请求 / 响应。
但是,TCP并不理解 HTTP流,当多个HTTP 请求复用一个 TCP 连接,如果前面的请求/ 响应没有处理完,后面的请求/ 响应也无法处理,也就是会出现头堵塞现象。
HTTP/3
HTTP/3 不是使用 TCP 作为会话的传输层,而是使用 QUIC (一种新的互联网传输协议)。该协议在传输层将流作为一等公民引入。多个 QUIC 流共享相同的 QUIC 连接,因此不需要额外的握手和慢启动来创建新的 QUIC 流。但 QUIC 流是独立的,因此在大多数情况下,只影响一个流的丢包不会响应其它流,这是因为 QUIC 数据包封装在 UDP 数据包。
非阻塞网络 I/O
计算机之间如何进行网络请求?
Socket、端口
服务器 – 客户端
一共有两个Socket
- 监听端口的Socket
- 通信的时候又创建一个Socket
多个客户端请求,就会排队、阻塞等待。
多线程服务器 – 客户端
线程创建的开销成本比较高。
线程池服务器
阻塞式的I/O,
- 读的时候阻塞,
- 写的时候缓存满的情况下阻塞
BIO Blocking I/O 阻塞 I/O
阻塞 I/O: 进行 I/O 操作时,用户线程会一直阻塞,直到读操作或者写操作完成。
Socket 接收数据,系统内核的处理过程
应用程序主要处理蓝色的部分 TCP 数据部分,其它部分都被操作系统处理掉了。
非阻塞 I/O ( Non-Blocking I/O )
非阻塞 I/O: I/O 操作立即返回,发起线程不会阻塞等待。
非阻塞 read 操作:
- Socket 接收缓冲区有数据,读 n 个(不保证数据被读完整,因此有可能需要多次读)。
- Socket 接收缓冲区没有数据,则返回失败(不会等待)。
非阻塞write 操作:
- Socket 发送缓冲区满,返回失败(不会等待)。
- Socket 发送缓冲区不满,写 n 个数据(不保证一次性全部写入,因此可能需要多次写)。
Java NIO (New I/O)
核心角色:
- Selector 选择器
- Buffer
- SelectableChannel
- SelectionKey
一个Channel就是对应一个Socket。
Java IO 与 NIO 比较
Java IO核心代码
ServerSocket serverSocket = new ServerSocket(port);
while(true) {final Socket socket = serverSocket.accept();new Thread(new Runnable() {@Overridepublic void run() {InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();byte[] content = new byte[1024];int len;StringBuilder sb = new StringBuilder();while ((len = in.read(content)) != -1) {sb.append(new String(content, 0, len));}out.write("Receive Success!\n".getBytes());out.flush();socket.shutdoownOutput();...}}).start();
}
Java IO 会阻塞的地方:
- accept()
new Thread(...)
- Read
- Write
NIO 核心代码
InetSocketAddress address = new InetSocketAddress(8888);
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(address);
server.configureBlocking(false);
Selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {selector.select();Iterator<SelectionKey> keys = selector.selectedKeys().iterator();while (keys.hasNext()) {SelectionKey key = keys.next();ByteBuffer buffer = ByteBuffer.allocate(1024);if (key.isAcceptable()) {serverSocketChannel serverChannel = (ServerSocketChannel)key.channel();SocketChannel channel = serverChannel.accept();channel.configureBlocking(false);channel.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {SocketChannel channel = (SocketChannel)key.channel();channel.read(buffer);...channel.register(selector.SelectionKey.OP_WRITE);} else if (key.isWritable()) {SocketChannel channel = (SocketChannel)key.channel();channel.write(buffer);...channel.register(selector, SelectionKey.OP_READ);}keys.remove();}
}
NIO 会阻塞的地方
selector.select()
实现这里很关键 (接下来重点分析)
系统 I/O 复用方式: select, poll, epoll
Select (poll) 管理下的read过程
epoll 管理下的read 过程
无活动连接时,Selector.select 方法被阻塞
数据库架构原理与性能优化
PrepareStatement 预编译
// style 1, not recommend. There is an explain in the below.
statment.executeUpdate("UPDATE Users SET status = 2 where userID = 2333");// style 2, recommend
PreparedStatement updateUser = con.prepareStatment("UPDATE Users SET status = ? where userID = 2333");
updateUser.setInt(1, 2);
updateUser.executeUpdate();
数据库架构
- 连接器,建立TCP/IP连接
- 语法分析器分析SQL语法树
- 语义分析与优化器,优化语义树
- 执行引擎 InnoDB
架构的设计,目标在于组件的复用,方便升级,高内聚低耦合。
MySQL有很多执行引擎,很容易替换,这是MySQL火
极客大学架构师训练营 网络通信协议 非阻塞网络I/O NIO 数据库架构原理 第16课 听课总结相关推荐
- 极客大学产品经理训练营:数据分析与商业分析,商业分析到业务分析 第18课总结
讲师:邱岳 1. 产品经理眼中的利润.成本.收入 利润 = 收入 - 成本 奶茶利润率极高,达到60%左右.但是奶茶盈利比较难. 所有买水的产品利润率都极高,比如可口可乐,咖啡,奶茶等. 案例:有个面 ...
- 极客大学产品经理训练营 产品文档和原型 作业4
作业 [本周作业]写一个用例,挑一个:你自己的产品 / 你喜欢的产品 / [拍东西]发起拍卖/ [知识星球]加入星球/ [极客时间]购买课程: 1. 标题作者修改历史 标题:[极客时间]购买课程 作者 ...
- 极客大学产品经理训练营:业务流程与产品文档 第11课总结
讲师:邱岳 1. 原型图 1.1 手绘图 + Scanner Pro 1.2 线框图 1.3 高保真产品图 1.4 做原型图的目的 坍缩:规划时梦到自己成了乔布斯,赶紧画个图让自己冷静冷静: 具体:具 ...
- 极客大学产品经理训练营:产品文档和原型咋弄 - 流程图 第9课总结
讲师:邱岳 1. 图的意义 流程图.活动图.时序图.状态图,本次聚焦于过程和行为描述. 提效.宏观.点睛. 梳理思路 用例:做什么? 流程图:怎么做? 2. 流程图.活动图.时序图 3. 动手画 – ...
- 极客大学产品经理训练营 极客时间购买课程-大作业
1. 标题作者修改历史 标题:[极客时间]购买课程 作者 历史 时间 易筋 创建 2021-01-09 易筋 添加购买流程图6 2021-03-02 易筋 添加购买时序图7 2021-03-16 2. ...
- 极客大学产品经理训练营:业务架构与概念模型 第10课总结
讲师:邱岳 1. 什么是状态图 系统中的概念或对象随着一些事件的发生,改变了状态,通常这个状态比较多.比较复杂时,我们需要用状态图来表示他们的边界,以及触发状态转换的活动. 2. 动手画 – 员工状态 ...
- 极客大学产品经理训练营 解决方案的设计与积累 第6课总结
说明 讲师:邱岳(二爷) 1. 解决方案 解决方案的前提是明确了 利益相关者 和 待解决的问题 出解决方案是产品经理的天职,不要直接转发 注意 X-Y Problem,核心关注 X 大量的练习/模仿/ ...
- 极客大学产品经理训练营:产品经理的职业规划 第20课总结
讲师:邱岳 1. 简历(你)作为产品 简历可能是你向你未来同事展示的第一个作品,关于你自己的经历.特点.审美,所以要像设计和研发一个产品那样设计好你的简历. 当谈论产品的时候,我们的思路应该依然是:用 ...
- 极客大学产品经理训练营:运营思维 第19课总结
讲师:邱岳 1. 运营是做什么的 运转·经营. 产品经理经常拆房子.盖新房子.经营是要持续经营一个产品. CEO.COO(Apple 的Tim Cook以前就是).CTO.CFO.CIO- 运营其实是 ...
- 极客大学产品经理训练营 认识产品经理下 第2课总结
说明 讲师:邱岳(二爷) 分享提纲 互联网产品经理的能力模型 互联网产品经理的个人素质 产品经理的特质与气场 互联网产品经理的职业发展阶段与晋级之路 互联网产品经理的若干真相 1. 产品经理的能力模型 ...
最新文章
- python软件代码示例-python 示例代码1
- 就是好骑!骑ofo小黄蜂和舒畅早晨say hi,跟闹心堵车say bye
- 全球及中国绿色建筑产业规模现状与未来走势分析报告2022版
- POJ - 3074 Sudoku(DLX)
- echarts tooltip的formatter回调参数设置,两组参数情况
- 清除word中超链接
- 使用Infinispan创建自己的Drools和jBPM持久性
- JSP实战型程序连载:通用数据库连接JavaBean
- C++学习之路 | PTA乙级—— 1040 有几个PAT (25 分)(精简)
- 集成LNMP/LAMP/FAMP的LuNamp2.1正式版开源发布
- linux系统加多个网卡,Linux环境下填加多个IP段在同一网卡
- 雷军公布小米高管团队:仅15位,常程位列其中
- selenium脚本编写的注意点,那些我踩过的坑
- Bellman_Ford边上权值为任意值的单源最短路径问题(+路径打印)边集合与邻接表两种实现
- 慕课网vue播放器最新QQ音乐api
- 谷歌地球到底有多厉害?附查看高清卫星影像方法
- GZHU - 1523 疯狂钻石 (完全背包)
- 海思HI3516A千兆网卡换百兆网卡配置方法
- 第五次作业:项目分类
- 沧小海笔记本之xilinx srio核的学习记录之目录
热门文章
- python 静态变量_python小课堂19 - 面向对象篇(二)
- c段服务器维护,服务器 多c段
- idea 新建java类 乱码,Intellij IDEA 2019 最新乱码问题及解决必杀技(必看篇)
- 完整的vue-cli3项目创建过程以及各种配置
- scrapy -selector
- xstream使用的第二个小问题
- vue 配置sass、scss全局变量
- Micropython教程之TPYBoard开发板制作电子时钟(萝卜学科编程教育)
- 内核里面writel(readl)是如何实现的
- APK反编译之二:工具介绍