Nginx网站服务

164 阅读15分钟

Nginx概述

Nginx是一款高性能、轻量级Web服务软件,稳定性高,系统资源消耗低,对HTTP并发连接的处理能力高,单台物理服务器理论上可支持30000~50000个并发请求

Nginx:

Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。

对HTTP并发连接的处理能力高,单台物理服务器可支持30000~50000个并发请求。

Apache:

Apache是以进程为基础的结构,进程要比线程消耗更多的系统开支,不太适用于多处理器环境,因此,在一个apache Web站点扩容时,通常是增加服务器或扩充群集节点而不是增加处理器。

Nginx和Apache的差异

  • Nginx是一个基于事件的Web服务器,
    Apache是一个基于流程的服务器;

  • Nginx所有请求都由一个线程处理,
    Apache单个线程处理单个请求;

  • Nginx避免子进程的概念,
    Apache是基于子进程的;

  • Nginx在内存消耗和连接方面更好,
    Apache在内存消耗和连接方面一般;

  • Nginx的性能和可伸缩性不依赖于硬件,
    Apache依赖于CPU和内存等硬件;

  • Nginx支持热部署,
    Apache不支持热部署;

  • Nginx对于静态文件处理具有更高效率,
    Apache相对一般;

  • Nginx在反向代理场景具有明显优势,
    Apache相对一般。

Apache: 创建多个进程或线程,而每个进程或线程都会为其分配cpu和内存(线程要比进程小的多,所以worker支持比perfork高的并发),并发过大会榨干服务器资源。

Nginx: 采用单线程来异步非阻塞处理请求(管理员可以配置Nginx主进程的工作进程的数量),不会为每个请求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换。所以才使得Nginx 支持更高的并发。

Nginx和Apache的优缺点比较

(1)nginx相对于apache的优点∶

  • 轻量级,同样起web服务,比apache占用更少的内存及资源
  • 抗并发,nginx处理请求是异步非阻塞的,而apache是阻塞型的在高并发下,nginx能保持低资源低消耗高性能
  • 高度模块化的设计,编写模块相对简
  • 支持热部署,平滑升级

(2)apache相对于nginx的优点∶

  • Rewrite比nginx的rewrite强大 (rewrite的主要功能就是实现统一资源定位符URL的跳转)
  • 模块多,基本想到的都可以找到
  • 少bug, nginx的bug相对较多
  • 超稳定
  • Nginx处理动态请求是弱项,动态请求要Apache去做。

Nginx的进程

Apache和Nginx的默认端口都是80,如果其中一个已经启动了,那么再启动另一个会报错。如果想要同时使用,可以修改其中一个的端口号。

Nginx有两个进程:

master process:主进程(守护进程),用来管理工作进程。

worker process:工作进程,用来处理用户的请求。

实验

编译安装Nginx服务

1、关闭防火墙,将Nginx所要的压缩包上传到/opt目录下

systemctl stop firewalld
setenforce 0
ls /opt/
 nginx-1.22.0.tar.gz  rh

image.png

2、安装依赖包

yum install -y pcre-devel zlib-devel gcc gcc-c++ make
 
 #各程序作用解释如下:
  gcc                     #C语言的编译器
  gcc-c++                 #C++的编译器
  make                    #源代码编译器(源代码转换成二进制文件)
  pcre-devel              #perl的接口开发包,提供正则表达式
  zlib-devel              #提供压缩功能

image.png

3、创建运行用户和组,便于管理

useradd -M -s /sbin/nologin nginx 
#创建用户Nginx,不生成家目录,不允许登陆系统

image.png

4、解压软件包,编译安装Nginx

tar zxf nginx-1.22.0.tar.gz
cd nginx-1.22.0/
./configure \
 --prefix=/usr/local/nginx \
 --user=nginx \
 --group=nginx \
 --with-http_stub_status_module
make -j 4 && make install

image.png

image.png

5、将Nginx的操作指令放入环境变量PATH的目录下

ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/    //让系统识别nginx的操作指令

