IO模型的原理以及nginx的相关配置

一、 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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值