性能指标
如何衡量程序的网络性能?你会看哪一层?看哪些指标?用哪些工具?
我们通常用带宽、吞吐量、延时、PPS(Packet Per Second)等指标衡量网络的性能。
- 应用层**[wrk、Jmeter]**
- **每秒处理请求数和延时,表示从网络请求发出后,一直到收到远端响应,所需要的时间延迟。**在不同场景中,这一指标可能会有不同含义。比如,它可以表示,建立连接需要的时间(比如 TCP 握手延时),或一个数据包往返所需的时间(比如 RTT)。
- 传输层**[iperf 或者 netperf]**
- 带宽,表示链路的最大传输速率,单位通常为 b/s (比特 / 秒)。
- **吞吐量,表示单位时间内成功传输的数据量,单位通常为 b/s(比特 / 秒)或者 B/s(字节 / 秒)。**吞吐量受带宽限制,而吞吐量 / 带宽,也就是该网络的使用率。
- 网络/链路层
- **PPS,是 Packet Per Second(包 / 秒)的缩写,表示以网络包为单位的传输速率。**PPS 通常用来评估网络的转发能力,比如硬件交换机,通常可以达到线性转发(即 PPS 可以达到或者接近理论最大值)。而基于 Linux 服务器的转发,则容易受网络包大小的影响。除了这些指标,网络的可用性(网络能否正常通信)、并发连接数(TCP 连接数量)、丢包率(丢包百分比)、重传率(重新传输的网络包比例)等也是常用的性能指标。
- 丢包率
给定一个端口号,比方说80吧,怎么查看占用这个端口的外部ip,输出前五个?
netstat
查看网络连接数量?
netstat(能查看tcp udp等) lsof
Linux网络模型
TCP/IP 模型是什么?
TCP/IP 模型,把网络互联的框架分为应用层、传输层、网络层、网络接口层等四层,其中,
- 应用层,负责向用户提供一组应用程序,比如 HTTP、FTP、DNS 等。
- 传输层,负责端到端的通信,比如 TCP、UDP 等。
- 网络层,负责网络包的封装、寻址和路由,比如 IP、ICMP 等。
- 网络接口层,负责网络包在物理网络中的传输,比如 MAC 寻址、错误侦测以及通过网卡传输网络帧等。
七层模型?
MTU是什么?
IP包分片大小。
网络接口配置的最大传输单元(MTU),就规定了最大的 IP 包大小。在我们最常用的以太网中,MTU 默认值是 1500(这也是 Linux 的默认值)。
一旦网络包超过 MTU 的大小,就会在网络层分片,以保证分片后的 IP 包不大于 MTU 值。
TCP和UDP
TCP和UDP的比较?
- 连接性:
TCP 是一种面向连接的协议,它在通信之前需要先建立连接,然后在连接上进行数据传输,最后释放连接。
UDP 是一种无连接的协议,通信不需要建立连接,直接进行数据传输,每个数据包都是独立的,不保持连接状态。
- 可靠性:
TCP 提供可靠的数据传输,通过序列号、确认应答、重传机制等来确保数据的可靠性,保证数据不丢失、不重复、按序到达。
UDP 不提供可靠性保证,数据包可能丢失、重复、或者乱序到达,不进行重传,需要应用层自行处理。
- 流量控制和拥塞控制:
TCP 提供流量控制和拥塞控制机制,通过滑动窗口、慢启动、拥塞避免等算法来调节发送端和接收端之间的数据传输速率,以避免网络拥塞。
UDP 不提供流量控制和拥塞控制,数据包的发送速率由应用程序自行控制,需要应用层根据需要进行流量控制和拥塞控制。
- 数据包大小:
TCP 数据包大小受到 MTU(Maximum Transmission Unit)的限制,一般较大,因为 TCP 头部较 UDP 头部更长,需要更多的空间来存放序列号、确认号、窗口大小等信息。
UDP 数据包大小一般较小,因为 UDP 头部较短,只有8个字节,不需要额外的控制信息。
- 应用场景:
TCP 适用于要求数据可靠传输、有序到达的应用场景,如文件传输、Web 浏览、电子邮件等。
UDP 适用于实时性要求较高、数据传输量较小、对数据可靠性要求不高的应用场景,如音视频传输、在线游戏、实时通信等。
在socket通信中,tcp和udp的区别是?
- 在TCP中,使用**socket()函数创建套接字,然后使用connect()**函数与远程主机建立连接。
- 在UDP中,也是使用**socket()**函数创建套接字,但不需要建立连接。
TCP如何保证可靠传输?
0. 在传递数据之前,会有三次握手来建立连接。
- 应用数据被分割成 TCP 认为最适合发送的数据块(按字节编号,合理分片)。这和 UDP完全不同,应用程序产生的数据报长度将保持不变。 (将数据截断为合理的长度)
- 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。(超时重发)
TCP建立连接后怎么保持连接?
在 TCP 中有一个 Keep-alive 的机制可以检测死连接,原理很简单,当连接闲置一定的时间(参数值可以设置,默认是 2 小时)之后,TCP 协议会向对方发一个 keepalive 探针包(包内没有数据),对方在收到包以后,如果连接一切正常,应该回复一个 ACK;如果连接出现错误了(例如对方重启了,连接状态丢失),则应当回复一个 RST;如果对方没有回复,那么,服务器每隔一定的时间(参数值可以设置)再发送 keepalive 探针包,如果连续多个包(参数值可以设置)都被无视了,说明连接被断开了。
TCP头部有哪些字段?
源端口 目的端口
序号
确认号 为上一个包的确认号+1 保证了TCP的可靠传输
窗口 用于拥塞控制,保证了网络传输的可靠性
数据偏移
保留位
TCP flags 包括ACK FIN SYN等等,用于保证连接可靠性
检验和 用于保证数据正确
紧急指针 用于指示带外数据
TFO和BBR算法了解吗?
TFO允许在第一次握手时就开始发送数据,从而减少了延迟。
BBR的核心思想是根据网络的带宽和往返时间(RTT)来调整发送数据的速率。它通过测量网络路径上的数据包往返时间和带宽来估计网络的瓶颈容量,并根据这些信息来调整发送速率。
三次握手四次挥手
linux的三次握手和系统调用的关系是什么?
- 进行第三次握手的原因是为了防止失效的连接请求报文段突然又传送到server因而产生错误
- syn重试次数、synack重试次数、半连接队列长度、全连接队列长度都可以通过内核参数控制
- 如果客户端发送syn,但是服务端无法建立连接,会发送RST报文
如何防范SYN Flood攻击?
在 Server 收到 SYN 包时,不去分配资源来保存 Client 的信息,而是根据这个 SYN 包计算出一个 Cookie 值,然后将 Cookie 记录到 SYNACK 包中发送出去。对于正常的连接,该 Cookies 值会随着 Client 的 ACK 报文被带回来。然后 Server 再根据这个 Cookie 检查这个 ACK 包的合法性,如果合法,才去创建新的 TCP 连接。
TCP状态转换的流程是什么样的?
linux四次挥手和linux系统调用的关系是什么?
TIME_WAIT状态出现的原因?
- FIN_WAIT_2和TIME_WAIT时间在稳定的网络环境下可以适当调小一些,TIME_WAIT一般是 2 个报文最长生存时间(2MSL)
- CLOSE_WAIT出现过多是危险的信号,要排查close()的问题
- server发送FIN是为了确保自己的数据已经发送完成,TIME_WAIT状态是为了处理FIN重发,让老的Server分节在网络中消逝
如何防止大量短连接的问题?
- 建议打开tcp_tw_reuse复用TIME_WAIT状态的连接,这个可以防止大量短连接的问题
- 可以调整init_cwnd的大小,增加网络流量
收发包过程
网络包的接收流程是什么样的?
- 当一个网络帧到达网卡后,网卡会通过 DMA 方式,把这个网络包放到收包队列(ring buffer)中;然后通过硬中断,告诉中断处理程序已经收到了网络包。
- 接着,网卡中断处理程序会为网络帧分配内核数据结构(sk_buff),并将其拷贝到 sk_buff 缓冲区中;然后再通过软中断,通知内核收到了新的网络帧。[一次处理的数量由netdev_budget控制]
- 四层协议栈处理数据包
sudo netstat -ntp | grep 8088 可以看sendq是不是阻塞
拥塞控制
拥塞控制的过程?
- 慢启动TCP 连接建立好后,发送方就进入慢速启动阶段,然后逐渐地增大发包数量(TCP Segments)。这个阶段每经过一个 RTT(round-trip time),发包数量就会翻倍。初始发送数据包的数量是由 init_cwnd(初始拥塞窗口)来决定的。当 TCP 的拥塞窗口大小达到了慢启动阈值(Slow Start Threshold,SSThresh)时,进入拥塞避免阶段。
- 拥塞避免在这个阶段 cwnd 不再成倍增加,而是一个 RTT 增加 1,即缓慢地增加 cwnd,以防止网络出现拥塞。连续出现了 3 个未响应的 ack 后,发送端会据此判断数据包出现了丢失,于是就进入了下一个阶段:快速重传。如果发送出去一个数据包,超过一段时间(RTO)都收不到它的 ack,那就认为是网络出现了拥塞。这个时候就需要将 cwnd 恢复为初始值,再次从慢启动开始调整 cwnd 的大小。进入超时重传流程。
- 接收方在收到数据包后,会给发送方回一个 ack,然后把自己的 rwnd 大小写入到 TCP 头部的 win 这个字段,这样发送方就能根据这个字段来知道接收方的 rwnd 了。接下来,发送方在发送下一个 TCP segment 的时候,会先对比发送方的 cwnd 和接收方的 rwnd,得出这二者之间的较小值,然后控制发送的 TCP segment 个数不能超过这个较小值。
滑动窗口过大或者过小有什么影响?
滑动窗口的大小对网络性能有很大的影响。
如果滑动窗口过小,会导致需要频繁等待确认 ACK,较小的滑动窗口可能导致数据传输的延迟增加,特别是在高延迟网络中。
如果滑动窗口过大,网络容易拥塞,容易造成接收端的缓存不够而溢出,容易产生丢包现象,则需要多次发送重复的数据,耗费了网络带宽。
C100K和C10M
可以扯一下xdp,dpdk,rdma
rdma
为什么要有dma?rdma有什么优势?xdp了解吗?和dpdk的区别是什么?
dma是为了减少到ring buffer的开销,但是ring buffer到内核的开销无法避免。
rdma则能够处理各层报文头和校验码,通过DMA将数据直接拷贝到用户空间内存中。必须要两边设备都支持。
dpdk是在用户态处理。
xdp依靠ebpf进行边缘设备协议栈处理,比dpdk理论单机效率更高。
性能优化汇总
从内核的角度怎么优化网络?
- 传输层优化
三次握手四次挥手优化
- 三次握手:调整syn重试次数、synack重试次数、半连接队列长度、全连接队列长度
- 四次挥手:增大处于 TIME_WAIT 状态的连接数量 net.ipv4.tcp_max_tw_buckets ,减小 FIN_WAIT2和TIME_WAIT时间 ,让系统尽快释放它们所占用的资源,开启TIME_WAIT端口复用
- 增大本地端口的范围 。这样就可以支持更多连接,提高整体的并发能力。
- 增加最大文件描述符的数量。
拥塞控制优化
- 增大cwnd 和 rwnd
发送缓冲区优化策略:
- TCP 发送缓冲区的大小默认是受 net.ipv4.tcp_wmem 来控制:
net.ipv4.tcp_wmem = 8192 65536 16777216
tcp_wmem 中这三个数字的含义分别为 min、default、max。内核根据需要动态调整。
- 应用程序有的时候会很明确地知道自己发送多大的数据,需要多大的 TCP 发送缓冲区,这个时候就可以通过 setsockopt(2) 里的 SO_SNDBUF 来设置固定的缓冲区大小。一旦进行了这种设置后,tcp_wmem 就会失效,而且这个缓冲区大小设置的是固定值,内核也不会对它进行动态调整。但是,SO_SNDBUF 设置的最大值不能超过 net.core.wmem_max,如果超过了该值,内核会把它强制设置为 net.core.wmem_max。
- 为了能够对 TCP/IP 数据流进行流控,Linux 内核在 IP 层实现了 qdisc(排队规则),可以调大这个值防止数据包被丢弃。
接收缓冲区优化策略:
-
调整tcp缓冲区大小,tcp_mem控制tcp发送和接收占用的内存。
-
网络层优化
调整MTU
禁用ICMP
开启IP转发,调整TTL
- 链路层优化
为网卡硬中断配置 CPU 亲和性(smp_affinity),或者开启 irqbalance 服务。
- dpdk xdp rdma
怎么减少网络时延?
- 关闭nagle算法
其它问题
常见的 HTTP 状态码有哪些?
- 信息性状态码(1xx):
100 Continue:服务器已收到请求的初始部分,并且正在等待客户端发送剩余的请求。
101 Switching Protocols:服务器已经理解了客户端的请求,并将通过 Upgrade 消息头通知客户端采用不同的协议来完成这个请求。
- 成功状态码(2xx):
200 OK:请求成功,服务器已成功处理了请求。
201 Created:请求已被服务器处理,并创建了新的资源。
204 No Content:服务器成功处理了请求,但不需要返回任何内容。
- 重定向状态码(3xx):
301 Moved Permanently:请求的资源已被永久移动到新的 URI。
302 Found:请求的资源临时移动到新的 URI。
303 See Other:服务器要求客户端使用新的 URI 来获取资源。
- 客户端错误状态码(4xx):
400 Bad Request:服务器无法理解客户端的请求,通常因为请求中包含语法错误。
401 Unauthorized:请求需要用户身份验证。
403 Forbidden:服务器拒绝执行请求,通常因为没有足够的权限。
404 Not Found:服务器未能找到请求的资源。
- 服务器错误状态码(5xx):
500 Internal Server Error:服务器遇到了一个未知的错误,无法完成请求。
502 Bad Gateway:服务器充当网关或代理时,从上游服务器接收到无效的响应。
503 Service Unavailable:服务器暂时无法处理请求,通常因为服务器过载或维护。
HTTP和HTTPS的区别?
- HTTPS协议需要使用CA申请证书,一般免费证书很少,因此是需要支付费用。
- HTTP是超文本传输协议,信息是明文传输,没有隐私,任何人都能看到内容,HTTPS则是具有安全性的SSL加密传输协议,因此HTTPS更具有安全性。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
说一下HTTP 1 1.1 2的区别
HTTP (Hypertext Transfer Protocol) 是用于在网络中传输超文本的协议,它的发展经历了几个版本,包括 HTTP/1.0, HTTP/1.1, HTTP/2 和 HTTP/3。
- HTTP/1.0:
- 基本的请求-响应模型,每个请求和响应都需要一个新的 TCP 连接。
- 没有持久连接,无法复用 TCP 连接,每次请求都需要重新建立连接。
- HTTP/1.1:
- 引入了持久连接(Keep-Alive),允许同一连接上发送多个请求和响应,以减少连接建立的开销。
- 增加了管道(Pipeline),允许客户端发送多个请求,而不必等待先前的响应。
- HTTP/2:
- 在 HTTP/1.1 中,如果客户端想发送多个并行的请求,那么必须使用多个 TCP 连接。
- 引入了二进制分帧和多路复用(Multiplexing),允许在单个连接上并发发送多个请求和响应,解决了 HTTP/1.x 中的队头阻塞问题。
- 使用头部压缩(Header Compression)和二进制协议,减少了传输的开销。
HTTP2的问题?
- TCP 以及 TCP+TLS 建立连接的延时
- TCP 的队头阻塞并没有彻底解决
- 多路复用导致服务器压力上升
- 多路复用容易 Timeout
HTTP3?
使用udp+unic协议
主要特点
- 改进的拥塞控制、可靠传输
- 快速握手
- 集成了 TLS 1.3 加密
- 多路复用
- 连接迁移
说一下websocket和http的区别?
ws天生是长连接
TLS的作用?流程?
作用是身份验证、数据加密、保证数据完整性
TLS 的主要流程包括:
- 协商加密算法和密钥:客户端向服务器发送一个连接请求,包含支持的加密算法和其他通信参数。服务器从中选择一种加密算法和密钥交换协议,并将其作为响应的一部分发送回客户端。
- 数字证书验证:服务器将自己的数字证书发送给客户端。客户端验证服务器证书的有效性,包括证书的签发者、有效期等信息。客户端也可能发送自己的数字证书给服务器,进行双向身份验证。
- 密钥交换:客户端和服务器使用已经协商好的密钥交换算法来生成会话密钥,用于后续的通信加密和解密。
- 数据传输:客户端和服务器使用协商好的加密算法和密钥来加密和解密通信数据,确保数据在传输过程中的机密性和完整性。
- 连接关闭:当通信结束时,客户端和服务器可以根据需要关闭连接。
别人作为客户端给Linux服务器上的程序发消息,但是你这边没收到,Linux下面用什么方式命令可以快速知道这个包有没有到你这边?
tcpdump
网络通信是大端还是小端?
大端
DNS查找的流程?
本地、本地域名服务器 – > 根域名/顶级域名/权威域名服务器
ARP协议的流程?
- 每个主机都会有 ARP 高速缓存,存储本局域网内 IP 地址和 MAC 地址之间的对应关系。
- 当源主机要发送数据时,首先检查 ARP 高速缓存中是否有对应 IP 地址的目的主机的
MAC 地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送 ARP 请求分
组,该数据包包括的内容有:(源主机 IP 地址,源主机 MAC 地址,目的主机的 IP 地址)。 - 当本网络的所有主机收到该 ARP 请求分组时,首先检查数据包中的 IP 地址是否是自
己的 IP 地址,如果不是,则忽略该数据包;如果是,则首先从数据包中取出源主机的 IP 地
址和 MAC 地址写入到 ARP 高速缓存中,如果已经存在,则覆盖,然后将自己的 MAC 地址
写入 ARP 响应包中,告诉源主机自己是它想要找的 MAC 地址。 - 源主机收到 ARP 响应分组后,将目的主机的 IP 和 MAC 地址写入 ARP 高速缓存中,
并利用此信息发送数据。如果源主机一直没有收到 ARP 响应分组,表示 ARP 查询失败
在浏览器中输入 URL 后,执行的全部过程。会用到哪些协议?(一次完整的 http 请求过程)。
整个流程如下:
- 为了将消息从你的 PC 上传到服务器上,需要用到 DNS、IP 协议、ARP 协议和 OSPF 协议。ARP是IP解析的到物理地址的协议,OSPF是环路协议
- 发起 TCP 的 3 次握手
- 建立 TCP 连接后发起 http 请求
- 服务器响应 http 请求
- 浏览器解析 html 代码,并请求 html 代码中的资源(如 js、css、图片等)
- 断开 TCP 连接
- 浏览器对页面进行渲染呈现给用户
get、post和put
GET:
用于从服务器获取数据。
参数通常附加在 URL 的末尾(即查询字符串)。
对服务器的请求不应该有副作用,即不应该修改服务器上的资源。
对请求的数据长度有限制。
可以被缓存。
POST:
用于向服务器提交数据,通常用于创建新资源或对现有资源进行修改。
参数通常包含在请求的主体中,而不是 URL 中。
对服务器的请求可能会有副作用,即可能会修改服务器上的资源。
对请求的数据长度没有明确的限制。
通常不被缓存。
PUT:
用于向服务器提交数据,通常用于对指定资源进行更新或创建新资源(与 POST 类似,但通常用于更新已知资源,而不是创建新的)。
参数通常包含在请求的主体中。
对服务器的请求可能会有副作用,即可能会修改服务器上的资源。
对请求的数据长度没有明确的限制。
通常不被缓存。
鉴权和跨域
cookie和session的区别是什么?
- 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
- 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
- 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
- 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
- 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。
如何解决分布式session问题
hash分配
缓存中间件
端口大小限制?
端口用16位表示,65536个
Reactor和Proactor的区别?
Reactor就是epoll,proactor是io_uring