image.png

6、检查、启动、重启、停止nginx服务
6.1、检查配置文件是否配置正确,并启动nginx服务

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
#查看配置文件是否配置正确
nginx
#启动nginx服务

image.png

6.2、多种方式查看Nginx的PID号

root@localhost nginx-1.22.0]#cat /usr/local/nginx/logs/nginx.pid 
6982
#查看Nginx主进程号的工作进程号

[root@localhost nginx-1.22.0]#pgrep nginx -l
6982 nginx
6983 nginx
#查看Nginx的主进程号和工作进程号

[root@localhost nginx-1.22.0]#lsof -i :80
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   6982  root    6u  IPv4  40101      0t0  TCP *:http (LISTEN)
nginx   6983 nginx    6u  IPv4  40101      0t0  TCP *:http (LISTEN)
#查看Nginx的主进程号和工作进程号

[root@localhost nginx-1.22.0]#netstat -ntap |grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6982/nginx: master  
#查看Nginx主进程的PID

[root@localhost nginx-1.22.0]#ss -ntap |grep nginx
LISTEN     0      128          *:80                       *:*                   users:(("nginx",pid=6983,fd=6),("nginx",pid=6982,fd=6))
[root@localhost nginx-1.22.0]#
#查看Nginx的主进程号和工作号

image.png

6.3、停止Nginx服务

kill -3 7344    
#通过主进程的PID号杀死nginx进程
netstat -ntap | grep nginx   
#此时已查不到进程
 
 #杀死nginx进程的多种方式
 kill -3 <PID号>             
 #"kill -3"杀死进程时可以记录事故现场的信息(打印进程各个线程的堆栈信息)
 kill -s QUIT <PID号>
 killall -3 nginx
 killall -3 QUIT <PID号>

image.png

6.4、重载Nginx

[root@localhost nginx-1.22.0]#nginx
#启动服务
[root@localhost nginx-1.22.0]#cat /usr/local/nginx/logs/nginx.pid 
7149
[root@localhost nginx-1.22.0]#kill -1 7149
#重载nginx服务
[root@localhost nginx-1.22.0]#netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      7149/nginx: master  
[root@localhost nginx-1.22.0]#kill -s HUP 7149
#重载nginx服务
[root@localhost nginx-1.22.0]#netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      7149/nginx: master  

image.png

7、日志分割

(释放磁盘空间,保障系统的平稳运行)

[root@localhost ~]#cd /usr/local/nginx/logs/  
#切换到日志目录
[root@localhost logs]#ls
access.log  error.log  nginx.pid
[root@localhost logs]#mkdir log.bak
[root@localhost logs]#mv *.log log.bak/
# 将原有日志移走
[root@localhost logs]#ls
log.bak  nginx.pid
[root@localhost logs]#kill -USR1 7149
#重新生成日志文件
[root@localhost logs]#ls
access.log  error.log  log.bak  nginx.pid
[root@localhost logs]#

image.png

8、升级nginx服务

 #平滑升级:
 kill -USR2 <PID号>
 ​
 #新版本升级:
 tar zxvf nginx-XX.XX.tar.gz       #XX代表新版本号
 cd nginx-XX.XX
 ./configure \
 --prefix=/usr/local/nginx \
 --user=nginx \
 --group=nginx \
 --with-http_stub_status_module \
 --with-http_ssl_module
 
 #重新编译:
 make                                            #重新编译
 mv /usr/local/nginx/sbin/nginx  /usr/local/nginx/sbin/nginx_old  #备份旧文件,方便回滚
 cp objs/nginx /usr/local/nginx/sbin/nginx             #将新的运行文件放入安装的运行目录
 make upgrade                                 #编译升级
 #或者先 killall -3 nginx ,再 /usr/local/nginx/sbin/nginx

9、添加nginx系统服务

