Nginx系列

537 阅读9分钟

Nginx是一款轻量级、高性能的web服务器软件,可以用于正向/反向代理、负载均衡、静态服务、缓存。

1.高并发连接:处理2-3万并发连接数,官方监测能支持5万并发。

2.内存消耗小:开启10个nginx才占150M内存,nginx处理静态资源好,消费内存少.

Nginx系列-安装

安装

官网下载安装包

nginx-1.18.0.tar.gz
复制代码

解压

tar -zxvf  nginx-1.18.0.tar.gz
cd  nginx-1.18.0
复制代码

编译

./configure --prefix=/usr/local/nginx --with-http_ssl_module
复制代码

安装

make && make install
复制代码

添加到环境变量

vim /etc/profile
export PATH=/usr/local/nginx/sbin:$PATH
复制代码

扩展安装其他模块,以with-http_stub_status_module为例

  • 查询当前安装的信息

    nginx -V
    复制代码
    

从上可以获取当前nginx编译安装的参数

  • 重新编译,在原先的参数后面添加新模块

    cd  nginx-1.18.0
    ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
    复制代码
    

tip:由于是覆盖安装,所以重新编译后直接使用;如果不是覆盖需要将新的nginx命令拷贝覆盖原先nginx命令

访问Nginx首页

配置文件

/usr/local/nginx/nginx.conf
复制代码

文件结构

main                         -工作进程数,所属用户/组,错误日志
events{                      -每个工作进程连接数
}
stream{
   upstream abc{

   }
   server{

   }
}
http{                        -包含虚拟主机
   server{                   -虚拟主机
        location {           -目录、代理

        }
    }
}
复制代码

events模块详见大佬博客:好博客

stream和http使用方法类似,可以转发、代理、负载均衡等。不同点在于stream使用的是4层协议,用于TCP请求的处理;http使用的是7层协议,用于http协议的处理

常用命令

  1. 检查配置文件

    nginx -t 
    nginx -t -c 配置文件路径
        
    区别:第一个检查默认路径下的配置文件,第二个检查指定配置文件
    复制代码
    
  2. 启动

    nginx 
    nginx -c 配置文件路径
        
    复制代码
    
  3. 已启动,但是更改了配置文件,优雅启动

    nginx -s reload
    复制代码
    
  4. 关闭

    ./nginx -s stop   直接关闭
    ./nginx -s quit   
        
    区别:第一个直接关闭,第二个请求处理完了才关闭
    复制代码
    
  5. 日志文件删除了,重新打开文件

    nginx -s reopen
    

Nginx系列-基本配置

进程设计思想

  • 启动Nginx后,会有一个主进程和多个工作进程,如下所示

主进程id为11086,所属root用户;工作进程id为16600,所属nobody用户;

以上进程所属用户和工作进程数,通过nginx.conf文件main部分配置

user 默认为nobody,可以指定用户和用户组,如user tuser tgroup;

worker_processes 指定工作进程数,一般为CPU总核数或者总核数的两倍

error_log 配置错误日志路径和级别,默认开启错误日志;如果要关闭,则配置为error_log /dev/null

pid 配置记录主进程id的文件路径

  • 主进程和工作进程

详见大牛博客

自定义错误页面

假设Nginx已配置http服务

location /merch { 
   alias html; 
   index index.html; 
}
复制代码

基于本地文件指定错误码页面

error_page 400 403 404 /40x.html;
location = /40x.html {
    root   html;
}
复制代码

访问/merch,响应码为200

访问/merch/123,重定向到了40x.html

基于在线页面指定错误码页面

error_page 400 403 404  https://juejin.cn/post/6922838161647206407;
复制代码

更改响应码

以上两种处理方式,请求获取到的响应码和error_page指定的错误码一致,但是如何自定义请求响应码呢

指定转换后的确切的响应码

error_page 400 403 404  =200 /40x.html;
location = /40x.html {
    root   html;
}
复制代码

访问/merch/123,重定向到了40x.html,但是响应码是200,而不是之前的404

也可以不指定确切的码值,由重定向后实际处理的结果来决定,设置如下

error_page 400 403 404  = /40x.html;
location = /40x.html {
    root   html;
}
复制代码

访问/merch/123,重定向到了40x.html,但是响应码是200,而不是之前的404

将40x.html页面从服务器删除,重新访问/merch/123,由于文件不存在了,返回404

tips1:error_page指令可以在http、server、location中配置

tips2:nginx-1.18.0版本如上设置即可,低版本如1.xx版本需要额外配置

Nginx系列-访问控制

访问控制的任务是保证网络资源不被非法访问

权限控制指令-deny 、allow

指令格式

deny IP/IP段/all
allow IP/IP段/all
复制代码

规则

