一起来了解nginx吧~

2,146 阅读15分钟

1、INPUT和OUTPUT

INPUT和OUTPUT对应就是I/O模型

1.1 I/O模型

影响用户体验的因素,主要是:响应的速度,与I/O模型有关。

常见的I/O模型:

  • 磁盘I/O:构建响应报文的速度,表示数据从内存回复到网卡的过程
  • 网络I/O:接收发送的速度,表示数据从网卡到内存的过程,在 进程的 fd文件夹下形成了 一个临时文件 用来存储这次访问的基本信息

image.png

1.2 零拷贝技术(磁盘I/O)

方法一: 在内核空间 开辟一块共享空间,用户空间的程序,可以直接去共享空间进行处理,从而减少拷贝次数。

image.png

方法二: sendfile (调优)

sendfile 类似于软链接,作用是:减少内核态和用户态之间的拷贝次数,加快i/o速度。

1.3 网络I/O模型⭐⭐⭐

1.3.1 同步/异步

同步/异步(消息反馈机制):关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。

  • 同步:nginx主动去问内核,是否完成了任务
  • 异步:内核主动反馈给nginx交代的任务

1.3.2 阻塞/非阻塞(用的少!)

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

  • 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。完成之前只能接待一个请求!
  • 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。完成之前可以接待多个请求!

1.3.3 四种组合

  1. 同步阻塞:发起方主动去问 接收方是否完成任务;处理完成之前,接收方会被挂起,不会处理别的事情
  2. 同步非阻塞:发起方主动去问 接收方是否完成任务;处理完成之前,可以处理别的请求
  3. 异步阻塞:接收方主动给发起方反馈消息;处理完成之前,接收方会被挂起,不会处理别的事情
  4. 异步非阻塞:接收方主动给发起方反馈消息;处理完成之前,可以处理别的请求

变种:是目前主流,即多路复用模型

1.3.4 五个模型

  1. 阻塞性I/O模型:相当于 异步阻塞(最简单、基本不用!)
  2. 非阻塞I/O模型:相当于 同步非阻塞
  3. 多路复用I/O模型(能满足,足够用!)
  4. 信号驱动式I/O模型:效率高
  5. 异步I/O模型:相当于 异步非阻塞 效率高

1.4 epoll

nginx共有8种模型,默认选择的epoll模型。最常用的模型是前3种:

  1. select
  2. poll
  3. epoll
  4. rtsig
  5. kqueue
  6. /dev/poll
  7. eventport
  8. Iocp
selectpollepoll
操作方式遍历遍历回调
底层实现数组链表哈希表
IO效率每次调用都仅从线性遍历,时间复杂度为O(n)同select时间复杂度O(1)
最大连接数1024(X86)、2048(X64)无上限无上限
fd拷贝每次调用select,都需要把fd集合,从用户态拷贝到内核态每次调用poll,都要把fd集合,从用户态拷贝到内核态调用epoll_ctl 时,拷贝进内核态并保存,之后每次epoll_wait不拷贝
  • select 遍历
  • poll 也是遍历,但是能用epoll就不用poll。
  • epoll 回调,主动反馈。epoll 在fd里有报警机制。

select和epoll之间的区别:

epoll是poll的升级版,epoll只能在linux中使用,window中不支持epoll。

2、nginx概述

nginx架构:主程序master+子进程worker

  • master:不干活,只接收请求,然后分配工作给worker
  • worker:干活

2.1 yum安装nginx

`nginx和apache共用80端口`

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1fc1c8f1096942639d1860a010649dd9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=391&h=452&s=63746&e=png&b=6cfc7a)
 yum install epel-release.noarch -y   //先下载epel源
 ​
 yum install nginx -y    //yum安装
 systemctl start nginx    //开启nginx

小拓展:nginx安装后 启动失败,如何解决?:

  1. 报错信息:开启nginx时 报错

image.png

image.png

  1. 解决方法: 排查可能是80端口 被httpd所占,需要先关闭httpd,再重新打开nginx。

image.png

2.1.1 主进程和子进程

