Nginx高性能Web服务器详解(二)-----接一

本文深入探讨Nginx的高级配置技巧,包括模块、配置指令与块的关系,进程管理,五种IO模型,以及如何限制用户访问和实现HTTPS加密认证。通过实践示例,解析root与alias指令的区别,获取真实客户端IP的方法,和如何设置连接数限制。
摘要由CSDN通过智能技术生成

Nginx高性能Web服务器详解(二)

在上一节中我们安装了nginx后,每次运行nginx都要到 /usr/local/nginx/sbin/nginx 下执行nginx,这样显然比较麻烦,所以我们可以制作软连接来解决此问题

在这里插入图片描述

1.nginx的常用命令

选项				说明
不加选项				启动nginx服务
-h或-?				查看inginx命令帮助
-v					查看nginx版本信息
-V					查看nginx编译信息
-c					启动nginx时指定主配置文件
-t					测试nginx.conf文件是否存在语法错误
-s					向正在运行的nginx主进程发送信号,信号的可用值有stop, quit, reopen, reload

具体说明:

nginx -h nginx -?
如果你想要看看nginx命令都有哪些可用的选项,则可以使用"-h选项"或者
-t选项或者-T
使用"-t"选项或者"-T"选项可以测试nginx.conf配t文件中是否存在语法错误
nginx.conf中的配置指令需要以分号结尾,如果没有以分号结尾,会在启动nignx时报语法错误。其实,在启动nginx服务之前,我们就可以使用nginx -t命令对nginx.conf文件进行语法检查,如果配文件中存在语法错误,那么相应的错误信息会输出
-s选项
-s选项的作用就是向正在运行的nginx进程发送信号
比如,当nginx服务已经启动,我们想要停止nginx服务,则可以使用nginx -s stop命令停止nginx服务,“nginx -s stop"命令表示向nginx进程发送stop信号,使用”-s"选项除了能够发送stop信号,还能发送quit信号、reopen信号以及reload信号
quit信号
与stop信号的作用类似,quit信号作用也是用于停止nginx服务, quit信号和stop信号的区别在于,nignx进程收到stop信号以后会立即停止服务,而收到quit信号后,不会再接收新的请求,但是会先处理完已经接受的链接请求,处理完这些请求之后再停止服务,这种停止方式被称之为"优雅的停止”
reload信号
reload信号的作用就是在不停止服务的情况下重载配文件,比如,nginx正在正常的提供服务,此时,管理员修改了nginx.conf文件中的配置指令,管理员希望新的配立刻生效,但是又不希望重启nginx服务,此时就可以使用nginx -s reload命令重载配置文件,以便在不重启nginx的情况下载入新的配置,同时避免了因重启而造成的服务中断
reopen信号
利用reopen信号可以使nignx进程重新打开日志文件,以便实现日志分割的效果

2.模块、配置指令、块之间的关系

下面通过一个实验让大家更好的理解三者之间的关系

在server1中:
vim /usr/local/nginx/conf/nginx.conf
在这里插入图片描述
配置发布目录:

mkdir /opt/demo
cd /opt/demo/
vim index.html
nginx -s reload

在这里插入图片描述
测试:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上述示例,你肯定明白了一个道理,同一个配指令,配在不同的块中时,对应的“作用域”是不同的。
某些配指令只能在http块中配置,某些配指令只能在location块中配置,有些配置指令既能在server块中配置又能在http块中配置,而有些配置指令只能在main区中进行配置
刚才示例中的index指令就属于那种既能在location块中配置,又能在server块中配置,还能在http块中配的指令,只不过,当index指令配置在不同的块中时,对应的作用域不同。

有些指令既能配在server块中,也能配在http块中,当多个server存在相同的配置时,我们可以将这些完全相同的配置指令提取到上一级的http块中,以便多个server块共用这些配置。
当然,如果你在某个server中单独配置了对应的指令,那么这个server仍然会以自己的配置为准。