同一块下出现多个权限控制指令,先出现的指令设置会覆盖后出现的指令范围,未覆盖的范围依然生效,覆盖的范围以先出现的指令为准

多块下(http/server/location)出现多个权限指令,内层块中权限级别比外层块中设置的权限级别高,注意不是覆盖

即:同一块多指令范围取交集,不同块内层块指令生效

简单示例

location / {
      root   html;
      index  index.html index.htm;
}
复制代码

访问/,正常显示

添加deny all; --禁止所有访问

location / {
      root   html;
      index  index.html index.htm;
      deny all;
}
复制代码

访问/,展示被禁止

权限控制指令-location

指令格式

location [=|^~|~|~*] URI {...}
复制代码

规则

= 精确匹配URI,完全一致才能匹配上

^~ 以指定URI开头的匹配,非正则表达式(属于最大前缀匹配,是最大前缀匹配的特例)

~ 正则匹配URI,区分大小写

~* 正则匹配URI,不区分大小写

最大前缀匹配,匹配最长的URI对应的location

以上规则优先级依次下降,匹配到了则不再向下匹配

示例

1.root 和 alias区别

location /merch {
    root html;
    index index.html;
}
复制代码

访问/merch,

将root修改为alias

location /merch {
      alias  html;
      index  index.html index.htm;
}
复制代码

访问/merch,正常展示

规则如下:

配置为root 则访问/merch 匹配后实际访问的文件地址为 html/merch/index.html

配置为alias 则访问/merch 匹配后实际访问的文件地址为 html/index.html

区别在于location指令后面的URI是否被使用与找实际资源文件

2.待补充

Nginx系列-日志

有效的使用日志有利于项目开发和维护的统计和排错。Nginx根据记录内容不同,区分为访问日志和错误日志

访问日志

记录客户端访问Nginx的每一个请求,日志格式通过log_format指定,日志路径、缓存大小通过access_log指定

默认日志

默认开启了访问日志,默认配置如下

1.log_format指令只能在http块;

日志格式说明

$remote_addr        记录访问网站的客户端地址;
$http_x_forwarded_for  当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器上也进行了相关的x_forwarded_for设置;
$remote_user        远程客户端用户名称;
$time_local        记录访问时间与时区;
$request          用户的http请求起始行信息;
$status           http状态码,记录请求返回的状态,例如200、404、301等;
$body_bytes_sent      服务器发给客户端的响应body字节数;
$http_referer       记录此次请求是从哪个链接访问呢过来的,可以根据referer进行防盗链设置;
$http_user_agent       记录客户端访问信息,例如:浏览器、手机客户端等;
复制代码

2.access_log指令可以在http/server/location块

指令格式

    access_log    off;  #关闭access_log,即不记录访问日志
    access_log path [format [buffer=size [flush=time]] [if=condition]];
    access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
    access_log syslog:server=address[,parameter=value] [format [if=condition]];
-------------------------
    说明:
    buffer=size #为存放访问日志的缓冲区大小
    flush=time  #为缓冲区的日志刷到磁盘的时间,单位秒
    gzip[=level #表示压缩级别
    [if = condition]  #表示其他条件

可选参数通常不需要配置,在极端情况下优化时使用。如何使用见后续说明
-------------------------

3.查看访问日志

tailf logs/access.log
复制代码

访问/merch,nginx访问日志如下所示

自定义日志

1.配置日志格式myLog

log_format  myLog '[ip:] $remote_addr - [user_agent:]$remote_user [time:][$time_local] "[request:] $request" '
                      '[status:] $status [referer:] "$http_referer" '
                      '[user_agent:] "$http_user_agent" [forward:] "$http_x_forwarded_for"';

    access_log  logs/myAccess.log  myLog buffer=2k flush=5s;
复制代码

其中使用了buffer和flush,规则是什么呢

buffer可以单独配置,使用buffer才能使用flush;只使用flush会报错

当缓存达到buffer上限的时候会写入磁盘

超过flush时间仍未达到缓冲区大小,会写入磁盘

2.查看访问日志,与指定格式一致

如何关闭日志

 access_log    off;
复制代码

错误日志

默认配置

默认开启错误日志,默认配置如下

访问/merch/fdsa,查看错误日志

自定义日志

1.不支持自定义日志格式

2.支持自定义存储路径和级别,指令格式如下

error_log 日志路径 [notice|info]

可配置与http/server/location块
复制代码

如何关闭日志

error_log /dev/null
复制代码

日志文件切割

核心命令

nginx -s reopen
在访问日志文件不存在的时候,运行该命令可以重新生成访问日志文件

nginx -s reload
配置文件重新生生效,通过测试发现,包含有nginx -s reopen的功能,日志切割文件通常不使用该命令
复制代码

该如何做

1.创建日志切割脚本autoLog.sh

!/bin/bash
logPath = /usr/local/nginx/logs;
#备份日志
mv $logPath/access.log $logPath/`date +%Y%m%d%H%M`.log
#重新打开日志
nginx -s reopen
复制代码

2.加入到系统定时任务列表

crontab -e   --编辑定时任务

0 0 * * * /usr/local/nginx/logs/autoLog.sh > /dev/null 2>&1

crontab -l   --查看定时任务列表

3.cron的时间格式

*    *    *    *    *
-    -    -    -    -
|    |    |    |    |
|    |    |    |    +----- 星期中星期几 (0 - 6) (星期天 为0)
|    |    |    +---------- 月份 (1 - 12) 
|    |    +--------------- 一个月中的第几天 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)