cd /lib/systemd/system/
vim nginx.service
 [Unit]
 Description=nginx
 After=network.target
 [Service]
 Type=forking
 PIDFile=/usr/local/nginx/logs/nginx.pid
 ExecStart=/usr/local/nginx/sbin/nginx
 ExecReload=/bin/kill -s HUP $MAINPID
 ExecStop=/bin/kill -s QUIT $MAINPID
 PrivateTmp=true
 [Install]
 WantedBy=multi-user.target
 ​
systemctl daemon-reload      
#重载配置
systemctl start nginx        
#启动服务
netstat -natp | grep nginx    
#查看服务
 tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2154/nginx: master
 ​
 #之后可以使用systemctl start|stop|restart|enable nginx 来管理服务

image.png

image.png 如果systemctl start nginx报错,先用netstat -natp |grep 80查看有没有被占用,有就用kill -9杀死这个进程在用

10、浏览器访问验证

[root@localhost system]#cd /usr/local/nginx/html/
#默认首页文件index.html存放在/usr/local/nginx/html/目录下
[root@localhost html]#ls
50x.html  index.html

image.png

image.png

Nginx服务的主配置文件

主配置文件位置:/usr/local/nginx/conf/nginx.conf

/usr/local/nginx/conf/ 目录下:

  • nginx.conf 是主配置文件
  • nginx.conf.default 是主配置文件的备份文件

主配置文件中有六个主要模块:

1、全局块:全局配置,对全局生效。

2、events块:配置影响Nginx服务器与用户的网络连接。

3、http块:配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。

4、server块:配置虚拟主机的相关参数,一个http块中可以有多个server 块。每个 server 块就相当于一个虚拟主机。。

5、location块:用于配置匹配的url,一个server块中可以有多个location块。

6、upstream:配置后端服务器具体地址,负载均衡配置不可或缺的部分。

全局块(全局配置)

就是配置文件从头开始到 events 块之间的内容,主要设置的是影响nginx服务器整体运行的配置指令。比如 worker_process,值越大,可以支持的并发处理量也越多,但是还是和服务器的硬件相关。

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

 #user  nobody;                  //运行用户,若编译时未指定则默认为nobody,若编译指定了用户则会写到二进制程序里变成默认配置。此前编译时指定了"--user=nginx",所以现在二进制程序中的运行用户为nginx
 worker_processes  1;            //工作进程数量,一般设置为和CPU核数一样
 #error_log  logs/error.log;     //错误日志文件的位置
 #pid  logs/nginx.pid;           //PID文件的位置

image.png

events块( I/O 事件配置)

events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 work process 可以同时支持的最大连接数等。

 events  {
         use epoll;    #使用epoll模型。2.6及以上版本的系统内核,建议使用epo11模型以提高性能,实现I/O多路复用
         worker_connections  4096;  #每个工作进程处理4096个连接。默认值为1024。一般设置为2的次方
 }
 ​
 #epoll是Linux内核为处理大批句柄而作改进的poll,是Linux 下多路复用IO接口select/poll的增强版本,它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
 ​
 #如提高每个进程的连接数还需执行“ulimit -n 65535”命令临时修改本地每个进程可以同时打开的最大文件数。
 #在Linux平台上,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是个文件句柄)。
 #可使用"ulimit -a"命令查看系统允许当前用户进程打开的文件数限制。

image.png

查看Nginx支持的最大并发量(软件支持、系统支持、CPU性能):

例如现在CPU有两核,想要实现支持30000并发量 。 系统会限制本地每个用户进程可以同时打开的最大文件数量,即系统会限制每个进程的连接数。

查看系统支持多少并发量:

  • 使用"ulimit -a"可查看系统允许当前用户进程打开的文件数限制。

image.png 修改系统支持的最大并发量:

  • “ulimit -n 65535”命令可临时修改本地每个用户进程可以同时打开的最大文件数。
  • vim /etc/security/limits.conf,编辑该文件可永久修改。

image.png

 nginx          hard    nofile          30000
 ​
 #第一列为用户和组
 #第二列为磁盘限额,软硬限制。hard表示硬限制。
 #第三列为项目。nofile表示最大可打开文件数量。
 #第四列为相应项目的数量