image.png

 [root@7-1 ~]#  pstree -p|grep nginx
            |-nginx(10708)-+-nginx(10709)
            |              `-nginx(10710)
 ​
 #自定义子进程数量:
 [root@7-1 ~]#  vim /etc/nginx/nginx.conf
 # worker_processes auto;   //注释第6行,auto是自动分配,基本上是1个cpu分配一个子进程worker。
 worker_processes 1;      //新增配置,自定义可以改成1,就只有一个子进程
 [root@7-1 ~]#  systemctl restart nginx
 [root@7-1 ~]#  pstree -p|grep nginx
            |-nginx(10971)---nginx(10972)

2.2 nginx模块

  • 核心模块
  • 标准HTTP模块
  • 可选HTTP模块
  • 邮件服务模块
  • stream服务模块
  • 第三方模块

重点是 前三个模块

     常用模块:
     ngx_http_core_module             核心模块
     ngx_http_access_module          访问控制  deny  allow
     ngx_http_auth_basic_module     身份验证
     ngx_http_gzip_module             压缩模块
     ngx_http_1og_module              日志模块
     ngx_http_proxy_module            代理模块
     ngx_http_rewrite_module          重写模块
     ngx http_stub_status_module     状态页模块
     ngx_http_upstream_module        反向代理
     ngx_http_stream_module            四层代理

2.3 编译安装nginx

可以查看老师之前给的nginx脚本!!!

nginx版本:

看中间列,偶数是正式版,奇数是测试版:

image.png

编译安装nginx步骤:

#官网地址
 https://nginx.org/en/download.html
 ​
 #查看帮助模块
 ./configure --help   
 ​
 ​
 #关闭防火墙
 systemctl stop firewalld    
 setenforce 0
 ​
 #新建/data文件夹
 mkdir /data    
 cd /data
 ​
 #下载源码包
 wget http://nginx.org/download/nginx-1.18.0.tar.gz    
 ​
 #解压软件包
 tar xf nginx-1.18.0.tar.gz
 cd nginx-1.18.0/
 mkdir /apps/nginx -p
 ​
 #安装依赖环境
 yum -y install make gcc pcre-devel openssl-devel zlib-devel openssl openssl-devel    
 ​
 #检测环境,指定安装目录
 ./configure --prefix=/apps/nginx \
 --user=nginx \
 --group=nginx \
 --with-http_ssl_module \
 --with-http_v2_module \
 --with-http_realip_module \
 --with-http_stub_status_module \
 --with-http_gzip_static_module \
 --with-pcre \
 --with-stream \
 --with-stream_ssl_module \
 --with-stream_realip_module
 ​
 #编译 
 make -j2       
 make install
 ​
 #建立软链接,下次输入nginx命令时,可以自动补全
 ln -s /apps/nginx/sbin/nginx /usr/local/sbin
 nginx    #运行nginx
 ​
 ​
 #新建nginx用户便于管理
 useradd -M -s /sbin/nologin nginx
 ​
 #修改权限
 chown -R nginx.nginx /apps/nginx
 ​
 ​
 ll /apps/nginx/
 total 0
 drwxr-xr-x 2 root root 333 Sep 22 12:49 conf
 drwxr-xr-x 2 root root  40 Sep 22 12:49 html
 drwxr-xr-x 2 root root   6 Sep 22 12:49 logs
 drwxr-xr-x 2 root root  19 Sep 22 12:49 sbin

安装好,生成的四个文件功能如下:

  1. conf:保存nginx所有的配置文件
  2. html:目录中保存了nginx服务器的web文件
  3. logs:用来保存nginx服务器的访问日志错误日志等日志
  4. sbin:保存nginx二进制启动脚本

源码包内的文件:

  • contrib:vim 格式文件,修改nginx配置文件的格式,

编译安装的高亮设置: cp -r /opt/nginx-1.18.0/contrib/vim/* /usr/share/vim/vimfiles/

  • conf:配置文件
  • man:man帮助 man man/nginx.8 不加路径看不了 nginx.8 文件
  • src:源码包 点c 点h 结尾的文件 find src -type f |xargs cat |wc -l 193678
  • objs:存储的是编译好的nginx文件

2.4 nginx信号⭐⭐

选项含义
-t检查语法格式
-T检查语法,并打印所有配置
-v显示版本
-V显示详细信息,包括编译的信息
-c指定配置文件位置,可以不用官方默认的文件,自己指定路径
-g单独指定配置,不以配置文件中的为准,但注意: 单独改之前,要先将配置文件里的注释掉,二者不能有冲突
-s发送信号,类似于kill
-hhelp帮助

2.4.1 检查语法格式 -t

 [root@7-1 ~]#  nginx -t     //检查语法
 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
 nginx: configuration file /etc/nginx/nginx.conf test is successful

2.4.2 显示版本 -v

 [root@7-1 ~]#  nginx -v
 nginx version: nginx/1.20.1

2.4.3 指定配置指令 -g

1:
 [root@7-1 ~]#  vim /apps/nginx/conf/nginx.conf   //编辑配置文件
 # worker_processes 4      //改配置之前,要将原配置文件中的注释掉,不能有冲突
 [root@7-1 ~]#  nginx -g "worker_processes 1"    //worker_processes 1是配置文件选项,格式是:关键字+值
 ​
 例2:
 nginx -g “daemon off”   //-g意思临时性的设定一次配置文件,不按照默认配置来,按照指定的要求来

小tips:nginx默认后台启动。

2.4.4 发送信号 -s

 nginx -s reload   重新加载配置文件⭐⭐
 nginx -s stop     停止nginx,并且立即停止
 nginx -s quit     优雅的退出,有人访问,不会立即关闭,而是等对方结束后再退出。
 nginx -s reopen   重新生成日志文件 等价于nginx -s USR1⭐⭐
 nginx -s USR2     飞行中升级

nginx -s 与 kill命令对比:

nginx -s信号kill信号含义
nginx -s reloadkill -1(HUP)重新加载配置文件
nginx -s stopkill -9 (KILL)立即退出
nginx -s quitkill -3(QUIT)优雅的退出
nginx -s reopenkill -USR1重新生成日志
nginx -s USR2——飞行中升级

2.5 nginx升级 USR2

实验目的:从nginx1.18.0版本,升级到nginx1.22.0版本

 [root@7-1 ~]#  cd /opt
 [root@7-1 opt]#  nginx -v
 nginx version: nginx/1.18.0
 [root@7-1 opt]#  curl -I 192.168.125.100
 HTTP/1.1 200 OK
 Server: nginx/1.18.0
 Date: Fri, 31 May 2024 07:33:29 GMT
 Content-Type: text/html
 Content-Length: 4833
 Last-Modified: Fri, 16 May 2014 15:12:48 GMT
 Connection: keep-alive
 ETag: "53762af0-12e1"
 Accept-Ranges: bytes
 ​
 [root@7-1 opt]#  wget https://nginx.org/download/nginx-1.22.0.tar.gz -P /usr/local/src/       //下载1.22.0版本的安装包
 ​
 ./configure --prefix=/apps/nginx \
 --user=nginx \
 --group=nginx \
 --with-http_ssl_module \
 --with-http_v2_module \
 --with-http_realip_module \
 --with-http_stub_status_module \
 --with-http_gzip_static_module \
 --with-pcre \
 --with-stream \
 --with-stream_ssl_module \
 --with-stream_realip_module
 ​
 make -j2
 make          //注意:千万不要make install!!!,不然就覆盖掉了!!!只输make的意思是:万一新版本安装的有问题,还可以还原回旧版本!!!

image.png

注意:老版本先不要删除,可以改个名字!!!然后新版本改成老版本改名之前的名字!!!这个时候nginx -v 会显示版本已变,但只是内存版本 变了,客户版本 并没有变化!!!最后使用飞行中升级:

 cat nginx.pid
 kill -s USR2 pid号

3、基本配置

nginx的配置文件的组成部分:

  • 编译安装:

    • 主配置:/apps/nginx/conf/nginx.conf
    • 子配置:/apps/nginx/conf.d/
  • yum安装:

    • 主配置:/etc/nginx/nginx.conf
    • 子配置:/usr/share/nginx/

nginx指令组成部分:

  • 全局配置(主配置)
  • 模块配置

image.png

指令注意事项:

  • nginx指令每条指令以 ;分号 结尾,指令与值之间以空格符号分隔
 pid       /apps/run/nginx.pid
 指令 [空格]    值
  • 部分指令需要放到指定位置,比如 alias别名指令,只能放到 location 模块

  • root 是主站点指令

  • 参考官方文档:nginx.org.en.docs

syntax:指令的语法
default:指令的默认值
context:指令可以在哪些配置上下文中使用

3.1 全局配置 main

3.1.1 关闭版本或修改版本

server_tokens off ,注意是在httpd模块下修改,也是唯一 一个在httpd模块下的。

 http {
     server_tokens  off;

 nginx -s reload     //重新加载

3.1.2 cpu与worker进程 绑定

cpu 的亲缘性,可以理解为cpu与nginx进程进行一 一对应,绑定在一起。

为什么要进行cpu与进程绑定?

当有多个cpu时,进程对应的cpu不是固定的,比如某进程第一次是在cpu1里面处理,第二次可能会在cpu2里面处理。这样就会形成,在cpu1产生的处理数据,cpu2里面是没有的,要从cpu1里面去拷贝,导致浪费资源、降低效率。

 [root@7-1 ~]#  ps axo pid,cmd,psr,|grep nginx    //挑选3个字段,中间以逗号隔开
  18620 nginx: master process /usr/   2   0
  18951 nginx: worker process         0   0
  18952 nginx: worker process         1   0
  18954 grep --color=auto nginx       2   0

 #######绑定########
 vim /etc/nginx/conf/nignx.conf
 worker_cpu_affinity 00000001 00000010 00000100 00001000;     //0-3个CPU,上限最多支持8个cpu
 nginx -s reload
 ​
 验证cpu乱跑可以刷新网页即可:
 while true ;do ab -c 1000 -n 1000 http://192.168.125.100/;done    //-c并发数量,-n总数量

小拓展:

安装压力测试工具:

 yum install httpd-tools -y

3.1.3 进程优先级

nice 优先级:-20到19

 worker_priority -20;    //-20优先级最高
 nginx -s reload

3.1.4 进程打开文件的数量⭐⭐⭐⭐⭐⭐

nginx 默认打开的 子进程数量 1024

修改进程打开的文件数量,分为两部分:

  1. nginx调优
worker_rlimit_nofile 65536; 
  1. 系统调优
 [root@localhost ~]#ulimit -a
 [root@localhost ~]#ulimit -n 60000

3.1.5 服务是否以 后台方式运行

服务运行分为:前台运行、后台运行。一般都是后台运行,但在某些特殊场景,比如:docker容器,必须设置前台运行

 daemon off     //前台运行

3.1.6 只有主进程,没有子进程

一般是在测试环境中使用!!!实际生产中极少使用!!!因为主进程类似监工、子进程是干活的。

3.2 event 事件模块

i/o模型调优:

 events {
    worker_connections  65535;  #设置单个工作进程的最大并发连接数
    worker_rlimit_nofile;     //总数量
    use epoll;   //event默认使用epoll
 }

惊群效应:

 accept_mutex on;    //轮流派任务
 ​
 multi_accept on;   //同一时间可以处理多个请求

3.3 http设置⭐⭐⭐⭐⭐

image.png 格式:

  • http

    • server:主要是对主机的设置,比如:端口号、ip地址、域名、主站点、日志

      • location:用来匹配url

// 注意:多个相同指令,内部的生效,比如在server和location里都有的话,location生效。

3.3.1 mime.types

格式里有的,就查看;没有的,就下载!

 vim /etc/mime.types

小拓展:

nginx默认使用的是gzip压缩 但是,gzip压缩不压缩图片!图片压缩是前端的工作,运维压缩容易造成图片失真!可以寻求第三方软件!!!

3.3.2 listen 监听端口

监听sock 等于监听本机

 listen 80;   //设置监听地址和端口

注意:listen 80之间没有写IP地址的话,就是默认本机所有IP地址的80端口都监听。

一台机器可以有四块网卡,每块网卡对应一个IP地址。

3.3.3 域名

 server_name  www.wxj.org;

3.3.4 root

root指令 类似于追加

 location /cxk {
     root /data/cxk;   //系统上的路径,相当于是/data/cxk/cxk/index.html
     index  index.html index.htm;   //先找index.html,没有的话 再找index.htm
 }
 # error_page 404 /404.html;      //两个都没有的话,就报错。

查看错误日志:

 tail -f /apps/nginx/logs/error.log

3.3.5 虚拟主机(实验)⭐⭐⭐⭐

nginx 主配置文件里面内容太多,可以在子配置文件里面设置!

实验目的:用一台服务器做两个站点:电脑端和手机端

  1. 先在主配置文件中,设置子配置文件的路径:
 [root@7-1 nginx]#  vim /apps/nginx/conf/nginx.conf
 http{
     include /apps/nginx/conf.d/*.conf;   //注意:不要忘记加结束符
 [root@7-1 nginx]#  cd /apps/nginx
 [root@7-1 nginx]#  mkdir conf.d
 [root@7-1 nginx]#  cd conf.d
 [root@7-1 nginx]#  nginx -s reload
  1. 设置电脑端:PC
 [root@7-1 conf.d]#  vim pc.conf
 server {
     listen 80;
     server_name www.pc.com;
     root /data/pc/;
 }
 [root@7-1 conf.d]#  nginx -t
 [root@7-1 conf.d]#  nginx -s reload
  1. 设置手机端:iphone
 [root@7-1 conf.d]#  cp pc.conf iphone.conf
 [root@7-1 conf.d]#  vim iphone.conf
 server {
     listen 80;
     server_name www.iphone.com;
     root /data/iphone/;
 }
 [root@7-1 conf.d]#  nginx -t
 [root@7-1 conf.d]#  nginx -s reload
  1. 新建文件及准备页面
 [root@7-1 data]#  cd pc
 [root@7-1 pc]#  echo "this is 电脑端PC" >index.html
 [root@7-1 pc]#  cd ..
 [root@7-1 data]#  cd iphone
 [root@7-1 iphone]#  echo "this is 手机端iphone" >index.html
  1. 对面服务器验证:
 [root@7-2 ~]#  vim /etc/hosts
 192.168.125.100  www.pc.com  www.iphone.com
 [root@7-2 ~]#  curl www.pc.com
 this is 电脑端PC
 [root@7-2 ~]#  curl www.iphone.com
 this is 手机端iphone    //实验成功

3.3.6 alias 别名

 location /cxk{
     alias /data/;    //访问/cxk等于访问/data
 }
 nginx -s reload
 cd /data
 echo data > index.html
 最后,用对面的服务器去验证!

如果配置一模一样的话,优先级 按照字母顺序读取。

3.3.7 location 去匹配(重点中的重点)

 #语法规则:
 location [ = | ~ | ~* | ^~ ] url { ... }

匹配规则:

  • 先看写法和含义,判断能不能匹配
  • 再看优先级,判断具体匹配哪一个

3.3.7.1 五种写法及其含义

写法样式含义
=location = /cxk精确匹配,必须一模一样,一字不差,一旦匹配成功,就不会继续往下匹配
^~location ^~ /cxk以什么开头、(起始于什么),一旦匹配成功,就不会继续去找下面的正则表达式
~(波浪符)location ~ /cxk开启正则,区分大小写
~*location ~* /cxk开启正则,不区分大小写
不带符号location /cxk前面不加符号,也是起始于什么什么的意思,但是优先级最低

3.3.7.2 优先级

 #匹配优先级从高到低:
 =,  ^~,   ~/~*,  不带符号

3.3.7.3 不区分大小写案例

 location ~* /A.?.jpg$ {
     root /opt/nginx
 }
 ​
 /A.?.jpg$ 拆分:
     /(第一个) :根
     A.?      :代表A后面的字符,出现0次或者1次
     .        :对点进行转义
     jpg$      :以jpg结尾

示例:

 ######格式种空格有问题,复制要注意#######
 location = /1.jpg {
    root /data/nginx/static1;
    index index.html;
  }
  location /1.jpg {
    root /data/nginx/static2;
    index index.html;
 }
  location ~* .(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
    root /data/nginx/static3;
    index index.html;
  }

 [root@centos8 ~]# mkdir -p /data/nginx/static{1,2,3}
 #上传图片到 /data/nginx/static{1,2,3} 并重启nginx访问测试

注意:不区分大小写,nginx系统不能识别。使用上述命令时,要准备一份小写文件、一份大写文件。

3.3.8 access 控制访问

控制访问 可以用两种方式:

  • 用户名和密码
  • 匹配IP地址

四层控制:网络层

 location / {
     deny  192.168.1.1;
     allow 192.168.1.0/24;
     allow 10.1.1.0/16;
     allow 2001:0db8::/32;
     deny  all;
 }

3.3.9 htpasswd

验证模块 需要输入用户名和密码

 htpasswd -c  文件路径 姓名             交互式生成密码
 htpasswd -bc 文件路径 姓名 密码         直接将密码跟在后面 
 ​
 -c  代表新建用户名和密码对应的文件
 -b  将密码跟在用户名后

nginx没有自己的密码生成工具,要用apache的:

 yum install httpd-tools -y