格式:
    f1 f2 f3 f4 f5 program
说明:
f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推
f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推
f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推
f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其馀类推

示例:

每一分钟执行一次 /bin/ls:
* * * * * /bin/ls

在 12 月内, 每天的早上 6 点到 12 点,每隔 3 个小时 0 分钟执行一次 /usr/bin/backup:
0 6-12/3 * 12 * /usr/bin/backup

周一到周五每天下午 5:00 寄一封信给 alex@domain.name:
0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata

每月每天的午夜 020 分, 220 分, 420 分....执行 echo "haha"20 0-23/2 * * * echo "haha"

Nginx系列-虚拟主机

何为虚拟主机

虚拟主机技术是指在一台物理服务器上划分出多个磁盘空间,每个磁盘空间都是一台虚拟主机,每台虚拟主机都可以独立对外提供Web服务,且互补干扰。在外界看来,虚拟主机就是一台独立的服务器主机,这就意味着用户能够利用虚拟机把不通域名的网站部署在同一台服务器上,而不必再为建立一个网站单独购买一台服务器,既解决了维护服务器技术的难题,同时又极大地节省了服务器硬件成本和相关的维护费用

如何配置虚拟主机

基于端口配置

一个Nginx监听多个端口,根据不同的端口号区分不同的网站

server {
        listen 80;
        server_name localhost;
 }
 server {
        listen 81;
        server_name localhost;
 }
复制代码

访问系统

http://172.16.116.250:80/
http://172.16.116.250:81/
复制代码

基于IP配置

通过设置IP别名的方式,实现一块物理网卡上绑定多个IP地址;

如果是多网卡,则有多IP,支持按基于IP配置

server {
        listen 80;
        server_name 172.16.116.251;
 }
 server {
        listen 80;
        server_name 172.16.116.252;
 }
复制代码

访问系统

http://172.16.116.251:80/
http://172.16.116.252:80/
复制代码

基于域名配置

在真实的上线环境中, 网站需要域名和公网 IP 地址才可以访问,但是申请域名和

IP 比较麻烦,且需要支付定的费用。为了便于学习和测试,可以利用系统提供的hosts

件来设置几个虚拟的域名,并将域名解析到指定 IP 地址

nginx.conf配置

server {
        listen 80;
        server_name test1.com.cn;
 }
 server {
        listen 80;
        server_name test2.com.cn test3.com.cn;
 }
复制代码

/etc/hosts配置

197.208.11.198 test1.com.cn 
197.208.11.198 test2.com.cn test3.com.cn;
复制代码

访问系统

http://test1.com.cn:80/
http://test2.com.cn:80/
http://test3.com.cn:80/
复制代码

tips1:server_name支持正则表达式,如*.com.cn,可以匹配 test1.com.cn test2.com.cn test3.com.cn

设置目录列表

简单示例

Nginx默认是不允许列出整个目录的,所以当用户访问某一站点或目录下没有index指令设置的默认索引文件,就会报403错误。如下配置

location / {
     root   html;
     index  index.html index.htm;
}
复制代码

删除html目录文件下的索引文件index.html和index.htm

访问/,如下所示

开启目录列表功能,如果出现上述情况可以让该站点或者目录下的文件以列表形式展示

location / {
     root   html;
     index  index.html index.htm;
     autoindex on;
}
复制代码

访问/,如下所

核心指令

autoindex on;
autoindex_exact_size off/on;   --默认on,以byte为单位显示,若为off表示使用kB/MB/GB为单位显示文件大小
autoindex_localtime off/on;    --默认off,显示格林威治时间,若为on表示显示文件服务器的时间,通常为北京时间(比格林威治时间快8小时)

Nginx系列-负载均衡

反向代理

在负载均衡之前先来看下反向代理

何为反向代理

所谓反向代理是指客户端访问目标服务器,实际上目标服务器是个代理服务器,将客户端的请求转发到内部网络的后端服务器处理,并将从后端服务器得到的响应结果返回给客户端