3、实际工作中还要进行压测,测试CPU性能能否支持这个最大并发量。

上述设置的软硬并发量都是理论上的,真正并发量还得看CPU的性能,在投放到生产环境前,我们需要进行压测 。

http块(HTTP 配置)

http块:包括 http 全局块,以及多个 server 块。

  • http 全局块: 配置的指令包括文件引入、 MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

  • server 块: 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。

    • 而每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块。
日志格式设定:  
$remote_addr$http_x_forwarded_for 用以记录客户端的ip地址。  

$remote_addr:记录上一个请求消息发送端的IP(代理服务器的IP)。 

$http_x_forwarded_for :会记录所有经过的服务器的IP地址。  

$remote_user:用来记录客户端用户名称。  

$time_local:用来记录访问时间与时区。  

$request:用来记录请求的url与http协议。 

$status:用来记录请求状态;成功是200。  

$body_bytes_sent:记录发送给客户端文件主体内容大小。  $http_referer:用来记录从哪个页面链接访问过来的。  $http_user_agent: 记录客户浏览器的相关信息。 

通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

查看nginx支持的文件类型:

image.png

 location块

  • 一个 server 块可以配置多个 location 块。

  • 主要作用是根据请求地址路径的匹配,匹配成功进行特定的处理。

  • 这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

根路径和虚拟路径:

 location / {
     root html;    #表示此时根目录为/usr/local/nginx/html/
     index index.html index.htm;
 }
 
 #此时访问路径和返回文件的关系为:
 http://192.168.50.110/index.html      --> /usr/loca/nginx/html/index.html
 http://192.168.50.110/test/index.html --> /usr/loca/nginx/html/test/index.html

为了更好地理解别名是一个整体,设置2个关于别名的location块。

 location / {
     alias /var/www/html;
     index index.html index.htm;
 }
 #此时 http://192.168.72.10/  匹配 /var/www/html/
 
 location /test{
     alias /var/www/html;       
     index index.html index.htm;
 }
 #此时 http://192.168.72.10/test/  匹配 /var/www/html/
 
 #此时访问路径和返回文件的关系为:
 http://192.168.72.10/index.html      --> /var/www/html/index.html
 http://192.168.72.10/test/index.html --> /var/www/html/index.html
 http://192.168.72.10/test/test/index.html --> /var/www/html/test/index.html

访问状态统计配置

查看nginx的安装模块,是否包含 HTTP_STUB_STATUS 模块

先使用命令 /usr/local/nginx/sbin/nginx -V 查看已安装的nginx是否包含 HTTP_STUB_STATUS 模块

 nginx -v    #查看nginx的版本。此前已将nginx的可执行文件放入PATH的目录中,所以可以直接使用nginx命令
 
 nginx -V    #查看nginx的版本,以及编译安装时的配置参数
 
 cat /opt/nginx-1.12.2/auto/options   #查看nginx已安装和未安装的模块,with表示已安装,without表示未安装
 
 cat /opt/nginx-1.12.2/auto/options | grep "YES"   #查看nginx已安装的所有模块

image.png

image.png

image.png

修改 nginx.conf 配置文件,指定访问位置并添加 stub_status 配置

image.png

image.png 重启服务,访问测试

[root@www conf]#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@www conf]#systemctl restart nginx

image.png

image.png

监控nginx当前并发数:

