admin管理员组

文章数量:1567272

文章目录

  • 一、网络基础
    • 1、网络分层模型
      • (1)四层与七层模型
      • (2)为什么要分层
      • (3)网络分层模型下的数据传输
      • (4)传输层与网际层有什么区别
    • 2、常用概念
      • (1)MAC地址(Media Access Control Address)
      • (2)ARP协议
      • (3)RARP协议
      • (4)IP和MAC的区别
      • (5)MTU和MSS
    • 3、常用的网络层次和协议
      • (1)概述
      • (1)网络层 - IP协议(Internet Protocol)
      • (2)网络层 - IP地址有哪些分类
      • (3)网络层 - IPV4不够用怎么办
      • (4)传输层 - UDP协议(User Datagram Protocol用户数据报协议)
      • (5)传输层 - TCP协议(Transmission Control Protocol传输控制协议)(重点)
      • (6)TCP和UDP协议每次能传输多少数据
    • 4、网络核心指标与监控
      • (1)前置知识
      • (2)速率
      • (3)带宽
      • (4)吞吐量
      • (5)时延
      • (6)往返时间RTT
      • (7)丢包率
      • (8)ifconfig命令
      • (9)netstat命令
      • (10)netstat -atnlp
    • 5、(重点)TCP底层设计交互
      • (1)TCP报文组成
      • (2)三次握手
      • (3)四次挥手
      • (4)TCP可靠传输ACK
      • (5)TCP的优化传输 - Nagle算法和延迟确认
    • 6、TCP洪水攻击
      • (1)ss命令
      • (2)什么是洪水攻击
      • (3)半连接队列(SYN队列)
      • (4)全连接队列(ACCEPT队列)
      • (5)连接队列总结
      • (6)洪水攻击防范 - TCP SYN Cookies
      • (7)洪水攻击防范 - 其他方案
      • (8)洪水攻击实战
    • 7、Linux常见内核参数调整
      • (1)查看内核参数
      • (2)修改Linux内核参数的方法
      • (3)Linux文件句柄数限制优化
    • 8、BIO、NIO、AIO、select-poll-epoll机制
    • 9、DNS详解
      • (1)什么是DNS
      • (2)负载均衡
      • (3)智能DNS
    • 10、HTTP核心知识详解
      • (1)什么是HTTP协议
      • (2)HTTP请求消息结构
      • (3)HTTP响应消息结构
      • (4)响应码
      • (5)HTTP协议发展历史
      • (6)HTTP/2.0
      • (7)HTTP/3.0
      • (8)对称和非对称加密
      • (9)什么是HTTPS

一、网络基础

1、网络分层模型

(1)四层与七层模型

OSI七层模型(Open System Interconnection)。

TCP/IP四层模型(Transmission Control Protocol/Internet Protocol):
应用层:负责应用程序之间的沟通,如HTTP、FTP、DNS等。
传输层:负责两台主机之间的数据传输,端到端通信,如TCP、UDP等。
网际层:负责网络包的封装、寻址和路由,如IP等。
网络接口层:负责网络包在物理网络中的传输,如MAC寻址转化、通过网卡传输网络数据帧等。


四层负载均衡:F5、LVS。
用虚拟ip+pord接收请求,再转发到对应的真实机器(仅做分发作用,没有流量产生);
基于IP报文的负载均衡,不解析协议,性能强,对内存和cpu资源消耗比较低;
根据负载均衡设备,把请求转发到后端对应的IP+端口,比较粗粒度。

七层负载均衡:HAProxy、Nginx。
用虚拟的url或主机名接收请求,再转向相应的处理服务器;
需要解析协议,根据报头内的信息来执行负载均衡任务,占用的系统资源对内存和cpu资源消耗较高;
在四层基础上,可以根据应用层的特征(URL/浏览器/Cookie等)进一步决定如何去转发流量。

(2)为什么要分层

如果不分层,应用程序需要自己来把01二进制数据,写代码操作网卡发送数据、建立网络连接、网络寻址、可靠性传输、失败重试等等……

分层之后,每层分工明确,利用单一职责和责任链模式,开发人员只需要编写应用层业务代码,操作系统负责建立网络连接、可靠性传输,交换机路由器负责物理媒介上传输二进制数据。

就像我们日常编写的代码一样,分层设计更能体现高内聚低耦合。

(3)网络分层模型下的数据传输


类似寄快递,中转站一层层分发,省 市 区 县 村 房号 具体联系人。

发送数据包时,在网络协议栈中从上到下逐层处理,最终到网卡发送出去。
接收数据包时,需要经过网络协议栈从下到上的逐层处理,最后送到应用程序中使用。

注意,应用层是直接面向用户的一层,为应用程序提供统一协议的接口,但不是应用程序。
目的是保障不同类型的应用采用的低层通信协议是一致的。

(4)传输层与网际层有什么区别

网际层协议负责提供主机间的逻辑通信,
互联网上N多台设备,通过IP地址识别通信主机,网络层可以具体定位到哪台设备;
网络层的只检验IP数据报首部中的校验和字段是否出现差错,而不检查数据部分。

传输层协议负责提供进程间的逻辑通信,
一个主机上N多个进程,通过端口号识别应用层进程,传输层可以具体定位到哪个进程,
需要对收到的报文更进一步进行差错检测

2、常用概念

(1)MAC地址(Media Access Control Address)

MAC地址用来定义网络设备的位置,也叫硬件地址,每一个电脑设备都拥有唯一的MAC地址共48位,使用十六进制表示。
MAC地址在世界是唯一的,通常表示为12个16进制数,如04-7C-16-1D-43-50

(2)ARP协议

ARP协议(Address Resolution Protocol),地址解析协议,实现IP地址到MAC地址的映射,ARP表是自动建立,不需要配置
为网卡的IP地址到对应的硬件地址提供动态映射,把网络层32位地址转化为数据链路层MAC的48位地址

表结构大致如下:

IP地址MAC地址
192.168.56.1000-11-3e-aa-dd
192.168.56.1100-11-3e-aa-ad
192.168.56.1200-11-3e-aa-cd

(3)RARP协议

Reverse Address Resolution Protocol,逆地址解析协议,把数据链路层MAC的48位转化为网络层32位地址

(4)IP和MAC的区别

MAC地址是数据链路层和物理层使用的地址,写在网卡上的物理地址,不可变更。
IP地址是网络层使用的地址,是一种逻辑地址,用来区别网络上的计算机。

路由器记住每个MAC地址,MAC地址的长度为48位,最多共有2的48次方个MAC地址,每个路由器需要256T来存储。
当设备连入网络时,还没有IP地址时,根据MAC地址来区分不同的设备。

就像是身份证(MAC)和居住证(IP)一样,身份证是每一个设备独有的,IP是连接不同的网络就会有不同的IP。

(5)MTU和MSS

MTU(Maximum Transmission Unit):
是指在网络中,单个数据包能够传输的最大字节数,数据链路层提供给上层网络层最大一次传输大小
是网络设备(如路由器)在处理数据包时所能支持的最大封装单元大小(不同网卡的MTU也不一样,物理接口限制)。
以太网数据链路层中约定的数据载荷部分最大长度,数据不超过它时就无需分片。
MTU值越大传输的速率就越快,但也会增加网络的延迟。
数据包从发送端传输到接收端,要经过多个网络,每条网络的MTU都可能不一样,通信过程中最小的MTU称为路径MTU,类似木桶效应,装水容量被最短的决定。