其实,“配置指令"不仅和"块"有一定的关系,“配置指令"和"模块"也有非常紧密的对应关系。nginx是模块化的,不同的"模块"负责不同的"功能”。所以,当我们需要针对某个"功能"进行配置时,就需要使用到对应的"配置指令"。从根本上来说,每个"配置指令"都属于某一个"模块",一个"模块"中会有一个或多个"配置指令",当我们想要对相关模块或者功能进行设定时,就会使用到对应模块中的配置指令。

3.nginx进程

1.查看nginx进程

当你启动nginx以后,使用ps命令查nginx进程,会发现nginx进程不只有一个。默认情况下,你会看到至少两个nginx进程

在这里插入图片描述
2.指定worker进程的运行用户

编译安装nginx后,默认情况下worker进程是以nobody用户的身份运行的,如果我们想要指定worker进程的运行用户,则可以使用user指令

在这里插入图片描述
指定worker进程以nginx用户的身份运行:

建立nginx用户:

useradd -u 900 nginx
id nginx
修改配置文件:

vim /usr/local/nginx/conf/nginx.conf		#修改文件第一行
nginx -t	#语法检测
nginx -s reload	#在不暂停服务的情况下重新加载
ps -ef | grep nginx|grep -v grep

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.定义worker进程数

当我启动nginx以后,有两个nginx进程:一个master进程,一个worker进程。

这两个nginx进程都有各自的作用,见名知意,"worker"进程天生就是来"干活"的,真正负责处理请求的进程就是你看到的"worker"进程,那么"master"进程有什么用呢? "mlaster"进程其实是负责管理"worker"进程的,除了管理"worker"进程,master"进程还负责读取配通文件、判断配文件语法的工作。

"master进程"也叫"主进程",在nginx中, "master"进程只能有一个,而"worker"进程可以有多个,worker"进程的数量可以由管理员自己进行定义

默认的nginx.conf配置文件中有这样一条配置worker_ processes 1;
上述配置的意思就是启动nginx后只有1个worker进程,你想要多少个worker进程,将worker_processes指令的值设成多少就好了。

worker_ processes指令只能在main区域中使用,通常情况下,worker_ processes的值通常不会大于服务器中cpu的核心数量。换句话说就是,worker进程的数量通常与服务器有多少cpu核心有关
比如,nginx所在服务器拥有4核cpu,那么worker_ processes的值通常不会大于4,这样做的原因是为了尽让每个worker进程都有一个cpu可以使用,尽量避免了多个worker进程抢占同一个cpu的情况,我们也可以将worker _processes的值设置为auto
当worker_ processes的值为auto时,nginx 会自动检测当前主机的cpu核心数,并启动对应数量的worker进程。比如,nginx检测到当前主机一共有4个cpu核心,那么nginx就会启动4个worker进程

将服务器的CPU数设置为4:

在这里插入图片描述
修改配置文件:

vim /usr/local/nginx/conf/nginx.conf		#修改文件第二行
nginx -t	#语法检测
nginx -s reload	#在不暂停服务的情况下重新加载
ps -ef | grep nginx|grep -v grep

在这里插入图片描述
在这里插入图片描述
4.绑定worker和CPU

为了避免cpu在切换进程时产生性能损耗,我们也可以将worker进程与cpu核心进行"绑定",当worker进程与cpu核心绑定以后,worker进程可以更好的专注的使用某个cpu核心上的缓存,从而减少因为cpu切换不同worker进程而带来的缓存失效。

如果想要让worker进程与某个cpu核心绑定,则需要借助另外-一个配置指令worker_ cpu_ _affinity指令

想要搞明白怎样使用"worker_ cpu_ _affinity"指令, 最好先来了解一个概念
这个概念就是"cpu掩码",我们可以通过"cpu掩码"表示某个cpu核心
比如,当前机器上一共有4个cpu核心,那么我们就用40表示这4个核
也就是说,我们可以使用如下字符表示这4个核: 0000那么:
第一个核就用如下字符表示
0001
第二个核就用如下字符表示
0010
第三个核就用如下字符表示
0100
第四个和就用如下字符表示