有反向代理,很容易联想到是不是有正向代理。奈斯,的确有。何为正向代理呢?

所谓正向代理是指客户端访问目标服务器,实际上是通过中间代理服务器去访问的,代理服务器将请求发给指定的目标服务器,并将从目标服务器得到的响应结果返回给客户端

反向代理特点

安全性:反向代理的客户端用户只能通过外网来访问代理服务器,并且用户并不知道自己访问的是一个代理服务器,好处就是反向代理服务器将真正的处理放在内网服务器中,有效提高了网络安全性

功能性:主要用于将防火墙后的服务器提供给因特网用户访问,还可以为多个后端服务器提供负载均衡功能、缓存功能等

正向代理有哪些特点呢

安全性:客户端可以隐藏自身信息的去访问任意网站,因此在使用时必须采取安全措施以保证仅为授权的客户端提供服务

功能性:主要用于为防火墙内的局域网用户提供访问因特网服务

Nginx的反向代理

通过来自ngx_http_proxy_module模块的命令proxy_pass实现,格式如下

proxy_pass URL

proxy_set_header 在将客户端请求发送诶后端服务器之前,更改来自客户端的请求信息
proxy_connect_timeout 配置Nginx与后端代理服务器尝试建立连接的超时时间
...
复制代码

配置nginx.conf,反向代理到百度首页

 location / {
     proxy_pass https://www.baidu.com/;
 }
复制代码

访问/(不是直接访问百度首页),展示如下

tips1:这里将客户端请求反向代理到了公网百度服务去处理,一般不这样使用。通常Nginx作为一组内网应用服务器集群的反向代理服务器,且Nginx与应用服务器集群之间通过内网通信来保证安全

负载均衡

何为负载均衡

所谓负载均衡是将负载分摊到多个操作单元上执行,从而提高服务的可用性和响应速度,带给用户更好的体验。Nginx通过命令upstream实现负载均衡,格式如下

upstream {
    server 195.9.116.18;
    server 195.9.116.19;
}
复制代码

负载均衡策略

上述tips1指出代理服务器会将客户端请求转发到一组应用服务器集群,那么具体是哪个应用服务器处理请求呢? 这个就需要负载均衡策略了,Nginx支持的策略如下:

轮询 - 默认方式,每个请求按照时间顺序一一分配到不通的后端服务器进行处理,如果有服务器宕机,会自动剔除

upstream example_test {
     server 127.0.0.1:8080;
     server 127.0.0.1:8081;
     server 127.0.0.1:8082;
     server 127.0.0.1:8083;
}
复制代码

权重 - 利用weight指定轮询的权重比率,与访问率成正比,用于后端服务器性能不均的情况;其中权重总和为一个循环,每台服务器在一个循环中分配的请求数占比是该台服务器权重的比率,但是分配到的请求是按照算法分散分配的,而不是连续分配

upstream example_test {
     server 127.0.0.1:8080 weight=1 max_fails=1 fail_timeout=2;
     server 127.0.0.1:8081 weight=3 max_fails=1 fail_timeout=2;
     server 127.0.0.1:8082 backup;
     server 127.0.0.1:8083 down;
}
复制代码

关于max_fails和fail_timeout参数的说明:

       用于判断后端节点的状态。详细过程为:在fail_timeout的时间内,某个server连接失败了max_fails次,则nginx会认为该server不工作了。同时,在接下来的 fail_timeout时间内,nginx不再将请求分发给失效的server。从认为该server不工作到fail_timeout时间结束,恢复去请求该server。

       如果不设置这2个参数,fail_timeout默认为10s,max_fails默认为1。就是说,只要某个server失效一次,则在接下来的10s内,就不会分发请求到该server上

ip_hash - 每个请求按照访问IP的hash结果分配,可以解决session共享问题。如果一个服务器服务器出现问题,请求也是会发送到该服务器上,不能自动剔除;在知道某台宕机后,手动为宕机ip设置处于down状态(添加关键字down),可以剔除并且请求哈希到其它机器上。

upstream example_test {
     ip_hash;
     server 127.0.0.1:8080;
     server 127.0.0.1:8081;
     server 127.0.0.1:8082;
     server 127.0.0.1:8083 down;
}

该方式不支持weight和backup
复制代码

fair - 每台服务器的响应时间来分配请求,响应时间段的服务器优先分配请求;需要安装第三方模块

upstream example_test {
     fair;
     server 127.0.0.1:8080;
     server 127.0.0.1:8081;
}
复制代码

url_hash - 按照访问url的hash值来分配请求;需要安装第三方模块

upstream example_test {
     hash  $request_uri;
     server 127.0.0.1:8080;
     server 127.0.0.1:8081;
}

Nginx跨域配置

aa

Nginx限流模块

详见大牛博客