MSS(Max Segment SIze,是TCP最大报文段大小):
是一个TCP报文段中包含的最大字节,传输层TCP提交给网络层最大分段大小
TCP在传输大量数据时以MSS的大小将数据进行分割发送,重发时也是以MSS为单位。
MSS的值由发送端和接收端在建立连接时在TCP报文中进行协商得到的,它的值受到网络中MTU(最大传输单元)的限制。
两端主机在三次握手发出建立连接的请求时,会在TCP首部写入MSS选项,告诉对方自己的接口能够适应的MSS的大小,然后在两者之间选择一个较小的值进行使用。
MSS = MTU - IP header头大小 - TCP头大小。
TCP的MSS最大值是:以太网MSS=1500(MTU)- 20(IP首部长度) - 20(TCP首部大小) = 1460字节。

总结:
MTU是指单次数据传输中可以传输的最大字节数,是由网络设备的硬件限制决定的,通常是1500字节。
MSS是指TCP传输数据报文中,由TCP首部和数据构成的部分的最大字节数,是由MTU和TCP首部长度决定的。
一般情况下MSS = MTU - IP header头大小 - TCP头大小,通常是1460字节。
MTU是网络传输最大报文包,MSS是网络传输数据最大值。(好比MTU是总重量,MSS是去皮后的重量)

3、常用的网络层次和协议

(1)概述

以下是工作中常用的网络层次和协议,其他的协议了解即可。
应用层:HTTP、HTTPS;
传输层:TCP、UDP;
网络层:IP。

网络层相关协议:
IP协议(Internet Protocol,因特网互联协议);
ICMP(Internet Control Message Protocol,因特网控制报文协议);
ARP协议(Address Resolution Protocol,地址解析协议);
RARP协议(Reverse Address Resolution Protocol,逆地址解析协议)

传输层:
网络层把数据发到对应的节点,传输层则进一步将数据可靠地传送到对应的端口。
使用端口区分不同的进程,信息传送的协议数据单元称为段或报文
主要的协议:TCP和UDP。

(1)网络层 - IP协议(Internet Protocol)


IP协议是一种工作在网际层的网络协议,定义如何将数据包从一台计算机传输到另一台计算机。
提供一种通用的方法在网络中传输数据,提供不可靠、无连接的传送服务
App发送请求,达到运营服务商的交换机,交换机根据IP地址再进行路由转发(多次),最后达到目标服务器

网络各层作用不一样,IP协议用途是把数据包投递过去。
IP协议没这个机制,不确保数据一定送达,可以用传输层TCP协议的机制做可靠性传输。
IP协议是其他协议的基础,比如TCP协议和UDP协议。

用途:
1、寻址和路由
IP数据报中有源IP地址和目的IP地址,表示数据包的源主机和目标主机。
数据报在传输过程中,每个中间的网络节点比如IP网关/路由器等,都只根据网络地址来进行转发,直到目标主机。
2、分片和重组
数据报传输过程中会经过不同的网络,不同的网络环境中数据报的最大长度限制是不同的。
通过给每个IP数据报分配一个标识符和分段组装信息,可以让数据报在不同的网络中能够被传输。
被分段后的IP数据报可以独立在网络中进行转发,在达到目标主机后由目标主机完成重组工作,恢复成原来的IP数据报。

(2)网络层 - IP地址有哪些分类

IP地址由4个小段,每个小段由8个bit,即四个字节组成,共32位(便于记忆采用4个十进制数来表示一个IP地址)。
例如192.168.0.0(二进制位1100 0000, 1010 0000, 0000 0000, 0000 0000)。

IP地址= {<网络号>, <主机号>}
网络号:属于互联网的哪一个网络。
主机号:属于该网络中的哪一台主机。

类别描述(商业应用那种只用到A、B、C三类)
A类0开头,前8位网络号,后24位的主机号;即0.0.0.0到127.255.255.255
B类10开头,前16位网络号,后16位的主机号;即128.0.0.0到191.255.255.255
C类110开头,前24位网络号,后8位的主机号,即192.0.0.0到223.255.255.255
D和E类留作未来社会的应用,或做一些实验用到

全球现有的IPV4地址一共有2的32次方个,估算约42.9亿个,除去一些特庸的IP和一些不能用的IP,剩下可用的不到40亿。

(3)网络层 - IPV4不够用怎么办

DHCP技术
动态主机配置协议,动态分配IP地址,只给接入网络的设备分配IP地址。
同一个MAC地址的设备,每次接入互联网时,得到的IP地址可能不一样。

NAT
网络地址转换协议,不同局域网的主机可以使用相同的IP地址,一定程度上缓解了IP资源枯竭的问题,
局域网中使用的IP地址是不能在公网中使用,当局域网主机想要与公网主机进行通信时,将主机IP地址转换为全球IP地址。
原理:从局域网出去的IP数据报,将其IP地址替换为NAT服务器拥有的合法的公共IP地址,并将替换关系记录到NAT映射表;从公共互联网返回的IP数据报,根据目的IP地址查找NAT映射表,把内部局域网IP地址替换目的IP地址,转发到内部网络。

IPV6
作为接替IPV4的下一代互联网协议,可以实现2的128次方个地址,即使给地球上每一粒沙子都分配一个IP地址也够用,从根本上解决IPV4地址不够用的问题。

(4)传输层 - UDP协议(User Datagram Protocol用户数据报协议)

面向无连接的协议,它不需要建立连接,就可以发送数据。
协议不需要握手,因此发送数据的速度更快,传输效率更高。
不提供可靠性,因为它不会检查发送的数据是否损坏或丢失,所以可能会发生数据丢失或损坏的情况。
支持多种应用,如视频会议、在线游戏等,它可以提供实时性和可靠性。

(5)传输层 - TCP协议(Transmission Control Protocol传输控制协议)(重点)

面向连接:TCP是面向连接的协议,在正式收发数据前,必须建立可靠的连接。
可靠性:TCP协议提供了丰富的可靠性机制,如检验和、确认和重传等,来保证数据的正确性。
流量控制:提供了流量控制机制,可以防止发送方发送数据速度过快,从而使接收方来不及处理,从而确保网络的稳定性。
拥塞控制:提供了拥塞控制机制,可以防止网络拥塞,从而提高网络的吞吐量。
常用于传输文件、电子邮件、FTP等服务,能够校验数据的完整性,以保证数据不被破坏。

通过源IP地址、源端口、目的IP地址、目的端口就可以确定一个TCP连接。

TCP协议内容解析:
源端口号:报文的发送端口。
目的端口号:报文的接收端口。
序号(seq):在TCP传送的数据流中每一个字节都有一个序号,在SYN标志是1时,表示初始发送的序列号。
确认号(ack):期望收到对方下次发送的数据的第一个字节的序号,是上次已成功收到数据字节序号+1。例如发送确认号为1001,则表示前1000个字节已经被确认接收。

