一、 I/O类型:系统I/O和网络I/O
系统I/O模型:同步/异步,阻塞/非阻塞
同步/异步:关注的是事件处理的消息通知机制 ,即在等待一件事情的处理结果时被调用者是否提供完成通知。
同步:进程发出请求调用后,内核不提供通知机制,即文件I/O处理完成后不通知进程,需要进程自己去问内核是否处理完成。
异步:进程发出请求调用后,内核会在调用处理完成后返回调用结果给进程。
阻塞/非阻塞:关注的是调用者等待被调用者返回调用结果时的状态
阻塞:调用结果返回之前,调用者会被挂起;调用者只有在得到返回结果之后才能继续;
非阻塞:调用者在结果返回之前,不会被挂起,即调用不会阻塞调用者;
网络I/O模型:阻塞型、非阻塞型、复用型、信号驱动型、异步
同步阻塞型I/O(blocking IO)
阻塞IO模型是最简单的IO模型,进程挂起将转为不可中断式睡眠进程状态,调用者在调用结果得到之前将一直处于等待过程中;
优点:程序简单,在阻塞等待数据期间进程挂起,基本不会占用CPU资源
缺点:每个连接需要独立的进程单独处理,当并发请求量大时为了维护程序,内存、进程切换开销较大,apache的prefork使用的时这种模式。
同步非阻塞型I/O(nonblocking IO)
非阻塞式IO,应用进程向内核发送IO请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回IO结果,进程将不再等待,而且继续处理其他请求,但是仍然需要进程隔一段时间就要查看内核IO是否完成。第一步盲等待,第二步阻塞式IO
IO多路复用型(IO multiplexing)
IO多路复用型就是我们说的select,它的好处就在于单个process就可以同时处理多个网络连接的IO,但是select最多只能存在1024个并发。Apache prefork是此模式的主进程+多进程/多线程+select,work是主进程+多线程/多线程+poll模式。
信号驱动式IO(signal driven IO)
进程向内核发送IO调用后,不用等待内核响应可以继续接受其他请求,内核收到进程请求后进行的IO如果不能立即返回,就由内核等待结果直到IO完成后内核再通知进程,apache event模型就是主进程+多线程/多线程+信号驱动。
优点:进程没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源利用率。
缺点:信号驱动式IO在大量IO操作时可能会因为信号队列溢出导致没法通知
异步(非阻塞)IO(asynchronous IO)
异步非阻塞:程序进程向内核发送IO调用后,不用等待内核响应可以继续接受其他请求。内核调用的IO如果不能立即返回内核会继续处理其他食物,直到IO完成后将结果通知给内核,内核再将IO完成 的结果返回给进程。在这期间进程可以接受新的请求,内核也可以处理新的事物,相互不影响可以实现较大的同时并实现较高的IO复用,因此异步非阻塞是使用最多的一种通信方式,nginx就是异步非阻塞模型。
一个进程发起IO调用以后,这个IO将由两个阶段组成一次IO。磁盘IO:第一步:数据从磁盘到内核内存,第二步:数据从内核内存复制到进程内存,真正称为IO的过程为数据从内核内存到进程内存的过程。
一次文件IO请求,都会由两阶段组成:
第一步:等待数据,即数据从磁盘到内核内存;
第二步:复制数据,即数据内核内存到进程内存;
二、nginx相关
编译安装nginx
# 安装依赖包
[root@node8 ~]# yum install -y openssl-devel pcre-devel zlib-devel gcc gcc-c++ unzip
# 下载源码包
[root@node8 ~]# useradd nginx -s /sbin/nologin
[root@node8 ~]# wget https://nginx.org/download/nginx-1.18.0.tar.gz
[root@node8 ~]# tar xf nginx-1.18.0.tar.gz
[root@node8 ~]# cd nginx-1.18.0
[root@node8 nginx-1.18.0]# ./configure --help #查看编译相关的参数
[root@node8 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module
[root@node8 nginx-1.18.0]# make -j4 && make install
[root@node8 nginx-1.18.0]# chown -R nginx. /usr/local/nginx/
[root@node8 nginx-1.18.0]# ll /usr/local/nginx/
drwxr-xr-x. 3 nginx nginx 4096 12月 26 19:58 conf
drwxr-xr-x. 2 nginx nginx 40 12月 26 17:19 html
drwxr-xr-x. 2 nginx nginx 58 12月 26 19:41 logs
drwxr-xr-x. 2 nginx nginx 19 12月 26 17:19 sbin
#验证版本及编译参数
[root@node8 nginx-1.18.0]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module
访问编译安装的nginx web界面
创建nginx自启动脚本
#先停止nginx
[root@node8 nginx-1.18.0]# /usr/local/nginx/sbin/nginx -s stop
[root@node8 nginx-1.18.0]# cat /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@node8 nginx-1.18.0]# systemctl daemon-reload
[root@node8 nginx-1.18.0]# systemctl start nginx
[root@node8 nginx-1.18.0]# systemctl status nginx
● nginx.service - nginx
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: active (running) since 日 2021-12-26 19:41:17 CST; 1h 6min ago
Process: 7569 ExecReload=/usr/local/nginx/sbin/nginx -s reload (code=exited, status=0/SUCCESS)
Process: 7558 ExecStart=/usr/local/nginx/sbin/nginx (code=exited, status=0/SUCCESS)
Main PID: 7559 (nginx)
CGroup: /system.slice/nginx.service
├─7559 nginx: master process /usr/local/nginx/sbin/nginx
├─7643 nginx: worker process
└─7644 nginx: worker process
12月 26 19:41:17 node8 systemd[1]: Starting nginx...
12月 26 19:41:17 node8 systemd[1]: Started nginx.
添加虚拟主机
[root@node8 ~]# vim /usr/local/nginx/conf/nginx.conf
include vhost/*.conf; #添加此段配置
[root@node8 ~]# mkdir /usr/local/nginx/conf/vhost
[root@node8 ~]# cat /usr/local/nginx/conf/vhost/pc.conf
server {
listen 80;
server_name www.ilinux.io;
location / {
index index.html;
root /data/nginx/vhost1;
}
}
[root@node8 ~]# mkdir /data/nginx/vhost1 -p
[root@node8 ~]# echo pc test page > /data/nginx/vhost1/index.html
[root@node8 ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node8 ~]# /usr/local/nginx/sbin/nginx -s reload
添加hosts访问测试
实现强制https跳转访问
生成自签名证书
##自签名CA证书
[root@node8 ~]# cd /usr/local/nginx/
[root@node8 nginx]# mkdir certs
[root@node8 nginx]# cd certs/
[root@node8 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
Generating a 4096 bit RSA private key
.....................................................................................++
.......................................................................................................................................................................................................................................................................................................................................................................++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN #国家代码
State or Province Name (full name) []:ShangHai #省份
Locality Name (eg, city) [Default City]:ShangHai #城市名称
Organization Name (eg, company) [Default Company Ltd]:ilinux.io #公司名称
Organizational Unit Name (eg, section) []:ilinux #部分
Common Name (eg, your name or your server's hostname) []:ilinux.ca #通用名称
Email Address []: #邮箱,可不填
[root@node8 certs]# ll ca.crt
-rw-r--r--. 1 root root 2025 12月 26 20:06 ca.crt
#自制key和csr文件
[root@node8 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.ilinux.io.key -out www.ilinux.io.csr
Generating a 4096 bit RSA private key
..............................++
...........................++
writing new private key to 'www.ilinux.io.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ShangHai
Locality Name (eg, city) [Default City]:ShangHai
Organization Name (eg, company) [Default Company Ltd]:ilinux.io
Organizational Unit Name (eg, section) []:ilinux.io
Common Name (eg, your name or your server's hostname) []:www.ilinux.io
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@node8 certs]# ll
总用量 16
-rw-r--r--. 1 root root 2025 12月 26 20:06 ca.crt
-rw-r--r--. 1 root root 3272 12月 26 20:06 ca.key
-rw-r--r--. 1 root root 1712 12月 26 20:10 www.ilinux.io.csr
-rw-r--r--. 1 root root 3272 12月 26 20:10 www.ilinux.io.key
#签发证书
[root@node8 certs]# openssl x509 -req -days 3650 -in www.ilinux.io.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.ilinux.io.crt
Signature ok
subject=/C=CN/ST=ShangHai/L=ShangHai/O=ilinux.io/OU=ilinux.io/CN=www.ilinux.io
Getting CA Private Key
#验证证书内容
[root@node8 certs]# openssl x509 -in www.ilinux.io.crt -noout -text
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
cf:4f:f4:97:c0:f4:86:b2
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=CN, ST=ShangHai, L=ShangHai, O=ilinux.io, OU=ilinux, CN=ilinux.ca
Validity
Not Before: Dec 26 12:11:44 2021 GMT
Not After : Dec 24 12:11:44 2031 GMT
Subject: C=CN, ST=ShangHai, L=ShangHai, O=ilinux.io, OU=ilinux.io, CN=www.ilinux.io
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
配置站点强制跳转https
[root@node8 ~]# cat /usr/local/nginx/conf/vhost/pc.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /usr/local/nginx/certs/www.ilinux.io.crt;
ssl_certificate_key /usr/local/nginx/certs/www.ilinux.io.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
server_name www.ilinux.io;
location / {
index index.html;
root /data/nginx/vhost1;
if ( $scheme = http ) { ##未加条件判断会造成死循环
rewrite / https://www.ilinux.io permanent;
}
}
}
[root@node8 ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node8 ~]# /usr/local/nginx/sbin/nginx -s reload
访问测试
三、nginx反向代理功能
环境准备:
node8:172.20.21.175 #nginx代理服务器
node3:172.20.21.129 #后端web A,Apache部署
node4:172.20.21.130 #后端web B,Apache部署
部署后端Apache服务器
[root@node3 ~]# yum install -y httpd
[root@node3 ~]# echo web1 172.20.21.129 > /var/www/html/index.html
[root@node3 ~]# systemctl start httpd
[root@node4 ~]# yum install -y httpd
[root@node4 ~]# echo web2 172.20.21.130 > /var/www/html/index.html
[root@node4 ~]# systemctl start httpd
# 访问测试
[root@node3 ~]# curl 172.20.21.129
web1 172.20.21.129
[root@node3 ~]# curl 172.20.21.130
web2 172.20.21.130
配置nginx 反向代理
[root@node8 ~]# cat /usr/local/nginx/conf/vhost/test.conf
server {
listen 80;
server_name www.ilinux.net;
location /web1/ {
index index.html;
proxy_pass http://172.20.21.129/;
#带斜线,等于访问后端服务器的http://172.20.21.129/index.html 内容返回给客户端
}
location /web2/ {
index index.html;
proxy_pass http://172.20.21.130/;
}
}
[root@node8 ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@node8 ~]# /usr/local/nginx/sbin/nginx -s reload
##添加hosts访问测试
[root@node3 ~]# cat /etc/hosts
172.20.21.175 www.ilinux.io www.ilinux.net
[root@node3 ~]# curl -L http://www.ilinux.net/web1
web1 172.20.21.129
[root@node3 ~]# curl -L http://www.ilinux.net/web2
web2 172.20.21.130
四、status(状态码)
2XX:200-206,成功
3XX:300-305,重定向
4XX:400-415,错误类信息,客户端错误
5XX:500-505,错误类信息,服务器端错误
常用的状态码:
200:成功,请求的所有数据通过响应报文的entity-body部分发送;OK
301:请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently,永久重定向;
302:与301相似,但在响应报文中通过Location指明资源现在所处临时新位置;Found,临时重定向;
304:客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端;Not Modified
401:需要输入账号和密码认证方能访问资源;Unauthorized
403:请求被禁止;Forbidden
404:服务器无法找到客户端请求的资源;Not Found
500:服务器内部错误;Internal Server Error
502:代理服务器从后端服务器收到了一条伪响应;Bad Gateway