规律就是,有几个核,就用几个0表示,如果想要使用某个核,就将对应位置的0改成1。从右边开始数。
比如:如果有8个核,我就可以使用如下字符表示这8个核中的第二个核:00000010

4.漫谈5种IO模型

5种IO模型分别是阻塞IO模型、非阻塞IO模型、IO复用模型、信号驱动的IO模型、异步IO模型

1.什么是IO

IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。

比如你打开浏览器,访问腾讯首页,浏览器这个程序就需要通过网络IO获取腾讯的网页。浏览器首先会发送数据给腾讯服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,腾讯服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。

I/O操作是相对于内存而言的,从外部设备进入内存就叫Input,反之从内存输出到外部设备就叫Output

通常用户进程中的一个完整IO分为两阶段:用户进程空间<- ->内核空间、内核空间<- ->设备空间(磁盘、网络等)。IO有内存IO、 网络IO和磁盘IO三种,通常我们说的IO指的是后两者。

I/O按照设备来分的话,分为两种,其一是网络I/O,也就是通过网络进行数据的拉取和输出。还有一种是磁盘I/O,主要是对磁盘进行读写工作。

LINUX中进程无法直接操作I/O设备,其必须通过系统调用请求kernel来协助完成I/O动作;内核会为每个I/O设备维护一个缓冲区。
对于一个输入操作来说,进程IO系统调用后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备中读取,因为设备IO一般速度较慢,需要等待;内核缓冲区有数据则直接复制到进程空间。
所以,对于一个网络输入操作通常包括两个不同阶段:

等待网络数据到达网卡→读取到内核缓冲区,数据准备好; 从内核缓冲区复制数据到进程空间

2.什么是用户空间和内核空间

虚拟内存被操作系统划分成两块:内核空间和用户空间。
为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。

内核空间是内核代码运行的地方,用户空间是用户程序代码运行的地方。
当进程运行在内核空间时就处于内核态,当进程运行在用户空间时就处于用户态。

3.什么是同步和异步

由于CPU和内存的速度远远高于外设的速度。所以在IO编程中,就存在速度严重不匹配的问题。

举个例子:

我们都是通过热水壶来烧水的。在很久之前,科技还没有这么发达的时候,如果我们要烧水,需要把水壶放到火炉上,我们通过观察水壶内的水的沸腾程度来判断水有没有烧开。

随着科技的发展,现在市面上的水壶都有了提醒功能,当我们把水壶插电之后,水壶水烧开之后会通过声音提醒我们水开了。

传统水壶的烧水就是同步的,电热水壶的烧水就是异步的。

同步请求:A调用B,B的处理是同步的,在处理完之前他不会通知A,只有处理完之后才会明确的通知A。

异步请求:A调用B,B的处理是异步的,B在接到请求后先告诉A我已经接到请求了,然后异步去处理,处理完之后通过回调等方式再通知A

同步和异步最大的区别就是被调用方的执行方式和返回时机。同步指的是被调用方做完事情之后再返回,异步指的是被调用方先返回,然后再做事情,做完之后再想办法通知调用方。

4.什么是阻塞和非阻塞

仍然用上面的例子来说:当你把水放到水壶里面,按下开关后,你可以坐在水壶前面,别的事情什么都不做,一直等着水烧好。你还可以先去客厅看电视,等着水开就好了。
对于你来说,坐在水壶前面等就是阻塞的,去客厅看电视等着水开就是非阻塞的。

阻塞请求:A调用B,A一直等着B的返回,别的事情什么也不干。
非阻塞请求:A调用B,A不用一直等着B的返回,先去忙别的事情了。

阻塞和非阻塞最大的区别就是在被调用方返回结果之前的这段时间内,调用方是否一直等待。阻塞指的是调用方一直等待别的事情什么都不做。非阻塞指的是调用方先去忙别的事情。