标志位(控制位)

  • URG(urgent紧急,很少用),当URG=1时,此报文应尽快传送
  • RST(reset重置,重置复位标志,用于复位对应的TCP连接),RST一般是在FIN之后才会出现为1的情况,表示的是连接重置
  • FIN(finish结束),结束标志,用于结束一个TCP会话,释放连接
  • PSH(push传送),指数据包到达接收端以后,不对其进行队列处理,尽快把数据交给应用程序处理。(常规数据发送流程:主机发送数据时,会放在TCP缓冲区中,直到该段达到一定大小,然后发送到接收器;当段到达接收端时,被放置在TCP传入缓冲器中,会等待直到其他段到达,完成后数据就被传递到应用层;这种设计保证数据传输尽可能高效,将它们组合成一个或多个较大的片段,节省时间和带宽;上述流程大多数情况下是没问题的,但是有些则需要尽快处理,所以有这个标识位。

ACK(acknowledgement确认):确认标志,1表示确认收到请求,0表示未确认。
SYN(同步序列编号Synchronize Sequence Numbers):SYN标志位和ACK标志位搭配使用,用来建立连接;当连接请求的时候,SYN=1,ACK=0,代表连接开始但是未获得响应;当连接被响应的时候,标志位中ACK会置为1代表确认收到连接请求,变成了SYN=1,ACK=1;SYN与FIN不会同时为1的,因为前者表示的是建立连接,而后者表示的是断开连接。

(6)TCP和UDP协议每次能传输多少数据

以太网数据包(packet)的大小是固定的1522字节,其中22字节是头信息(head),1500字节是负载(payload)。
IP数据包在以太网数据包的负载里面,它也有自己的头信息20字节,所以IP数据包的负载最多为1480字节。
TCP数据包在IP数据包的负载里面,它的头信息最少也需要20字节,所以TCP数据包的最大负载是1480 - 20 = 1460字节。
但IP和TCP协议往往有额外的头信息,所以TCP负载实际为1400字节左右。

UDP数据包每次能够传输的最大长度MSS = MTU(1500B) - IP头(20B) - UDP头(8B) = 1472(Bytes)。

TCP数据包每次能够传输的最大长度MSS = MTU(1500B) - IP头(20B) - TCP头(20B) = 1460(Bytes)。

假如发送数据过大怎么办,发送10MB的数据包,应用程序是如何获取数据的?
假如发送一个10MB的文件,因为一个包最多1400字节,就必须分成多个包,起码需要发送7100多个包(注意数据包大小在不同协议下不一样,HTTP/2对比HTTP/1有优化压缩HTTP协议的头信息)。
服务器的操作系统会把收集的数据包组装完成,根据TCP包的端口转给应用程序,应用程序不用关心数据通信的细节。
但是,由于各种因素,比如带宽、网络不稳定等问题导致丢包怎么解决?这就涉及到TCP的可靠性传输机制了。

4、网络核心指标与监控

(1)前置知识

比特是计算机中的数据量单位,一个比特是一个1或一个0.
1Byte(字节) = 8bit(比特),字节的简写为B,比特简写为b
小写b和大写B分别对应大小单位bit(比特)和byte(字节)。

(2)速率

连接在计算机网络上的主机在数字信道上传送比特的速率,也称为比特率或速率。
单位:bit/s(b/s,bps)或kb/s = 103b/s(小写k指103)。

假如数据块大小100MB,网卡发送速率是100Mbps,发送时间大体是8秒多。
100MB*8/100Mbps约等于9秒,特别注意,1/8(B/s)= b/s,即1B=8bit,平时计算需要单位换算

(3)带宽

网络通信线路所能传送数据的能力,在单位时间内从网络中的某一点到另一点所能通过的“最高数据率”,单位同速率也是bps。

比如带宽为800M,是指800Mbps或800Mb/s,真实速度其实要在带宽的基础上除以8,即800Mbps/ 8 = 100M/s。
用户在网上下载时显示的速率单位往往是Byte(字节)/s(秒),注意大写字母B,字节和比特之间的关系为1Byte = 8bit。

(4)吞吐量

单位时间内通过某个网络(或信道、接口)的实际的数据量,单位通常为b/s(比特/秒)或者B/s(字节/秒)。
吞吐量受带宽限制,吞吐量/带宽,就是该网络的使用率。

常用的网络 吞吐率的单位有:
PPS(即每秒发送多少个分组数据包)Packet Per Second(包/秒)表示以网络包为单位的传输速率,PPS越大网络性能越好。
BPS(Byte Per Second),每秒发送多少字节。
bPS(bits Per Second),每秒发送多少比特。

(5)时延

指数据(一个报文或分组,甚至比特)从网络的一端传送到另一段所需的时间。
源主机和目的主机之间路径会由多个链路和多个路由器组成,网络时延主要由 发送+传播+时延组成。

(6)往返时间RTT

从源主机发送信号到目标主机,目标主机接收信号再返回到源主机所需要的时间(一个来回)。

(7)丢包率

丢包率即分组丢失率,是指在一定时间范围内,传输过程中丢失的分组数量与总分组数量的比率。
比如说玩游戏卡顿、看直播卡顿。

(8)ifconfig命令

ifconfig 展示网络信息和网卡接口收发数据包的统计信息,新版Linux已经被ip addr取代了,想要使用需要安装yum install

[root@localhost ~]# ifconfig -a
# RUNNING表示物理网络是连通的,网卡已连接到交换机或路由器,如果没有,通常表示网线被拔掉。
# mtu 最大的传输单元,默认大小是1500
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
# inet:ipv4地址,通常是私网IP
# netmask:子网的掩码
# broadcast:广播地址
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::5054:ff:fe4d:77d3  prefixlen 64  scopeid 0x20<link>
# ehter:mac地址
        ether 52:54:00:4d:77:d3  txqueuelen 1000  (Ethernet)
# RX,TX:接收和发送的数据包的个数或字节数
        RX packets 407  bytes 359262 (350.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 332  bytes 22773 (22.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.10  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::a00:27ff:feb4:a0b  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:b4:0a:0b  txqueuelen 1000  (Ethernet)
        RX packets 180  bytes 15278 (14.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 147  bytes 39231 (38.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 132  bytes 11464 (11.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 132  bytes 11464 (11.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(9)netstat命令

内核中访问网络及相关信息的命令,显示与IP、TCP、UDP和ICMP协议相关的统计数据,检验本机各端口的网络连接情况。

参数说明:
-r:–route,显示路由表信息
-n:-n选项禁用域名解析功能,默认情况下netstat会通过反向域名解析技术查找每个ip地址对应的主机名
-s:–statistics,按照每个协议来分类进行统计
-p:–programs,与链接相关程序名和进程的PID
-l:–listening,显示所有监听的端口
-a:-all,显示所有链接和监听端口
-u:–udp,显示UDP传输协议的连接情况
-t:–tcp,显示TCP传输协议的连接情况
-i:–interfaces,显示网卡界面信息

# 显示系统端口使用和进程情况,筛选指定端口
netstat -anp | grep 端口

# UDP类型的端口
netstat -nupl

# TCP类型的端口
netstat -ntpl
# 统计已连接上的,状态为“established”
netstat -an | grep ESTABLISHED | wc -l

# 只显示所有监听端口
netstat -l

# 只显示所有监听tcp端口
netstat -lt

(10)netstat -atnlp

[root@localhost ~]# netstat -atnlp
Active Internet connections (servers and established)

# Proto:协议名,tcp协议或UDP协议
# recv-Q:网络接收队列,表示收到的数据已经在本地接收缓冲,但还有多少没有被进程取走
# send-Q:网络发送队列,发送队列不能很快清零,则可能是有应用向外发送数据包过快,或对方接收数据包不够快

# Local Address:本地IP,:::port表示对外开放IPV6端口,外网可访问;127.0.0.1:端口表示只能本机访问,外网无法访问;0.0.0.0:端口表示对外开放IPV4端口,外网可访问。
# Foreign Address:表示远程IP地址,显示规则与Local Address相同,一般都是0.0.0.0:(IPV4)和:::(IPV6)

# State:链路状态有11种,TCP建立连接的三次握手和TCP连接断开的四次挥手来描述
# LISTEN:Socket进行监听
# SYN_SENT:客户端tcp发送一个SYN以请求建立一个连接之后的状态
# SYN_RECV:服务端发出ACK确认客户端的SYN后状态置为SYN_RECV
# ESTABLISHED:打开的连接,双方可以进行或已经在数据交互
# FIN_WAIT1:主动关闭端应用程序调用close,TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态
# CLOSE_WAIT:被动关闭端TCP接到FIN后,发出ACK以回应FIN请求,并进入CLOSE_WAIT
# FIN_WAIT2:主动关闭端接到ACK后,就进入了FIN_WAIT2
# LAST_ACK:被动关闭端一段时间后程序将调用CLOSE关闭连接,TCP发送一个FIN,等待对方的ACK,进入LAST_ACK
# TIME_WAIT:在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME_WAIT状态
# CLOSIING:少见,等待远程TCP对连接中断的确认
# CLOSED:被动关闭端在接收到ACK包后,就进入了CLOSED状态,连接结束
# UNKNOWN:未知的Socket状态

# PID/Program:PID即进程id,Program即使用该socket的应用程序

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      743/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      831/master          
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      1166/docker-proxy   
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1143/docker-proxy   
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      419/rpcbind         
tcp        0     36 192.168.56.10:22        192.168.56.1:51377      ESTABLISHED 1415/sshd: root@pts 
tcp6       0      0 :::22                   :::*                    LISTEN      743/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      831/master          
tcp6       0      0 :::3306                 :::*                    LISTEN      1173/docker-proxy   
tcp6       0      0 :::6379                 :::*                    LISTEN      1153/docker-proxy   
tcp6       0      0 :::111                  :::*                    LISTEN      419/rpcbind         

5、(重点)TCP底层设计交互

(1)TCP报文组成

TCP协议报文的组成:

(2)三次握手

TCP的可靠性传输机制:TCP三次握手的流程:
1、一次握手:客户端发送一个SYN(Synchronize)数据包到服务器,用来请求建立连接,状态变为SYN_SEND;
报文首部中的同部位SYN=1,同时随机生成初始序列号seq=x。
2、二次握手:服务器收到客户端的SYN数据包,并回复一个SYN+ACK数据包,用来确认连接,状态变味SYN_RECEIVED;
确认报文中应该ACK=1,SYN=1,确认号是ack=x+1,同时随机初始化一个序列号seq=y。
3、三次握手:客户端收到服务器的SYN+ACK数据包,并回复一个ACK数据包,用来确认连接建立完成,状态变为ESTABLISHED;
确认报文的ACK=1,ack=y+1,seq=x+1。出于安全的考虑,第一次握手不能携带数据,第三次握手是可以携带数据的。


TCP三次握手的状态变化:
客户端:CLOSED ->SYN_SEND ->ESTABLISHED
服务端:CLOSED ->LISTEN ->SYN_RECEIVED ->ESTABLISHED

TCP连接的数据结构:
TCP是有状态的协议,有多个连接存在时通过TCP的控制台TCB(Transmission Control Block)来记录每一个连接的状态,通常一个TCB至少需要280个字节。
通过四元组区分不同的TCP数据报属于哪一个连接(源IP地址、源端口、目的IP、目的端口)。
连接对象信息存在一个容器中,每次接收到报文后从容器中取出对应的控制块来处理。

struct tcb // tcp 控制块
{
	_u32 remote_ip; 	// 远程ip
	_u32 local_ip;		// 本地ip
	_u16 remote_port; 	// 远端端口号
	_u16 local_port;	// 本地端口号
	int status;			// 连接状态
	...
}

TCP连接为什么是三次握手?而不是两次或者四次
三次握手的主要目的是保证连接是双工+可用的,保证双方都具有接受和发送数据的能力。
防止 重复历史连接的初始化,避免资源的浪费。
同步双方初始序列号序列号seq:用来解决网络包乱序问题确认号ack:用来解决丢包的问题
可靠性传输主要是通过重传机制来保证

(3)四次挥手

TCP通过三次握手建立连接,而断开连接则是通过四次挥手,详细流程如下:

第一次:
客户端发送FIN(Finish)报文段,用于关闭客户端到服务端的数据传输,表示客户端的数据发送完毕;
客户端进入FIN_WAIT_1 状态

第二次:
服务端收到客户端的FIN报文段后,发送ACK报文段,确认收到了客户端的FIN报文段;
服务端进入CLOSE_WAIT状态,客户端接收到这个确认包后进入 FIN_WAIT_2 状态

第三次:
服务端发送FIN报文段,用于关闭服务端到客户端的数据传输,表示服务端的数据发送完毕;
服务器端进入 LAST_ACK状态,等待客户端的最后一个 ACK

第四次:
客户端收到服务端的FIN报文段后,发送ACK报文段,确认收到了服务端的FIN报文段;
客户端接收后进入TIME_WAIT状态,在此阶段下等待2MSL时间(两个最大段生命周期,2Maximum Segment Lifetime);
如果这个时间间隔内没有收到服务端的请求,进入CLOSED状态;服务器端接收到ACK确认包之后,也进入CLOSED 状态。
从而完成TCP四次挥手

疑问:客户端为何要等待2MSL时间?
2MSL是报文最大生存时间,是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃;
假如最后一次客户端发送ACK给服务端没收到,超时后服务端重发FIN,客户端响应ACK,来回就是2个MSL;
等待2MSL,可以让本次连接持续的时间内所产生的所有报文段都从网络中消失,避免旧的报文段。

疑问:CLOSE-WAIT和TIME-WAIT的区别?
CLOSE-WAIT是等待关闭
服务端收到客户端关闭连接的请求并确认之后,进入CLOSE-WAIT状态。但服务端可能还有一些数据没有传输完成,不能立即关闭连接;所以CLOSE-WAIT状态是为了保证服务端在关闭连接之前将待发送的数据处理完。
TIME-WAIT是在第四次挥手
当客户端向服务端发送ACK确认报文后进入TIME-WAIT状态,主动关闭连接的,才有time_wait状态。
防止旧连接的数据包:如果客户端收到服务端的FIN报文之后立即关闭连接,但服务端对应的端口并没有关闭,客户端在相同端口建立新的连接,可能导致新连接收到旧连接的数据包,从而产生问题。
保证连接正确关闭:假如客户端最后一次发送的ACK包在传输的时候丢失,由于TCP协议的超时重传机制,服务端将重发FIN报文,如果客户端不是TIME-WAIT状态而直接关闭的话,当收到服务端重送的FIN包时,客户端会用RST包来响应服务端,导致服务端以为有错误发生,但实际是关闭连接是没问题的。

疑问:TIME-WAIT状态有啥坏处?
过多TIME-WAIT状态 会占用文件描述符/内存资源/CPU 和端口,占满所有端口,则会导致无法创建新连接。
高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接,会出现大量socket处于TIME_WAIT状态,端口有个0-65535的范围,排除系统和其他服务要用的,剩下的很少。
解决方案:调整短链接为长链接,HTTP 请求的头部,connection设置为keep-alive,减少TCP的连接和断开;
配置 SO_REUSEADDR,在 端口不够用时,TCP连接位于TIME_WAIT状态时可以重用端口;
缩减 time_wait 时间,设置为1MSL

疑问:为什么建立连接是三次挥手,关闭连接是四次挥手?
为了确保数据能够完成传输,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了,但未必所有的数据都全部发送给对方了,所以不能马上会关闭SOCKET。可能还需要发送一些数据给对方之后,再发送FIN报文告诉对方来表示同意现在可以关闭SOCKET连接对比:三次握手中第二次握手SYN和ACK是一起发送,TCP断开连接的FIN 和 ACK需要分开 表示服务端仍可以接受数据,因此需要四次挥手。

(4)TCP可靠传输ACK

ACK机制:
接收方收到TCP 数据包,要响应一个确认消息 acknowledgement,简称 ACK。ACK有两个信息:期待要收到下一个数据包的编号和 当前接收方的接收窗口的剩余容量。

流量控制(通过接收方来控制流量的一种方式,属于 端 对 端的控制):
TCP 连接的双方都有固定大小的buffer缓冲空间,接收端只允许发送端发送接收端缓冲区能接纳的数据,当接收方处理不过来发送方的数据,会提示发送方降低发送的速率,防止包丢失。
流量控制是让发送方的发送速率不要太快,让接收方来得及接收,利用的是可变大小的滑动窗口机制,在TCP连接上实现对发送方的流量控制。
TCP 协议有个叫 win,即 16 位的窗口大小,接受方每次收到数据包,在发送确认报文的时候也告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,称为接受窗口大小。

拥塞控制(通过发送方来控制流量的一种方式,对整个网络全局性考虑):
这是一种自适应算法,利用多种机制,根据网络的状况自动调整发送端的发送速率,以避免网络拥塞。
慢启动:发送端会以一个较小的窗口值开始发送,每收到一个ACK消息后,窗口值就会翻倍增加,直到窗口值达到最大值。如果不丢包,就加快发送速度;如果丢包,则降低发送速度。这样就可以慢慢地增加发送端的发送速率,避免突然发送大量数据造成网络拥塞。
快速重传:当发送端发送的数据报文没有在规定时间内收到ACK确认消息时,发送端就会认为该数据报文丢失,它会立即重发该数据报文,从而提高数据传输的效率。
拥塞避免:当收到三个重复的ACK消息时,发送端会认为网络出现拥塞,它会减少发送速率,降低发送端的数据量,从而减少网络的拥塞情况。

重传机制:
超时重传RetransmissionTimeout(时间驱动):发送一个数据包后就开启计时器,在一定时间内如果没有得到发送的数据报的ACK报文,就重发数据,直到发送成功。配置超时重传时间就是 RTO,一般大于RTT(Round-TripTime,往返时间)就行。
缺点:报文丢失会等待一定的超时时候才重传,增加端到端的时延。
快速重传 Fast Retransmit(数据驱动):TCP 协议给每个包编号seq(sequence number),第1个包的编号是一个随机数,接收方收到多个包后,方便组装还原,如果发生丢包,可以知道丢失的是哪一个包。
例子:接收方收到了6号包,没有收到14号包,ACK就会记录,期待收到14号包,过了一段时间14号包还是没收到,但是收到24号包,ACK里面的编号不会变化,总是响应期待14号包。如果发送方收到三个连续的重复 ACK或者 超时还没有收到任何 ACK,会确认14号包丢包,再次重发这个包。重传成功后,接收方会返回正常最新的ACK。
缺点:快速重传 解决了超时时间的问题,但存在重传的时候,是重传之前的一个,还是重传所有的问题。根据不同的实现,两种重传都可能,也有更多机制SACK和D-SACK。

(5)TCP的优化传输 - Nagle算法和延迟确认

背景:
TCP的报文发送数据少,加入只有几个字节,那网络传输效率特别低。
每个报文中都会有20个字节的TCP头部,20个字节的IP头部,而数据只有几个字节或者没数据的时候特别浪费。

Nagle算法:
是TCP协议的一种流量控制算法,它的目的是为了减少网络中的小数据包的数量,提高网络的效率。
TCP/IP协议中,无论发送多少数据都要在数据前面加上协议头,对方接收到数据也需要发送ACK表示确认。
为了提高利用网络带宽,TCP希望尽可能的发送足够大的数据,诞生了Nagle算法:任意时刻,最多只能有一个未被确认的小段;“小段” 指的是小于MSS尺寸的数据块;“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认。
TCP协议默认开启了Nagle算法,默认TCP_NODELAY选项为false。

做法:
一个TCP 连接上最多只能有一个未被ACK确认的数据包,在收到确认信息之前,不再发送后续数据包。
在上一个数据包未到达目的地前,即未收到 ack 前,将多个数据包组合成一个数据包发送。
当上一个小分组的 ack 收到后,TCP 就将收集的小分组合并成一个大分组发送出去,以减少小包的发送数量。
上面条件都没满足,发生了超时(一般为200ms),也会立即发送。

禁用Nagle算法(类似于坐公交和开车,开启Nagle算法就相当于等公交):
默认开启的,比较适用于发送方发送大批量的小数据,并且接收方作出及时回应的场合,降低包的传输个数。
如果业务是实时的发送数据并需要及时获取响应,则不适合开启Nagle算法。
延迟要求比较严格的地方,网络比较通畅 或 内部网的情况下,应该关闭nagle算法。
游戏类服务器开发也会禁用Nagle。
linux提供了TCP_NODELAY的选项来禁用Nagle算法。
禁止Nagle算法,每一次send 都会组一个包进行发送,hello被分成5个小包分别发送,不用等待ACK,可以连续发送数据包。
netty框架里面.childOption(channelOption.TCP_NODELAY,true)禁用。

延迟确认:
TCP报文中假如没携带数据,只是发ACK,但有 40个字节的IP 头 和 TCP 头,网络效率也是很低的,就产生出 TCP 延迟确认。
做法:当TCP 收到一个数据包时,它不会立即发出确认,而是等待一段时间,Linux默认延时时间为 40ms。如果在这段时间内有响应数据要发送时,ACK会随着响应数据一起发送给对方;如果期间没数据发送则40ms后才ACK。TCP 就将这两个数据包一起确认,从而减少了确认报文的数量,这种策略可以有效地减少网络中的报文交换,从而提高网络效率。

注意
Nagle 算法和延迟确认不能一起使用。
Nagle 算法 是用于延迟发送数据包,延迟确认 是用于 延迟接收数据包。
两个凑在一起就会造成更大的延迟,会产生性能问题。

Kafka的producer生产者发送到Broker机制的优化:

#当producer向leader发送数据时,可以通过request.required,acks参数来设置数据可靠性的级别,分别是0,1,all
acks

#请求失败,生产者会自动重试,指定是0次,如果启用重试,则会有重复消息的可能性
retries

#每个分区未发送消息总字节大小,单位:字节,超过设置的值就会提交数据到服务端,默认值是16KB
batch.size

# 默认值就是0,消息是立刻发送的,即便batch.size缓冲空间还没有满,如果想减少请求的数量,可以设置 1inger.ms 大于0,即消息在缓冲区保留的时间,超过设置的值就会被提交到服务端
#通俗解释是,本该早就发出去的消息被迫至少等待了1inger.ms时间,相对于这时间内积累了更多消息,批量发送 减少请求
#如果batch被填满或者1inger.ms达到上限,满足其中一个就会被发送
linger.ms

6、TCP洪水攻击

(1)ss命令

Socket Statistics是Linux中的一条网络工具命令,用于显示当前系统的各种网络连接状态,包括TCP、UDP以及Unix套接字等。
显示的内容和netstat类似,但ss命令能够显示更多更详细的有关TCP和连接状态的信息。
使用格式:ss [OPTIONS],常用选项如下:

-s:显示概要信息
-a:显示所有网络连接状态
-l:显示正在监听的网络连接
-n:显示IP地址和端口号
-t:显示TCP状态
-u:显示UDP状态

(2)什么是洪水攻击

洪水攻击(SYN Flood),是一种网络攻击,它使用伪造的TCP连接请求来淹没服务器的资源,从而使服务器无法响应正常的用户请求。

这种攻击通过不断地发送同步(SYN)连接请求到服务器,而服务器会尝试建立连接,当服务器回复SYN+ACK报文后,攻击者不会发送确认(ACK),那SYN队列里的连接则不会出队,逐步就会沾满服务器端的SYN半连接队列,服务器会一直等待,耗尽服务器的资源,最终就是服务器不能为正常用户提供服务。

攻击的背景来源:
TCP进入三次握手前,服务端会从内部创建了两个队列,半连接队列(SYN队列)、全连接队列(ACCEPT队列)

(3)半连接队列(SYN队列)

存放的是三次握手未完成的连接,客户端发送SYN到服务端,服务端收到回复ACK和SYN。,状态由LISTEN变味SYN_RCVD,此时这个链接就被放进SYN半连接队列。
半连接队列的个数一般是有限的,在SYN攻击时服务器会打开大量的半连接,分配TCP耗尽服务器的资源,使得正常的连接请求无法得到响应。
系统最大半队列(半连接队列的最大长度不一定由tcp_max_syn_backlog值决定,Linux内核版本实现不一样)。

# 查看最大半队列配置值大小
[root@localhost ~]# sysctl -a | grep max_syn
net.ipv4.tcp_max_syn_backlog = 128
# 查看最大半队列配置值大小
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog 
128

# 查看系统当前半队列大小,synrecv 0就是
[root@localhost ~]# ss -s
Total: 291 (kernel 400)
TCP:   15 (estab 1, closed 4, orphaned 0, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6
*	  400       -         -        
RAW	  0         0         0        
UDP	  7         4         3        
TCP	  11        6         5        
INET	  18        10        8        
FRAG	  0         0         0  

# 查看系统当前半连接队列大小
[root@localhost ~]# netstat -natp | grep SYN_RECV | wc -l
0

# 查看SYN队列是否有溢出
# 间隔执行下面命令,如果有持续大量递增就是溢出
# 会显示:6891 SYNs to LISTEN sockets dropped
netstat -s | grep LISTEN

(4)全连接队列(ACCEPT队列)

存放的是完成三次握手的连接,客户端回复ACK,并且服务端接收后,三次握手就完成了。
连接会等待别的应用取走,在被取走之前,它被放进ACCEPT全连接队列。

# 查看系统最大全连接队列大小
# 长度由net.core.somaxconn和应用程序使用listen函数时传入的参数,二者取最小值,默认128,表示最多有129的ESTABLISHED的连接等待accept
[root@localhost ~]# cat /proc/sys/net/core/somaxconn 
128

# 查看系统当前全连接队列大小,如果指定端口,可以用ss -lnt | grep 80
# 常规可以通过port端口看是哪类应用,80端口这一行,
# Send-Q表示listen端口上的全连接队列最大为128
# Recv-Q为全连接队列当前使用了多少
[root@localhost ~]# ss -lnt
State       Recv-Q Send-Q     Local Address:Port       Peer Address:Port              
LISTEN      0      128                    *:22                    *:*                  
LISTEN      0      100            127.0.0.1:25                    *:*                  
LISTEN      0      128                    *:3306                  *:*                  
LISTEN      0      128                    *:6379                  *:*                  
LISTEN      0      128                    *:111                   *:*                  
LISTEN      0      128                 [::]:22                 [::]:*                  
LISTEN      0      100                [::1]:25                 [::]:*                  
LISTEN      0      128                 [::]:3306               [::]:*                  
LISTEN      0      128                 [::]:6379               [::]:*                  
LISTEN      0      128                 [::]:111                [::]:*                  

# 查看Accept队列是否有溢出
# 间隔执行下面命令,如果有持续大量递增则溢出,累计的值
netstat -s | grep TCPBacklogDrop

全连接队列满了之后会怎么样?
查看配置:cat /proc/sys/net/ipv4/tcp_abort_on_overflow 结果:0
系统会根据net.ipv4.tcp_abort_on_overflow参数决定返回,有两个值分别是0和1(推荐默认0):
0:如果全连接队列满了,那么server扔掉client发过来的ack。
1:如果全连接队列满了,server发送一个reset包给client,表示废掉这个握手过程和这个连接。
客户端连接不上服务器,判断是否是服务端TCP全连接队列满的原因,可以把tcp_abort_on_overflow设为1,client异常中会报connection reset by peer,大概率是由于服务端TCP全连接队列溢出导致的问题。

(5)连接队列总结

不管是半连接队列还是全连接队列,都有最大长度限制,超过限制时内核会直接丢弃或返回RST包。

全连接队列、半连接队列溢出很关键,对于一些短连接应用(比如nginx、php)更容易爆发,一旦溢出,从cpu、线程状态看起来都比较正常,但是压力上不去。

(6)洪水攻击防范 - TCP SYN Cookies

TCP SYN Cookies是一个基础缓解方案,延缓TCB分配。

使用连接信息(源地址、源端口、目的地址、目的端口等)和一个随机数,计算出一个哈希值(SHA1),哈希值被用作序列号应答SYN+ACK包,客户端发送完三次握手的最后一次ACK,服务器就会重新计算这个哈希值,确认是之前的SYN+ACK的返回包,则进入TCP的连接状态。

SYN-Cookie避免内存空间被耗尽,但是加密会消耗CPU,攻击者发送大量的ACK包过来,被攻击机器将会花费大量的CPU时间在计算Cookie上,造成正常的逻辑无法被执行。

当开启了syncookies功能就可以在不使用SYN半连接队列的情况下成功建立连接,不需要维护半连接数的限制,如果是DDOS则难解决,需要花钱购买流量设备。

# 开启syncookies ,阿里云ECS默认开启

vi /etc/sysctl.conf

net.ipv4.tcp_syncookies = 1

# 0:表示关闭该功能;
# 1:表示仅当SYN半连接队列放不下时,再启用它
# 2:表示无条件开启功能

(7)洪水攻击防范 - 其他方案

增大半连接队列和全连接队列。

减少SYN+ACK重传次数(减小tcp_synack_retries的值),收到syn攻击时,服务端会重传syn+ack报文的最大次数,才会断开连接,所以可以减少重传次数。

(8)洪水攻击实战

1、准备工作
准备两台服务器,一台安装hping3,一台安装nginx,并且要关闭tcp_syncookies。

2、安装hping3
hping3是一款开源的网络扫描和测试工具,可用于模拟tcp洪水攻击。

# 安装
yum -y install libpcap
yum -y install libpcap-devel
yum -y install tcl-devel

yum -y install hping3

参数说明:
-S:表示发送SYN数据包
-U:表示发送UDP包
-A:发送ACK包
-p:表示攻击的端口
-i u100:和洪水一样不停地攻击
--rand-source:随机构造发送方的IP地址

3、开始攻击

# -S是发送SYN数据包,-p是目标端口,192.168.56.10是目标机器ip
hping3 -S -p 80 --flood 192.168.56.10

攻击时,CPU平均负载和使用率都很低,CPU的si软中断升高,但是用户访问非常慢了。

4、分析
top查看内存占用率不高、CPU平均负载和使用率等比较低,CPU耗在 si 软中断 消耗时间比例升高

流程浅析:
网卡接收到数据包后,通过硬件中断的方式,通知内核有新的数据,内核调用中断处理程序,把网卡的数据读到内存中;
更新一下硬件寄存器的状态,再发送一个软中断信号,通知从内存中找到网络数据;
按照网络协议栈对数据进行逐层解析和处理,然后把数据交给应用程序进行处理,前面部分处理硬件请求,属于硬中断,特点是快速执行,后面部分处理是内核触发,属于软中断,特点是延迟执行。

CPU主要用在软中断上,从进程列表上看到CPU 使用率最高的也是软中断进程ksoftirqd,这是运行在Linux的进程,专门处理系统软中断的,格式是“ksoftirqd/CPU编号”,在多核服务器上每核都有一个ksoftirqd进程,经常看到ksoftirqd/0表示这是CPU0的软中断处理程序。

所以软中断过多比较大可能导致问题,通过文件系统/proc/softirqs 看是哪类下软中断导致
/proc/softirqs 提供了软中断的运行情况
/proc/interrupts 提供了硬中断的运行情况

# 查看
watch -d cat /proc/softirqs
# HI 高优先级软中断
# TIMER 表示定时器软中断,用于定时触发某些操作
# NET_TX 表示网络发送软中断,用于处理网络发送的数据包
# NET_RX 表示网络接收软中断,用于处理网络接收的数据包
# BLOCK 表示快设备软中断,用于处理磁盘读写请求
# TASKLET:任务中断,用于处理任务的中断请求
# SCHED 表示内核调度软中断
# HRTIMER 高精度定时器中断,用于处理高精度定时任务
# RCU Read-Copy Update中断,用于处理读写锁的内核操作
Every 2.0s: cat /proc/softirqs                                                                                                                                                                                                           Fri Jun 28 17:35:44 2024

                    CPU0       CPU1	  CPU2       CPU3
          HI:          0          0          0          0
       TIMER:    4534306    4461536    5386907    7259278
      NET_TX:	   75285      75278          0          3
      NET_RX:     216963         56     231921         47
       BLOCK:       5833       3792	  4270       5512
BLOCK_IOPOLL:          0          0          0          0
     TASKLET:         17          0          0          0
       SCHED:    2840069    2602469    3017211    1805987
     HRTIMER:          0          0          0          0
         RCU:    3409904    3332487    3981961    4612966

# 抓包
tcpdump -i eth0 -n tcp port 80

7、Linux常见内核参数调整

Linux内核参数,尽量不要随意调整,除非自己对相关特性和参数特别了解,否则不建议修改。

(1)查看内核参数

# 查看当前系统生效的所有参数
sysctl -a

参数有许多,此处就不一一列举了

(2)修改Linux内核参数的方法

方法一:通过/proc/sys目录查看和修改内核参数,/proc/sys目录是Linux内核启动后生成的伪目录,目录下的net文件夹存放了当前系统中开启的所有内核参数,目录树结构与参数的完整名相关。
比如net.ipv4.tcp_tw_recycle,对应的文件是/proc/sys/net/ipv4/tcp_tw_recycle文件,文件的内容就是参数值。

# 查看内核参数
[root@localhost ~]# cat /proc/sys/net/ipv4/tcp_tw_recycle
0
# 修改内核参数
echo "0" > /proc/sys/net/ipv4/tcp_tw_recycle

方法二:通过sysctl.conf文件查看和修改内核参数

# 编辑
vi /etc/sysctl.conf
# 使配置生效
/sbin/sysctl -p

(3)Linux文件句柄数限制优化

在Linux系统设计里面遵循一切都是文件的原则,即磁盘文件、目录、网络套接字、磁盘、管道等。所有这些都是文件,进行打开的时候会返回一个fd,即是文件句柄。
如果频繁的打开文件,或者打开网络套接字而忘记释放就会有句柄泄露的现象。
在Linux系统中对进程可以调用的文件句柄数进行了限制,在默认情况下每个进程可以调用的最大句柄数是1024个。
如果超过了这个限制进程将无法获取新的句柄,而从导致不能打开新的文件或者网络套接字,对于线上服务器即会出现服务被拒绝的情况。
遇到文件句柄达到上限时,会碰到Too many open files或者Socket/File:can't open so many files等错误。

进程级的文件句柄65535一般就够用,全局的要比进程级的大。

# 局部文件句柄数(单个进程最大打开文件数)
# 查看一个进程最大打开的文件数fd,不同系统有不同的默认值
[root@localhost ~]# ulimit -n
1024

# 修改文件句柄
vi /etc/security/limits.conf
#文末添加
* hard nofile 100000
* soft nofile 100000
# 其中*代表所有用户,100000代表修改的值,修改以后需要重新登录才能生效,常规设置65535就够用,这也是云服务器默认的
# 全局文件句柄(所有进程能够创建的文件句柄数之和)
[root@localhost ~]# cat /proc/sys/fs/file-max
382508

# 修改全局文件句柄
vi /etc/sysctl.conf
# 文末加上
fs.file-max=10000000000
# 使配置生效
sysctl -p

8、BIO、NIO、AIO、select-poll-epoll机制

BIO、NIO、AIO模型与select-poll-epoll机制全解

9、DNS详解

(1)什么是DNS

Internet上当一台主机要访问另外一台主机时,必须首先获知其地址,IP中是由四段以"."分开的数字组成。
IPv4的地址和IPv6的地址同理,记起来总是不如名字那么方便,所以就采用了域名系统来管理名字和IP的对应关系。

域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。
将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。
DNS使用域名服务器一般监听在端口53上。
对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。

总的来说,DNS的用途一是记录IP和域名的关系,方便查找,用途二是负载均衡,分摊节点的压力,业务更加稳定。

(2)负载均衡

DNS实现负载均衡,我们直接接触的就是使用openfeign,通过服务名进行服务之间的调用。
DNS给微服务返回不同的IP,可以轮询获取,可以随机获取,可以通过不同的负载均衡算法实现负载均衡。

可以用于负载均衡、故障切换、隐藏动态IP(k8s)等场景。

(3)智能DNS

就近原则,基于用户地理位置、运营商实现就近接入的智能解析。
传统DNS解析,不判断访问者来源,会随机选择其中一个IP地址返回给访问者。
智能DNS解析,会判断访问者的来源,为不同的访问者智能返回不同的IP地址。
可使访问者在访问网站时可获取用户指定的IP地址,能够减少解析时延,并提升网站访问速度的功效。

比如说,可以根据用户的网络供应商,访问网站时返回对应供应商的IP地址,加快访问速度。
可以根据用户所处的地址,获取就近服务器的IP地址,加快访问速度。

10、HTTP核心知识详解

(1)什么是HTTP协议

HTTP协议,超文本传送协议(Hypertext Transfer Protocol),是Web联网的基础,也是手机PC联网常用的协议之一。
HTTP协议建立在TCP协议之上的一种应用,HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应。
从建立连接到关闭连接的过程称为“一次连接”。
HTTP经过 20 多年的演进出现过0.9、1.0、1.1、2.0、3.0 五个主要版本。

(2)HTTP请求消息结构

请求行
请求方法、URL地址、协议名

请求头
报文头包含若干个属性,格式为“属性名:属性值”。
服务端据此获取客户端的基本信息。

请求体
请求的参数,可以是json对象,也可以是前端表单生成的key=value&key2=value2的字符串。

(3)HTTP响应消息结构

响应行
报文协议及版本、状态码

响应头
报文头包含若干个属性,格式为“属性名:属性值”。

响应正文
响应报文体,我们需要的内容,多种形式比如html、json、图片、视频文件等。

(4)响应码

1XX:收到请求,需要请求者继续执行操作,比较少用。

2XX:请求成功,常用的 200。

3XX:重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取;
好处:网站改版、域名迁移等,多个域名指向同个主站导流。
301:永久性跳转,比如域名过期换个域名。
302:临时性跳转。

4XX:客户端出错,请求包含语法错误或者无法完成请求。
400:请求出错,比如语法协议、
403:没权限访问、
404:找不到这个路径对应的接口或者文件、
405:不允许此方法进行提交,Method not alowed,比如接口一定要POST方式,而你是用了GET。

5XX:服务端出错,服务器在处理请求的过程中发生了错误。
500:服务器内部报错了,完成不了这次请求。
503:服务器宕机。

(5)HTTP协议发展历史

HTTP/0.9:
只支持 GET 请求方式,不支持其它。
不支持请求头 Header,只支持HTML字符串。
TCP连接特性:服务端相响应完成,立刻关闭TCP 连接。

HTTP/1.0:
请求方式新增了 POST、HEAD 等多种方法。
增加请求头和响应头,支持更丰富的内容,定制化更强(大部分目前使用)。
拓展数据传输内容格式,支图片,音频,视频,二进制流等(大部分目前使用)。
TCP连接特性:建立 TCP 连接不能复用,每个TCP 连接只能发送一个请求,数据发送完毕连接就关闭。如果还要请求其他资源,须重新建立连接,由于建立连接成本很高,性能不理想。

HTTP/1.1:(目前使用最广泛)
支持更多请求方法,增加了PUT、PATCH、OPTIONS、DELETE等请求方式;(大部分目前使用)
TCP连接特性:请求头新增 Connection 字段,设置 Keep-Alive 值保持连接不断开,即响应头加入这行码:Connection:keep-alive
Keep-Alive 不会永久保持连接,有一个保持时间,实现长连接需要客户端和服务端都支持长连接。
HTTP 协议的长连接和短连接,实质上是TCP 协议的长连接和短连接。
TCP 连接默认不关闭,可以被多个请求复用,是此版本最重要的优化
同一个 TCP 连接中,客户端可以同时发送多个请求,提升了 HTTP 协议的传输效率。

(6)HTTP/2.0

二进制分帧,1.x是文本协议,2.0是以二进制帧为基本单位,使用二进制编码来代替传统的文本编码,可以更有效地传输数据。

多路复用,可以在单一的TCP连接上同时传输多个请求/响应消息,从而节省连接时间。

服务器推送,允许服务器主动推送资源给客户端,从而提高网页加载速度。

Header压缩,使用HPACK压缩格式对头部进行压缩,从而减少请求/响应消息的体积。
之前每次发送都要带相同的 Header,冗余比较多,新版对头部信息进行增量更新,有效减少了头部数据的传输。
每个网页平均包含 100 多个 HTTP 请求,每个请求头平均有 300-500 字节,数据量达到几十 KB 以上。
上述说的多个请求头之间通常几乎没有变化,但是过多重复的头导致性能下降。
在 2版本的 HPACK 算法出现前,旧版使用HTTP的gzip 去压缩请求。
更好的请求优先级,允许客户端为请求设定优先级,从而更好地控制请求的执行顺序。

HPACK算法简单说明:
客户端和服务端共同维护一个 key-value 的数据存储结构,如果两端有发生变化时则更新传输,否则就不用重复传输。
在首次全量传输,后续交互就是增量更新传输,更省空间。
日常项目开发里面也很多采用的方案:比如浏览器缓存等,计算相关数据hash值是否变动,未变动则不用重新请求。

(7)HTTP/3.0

采用QUIC协议,Quick UDP Internet Connections 的缩写【快速 UDP 互联网连接】可以更快的建立连接,提高传输效率;
谷歌不满足HTTP2,想继续提升 HTTP 的性能,基于 UDP 来开发新一代 HTTP 协议。
采用 TCP和UDP的优点,在 UDP 基础上改造一个具备 TCP 协议优点的新协议。

QUIC 直接把以往的TCP的3次 和TLS的 3握手,总共6 次交互合并成了3 次,减少了交互次数。
支持更多的头部字段,如X-Forwarded-For,X-Real-IP等;
支持更多的加密技术,如TLS 1.3,DTLS 1.2等;
支持更多的数据传输形式,如文件传输,流式传输,管道传输等。

建议:新技术都需要时间推移逐步推广
HTTP/2.0 和 HTTPS 协议的普及度都没有预想高,就像IPv4不够用,早就出现IPv6,但是现在依旧很少。

(8)对称和非对称加密

数据传输过程中,需要保密(防止被窃取)、完整(防止被篡改)、可用(保证授权方可以正常使用)。

对称加密:

场景:消息发送方需要加密大量数据时使用。
优点:操作比较简单,加密速度快,秘钥简单。
缺点:秘钥一旦被窃取,信息会暴露,安全性不高。

常见的对称加密算法:
DES:全称:Data Encryption Standard,现已被破解
3DES:全称:Triple Data Encryption Algorithm,暂时未被破解,解释:3DES 是在 DES 基础算法上的改良,该算法可向下兼容 DES 加密算法,但计算性能不高,暂时还未被破解。
AES:全称:Advanced EncryptionStandard,暂未被破解

非对称加密:

加密与解密的过程不是对称的,不是用的同一个秘钥,一把是公钥,一把是私钥,在加密的时候,用公钥去加密,接收方再用对应的私钥去解密
注意:非对称加密具有双向性,即公钥和私钥中的任一个均可用作加密,此时另一个则用作解密。
优点:安全性更高,公钥是公开的,秘钥是自己保存的,不需要将私钥给别人。
缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
场景:数字签名与验证

常见的非对称加密算法:RSA,DSA,ECC等,ECC也是比特币底层用的比较多的算法

(9)什么是HTTPS

HTTPS (Hyper Text Transfer Protocol over SecureSocket Layer )安全超文本传输协议,是身披SSL外壳的HTTP。
主要由两部分组成:HTTP+SSL/TLS。
HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。
比 HTTP 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性,增加破解成本。
缺点:同网络环境下,HTTPS 协议会使页面的加载时间延长近 50%,增加额外的计算资源消耗,增加 10%到 20%的耗电等。不过利大于弊,所以Https是趋势,相关资源损耗也在持续下降。
注意:在进行通信前,会进行TCP 的三次握手,握手完成后,再进行TLS的握手过程。

HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议。
要比 HTTP 协议安全,可防止数据在传输过程中被窃取、改变,确保数据的完整性。

HTTPS的流程:
Server端有一套权威机构颁布的数字证书(证书内容有公钥、证书颁发机构、失效日期等)。
Client端发起 HTTPS 请求,连接到服务端的 443 端口。
Server端把自己的数字证书发送给Client端,公钥在证书里面,私钥由服务器自己存储。
Client端收到数字证书验证证书的合法性。如果证书验证通过,生成一个随机的对称密钥,用证书的公钥加密并发送给Server端。
Server端接收到Client端发来的密文后,用自己的私钥进行非对称解密,解密之后就得到Client端的对称加密的密钥。
然后用Client端的对称加密的密钥对数据进行对称加密。
Server端将加密后的密文返回到Client端。
Client端收到后,用自己的对称密钥进行对称解密,得到服务器返回的数据。

说明:
服务端的证书是由CA(Certiicate Authoriy,证书认证机构)颁布的,CA机构类似网络世界里的公安部门。
客户端内置 CA 对应的证书称为根证书,颁发者和使用者相同,自己为自己签名。
客户端首先在本地电脑寻找是否有这个服务器证书上的ca机构的根证书。
如果有继续下一步,如果没有弹出警告认为证书是非法的。
客户端会内置信任CA的证书信息,包括CA的公钥,证书颁布验证过程也是使用非对称加密进行。
HTTPS非对称加密只作用在证书验证阶段。
内容传输的加密上使用的是对称加密
既保证了秘钥的安全性,又保证了后继数据传输的数据加解密的性能。
简单说:秘钥交换使用非对称加密,内容传输使用对称加密的方式

本文标签: 网络不了解开发人员基础