可使用 curl -Ls http://192.168.50.105/status 结合awk与if语句进行性能监控。

 #!/bin/bash
 
 CON=$(curl -Ls http://192.168.50.105/status | awk '/Active connections:/{print $3}')
 if[ $CON -gt 25000 ];then
 echo "警告!当前并发数量为$CON,超过预警值!"

基于授权的访问控制

设置只有指定用户才可以访问该网页,想要对哪个路径进行限制,就在location下添加路径和认证配置。

生成用户密码认证文件

yum -y install httpd-tools
htpasswd -c /usr/local/nginx/passwd.db zhangsan
chown nginx /usr/local/nginx/passwd.db
#文件属主必须修改为nginx,否则会报错
chmod 400 /usr/local/nginx/passwd. db
#文件权限必须设置为400,否则会报错

image.png

image.png

image.png 修改主配置文件相对应目录,添加认证配置项

vim /urs/local/nginx/conf/nginx.conf
auth_basic "abc";
#设置提示框显示的文字
auth_basic_user_file /usr/local/nginx/passwd.db 
#指定密码验证文件

image.png 重启服务,访问测试 image.png 浏览器访问测试

image.png

image.png

image.png

基于客户端的访问控制

设置只有指定IP/IP段才可以访问该网页,或指定IP/IP段不能访问。想要对哪个路径进行限制,就在location块下添加路径和控制规则,我这里直接使用根目录做实验。

访问控制规则如下:

  • deny IP/IP段:拒绝某个IP或IP段的客户端访问。(黑名单)
  • allow IP/IP段:允许某个IP或IP段的客户端访问。(白名单)
  • 规则从上往下执行,匹配到则停止,不再往下匹配。

注意要先关闭web服务器的防火墙,以免防火墙的原因导致无法访问。

 [root@yuji ~]# vim /usr/local/nginx/conf/nginx.conf
 ...........
       server {
            location / {
                root   html;
                index  index.html index.htm;
                ##添加控制规则
                allow  192.168.72.0/24;    #允许192.168.72.0网段的客户端ip访问
                deny   all;            #拒绝其他ip客户端访问
            }
       }
 ​
 [root@yuji ~]# nginx -t
 [root@yuji ~]# systemctl restart nginx
 ​
 使用192.168.72.192客户端,访问http://192.168.72.10

image.png

image.png

配置虚拟主机

配置虚拟主机的方法

配置虚拟主机有三种方法:

  • 基于域名的虚拟主机 : 不同的域名、相同的IP(此方式应用最广泛)。
  • 基于IP地址的虚拟主机 : 不同的域名、不同的IP ( 需要加网络接口 ,应用的不广泛), 基于IP地址。
  • 基于端口的虚拟主机 : 不使用域名、IP来区分不同站点的内容,而是用不同的TCP端口号。

二、基于域名的 Nginx 虚拟主机

为虚拟主机提供域名解析

[root@localhost html]#echo "192.168.50.102 www.ykw.com www.nan.com"  >> /etc/hosts
[root@localhost html]#cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.50.102 www.ykw.com www.nan.com

image.png

为虚拟主机准备网页文档

[root@localhost html]#mkdir -p /var/www/html/ykw
[root@localhost html]#mkdir -p /var/www/html/nan
[root@localhost html]#echo '<h1>www.ykw.com</h1>' > /var/www/html/ykw/index.html
[root@localhost html]#echo '<h1>www.nan.com</h1>' > /var/www/html/nan/index.html

image.png

修改Nginx的配置文件

vim /usr/local/nginx/conf/nginx.conf
 .........
 http {
 .........
       server {
            listen   80;
            server_name   www.yuji.com;       #设置域名www.yuji.com
            charset   utf-8;
            access_log   logs/www.yuji.access.log;  #设置日志名
            location / {
                   root   /var/www/html/yuji;  #设置 www.yuji.com 的工作目录
                   index   index.html   index.php;
            }
            error_page   500 502 503 504 /50x.html;
            location = 50x.html {
                  root   html;
            }
       }
 ​
       server {
            listen   80;
            server_name   www.nan.com;     #设置域名www.nan.com
            charset   utf-8;
            access_log   logs/www.nan.access.log;  #设置日志名
            location / {
                   root   /var/www/html/nan;   #设置 www.nan.com 的工作目录
                   index   index.html   index.php;
            }
            error_page   500 502 503 504 /50x.html;
            location = 50x.html {
                  root   html;
            }
       }
 }
 
 nginx -t #检查配置文件的配置项是否有误
 systemctl restart nginx  #重启Nginx服务

image.png image.png

image.png

image.png