互联网基础之HTTP协议
【iptables简介】(原文链接:
iptables系列教程(一)| iptables入门篇 - 腾讯云开发者社区-腾讯云 (tencent.com)
iptables系列教程(二)| iptables语法规则 - 腾讯云开发者社区-腾讯云 (tencent.com)
iptables系列教程(三)| iptables 实战篇 - 腾讯云开发者社区-腾讯云 (tencent.com))
iptables 是 Linux 防火墙工作在用户空间的管理工具,通过 iptables 的代理,将⽤户配置的安全策略执⾏到对应的安全框架中,真正实现IP信息包过滤的是安全框架称之为 netfilter,位于内核空间,它俩共同组成了Linux防火墙。
在Centos7发行版本下,firewalld防火墙取代了iptables防火墙;
1、iptables的作用
用来设置、维护和检查 Linux 内核的 IP 数据包过滤规则,实现数据包过滤、网络地址转换等。
2、iptables组成
iptables的结构是由表(tables)组成,而tables是由链组成,链又是由具体的规则组成。因此我们在编写iptables规则时,要先指定表,再指定链。tables的作用是区分不同功能的规则,并且存储这些规则。
filter表 | INPUT、FORWARD、OUTPUT |
nat表 | PREROUTING(DNAT)、OUTPUT、POSTROUTING(SNAT) |
mangle表 | PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING |
raw表 | PREROUTING、OUTPUT |
注意:raw表
:用于处理异常,包括的规则链有:prerouting,output;一般使用不到。
四表:filter、nat、managle、raw,默认是filter表。表的处理优先级:raw>managle>nat>filter
filter | 过滤数据包 |
nat | 网络地址转换(端口映射、地址映射等。) |
mangle | 用于对特定数据报的修改。 |
raw | 优先级最高,设置raw时一般是为了不再让iptables做数据报的链接跟踪处理,提高性能。 |
五链:PREROUTING 、INPUT、FORWARD、OUTPUT、POSTROUTING
PREROUTING | 数据包进入路由表之前,对数据包做路由选择前应用此链路中的规则,所有的数据包进来的时候都先由这个链处理 |
INPUT | 通过路由表后目的为本机,进来的数据报应用此规则链上的策略 |
FORWARD | 通过路由表后,目标地址不为本机,做转发数据报时应用此规则链上的策略 |
OUTPUT | 由本机产生的外出的数据包向外转发时,应用此规则链中的策略 |
POSTROUTING | 数据报做路由选择后发送后到网卡接口之前应用此链中的规则,所有的数据包出来的时候都先由这个链处理 |
3、iptables数据包流向:
(1)Network IN数据包到达服务器的网络接口;
(2)进入raw表的 PREROUTING 链,这个链的作用是决定数据包是否被状态跟踪;
进入 mangle 表的 PREROUTING 链,在此可以修改数据包,比如 TOS 等;
进入 nat 表的 PREROUTING 链,可以在此做DNAT(目标地址转换);
(3)决定路由,查看目标地址是交给本地主机还是转发给其它主机;
(4)到这里分两种情况,一种情况是数据包要转发给其它主机(一般情况下它是在担任网关服务器),数据包会依次经过;
(5)进入 mangle 表的 FORWARD 链
进入 filter 表的 FORWARD 链,在这里我们可以对所有转发的数据包进行过滤。
(6)进入 mangle 表的 POSTROUTING 链
进入 nat 表的 POSTROUTING 链,在这里一般都是用来做 SNAT (源地址转换)
(7)数据包流出网络接口,发往network out;
(8)另一种情况,数据包的目标地址就是发给本地主机的,它会依次穿过:
(9)进入 mangle 表的 INPUT 链,
进入 filter 表的 INPUT 链,在这里我们可以对流入的所有数据包进行过滤,
数据包交给本地主机的应用程序进行处理。
(10)应用程序处理完毕后发送的数据包进行路由发送决定。
(11)进入 raw 表的 OUTPUT 链。
进入 mangle 表的 OUTPUT 链,
进入 nat 表的 OUTPUT 链,
进入 filter 表的 OUTPUT 链。
(12)进入 mangle 表的 POSTROUTING 链,
进入 nat 表的 POSTROUTING 链。
(13)进入出去的网络接口,发送往network out。
4、iptables语法规则
iptables [-t table] command [链名] [条件匹配] [-j 目标动作]
-t table
用来指明使用的表,有三种选项: filter
,nat
,mangle
。若未指定,则默认使用filter表
command参数
指定iptables 对我们提交的规则要做什么样的操作,以下是command常用参数:
-A
Append,追加一条规则(放到最后)
-I
Insert,在指定的位置插入规则
-L
List,查看规则列表
-D
Delete,从规则列表中删除规则
-P
Policy,设置某个链的默认规则
-F
Flush,清空规则
-Z
zero,将指定链的所有计数器归零。(如未指定,则认为是所有链)
条件匹配参数
按网络接口匹配:
-i
匹配数据进入的网络接口,此参数主要应用nat表,例如目标地址转换。
-o
匹配数据流出的网络接口
按源及目的地址匹配
-s
匹配源地址,可以是IP、网段、域名,也可空(代表任何地址)
-d
匹配目标地址
按协议类型匹配
-p
匹配协议类型,可以是TCP、UDP、ICMP等
按源及目的端口匹配
--sport
匹配源端口;可以是单个端口,也可以是端口范围
--dport
匹配目的端口
注意:--sport 和 --dport 必须配合 -p 参数使用
目的动作
-j ACCEPT
允许数据包通过本链而不拦截它
-j DROP
丢弃数据包;阻止数据包通过本链
-j SNAT
源地址转换,支持转换为单IP,也支持转换到IP地址池
-j DNAT
目的地址转换,支持转换为单IP,也支持转换到IP地址池
-j MASQUERADE
动态SNAT转换(适用于动态 IP 场景 )
iptables 常用附加模块:
按包状态匹配 (state)
-m state --state 状态
按来源 MAC 匹配(mac)
-m mac --mac-source MAC
按包速率匹配 (limit)
-m limit --limit 匹配速率
多端口匹配 (multiport)
-m multiport <--sports|--dports|--ports> 端口 1[,端口 2,..,端口 n]
iptables 规则保存
[root@junwu_client ~]# yum -y install iptables-services
[root@junwu_client ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
##从提示中可以看到,防火墙规则保存在 /etc/sysconfig/iptables
案例
1、禁⽌服务器被ping,服务器拒绝icmp的流量,给与响应
##给INPUT链添加规则,指定icmp协议,指定icmp类型 是8(回显请求), -s指定源地址,-j拒绝数据包
##此时在filter表中input链有多条规则,iptables执行规则时,是从从规则表中从上至下顺序执行的,此时其它主机依旧可以ping通,,只有REJIECT写在第一条才不会让数据进入本机
[root@junwu_client ~]# iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j REJECT
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
INPUT_direct all -- anywhere anywhere
INPUT_ZONES_SOURCE all -- anywhere anywhere
INPUT_ZONES all -- anywhere anywhere
DROP all -- anywhere anywhere ctstate INVALID
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
REJECT icmp -- anywhere anywhere icmp echo-request reject-with icmp-port-unreachable
##写在input链中第一条后,其它主机无法ping通
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT icmp -- anywhere anywhere icmp echo-request reject-with icmp-port-unreacha
[root@junwu_server ~]# ping 10.0.0.15
PING 10.0.0.15 (10.0.0.15) 56(84) bytes of data.
From 10.0.0.15 icmp_seq=1 Destination Port Unreachable
From 10.0.0.15 icmp_seq=2 Destination Port Unreachable
2、服务器禁ping,请求直接丢弃
[root@junwu_client ~]# iptables -F
[root@junwu_client ~]# iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- anywhere anywhere icmp echo-request
[root@junwu_server ~]# ping 10.0.0.15
PING 10.0.0.15 (10.0.0.15) 56(84) bytes of data.
--- 10.0.0.15 ping statistics ---
57 packets transmitted, 0 received, 100% packet loss, time 56416ms
5、删除第⼀条规则
[root@junwu_client ~]# iptables -D INPUT 1
[root@junwu_client ~]# iptables -A INPUT -p tcp --dport 80 -j DROP
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:http
7、禁⽌服务器的FTP端⼝,也就是禁⽌21端⼝
[root@junwu_server ~]# iptables -A INPUT -p tcp --dport 21 -j DROP
[root@junwu_server ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:ftp
##此时无法连接ftp
[root@junwu_client ~]# ftp 10.0.0.10
ftp: connect: Connection timed out
8、只允许指定的ip远程连接此服务器,拒绝其他主机22端⼝流量
[root@junwu_client ~]# iptables -A INPUT -s 192.168.10.5 -p tcp --dport 22 -j ACCEPT
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.10.5 anywhere tcp dpt:ssh
9、禁⽌指定的机器ip,访问本机的80端⼝策略,可以封禁某些恶意请求
[root@junwu_client ~]# iptables -I INPUT -p tcp -s 192.168.132.2 --dport 80 -j REJECT
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- 192.168.132.2 anywhere tcp dpt:http reject-with icmp-port-unreachable
ACCEPT tcp -- 192.168.10.5 anywhere tcp dpt:ssh
10、禁⽌所有的主机⽹段,访问本机的8000~9000的端⼝
[root@junwu_client ~]# iptables -A INPUT -p tcp -s 0/0 --dport 8000:9000 -j REJECT
[root@junwu_client ~]# iptables -A INPUT -p udp -s 0/0 --dport 8000:9000 -j REJECT
[root@junwu_client ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- anywhere anywhere tcp dpts:irdmi:cslistener reject-with icmp-port-unreachable
REJECT udp -- anywhere anywhere udp dpts:irdmi:cslistener reject-with icmp-port-unreachable
Web基础
HTTP协议(原文:关于HTTP协议,一篇就够了 - ranyonsue - 博客园 (cnblogs.com))
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
![](https://upload-images.jianshu.io/upload_images/2964446-5a35e17f298a48e1.jpg?imageMogr2/auto-orient/strip%7CimageView2/2)
TCP/IP协议实际上是一个协议族。
TCP/IP协议主要由网络层的IP协议 和 传输层的TCP协议组成 。
IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议,他们与 TCP 或 IP 的关系紧密。因此,也称 TCP/IP 为网际协议群。
TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。
打个比方:TCP协议就相当于中国邮政快递,用来做运输
IP协议就相当于邮政编码,用来唯一标记目的地。
TCP协议
TCP协议是传输控制协议,工作在传输层。提供面向链接的,可靠的传输服务(三次握手,四次挥手)
面向链接:数据传输之前,客户端与服务器之间要建立连接,才可以传输数据
可靠的:数据传输是有序的,要对数据进行校验,数据不会丢失
与TCP协议对应的还有一个UDP协议。
TCP/IP是一套用于网络通信的协议集合或者系统。TCP/IP协议模型就有OSI模型分为7层。但其实一般我们所谈到的都是四层的TCP/IP协议栈。
网络接口层:主要是指一些物理层层次的接口,比如电缆等
网络层:提供了独立于硬件的逻辑寻址,实现物理地址和逻辑地址的转换。网络层协议包括IP协议(网际协议),ICMP协议(互联网控制报文协议),IGMP协议(Internet组协议管理)
传输层:为网络提供了流量控制,错误控制和确认服务。传输层有两个互不相同的传输协议:TCP(传输控制协议)、UDP(用户数据报协议)
应用层:为文件传输,网络排错和Internet操作提供具体的程序应用
TCP传输原理(原文链接:https://blog.csdn.net/mocas_wang/article/details/109366736)
![](https://img2023.cnblogs.com/blog/3042329/202211/3042329-20221128223233583-55530250.png)
源主机封包:
1、 应用层:源主机将数据向下传输给传输层;
2、 传输层:将数据分组,加上TCP首部形成TCP数据段,向下传输给网络层;
3、 网络层:给TCP数据段加上源主机、目的主机IP首部,生成IP数据包,向下传输给链路层;
4、 链路层:链路层在其MAC帧的数据部分装上IP数据包,再加上源主机,目的主机的MAC地址和帧头,并根据其目的的MAC地址,将MAC帧发往目的主机或IP路由器;
目的主机拆包:
1、 链路层:在目的主机,链路层将MAC帧的帧头去掉,并将IP数据包向上传递给网络层;
2、 网路层:检查IP报头,如果报头中校验和计算结果不一致,则丢弃该IP数据包,若校验和计算结果一致,则去掉IP报头,将TCP数据段向上传递给传输层;
3、 传输层:检查顺序号,判断是否是正确的TCP分组,然后检查TCP报头数据,若正确,则向源主机发送确认信息,若不正确或丢包,则向源主机要求重发信息;
4、 应用层:目的主机,传输层去掉TCP报头,将排好顺序的分组组成应用数据流送给应用程序,这样目的主机接收到的来自源主机的字节流,就像是直接接收来自源主机的字节流一样。
总结
数据在每层有不同的格式,从上到下依次叫数据段,数据包,数据帧,数据从应用层通过协议栈向下传递,每经过一层加上对应层协议报头,最后封装成"数据帧"发送到传输介质上,到达路由器或者目的主机去掉头部,交付给上层需要者。这一过程称为封装,传输,分离,分用。
数据段:TCP 数据流中的信息;
数据包:IP 和 UDP 等网络层以上的分层中包的单位;
数据帧:数据链路层中包的单位;
IP协议与ARP(原文链接https://blog.csdn.net/weixin_53186633/article/details/120514627)
IP协议是TCP/IP协议的核心,所有的TCP,UDP等数据都以IP数据格式传输。IP协议没有提供一种数据未传达以后的处理机制,这被认为是上层协议:TCP或UDP要做的事情,所以IP不是可靠的协议。
ARP协议是处于数据链路层和网络层之间的协议,只要用来将IP地址和MAC地址建立映射。
TCP协议
TCP协议是传输控制协议,工作在传输层。提供面向链接的,可靠的传输服务(三次握手,四次挥手)
面向链接:数据传输之前,客户端与服务器之间要建立连接,才可以传输数据
可靠的:数据传输是有序的,要对数据进行校验,数据不会丢失
与TCP协议对应的还有一个UDP协议。
三次握手——TCP连接的建立(原文链接:(13条消息) TCP/IP协议工作原理和工作流程_mocas_wang的博客-CSDN博客_tcp工作原理)
在通信之前,会先通过三次握手的机制来确认两端口之间的连接是否可用。而UDP是不需要确认的,直接传
最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。
某个时刻客户端和服务器要进行通信,此时双方都有备好的端口,服务器的端口会处于监听状态,等待客户端的连接。
怎么知道服务器端口号的?
http在访问url中已经拿到!
怎么知道客户端要连接进来,服务器才进入listen状态?
TCP老早就创建了传输控制块TCB,时刻待命准备接受客户端的连接请求,此时服务器就被动地进入了listen状态。
第一次握手:
客户端想要连接,创建传输控制块TCB,状态变为主动打开。发送给服务器不包含数据内容的连接请求报文。该请求报文首部中同步位SYN=1,同时选择一个初始序列号seq=x(携带了x个字节)。然后客户端进入 SYN-SENT (同步已发送)状态,告诉服务器我想和你同步连接。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
第二次握手:
TCP服务器收到连接请求报文,如果同意连接则发送确认报文。为了保证下次客户端发送报文时seq序列号是正确的,需要发送确认号ack=x+1,同时确认号ack要生效必须发送ACK=1,再加上同步位SYN=1,序列号seq=y(携带Y个字节),然后服务器也进 入SYN-RCVD (同步已收到) 状态,完成同步连接。这个报文也是SYN报文,也不能携带数据,但是同样要消耗一个序号。
第三次握手:
客户端收到确认后还要再向服务器发送确认报文。确认报文已经不是请求报文SYN了,不再包含SYN同步位。发送的内容有序列号seq=x+1(和第二次握手的ACK对应),确认号ack=y+1,ACK=1。客户端发送确认报文以后进入ESTABLISHED(已建立)状态,服务器接收到确认报文以后也进入ESTABLISHED状态。此时TCP连接完成建立。
然后就可以发送TCP接收到Http的数据包后生成的新数据包了!
但是貌似看起来两次握手请求就可以完成事,为什么非要三次握手呢?
主要是为了防止已经失效的连接请求报文突然又传到了服务器,从而产生错误。
如果是两次握手,假设一种情景:客户端发送了第一个请求连接报文并未丢失,只是因为网络问题在网络节点中滞留太久了。由于客户端迟迟没有收到确认报文,以为服务器没有收到。于是再发送一条请求连接报文,此时一路畅通完成两次握手建立连接,传输数据,关闭连接。然后那个前一条龟速的请求报文终于走到了服务器,再次和服务器建立连接,这就造成了不必要的资源浪费。
如果是三次握手,就算那一条龟速的请求报文最后到达了服务器,然后服务器也发送了确认连接报文,但是此时客户端已经不会再发出确认报文了,服务器也接受不到确认报文,于是无法建立连接。
四次挥手——TCP连接的释放
数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。
第一次挥手:
客户端从ESTABLISHED状态变为主动关闭状态,客户端发送请求释放连接报文给服务器,FIN=1,seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
第二次挥手:
服务器接收到客户端发来的请求释放报文以后,发送确认报文告诉客户端我收到了你的请求,内容差不多就是seq=v,ack=u+1,ACK=1,此时服务器进入CLOSE-WAIT(关闭等待)状态。
为什么是CLOSE-WAIT状态?可能自己服务器这端还有数据没有发送完,所以这个时候整个TCP的连接就变成了半关闭状态。服务器还能发送数据,客户端也能接收数据,但客户端不能再发送数据了,只能发送确认报文。
客户端接收到服务器传来的确认报文以后,进入 FIN-WAIT-1(终止等待2)状态,等待服务器发送连接释放的报文(在这之前,还需要接受服务器没有发送完的最后的数据)。
第三次挥手:
服务器所有的数据都发送完了,认为可以关闭连接了,于是向客户端发送连接释放报文,内容FIN=1,seq=w,ack=u+1(客户端没发送消息,所以提醒客户端下一次还是从u+1开始发送序列),ACK=1。此时服务器进入了 LAST-ACK(最后确认)状态,等待客户端发送确认报文。
第四次挥手:
客户端接收到了服务器发送的连接释放报文,必须发出确认。确认报文seq=u+1,ack=w+1,ACK=1。此时客户端进入 TIME-WAIT (时间等待)状态,但是没有立马关闭。此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
因为这个确认报文可能丢失。服务器收不到确认报文心想这可能是我没传到或者丢失了啊,于是服务器再传一个FIN,然后客户端再重新发送一个确认报文。然后刷新2∗∗MSL时间。直到这个时间内收不到FIN连接释放报文,客户端撤销TCB进入CLOSE状态。
而服务器,在接收到确认报文的时候就立马变为CLOSE状态了。所以服务器结束TCP连接的时间略早于客户端。
万一确认连接以后客户端故障怎么办?
TCP设有一个保活计时器。显然客户端故障时服务器不会智障般等下去,白白浪费资源。服务器每次收到一次客户端的请求以后都会刷新这个保活计时器,时间通常设置为2小时。若2个小时依旧没有收到客户端的任何数据,服务器会发送一个探测报文段,每隔75分钟发一个,如果连发十个都没有数据反应,那么服务器就知道客户端故障了,关闭连接
URI和URL(原文链接:关于HTTP协议,一篇就够了 - ranyonsue - 博客园 (cnblogs.com))
URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的
URI一般由三部组成:
①访问资源的命名机制
②存放资源的主机名
③资源自身的名称,由路径表示,着重强调于资源。
URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL一般由三部组成:
①协议(或称为服务方式)
②存有该资源的主机IP地址(有时也包括端口号)
③主机资源的具体地址。如目录和文件名等
Html、CSS与JavaScript的关系(原文链接:https://www.jianshu.com/p/c25f1ff07163)
1、HTML是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片、视频等。
CSS样式是表现。就像网页的外衣。比如,标题字体、颜色变化,或为标题加入背景图片、边框等。所有这些用来改变内容外观的东西称之为表现
JavaScript是用来实现网页上的特效效果。如:鼠标滑过弹出下拉菜单。或鼠标滑过表格的背景颜色改变。还有焦点新闻(新闻图片)的轮换。可以这么理解,有动画的,有交互的一般都是用JavaScript来实现的。
静态资源、动态资源
【静态web资源】供用户浏览的web页面中的数据始终是写死的,是固定不变的。
优 点:访问速度快。
缺 点:交互性差,要想页面内容发生改变则必须手动修改页面文件,很不方便。
如:HTML、CSS、JavaScript、图片......
【动态web资源】
供用户浏览的web页面中的数据 由程序动态产生的。能根据用户输入的不同参数条件,而展现出不同的数据内容。
如:JSP/Servlet....
优 点:动态资源可以根据需求获取不同的内容;而页面内容数据的更新,却无需修改页面文件。
缺 点:访问速度不及静态页面。
并发模式(原文链接:并发模型 - 知乎 (zhihu.com))
进程
进程是系统进行资源分配的一个独立单位,操作系统内核通过进程控制块(PCB,process control block)来感知进程
进程申请系统资源包含如下
- 已打开的文件
- 已申请到的I/O设备
- 用户的地址空间
- 进程维护的地址映射表
- 实现进程(线程)间同步和通信的机制
线程
是操作系统能够进行运算调度的最小单位
线程本身不拥有系统资源,大部分情况下,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并行多个线程,每条线程并行执行不同的任务
线程按照实现方式分为
- 内核支持线程KST
内核支持线程是驻留在内核空间中的内核对象。用户进程或者系统进程中的线程的创建、撤消、切换都是在内核空间中实现的,并由内核为其分配线程控制块进行管理。每个用户线程会被映射或者绑定到一个内核线程,形成一对一的线程对应关系,如下图所示,内核可以感知线程的存在,其调度是以线程为基本单位。 - 用户级线程ULT
内核支持线程是驻留在内核空间中的内核对象。用户进程或者系统进程中的线程的创建、撤消、切换都是在内核空间中实现的,并由内核为其分配线程控制块进行管理。每个用户线程会被映射或者绑定到一个内核线程,形成一对一的线程对应关系,如下图所示,内核可以感知线程的存在,其调度是以线程为基本单位。 - 组合方式
用户级线程仅存在于用户空间中,对于这种线程的创建、撤消、线程之间的同步与通信等,无须利用系统调用来实现,也同样无须内核的运行,而是通过中间系统(线程库)在用户空间中来完成。由于不需要用户/内核态切换,线程切换速度比较快。但由于内核无法感知用户级线程的存在,其调度仍是以进程为单位进行的。当内核调度一个进程运行时,用户级线程库调度该进程的一个线程执行,如果时间片允许,进程的其他线程也可能被执行,该进程的多个线程共享该进程的运行时间片。如果一个线程需要进行i/o读写,该线程调用系统调用进入内核,在启动I/O设备后内核会把该进程值为阻塞态,并把CPU分配给其他进程。即使该进程的其他线程可以运行,内核也不会发现这一情况,在该进程的状态变为就绪之前内核不会调度该进程运行,因而属于该进程的线程都不可能运行,因而用户级线程的并行性会受到一定的限制。用户级线程是一种"多对一"的线程映射。
协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制,协程间切换只需要保存任务的上下文,没有内核的开销。
协程是编译器级别的,现在很多编程语言都支持协程,如 Erlang、Lua、Python、Golang。准确来说,协程只是一种用户态的轻量线程。
协程的优势
- 内存占用少:线程栈空间通常是 2M,Goroutine 栈空间最小 2K;Golang 程序中可以轻松支持10w 级别的 Goroutine 运行,而线程数量达到 1k 时,内存占用就已经达到 2G。
- 上下文切换代价小:Goroutine 上下文切换只涉及到三个寄存器(PC / SP / DX)的值修改;而对比线程的上下文切换则需要涉及模式切换(从用户态切换到内核态)、以及 16 个寄存器、PC、SP…等寄存器的刷新;
- Go 协程使用信道(Channel)来进行通信。信道用于防止多个协程访问共享内存时发生竞态条件(Race Condition)。信道可以看作是 Go 协程之间通信的管道。我们会在下一教程详细讨论信道。
线程的出现,是为了分离进程的两个功能:资源分配和系统调度。让更细粒度、更轻量的线程来承担调度,减轻调度带来的开销。但线程还是不够轻量,因为调度是在内核空间进行的,每次线程切换都需要陷入内核,这个开销还是不可忽视的。协程则是把调度逻辑在用户空间里实现,通过自己(编译器运行时系统/程序员)模拟控制权的交接,来达到更加细粒度的控制。
进程调度方式
- 非剥夺调度方式,又称非抢占方式。是指当一个进程正在处理机上执行时 ,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在执行的进程继续执行,直到该进程完成或发生某种事件而进入阻塞状态时,才把处理机分配给更为重要或紧迫的进程。
- 剥夺调度方式,又称抢占方式。是指当一个进程正在处理机上执行时,若有某个更为重要或紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给这个更为重要或紧迫的进程。
并发模型比较
一、多进程模型
主进程监听和管理连接,当有客户请求的时候,fork 一个子进程来处理连接,父进程继续等待其他客户的请求。但是进程占用服务器资源是比较多的,服务器负载会很高。
Apache的web容器实现就是这种模型
二、多线程与锁
几乎每种编程语言都以某种形式提供了支持,我们应该了解底层的原理,但是,多数时候,应该使用更上层的类库,更高效,更不易出错。这种方式无外乎几种经典的模式,互斥锁(临界区),生产者-消费者,同步等等
优点:
- 好理解 基础语言库都有支持,容易实现
- 其他并发模型的基础
缺点:
- 难以测试,很容易隐藏某些难以发现的问题
- 会频繁地创建、销毁线程。这对系统也是个不小的开销
服务器接入与响应过程(链接:https://www.jianshu.com/p/eb8eb4ea7286)
![](https://img2023.cnblogs.com/blog/3042329/202211/3042329-20221130234301959-708374658.png)
![](https://img2023.cnblogs.com/blog/3042329/202212/3042329-20221201012035567-941587440.png)
- Accept 就是告诉服务器端,我接受那些MIME类型
- Accept-Encoding 这个看起来是接受那些压缩⽅式的⽂件
- Accept-Lanague 告诉服务器能够发送哪些语⾔
- Connection 告诉服务器⽀持keep-alive特性
- Cookie 每次请求时都会携带上Cookie以⽅便服务器端识别是否是同⼀个客户端
- Host ⽤来标识请求服务器上的那个虚拟主机,⽐如Nginx⾥⾯可以定义很多
- 虚拟主机.那这⾥就是⽤来标识要访问那个虚拟主机。
- User-Agent ⽤户代理,⼀般情况是浏览器,也有其他类型,如:
- wget curl 搜引擎的蜘蛛等
- If-Modified-Since 是浏览器向服务器端询问某个资源⽂件如果⾃从什么时间修过,那么重新发给我,这样就保证服务器端资源.⽂件更新时,浏览器再次去求,⽽不是使⽤缓存中的⽂件。
- If-None-Match:本地缓存中存储的⽂档的ETag标签是否与服务器⽂档的Etag不匹配;
- 1xx 信息状态码,服务器收到请求,需要客户端继续操作
- 2xx 操作成功
- 3xx 重定向状态码,需要进⼀步的操作
- 4xx 客户端错误,请求语法错误等
- 5xx 服务端错误,服务器处理过程中出错了
-
⼀些常⻅HTTP状态码为:200 – 服务器成功返回⽹⻚404 – 请求的⽹⻚不存在503 – 服务不可⽤
4、浏览器解析HTML
![](https://img2023.cnblogs.com/blog/3042329/202212/3042329-20221201012728234-119578997.png)
什么是事务
事务是指是程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所作的所有更改都会被撤消。可以通俗理解为:就是把多件事情当做一件事情来处理,好比大家同在一条船上,要活一起活,要完一起完 。
事物的四个特性(ACID)
● 原子性(Atomicity):操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。
eg:拿转账来说,假设用户A和用户B两者的钱加起来一共是20000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是20000,这就是事务的一致性。
● 一致性(Consistency):事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。
● 隔离性(Isolation):隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
● 持久性(Durability):当事务正确完成后,它对于数据的改变是永久性的。
eg: 例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。