5.阻塞IO模型

进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程。操作成功则进程获取到数据

在这里插入图片描述

6.非阻塞IO模型

进程发起IO系统调用后,如果内核缓冲区没有数据,需要到IO设备中读取,进程返回一个错误而不会被阻塞;进程发起IO系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程。
对于上面的阻塞IO模型来说,内核数据没准备好需要进程阻塞的时候,就返回一个错误,以使得进程不被阻塞

在这里插入图片描述

小明去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。 耗费:往返车站6次,路上6小时,其他时间做了好多事

7.IO复用模型

多个的进程的IO可以注册到一个复用器(select)上,然后用一个进程调用该select,,select会监听所有注册进来的IO

在这里插入图片描述
如果select没有监听的IO在内核缓冲区都没有可读数据,select调用进程会被阻塞;而当任一IO在内核缓冲区中有可数据时,select调用就会返回;而后select调用进程可以自己或通知另外的进程(注册进程)来再次发起读取IO,读取内核中准备好的数据
典型应用:select、 poll、 epoll三种方案,nginx都可以选择使用这三个方案

Linux中IO复用的实现方式主要有select,poll和epoll:

Select:注册IO、阻塞扫描,监听的IO最大连接数不能多于FD_ SIZE(1024)
Poll:原理和Select相似,没有数量限制,但IO数量大扫描线性性能下降
Epoll:事件驱动不阻塞,mmap实现内核与用户空间的消息传递,数量很大,Linux2.6后内核支持

select/poll: 小明去火车站买票,委托黄牛,黄牛三天内买到票,然后打便所有人要买票人的电话找到小明,小明去火车站交钱领票。
耗费:往返车站2次,路上2小时,黄牛手续费100元,等待通知3小时 epoll:
小明去火车站买票,委托黄牛,黄牛买到后即通知小明去领,然后小明去火车站交钱领票。
耗费:往返车站2次,路上2小时,黄牛手续费100元,无需打电话

8.信号驱动IO模型

当进程发起一个IO操作,会向内核注册一个信号处理函数,然后进程返回不阻塞;当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用IO读取数据

在这里插入图片描述

小明去火车站买票,给售票员留下电话,有票后,售票员电话通知小明,然后小明去火车站交钱领票。
耗费:往返车站2次,路上2小时,免黄牛费100元,无需打电话

9.异步IO模型

当进程发起一个IO操作,进程返回(不阻塞),但也不能返回结果;内核把整个IO处理完后,会通知进程结果。如果IO操作成功则进程直接获取到数据

在这里插入图片描述

小明去火车站买票,给售票员留下电话,有票后,售票员电话通知小明并快递送票上门。
耗费:往返车站1次,路上1小时,免黄牛费100元,无需打电话

注意:
此模型和前面模型最大的区别是:前4个都是阻塞的,因为需要自己把用户准备好的数据,放在我的用户空间,而全异步都帮我们做好了。
用户线程完全不需要关心实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO操作已经完成,可以直接去使用数据了。它是最理想的模型

10. 5种IO模型的区别

在这里插入图片描述

5.root和alias的区别

在nginx中,我们可以通过location块与root指令结合的方式,将"url"与"服务器路径"建立起对应关系,location块负责匹配url,root指令负责将匹配到的url与服务器中某个具体目录对应起来
其实,除了root指令,还有另一个指令也能实现类似的功能,它就是alias指令,root指令和alias指令都能将urI和服务器路径进行对应,但是它们之间又存在一些区别
下面通过一个实验来了解root和alias的区别

在root下

vim /usr/local/nginx/conf/nginx.conf

         location /demo {
              root /opt/test;
  }

[root@server1 ~]# cd /opt/
[root@server1 opt]# ls
demo
[root@server1 opt]# mkdir test
[root@server1 opt]# mv demo test/

nginx -s reload	#在不暂停服务的情况下重新加载

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
测试:

在这里插入图片描述
在这里插入图片描述

location块匹配的url为"/demo",root指令的路径为"/opt/test",那么,根据上述配置,当我们访问"/demo"这个urI时,实际上访问的是/opt/test/demo路径
配置上述location块后,当我们访问/demo/timg.jpg这个url时,我们访问的是/opt/test/demo/timg.jpg
简单来说,root就是把url路径补在指定路径后面

在alias下

vim /usr/local/nginx/conf/nginx.conf

         location /demo {
             alias /opt/test;
 }

nginx -s reload

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

为什么会访问不到呢?

在这里插入图片描述
在这里插入图片描述
总结:
location块匹配的url为"/demo",alias指令的路径为/opt/test 。如你所见,alias指令对应的值也是一个路径,当alias指令与location块结合时,当我们访问/demo/timg.jpg时,其实就是在访问服务器的/opt/test/timg.jpg,也就是说,当我们使用alias时,location的urI是与alias的路径完全对等的

root指令和alias指令的区别的区别总结:

root指令会将location块的"url路径"带入到"root指令路径"中,将带入后的路径作为"最终路径",使用"最终路径"与urI建立对应关系。

alias指令则直接将location块的"urI路径"与"alias指令路"建立对应关系

alias指令和root指令能够处于的上下文位置也不同,alias指令只能在location块中使用,而root指令则不然

6.获取真实的客户端ip

1.获取真实的客户端ip

实验环境:server1作为nginx服务器;server2为server1的代理;server3为客户端

7.限制用户访问

1.为什么要限制用户访问?

我们经常会遇到这种情况,服务器流量异常,负载过大等等。对于大流量恶意的攻击访问,会带来带宽的浪费、服务器压力、影响业务,往往考虑对同一个ip的连接数、并发数进行限制。

2.限制用户访问

修改nginx配置文件:

vim /usr/local/nginx/conf/nginx.conf

 36     #gzip  on;
 37     limit_conn_zone $binary_remote_addr zone=addr:10m;  #大小是10M内存来对于IP传输开销
 38     limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;  #1s中不超过一个请求
 39     server {

 48         location /download {
 49             limit_conn addr 1; #只能一个并发,多了会报错
 50             #limit_rate 50k;    #限制带宽,每秒最多50k
 51 }

nginx -t	#语法检测
nginx -s reload	#在不暂停服务的情况下重新加载

在这里插入图片描述

mkdir /usr/local/nginx/html/download/
cd /usr/local/nginx/html/download/
ls
cd /usr/local/nginx/logs
>access.log 	#清空日志(方便实验效果的观察)

在这里插入图片描述

测试:

ab -c 10 -n 1000 http://172.25.254.1/download/c.jpg	#查看日志503报错

在这里插入图片描述

8.HTTPS加密认证

同http服务一样,nginx也可以设置https加密认证。当我们访问http://www.westos.org时,它会帮我们自动跳转到https://www.westos.org

下面是设定加密认证的步骤:

 修改配置文件:

vim /usr/local/nginx/conf/nginx.conf

103     server {
104         listen       443 ssl;
105         server_name  www.westos.org;
106 
107         ssl_certificate      cert.pem;
108         ssl_certificate_key  cert.pem;
109 
110         ssl_session_cache    shared:SSL:1m;
111         ssl_session_timeout  5m;
112 
113         ssl_ciphers  HIGH:!aNULL:!MD5;
114         ssl_prefer_server_ciphers  on;
115 
116         location / {
117             root   /web;
118            index  index.html index.htm;
119         }
120     }

在这里插入图片描述

制作key:

cd /etc/pki/tls/certs/
make cert.pem

在这里插入图片描述
在这里插入图片描述

发送key:
cp cert.pem /usr/local/nginx/conf/

制作发布页面:
mkdir /web
vim /web/index.html

 重新启动nginx:
nginx -t #语法检测
nginx -s reload #在不暂停服务的情况下重新加载

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值