分布式调用与高并发处理(三)| Nginx

目录

Nginx概述

Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。Nginx 专为性能优化而开发,使用异步非阻塞事件驱动模型。

Nginx 四大应用场景

HTTP服务器

Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。

反向代理

反向代理应该是Nginx使用最多的功能了,反向代理(ReverseProxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

负载均衡

负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

动静分离

动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路。

为什么用Nginx

单机架构

Tomcat 默认配置的最大请求数是150,也就是说同时支持150个并发。具体能承载多少并发,须要看硬件的配置,线程CPU越多性能越高,分配给JVM的内存越多性能也就越高,但也会加剧GC的负担。

引入反向代理实现负载均衡

负载均衡就是一个web服务器解决不了的问题可以通过多个web服务器来平均分担压力来解决,并发过来的请求被平均分配到多个后台web服务器来处理,这样压力就被分解开来。

总结

  1. 它可以高并发连接,官方测试能够支撑5万并发连接,在实际生产环境中可以支撑2到4万并发连接。
  2. 内存消耗少
  3. 购买F5 BIG-IP ,NetScaler等硬件负载均衡交换机需要10多万甚至几十万人民币。而Nginx为开源软件,可>以免费试用,并且可用于商业用途。
  4. 内置的健康检查功能:如果Nginx proxy后端的某台服务器宕机了,不会影响前端访问。
  5. 节省带宽,支持gzip压缩。
  6. 稳定性高:用于反向代理(负载均衡),宕机的概率微乎其微。
  7. 支持热部署。在不间断服务的情况下,对软件版本升级。

环境准备

四项确认

  1. 确认网络
shell 复制代码
ping baidu.com
  1. 确认yum可用
shell 复制代码
yum list
  1. 确认防火墙
shell 复制代码
firewall-cmd --state
  1. 确认SELinux
shell 复制代码
vim /etc/selinux/config

一项安装

shell 复制代码
yum -y install gcc make automake pcre-devel zlib zlib-devel openssl openssl-devel

参数:

gcc:编译依赖gcc环境

pcre:PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 Perl 兼容的正则表达式库。

zlib:zlib库提供了很多种压缩和解压缩的方式,Nginx使用zlib对http包的内容进行gzip,所以需要在linux上安装zlib库。

Openssl:OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

下载与安装

下载Nginx源码

https://nginx.org/en/download.html

Nginx 官方提供了三个类型的版本:

Mainline Version:主线版,是最新版,但未经过过多的生产测试。

Stable Version:稳定版,生产环境使用版本。

Legacy Version:老版本。

Nginx源码编译

解压 Nginx查看 Nginx 的目录。

auto:存放 Nginx 自动安装的相关文件

conf:存放 Nginx 服务器配置文件

configure:命令,用于对即将安装的软件的配置,完成

makefile 编译文件的生成

contrib:存放由其他机构贡献的文档材料

html:存放 Nginx 欢迎页面

man:manual,手册,存放 Nginx 帮助文档

src:存放 Nginx 源码

生成 makefile

先创建临时文件

shell 复制代码
mkdir -p/var/temp/nginx/client

使用 configure 命令生成makefile文件

shell 复制代码
./configure \
--prefix=/usr/local/nginx \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--with-http_ssl_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi

安装编译参数

编译安装

[root@bogon nginx-1.24.0]# make && make install

这是两个命令,make 为编译命令,make install 为安装命令,可以分别执行。这里使用&&将两个命令连接执行,会在前面命令执行成功的前提下才会执行第二个命令。

安装完成之后再/usr/loacl会出现一个niginx目录

Nginx目录详解

conf目录

Nginx所有配置文件的目录,极其重要。在该目录中包含一个Nginx.conf配置文件。

html目录

Nginx的默认站点目录。

logs目录

存放Nginx的日志文件。 access.log error.log

sbin目录

Nginx命令的目录,如Nginx的启动命令。

Docker安装Nginx

拉取官方的Nginx镜像

[root@localhost ~]# docker pull nginx

启动一个 Nginx 容器实例

[root@localhost ~]# docker run --rm --name nginx-test -p 8080:80 -d nginx 

参数的含义如下:

    • rm:容器终止运行后,自动删除容器文件
    • name nginx-test:容器的名字叫做Nginx-test,名字自己定义

-p: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口

-d:容器启动后,在后台运行

Nginx 服务部署,映射本地目录到Nginx容器

创建本地目录,用于存放Nginx的相关文件信息.

shell 复制代码
mkdir -p /opt/nginx/html /opt/nginx/conf

参数:

html: 目录将映射为 nginx 容器配置的虚拟目录。

conf: 目录里的配置文件将映射为 nginx 容器的配置文件。

拷贝容器内 Nginx 默认配置文件到本地当前目录下的 conf 目录,容器ID可以查看 docker ps 命令输入中的第一列

shell 复制代码
docker cp b0:/etc/nginx/nginx.conf /opt/nginx/conf/

关闭容器。重新部署

shell 复制代码
docker run --rm -d -p 8081:80 --name nginx-web \
 -v /opt/nginx/html:/usr/share/nginx/html \
 -v /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
nginx

命令说明:

  • -rm:容器终止运行后,自动删除容器文件。

-p 8081:80: 将容器的 80 端口映射到主机的 8081 端口.

  • -name nginx-test-web:将容器命名为 Nginx-test-web

-v /home/Nginx/html:/usr/share/Nginx/html:将我们自己创建的 html 目录挂载到容器的 /usr/share/Nginx/html。

-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:将我们自己创建的 nginx.conf 挂载到容器的 /etc/nginx/nginx.conf。

Nginx服务启停控制

Nginx服务的启动

在Linux 平台下,启动Nginx服务器直接运行安装目录下sbin目录中的二进制文件即可。

shell 复制代码
./Nginx

参数:

-v : 打印版本号

-V : 打印版本号和配置

-t:测试配置正确性并退出

-q:测试配置时只显示错误

-s:向主进程发送信号

-p:指定Nginx服务器路径前缀

-c: 指定Nginx配置文件路径

-g: 指定Nginx附加配置文件路径

Nginx服务的停止

两种方式

快速停止,快速停止是指立即停止当前Nginx服务正在处理的所有网络请求,马上丢弃连接,停止工作。

shell 复制代码
./nginx -s stop # 快速关闭

平缓停止,平缓停止是指允许Nginx服务将当前正在处理的网络请求处理完成,但不再接收新的请求,之后关闭连接,停止工作。

shell 复制代码
./nginx -s quit  # 等待工作进程处理完成后关闭关闭

Nginx服务的重启

shell 复制代码
./nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启
./nginx -s reopen # 重启 Nginx

Nginx配置指令详解_全局块

配置运行Nginx服务器用户(组)

shell 复制代码
user user [用户组]

只有被设置的用户或者用户组成员才有权限启动你那个Nginx进程,如果是其他用户尝试启动Nginx进程,将报错。

如果希望所有用户都可以启动Nginx进程,有两种办法:一是将指令注释:或者把用户(和用户组)设置为nobody;

shell 复制代码
# user user [用户组]
user nobody nobody;

配置允许生成worker process数

worker process是Nginx服务器实现并发处理的关键所在。理论来说worker_process的值越大,可以支持的并发处理也越多。
语法格式:

shell 复制代码
worker_process number | auto
  • number 指定Nginx进程最多可以产生的worker_process数。
  • auto ,设置此值,Nginx进程将自动检测。

配置Nginx进程PID存放路径

shell 复制代码
pid logs/nginx.pid;

次指令只能在全局快中设置。 在指令path的时候,一定要包括文件名,如果只设置了路径,没有设置文件名,会报错。

配置错误日志的存放路径

shell 复制代码
error_log logs/error.log;

配置文件的引入

shell 复制代码
include test2.conf;

Nginx配置指令详解_events块

事件驱动模型

Nginx服务器提供了多种事件驱动模型来处理网络消息。

shell 复制代码
user method

其中,method可选择的内容有: selectpollkqueueepollrtsigldev/poll l以及 eventport

A)标准事件模型

Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,Nginx会选择select或poll
B)高效事件模型

Kqueue:使用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用双处理器的MacOSX系统使用kqueue可能会造成内核崩溃。

Epoll:使用于Linux内核2.6版本及以后的系统。

/dev/poll:使用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX5.1A+。

Eventport:使用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。

可以在编译时使用--with-select module--without-select_module设置是否强制编译select模块到Nginx内核;

使用--with-poll_module--without-poll_module设置是否强制编译poll模块到Nginx内核。此指令只能在events块中进行配置。

配置最大连接数

shell 复制代码
worker_connections number;

此指令的默认设置为512。

理论上每台Nginx服务器的最大连接数为。worker_processes * worker_connections

Nginx配置指令详解_HTTP块

定义MIME-Type

shell 复制代码
include       mime.types;
default_type application/octet-stream;

自定义服务日志

Nginx服务器支持对服务日志的格式、大小、输出等进行配置,需要使用两个指令,分别是access _log 和 log_format指令。

shell 复制代码
access_log path[format[buffer=size]]

path,配置服务日志的文件存放的路径和名称。
format,可选项,自定义服务日志的格式字符串,也可以通过"格式串的名称"使log_format指令定义好的格式。"格式串的名称"在 log_format 指令中定义。
size,配置临时存放日志的内存缓存区大小。

access_log联合使用的另一个指令是log_format,它专门用于定义服务日志的格式,并且可以为格式字符串定义一个名字,以便access_log 指令可以直接调用。其语法格式为:

shell 复制代码
log_format name string ..;

name,格式字符串的名字,默认的名字为combined。

string,服务日志的格式字符串。在定义过程中,可以使用Nginx 配置预设的一些变量获取相关内容,变量的名称使用双引号括起来,string整体使用单引号括起来。

例如:

shell 复制代码
log_format main '$remote_addr - $remote_user "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

log_format log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location';

日志格式设置 :

remote_addr与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地址和原来客户端的请求的服务器地址。

配置连接超时时间

shell 复制代码
keepalive_timeout timeout [header timeout];

timeout,服务器端对连接的保持时间。默认值为75s。
header_timeout,可选项,在应答报文头部的Keep-Alive域设置超时时间"Keep-Alive:timeout=header_timeout"。报文中的这个指令可以被Mozilla或者Konqueror识别。

配置示例:

shell 复制代码
keepalive_timeout 120s 100s;

其含义是,在服务器端保持连接的时间设置为120 s,发给用户端的应答报文头部中Keep-Alive域的超时时间设置为100 s。

配置虚拟主机

bash 复制代码
server{

 # 监听端口号
 listen 80;

 # 域名和IP
 server_name *.bandits.asia;
}

基于名称虚拟主机配置

四种写法

server_name www.baidu.com;

server_name *.baidu.com;

server_name www.baidu.*;

server_name ~^www.baidu.*$;

在Nginx核心配置文件中基于名称虚拟主机配置顺序:精准匹配,左侧通配符、右侧通配符、正则表达式

配置文件详细解释

bash 复制代码
#运行用户
user nobody;
#启动进程,通常设置成和cpu的数量相等
worker_processes  1;


#全局错误日志及PID文件
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;


#pid     logs/Nginx.pid;


#工作模式及连接数上限
events {
   #epoll是多路复用IO(I/O Multiplexing)中的一种方式,
   #仅用于linux2.6以上内核,可以大大提高Nginx的性能
   use  epoll; 


   #单个worker进程的最大并发链接数  
   worker_connections  1024;


   # 并发总数是 worker_processes 和 worker_connections 的乘积
   # 即 max_clients = worker_processes * worker_connections
   # 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4  为什么
   # 为什么上面反向代理要除以4,应该说是一个经验值
   # 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
   # worker_connections 值的设置跟物理内存大小有关
   # 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
   # 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
   # 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
   # $ cat /proc/sys/fs/file-max
   # 输出 34336
   # 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
   # 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
   # 使得并发总数小于操作系统可以打开的最大文件数目
   # 其实质也就是根据主机的物理CPU和内存进行配置
   # 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
   # ulimit -SHn 65535


}




http {
   #设定mime类型,类型由mime.type文件定义
   include   mime.types;
   default_type  application/octet-stream;
   #设定日志格式
   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
            '$status $body_bytes_sent "$http_referer" '
            '"$http_user_agent" "$http_x_forwarded_for"';


   access_log  logs/access.log  main;


   #sendfile 指令指定 Nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
   #对于普通应用,必须设为 on,
   #如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
   #以平衡磁盘与网络I/O处理速度,降低系统的uptime.
   sendfile   on;
   #tcp_nopush   on;


   #连接超时时间
   #keepalive_timeout  0;
   keepalive_timeout  65;
   tcp_nodelay   on;


   #开启gzip压缩
   gzip  on;
   gzip_disable "MSIE [1-6].";


   #设定请求缓冲
   client_header_buffer_size   128k;
   large_client_header_buffers  4 128k;




   #设定虚拟主机配置
   server {
     #侦听80端口
     listen   80;
     #定义使用 www.Nginx.cn访问
     server_name  www.Nginx.cn;


     #定义服务器的默认网站根目录位置(编译的时候--prefix是整个Nginx的根目录,这里的html文件夹是相对--prefix的路径)
     root html;


     #设定本虚拟主机的访问日志
     access_log  logs/Nginx.access.log  main;


     #默认请求
     location / {
      
       #定义首页索引文件的名称
       index index.php index.html index.htm;  


     }


     # 定义错误提示页面
     error_page  500 502 503 504 /50x.html;
     location = /50x.html {
     }


     #静态文件,Nginx自己处理
     location ~ ^/(images|javascript|js|css|flash|media|static)/ {
      
       #过期30天,静态文件不怎么更新,过期可以设大一点,
       #如果频繁更新,则可以设置得小一点。
       expires 30d;
     }


     #PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.
     location ~ .php$ {
       fastcgi_pass 127.0.0.1:9000;
       fastcgi_index index.php;
       fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
       include fastcgi_params;
     }

     #禁止访问 .htxxx 文件
       location ~ /.ht {
       deny all;
     }
   }
}

Nginx配置指令详解_location指令

配置location块

匹配规则 含义 示例
= 精确匹配 location = /images/ {...}
~ 正则匹配,区分大小写 location ~ .(jpg
~* 正则匹配,不区分大小写 location ~* .(jpg
^~ 匹配到即停止搜索 location ^~ /images/ {...}
不带任何符号 location / {...}
bash 复制代码
location  /abc # 没有修饰符
location = /abc # 必须与指定的模式精确匹配
location ~ ^/abc$ # 指定的正则表达式要区分大小写
location ~* ^/abc$ # 指定的正则表达式不区分大小写

配置请求的根目录

bash 复制代码
root path

path为Nginx服务器接收到请求以后查找资源的根目录路径。

bash 复制代码
location /data/
{
root /localtion1;
}

在Nginx核心配置文件中location指令url匹配顺序: =、^~、~、~*

虚拟主机的分类

虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响的。

Nginx支持三种类型的虚拟主机配置

基于IP的虚拟主机

基于端口的虚拟主机

基于域名的虚拟主机

Nginx虚拟主机单网卡多IP配置

这中方式比较少见
需求

一台Linux服务器绑定两个ip:192.168.66.100、192.168.66.101

访问不同的ip请求不同的html目录,即:

访问http://192.168.66.100将访问"html101"目录下的html网页

访问http://192.168.66.101将访问"html99"目录下的html网页

Linux绑定多IP

bash 复制代码
[root@node1 ~]# cd /etc/sysconfig/networkscripts
[root@node1 network-scripts]# ls
ifcfg-ens33
[root@node1 network-scripts]# vim ifcfgens33
BOOTPROTO="static"
IPADDR0=192.168.66.100
IPADDR1=192.168.66.101
[root@node1 network-scripts]# service
network restart # centos6、7重启网卡
[root@node1 ~]# systemctl restart network
#centos7重启网卡
[root@node0 network-scripts]#reboot #各种发行
版都是可以的
#CentOS8重启网卡 nmcli c reload ens33

修改配置nginx.conf

bash 复制代码
[root@node1 network-scripts]# vim /usr/local/nginx/conf/nginx.conf
#一个Server就是一个虚拟主机
    server {
        listen       80;
 #为虚拟机指定IP或者是域名
        server_name 192.168.66.100;
 #主要配置路由访问信息
        location / {
    #用于指定访问根目录时,访问虚拟主机的web目录
            root   html100;
    #在不指定访问具体资源时,默认的展示资源的列表
            index  index.html index.htm;
       }  
        error_page   500 502 503 504 /50x.html;
        location = /50x.html {
            root   html;
       }
   }
    #一个Server就是一个虚拟主机
    server {
        listen       80;
    #为虚拟机指定IP或者是域名
    server_name 192.168.66.101;
    #主要配置路由访问信息
        location / {
    #用于指定访问根目录时,访问虚拟主机的web目录
            root   html101;
    #在不指定访问具体资源时,默认的展示资源的列表
            index  index.html index.htm;
       }  
        error_page   500 502 503 504 /50x.html;
        location = /50x.html {
            root   html;
       }
   }
}

重启Nginx服务

bash 复制代码
./nginx -s reload

Nginx虚拟主机基于域名的配置

需求

两个域名指向同一个nginx服务器,用户访问不同的域名时显示不同的内容。

域名规划:

1, www.bjsxt.cn => 前台

2, www.baizhan.cn =》 后台

修改nginx.conf配置文件

bash 复制代码
server {
    listen       80;
 #为虚拟机指定IP或者是域名
    server_name www.bjsxt.cn;
 #主要配置路由访问信息
    location / {
    #用于指定访问根目录时,访问虚拟主机的web目录
        root   bjsxt;
    #在不指定访问具体资源时,默认的展示资源的列表
        index  index.html index.htm;
   }
    error_page   500 502 503 504 /50x.html;
    location = /50x.html {
        root   html;
   }
}
#一个Server就是一个虚拟主机
server {
    listen       80;
#为虚拟机指定IP或者是域名
    server_name www.baizhan.cn;
#主要配置路由访问信息
    location / {
    #用于指定访问根目录时,访问虚拟主机的web目录
        root   baizhan;
        #在不指定访问具体资源时,默认的展示资源的列表
        index  index.html index.htm;
   }
    error_page   500 502 503 504 /50x.html;
    location = /50x.html {
        root   html;
   }
}

重启Nginx服务

bash 复制代码
./nginx -s reload

Nginx虚拟主机基于多端口的配置

需求

Nginx对提供8888与9999两个端口的监听服务

请求8888端口则访问html8888目录下的index.html

请求9999端口则访问html9999目录下的index.html

修改Nginx的配置文件完成基于端口的虚拟主机配置

bash 复制代码
#一个Server就是一个虚拟主机 基于端口
server {
   listen       8888;
 #为虚拟机指定IP或者是域名
   server_name  192.168.66.100;
 #主要配置路由访问信息
   location / {
    #用于指定访问根目录时,访问虚拟主机的web目录
       root   html8888;
    #在不指定访问具体资源时,默认的展示资源的列表
       index index.html index.htm;
   }
   error_page   500 502 503 504 /50x.html;
   location = /50x.html {
       root   html;
   }
}
#一个Server就是一个虚拟主机
server {
   listen       9999;
 #为虚拟机指定IP或者是域名
   server_name  192.168.66.100;
 #主要配置路由访问信息
   location / {
 #用于指定访问根目录时,访问虚拟主机的web目
录
       root   html9999;
 #在不指定访问具体资源时,默认的展示资源的列
表
       index index.html index.htm;
   }
   error_page   500 502 503 504 /50x.html;
   location = /50x.html {
       root   html;
   }
}

重启Nginx服务

bash 复制代码
./nginx -s reload

Nginx核心指令_root和alias指令的区别

区别

共同点 : root和alias两者都都是用来指定URI和磁盘文件的映射关系;

区别: root会将定义路径与URI叠加;而alias只取定义路径;
root示例

客户端请求www.test.com/images/1.jpg,则对应磁盘映射路径/opt/nginx/html/images/images/1.jpg

bash 复制代码
location /images {
   root /opt/nginx/html/images;
   index index.html index.htm;
}

alias示例

客户端请求www.test.com/images/1.jpg,则对应磁盘映射路径/opt/nginx/html/images/1.jpg

bash 复制代码
location /images {
   root /opt/nginx/html/images;
   index index.html index.htm;
}

Nginx核心指令_return指令

return功能

  1. 停止处理请求,直接返回响应码或重定向到其他URL;
  2. 执行return指令后,location中后序指令将不会被执行;

return语法结构

  1. return code [text]; # 如果返回2XX的,text才有意义,text会在body中;
  2. return code URL; #主要用于重定向;
  3. return URL; #须以http或者https开头的;

常用状态码:

200 请求成功

301 永久转移到其他URL

404 请求资源不存在

500 内部服务器错误

示例
code + text

bash 复制代码
location / {
   return 200 'your success';
}

code + URL

bash 复制代码
#302 表示临时性重定向。访问一个Url时,被重定向到另一个url上。常#用于页面跳转。
location / {
   return 302 /bbs;
}
location /bbs {
   root html;
   index index.html;
}

URL

bash 复制代码
location / {
   return http://baidu.com;
}

Nginx核心指令_rewrite指令

rewrite常用全局变量

变量 说明
$args 请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2
$body_bytes_sent 服务器发送给客户端的响应body字节数
$content_length HTTP请求信息里的"Content-Length"
$conten_type HTTP请求信息里的"Content-Type"
$document_root nginx 虚拟主机配置文件中的root参数对应的值
$document_uri 当前请求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的
$document_uri 就是1.php,不包含后面的参数
$http_referer 记录此次请求是从哪个连接访问过来的,可以根据该参数进行防盗链设置
$host 主机头,也就是域名
$http_user_agent 客户端的详细信息,也就是浏览器的标识,用curl -A可以指定
$http_cookie 客户端的cookie信息
$http_x_forwarded_for 当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器也要进行相关的x_forwarded_for设置
$limit_rate 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示0
$remote_addr 客户端的公网ip
$remote_port 客户端的port
$remote_user 如果nginx有配置认证,该变量代表客户端认证的用户名
$request 请求的URI和HTTP协议,如"GET /article-10000.html HTTP/1.1"
$request_body_file 做反向代理时发给后端服务器的本地资源的名称
$request_method 请求资源的方式,GET/PUT/DELETE等
$request_filename 当前请求的资源文件的路径名称,相当于是 d o c u m e n t r o o t / document_root/ documentroot/document_uri的组合
$request_uri 请求的链接,包括 d o c u m e n t u r i 和 document_uri和 documenturi和args
$scheme 请求的协议,如ftp,http,https
$server_protocol 客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr 服务器IP地址
$server_name 服务器的主机名
$server_port 服务器的端口号
$status http 状态码,记录请求返回的状态码,例如:200、301、404等
$uri 和$document_uri相同
$http_referer 客户端请求时的referer,通俗讲就是该请求是通过哪个链接跳过来的,用curl -e可以指定
$time_local 记录访问时间与时区,如18/Jul/2014:17:00:01 +0800

rewrite指令

该指令可以在server快或者location块中配置,其语法结构为:

rewrite regex replacement [flag];
关键字   正则   替代内容     flag标记

regex,用于匹配URI的正则表达式。使用括号 "()" 标记要截取的内容。

常用正则表达式

字符 描述
\ 将后面接着的字符标记为一个特殊字符或者一个原义字符或一个向后引用
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或者多次
+ 匹配前面字符串一次或者多次
? 匹配前面字符串的零次或者一次
. 匹配除"\n"之外的所有单个字符
(pattern) 匹配括号内的pattern

rewrite 最后一项flag参数

标记符号 说明
last 本条规则匹配完成后继续向下匹配新的location URI规则
break 本条规则匹配完成后终止,不在匹配任何规则
redirect 返回302临时重定向
permanent 返回301永久重定向

示例1:

bash 复制代码
# 无论/search 后面跟什么内容,最后都会被永久重定向到百度页面
location /search {
   rewrite   ^/(.*)   http://baidu.com
permanent;
}

示例2:

创建三个文件夹,每个文件夹下有个1.html文件;

bash 复制代码
location /images {
   rewrite /images/(.*) /pics/$1;          //•将URL /images/1.html 重写为 /pics/1.html
}
location /pics {
   rewrite /pics/(.*) /photos/$1;     //•将URL /pics/1.html 重写为 /photos/1.html
}
location /photos {
}

示例3:

将URL /images/1.html 重写为 /pics/1.html, 并且不再匹配其他location段

bash 复制代码
location /images {
   rewrite /images/(.*) /pics/$1 break;
}

示例4:
域名跳转

旧域名www.test.com直接跳转到新域名www.baizhan.com

bash 复制代码
server {
   listen     80;
   server_name www.test.com;
   rewrite ^/(.*) http://www.baizhan.com/$1 permanent;
}
server {
   listen       80;
   server_name www.baizhan.com;
   location / {
       root   html;
       index index.html index.htm;
   }
   access_log logs/brian.log main gzip buffer=128k flush=5s;
   error_page   500 502 503 504 /50x.html;
   location = /50x.html {
       root   html;
   }
}

Nginx核心指令_if指令

该指令用来支持条件判断,并根据条件判断结果选择不同的Nginx配置,可以在server块或locatio块中配置该指令。

语法结构:

sh 复制代码
if (condition) { ... }

变量与正则表达式

  • ~ 表示匹配过程对大小写敏感
  • ~* 表示匹配过程对大小写不敏感
  • !~ 表示匹配失败是if指令认为条件为true否则为false
bash 复制代码
if ($http_user_agent ~ MSIE) {
   # $http_user_agent 的值中是否包含MSIE字符串,如果包含,为true
}

示例:

bash 复制代码
location /search {
 # 判断ip地址是否为192.168.66.10如果是返回"test if ok in Url serach"
 if ($remote_addr = "192.168.66.10"){
     return 200 "test if ok in url search"
 }
 # 不允许谷歌浏览器访问,如果时候谷歌浏览器放回500
 if ($http_user_agent ~ Chrome){
	 return 500;
 }
}

Nginx核心指令_set和break指令

set指令

该指令用于设置一个新的变量。

bash 复制代码
set variable value

variable,为变量的名称。注意要用符号"$"作为变量的第一个字符,且变量不能与Nginx服务器预设的全局变量同名。

value,为变量的值,可以是字符串、其他变量或变量的组合等。

示例:

bash 复制代码
location / {
 if ($slow){
   set $id $1 ; # 处于break指令之前,配置生效
   break;      
   limit_rate 10k; #处于break指令之后,配置无效
 }
}

Nginx核心指令_Gzip压缩指令

Nginx开启Gzip压缩功能, 可以使网站的css、js 、xml、html 文件在传输时进行压缩,提高访问速度, 进而优化Nginx性能

Gzip压缩作用

将响应报⽂发送⾄客户端之前可以启⽤压缩功能,这能够有效地节约带宽,并提⾼响应⾄客户端的速度。Gzip压缩可以配置

http,server和location模块下。
Nginx开启Gzip压缩参数说明:

如下是线上常使用的Gzip压缩配置

bash 复制代码
http {
   gzip on;
   gzip_min_length 1k;
   gzip_buffers     4 16k;
   gzip_http_version 1.1;
   gzip_comp_level 9;
   gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
   gzip_disable "MSIE [1-6]\.";
   gzip_vary on;
}

Nginx的Gzip压缩功能虽然好用,但是下面两类文件资源不太建议启用此压缩功能。
1) 图片类型资源 (还有视频文件)

原因:图片如jpg、png文件本身就会有压缩,所以就算开启gzip后,压缩前和压缩后大小没有多大区别,所以开启了反而会白白的浪费资源。
2) 大文件资源

原因:会消耗大量的cpu资源,且不一定有明显的效果。

Nginx场景实践_浏览器缓存

浏览器缓存是为了加速浏览,浏览器在用户磁盘上,对最近请求过的文档进行存储。当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样,就可以加速页面的阅览,缓存的方式节约了网络的资源,提高了网络的效率。

expires

浏览器缓存可以通过expires指令输出Header头来实现。

sh 复制代码
语法:expires[time| epoch | max |off]
默认值:expires off
作用域:http、server、location

Cache-Control

设置相对过期时间, max-age指明以秒为单位的缓存时间. 若对静态资源只缓存一次, 可以设置max-age的值为315360000000 (一万年).比如对于提交的订单,为了防止浏览器回退重新提交,可以使用Cache-Control之no-store绝对禁止缓存,

Http协议的cache-control的常见取值及其组合释义:
no-cache: 数据内容不能被缓存, 每次请求都重新访问服务器, 若有max-age, 则缓存期间不访问服务器
no-store: 不仅不能缓存, 连暂存也不可以(即: 临时文件夹中不能暂存该资源)
private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有- - maxage, 则缓存期间不访问服务器
public: 可以被任何缓存区缓存, 如: 浏览器、服务器、代理服务器等
max-age: 相对过期时间, 即以秒为单位的缓存时间

缓存流程

实战示例

下面是开发部门同事发过来的配置需求:

  1. 禁用html文件缓存,即cache control设置为no-cache;
  2. 对于js,图片,css,字体等,设置max-age=2592000. 也就是30天;
bash 复制代码
server{
 listen 80;
 server_name 192.168.66.100;
 location ~ \.(css|js|gif|jpg|jpeg|png|bmp|swf|ttf|woff|otf|ttc|pfa)$ {
     root /data/web/kevin;
     expires 30d;
 }
 location ~ \.(html|htm)$ {
   root /data/web/kevin;
   add_header Cache-Control no-cache;
 }
}

Nginx场景实践_防盗链

防盗链的概念

内容不在自己的服务器上,通过技术手段将其他网站的内容(比如一些音乐、图片、软件的下载地址)放置在自己的网站中,通过这种方法盗取其他网站的空间和流量。

基于http_refer防盗链配置模块

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。

语法结构:

bash 复制代码
valid_referers none blocked 192.168.66.100; # 相当于白名单 如果是这个IP的 相当于给valid_referers 赋值为0 , 反之为1
if ($invalid_referer) { # invalid_referer 获取valid_referers 的变量值
   return 403;
}

参数:

none : 允许没有http_refer的请求访问资源;

blocked : 允许不是http://开头的,不带协议的请求访问资源;

192.168.66.100: 只允许指定ip来的请求访问资源;

Nginx场景实践_代理服务

正向代理

正向代理,是在用户端的。比如需要访问某些国外网站,我们可能需要购买vpn。

反向代理

客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色。

反向代理,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。

Nginx场景实践_反向代理

反向代理设置指令

proxy_pass指令

该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号等形式。

proxy_pass URL;

URL为要设置的被代理服务器的地址,包含传输协议、主机名称或P地址加端口号、URI等要素。传输协议通常是"http"或

者"https://"。
示例:

bash 复制代码
server{
   ....
   listen 80;
   server_name *.*;
   location / {
     proxy_pass http://192.168.66.101:8080;
   }
}

Nginx场景实践_负载均衡

负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。

upstream指令

upstream块不属于虚拟主机,只能在http块里配置,它定义了在反向代理时Nginx需要访问的后端服务器集群和负载均衡策略。

语法格式:

bash 复制代码
upstream back_end {           # upstream需要一个名字
   server 192.168.66.100 max_conns=2 fail_timeout=1s;
   server 192.168.66.101 weight = 1;
   server 192.168.66.102 weight = 1;
}
server{
 lisetn 80;
 server_name *.*;
 location / {
     proxy_set_header Host $host; #转发原始请求的host头部
     proxy_pass http://back_end;   #转发到upstream块定义的服务器集群。
 }
}

upstream参数:

max_conns 节点的最大连接数

slow_start 缓慢启动时间

down 节点下线

backup 备用节点

max_fails 允许的最大失败数

fail_timeout 超过最大失败数后的等待时间

负载均衡算法

轮询(默认)

轮询方式,依次将请求分配到各个后台服务器中,默认的负载均衡方式。

bash 复制代码
upstream bakend {    
 server 192.168.0.14;    
 server 192.168.0.15;    
}

轮询加权重

根据权重来分发请求到不同的机器中,指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

bash 复制代码
upstream bakend {    
 server 192.168.0.14 weight=10;    
 server 192.168.0.15 weight=10;    
}

IP_hash

每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。俗称IP绑定。

bash 复制代码
upstream bakend {    
 server 192.168.0.14;    
 server 192.168.0.15;
 ip_hash;    
}

url_hash

按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。

fair

比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。

fair模块安装

下载

fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。

模块安装

切换到nginx目录执行一下操作

bash 复制代码
./configure --prefix=/usr/local/nginx / --add-module=/opt/nginx-upstream-fair-master

编译

bash 复制代码
make

备份原来的nginx命令

bash 复制代码
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_bak

替换原来的 nginx 命令

bash 复制代码
cp /usr/local/nginx-1.16.1/objs/nginx /usr/local/nginx/sbin/nginx

配置实现

bash 复制代码
upstream backserver {
 fair;
 server 192.168.0.14;
 server 192.168.0.15;
}

注意:

已安装Nginx,配置第三方模块时,只需要--add-module=/第三方模块目录,然后make编译一下就可以,不要 make install

安装。编译后复制objs下面的nginx到指定目录下。

Nginx场景实践_Nginx配置故障转移

当上游服务器(真实访问服务器),一旦出现故障或者是没有及时相应的话,应该直接轮训到下一台服务器,保证服务器的高可用。

Nginx配置代码

bash 复制代码
server {
   listen 80;
   server_name www.itmayiedu.com;
   location / {
      # 指定上游服务器负载均衡服务器
      proxy_pass http://backServer;
      #故障转移的条件:如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。
      # error 连接到服务器发送错误
      # timeout 连接服务器超时
      # invalid_header 服务器返回空或者错误的应答
      proxy_next_upstream http_502 http_504 error timeout invalid_header;  
      # nginx与上游服务器(真实访问的服务器)超时时间 后端服务器连接的超时时间_发起握手等候响应超时时间
      proxy_connect_timeout 1s;
      # nginx发送给上游服务器(真实访问的服务器)超时时间
      proxy_send_timeout 1s;
      # nginx接受上游服务器(真实访问的服务器)超时时间
      proxy_read_timeout 1s;
      # 重试次数
      proxy_next_upstrem_tries 3;
      index index.html index.htm;
   }
}

Nginx场景实践_跨域问题

为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

什么是跨域

当一个请求URL的协议域名端口三者之间任意一个与当前页面url不同即为跨域。

当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)

跨域问题解决

解决方案

只需要在Nginx的配置文件中配置以下参数:

bash 复制代码
location / {  
   add_header Access-Control-Allow-Origin *;
   add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
   add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
   if ($request_method = 'OPTIONS') {
       return 204;
   }
}

参数:

  1. Access-Control-Allow-Origin 表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。
  2. Access-Control-Allow-Methods 明确了客户端所要访问的资源允许使用的方法或方法列表。
  3. Access-Control-Allow-Headers 设置预检请求。

Nginx场景实践_动静分离

Nginx动静分离简单来说就是把动态和静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求和静态请求分开,可以理解成使用Nginx处理静态请求,Tomcat处理动态请求。
什么是动静分离

动:必须依赖服务器生存的文件 比如jsp。

静:不需要依赖容器的比如css/js或者图片等文件
动静分离的好处

Nginx本身就是一个高性能的静态web服务器

其实静态文件有一个特点就是基本上变化不大,所以动静分离以后我们可以对静态文件进行缓存、或者压缩提高网站性能
静态资源的类型

在Nginx的conf目录下,有一个mime.types文件里边列出了 静态资源的类型,如下

当用户访问一个网站,然后从服务器端获取相应的资源,通过浏览器进行解析渲染最后展示给用户,服务端可以返回各种类型的内容,比如xml、jpg、png、gif、flash、MP4、html、css等等,浏览器就是根据mime-type来决定用什么形式来解析和展示的。服务器返回的资源给到浏览器时,会把媒体类型告知浏览器,这个告知的标识就是Content-Type,比如Content-Type:text/html。

通过请求分离

bash 复制代码
upstream webservers {
       server 192.168.66.101:8080 weight=5;
       server 192.168.66.102:8080 weight=5;
}
server {
    listen       80;
    server_name *.*;
    location / {
    root   html;
        index index.html index.htm;
        proxy_set_header Host $host;
        proxy_pass http://webservers;
    }
    location /image/ {
        root static;
    }
    location /web/ {
        proxy_set_header Host $host;
        proxy_pass http://webservers;
    }
}

根据扩展名分离

bash 复制代码
upstream webservers {
    server 192.168.66.101:8080 weight=5;
    server 192.168.66.102:8080 weight=5;
}
server {
    listen 80;
    server_name *.*;
    location / {
        root   html;
        index index.html index.htm;
        proxy_set_header Host $host;
        proxy_pass http://webservers;
    }
    location ~ .*.(jpg|png|gif|css|js)$ {
      root static;
    }
}

Nginx场景实践_限流

为什么需要限流

系统设计时一般会预估负载,当系统暴露在公网中时,恶意攻击或正常突发流量等都可能导致系统被压垮,而限流就是保护措施之一。

Nginx 的二种限流设置:

控制速率。

控制并发连接数。

限流算法

漏桶算法

原理:

漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

令牌桶算法

原理:

令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

漏桶 vs 令牌桶的区别

漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以"预存"一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。

限流实战

根据nginx官网提供的说法,有两种算法,一种是漏桶算法,一种是令牌桶算法
limit_req_zone 用来限制单位时间内的请求数目,以及速度限制。
limit_req_conn 用来限制同一时间连接数,即并发限制。

Nginx限速配置指令

放在http{} 内

bash 复制代码
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;

参数解析:

第一个参数:$binary_remote_addr 限制同一客户端ip地址。

第二个参数:zone=mylimit:10m 用来存储访问的频次信息。

第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的。

放在server{}内

bash 复制代码
limit_req zone=mylimit burst=1 nodelay;

参数:

第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。

第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到

这个缓冲区内。

第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队。

Nginx并发限制配置指令

ngx_http_limit_conn_module 提供了限制连接数的能力,利用limit_conn_zonelimit_conn 两个指令即可。

bash 复制代码
http{
 #ip limit
 limit_conn_zone $binary_remote_addr zone=perip:10m;
 limit_conn_zone $server_name zone=perserver:10m;
}

在需要 限制并发数 和 下载带宽 的网站配置 server {}里加上如下代码:

bash 复制代码
server {
   limit_conn perip 10;
   limit_conn perserver 100;
}

参数说明:

limit_conn perip 10 作用的key 是 $binary_remote_addr,表示限制单个IP同时最多能持有10个连接。

limit_conn perserver 100 作用的key是 $server_name,表示虚拟主机(server) 同时能处理并发连接的总数。

设置白名单

限流主要针对外部访问,内网访问相对安全,可以不做限流,通过设置白名单即可。利用 Nginx ngx_http_geo_module
ngx_http_map_module 两个工具模块即可搞定。
查看是否具有该功能

bash 复制代码
./configure --help |grep http_limit_req_module
./configure --help |grep http_geo_module
./configure --help |grep http_map_module

nginx.confhttp 部分中配置白名单:

bash 复制代码
geo $limit {
   default 1;
   39.100.243.125 0;
   192.168.0.0/24 0;
   172.20.0.35 0;
}
map limit limit_key {
   0 "";
   1 $binary_remote_addr;
}
limit_req_zone $limit_keyzone=myRateLimit:10m rate=10r/s;

参数:
geo 对于白名单(子网或IP都可以) 将返回0,其他IP将返回1。
map 将limit转换为 limit_key,如果是 $limit 是0(白名单),则返回空字符串;如果是1,则返回客户端实际IP。
limit_req_zone 限流的key不再使用 binary_remote_addr,而是limit_key 来动态获取值。

如果是白名单,limit_req_zone 的限流key则为空字符串,将不会限流;若不是白名单,将会对客户端真实IP进行限流。

Nginx场景实践_WEB缓存机制

响应速度历来是衡量WEB应用和服务性能优劣的重要指标之一,尤其动态网站在网络上泛滥的今天。除了优化发布内容以

外,另外一个主要的办法就是把不需要实时更新的动态页面输出结果转为静态网页形式缓存,进而按照静态网页来访问。

proxy Cache缓存机制

配置proxy_cache模块

在nginx.conf文件中添加如下代码:

bash 复制代码
http{
   ......
   proxy_cache_path /data/nginx/tmp-testlevels=1:2 keys_zone=tmp-test:100m inactive=7d max_size=1000g;
}

参数说明:
proxy_cache_path 缓存文件路径
levels 设置缓存文件目录层次;levels=1:2 表示两级目录
keys_zone 设置缓存名字和共享内存大小
inactive 在指定时间内没人访问则被删除
max_size 最大缓存空间,如果缓存空间满,默认覆盖掉缓存时间最长的资源。

当配置好之后,重启nginx,如果不报错,则配置的proxy_cache会生效

查看 proxy_cache_path / data/ nginx / 目录,会发现生成了 tmp -test 文件夹。

使用proxy_cache

bash 复制代码
location /tmp-test/ {
 proxy_cache tmp-test;
 proxy_cache_valid 200 206 304 301 302 10d;
 proxy_cache_key $uri;
 proxy_set_header Host $host:$server_port;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_pass http://127.0.0.1:8081/media_store.php/tmp-test/;
}

参数:
Proxy_cache tmp -test 使用名为 tmp -test 的对应缓存配置
proxy_cache_valid 200 206 304 301 302 10d; 对httpcode为200...的缓存10天
proxy_cache_key $uri 定义缓存唯一key,通过唯一key来进行hash存取
proxy_set_header 自定义http header头,用于发送给后端真实服务器。
proxy_pass 指代理后转发的路径,注意是否 需要 最后的 /

主动清理缓存文件

需要引入第三方模块

bash 复制代码
location /tmp-test/ {
       allow 127.0.0.1; //只允许本机访问
       deny all; //禁止其他所有ip
       proxy_cache_purge tmp-test $uri; //清理缓存
}

Nginx场景实践_Nginx高可用

双机热备方案

这种方案是国内企业中最为普遍的一种高可用方案,双机热备其实就是指一台服务器在提供服务,另一台为某服务的备用状态,当一台服务器不可用另外一台就会顶替上去。

Nginx场景实践_LVS负载均衡

LVS是一个开源的软件,可以实现传输层四层负载均衡。LVS是Linux Virtual Server的缩写,意思是Linux虚拟服务器。

LVS的八种调度算法
1. 轮叫调度 rr
2. 加权轮叫 wrr
3. 最少链接 lc
4. 加权最少链接 wlc
5. 基于局部性的最少连接调度算法 lblc
6. 复杂的基于局部性最少的连接算法 lblcr
7. 目标地址散列调度算法 dh
8. 源地址散列调度算法 sh

Nginx场景实践_keepalived健康监测

LVS可以实现负载均衡,但是不能够进行健康检查,比如一个rs出现故障,LVS 仍然会把请求转发给故障的rs服务器,这样就会导致请求的无效性。keepalive 软件可以进行健康检查,而且能同时实现LVS 的高可用性,解决 LVS 单点故障的问题,其实 keepalive 就是为 LVS 而生的。

keepalived工作原理

keepalived是基于VRRP协议实现的保证集群高可用的一个服务软件,主要功能是实现真机的故障隔离和负载均衡器间的失败切换,防止单点故障。

VRRP协议

VRRP是一种容错协议,它保证当主机的下一跳路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。

主要作用:

VRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由,这个虚拟路由器通过虚拟IP(一个或者多个)对外提供服务。

Nginx场景实践_企业双机热备方案

环境服务配置

两台Nginx服务器
Nginx 主服务器 192.168.66.100
Nginx 备服务器 192.168.66.101
Lvs 虚拟VIP     192.168.66.99

环境搭建

yum install -y keepalived

keepalived 常用命令

service keepalived start
service keepalived stop

使用keepalived虚拟VIP

修改主keepalived信息

修改主Nginx服务器keepalived文件, /etc/keepalived/keepalived.conf

bash 复制代码
! Configuration File for keepalived


vrrp_script chk_nginx {
   script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕机以后,自动开启服务
   interval 2 #检测时间间隔
   weight -20 #如果条件成立的话,则权重 -20
}
# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
   state MASTER #来决定主从
   interface ens33 # 绑定虚拟 IP 的网络接口,根据自己的机器填写
   virtual_router_id 121 # 虚拟路由的 ID 号, 两个节点设置必须一样
   mcast_src_ip 192.168.212.141 #填写本机ip
   priority 100 # 节点优先级,主要比从节点优先级高
   nopreempt # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 # 组播信息发送间隔,两个节点设置必须一样,默认 1s
   authentication {
     auth_type PASS
     auth_pass 1111
   }
   # 将 track_script 块加入 instance 配置块
   track_script {
     chk_nginx #执行 Nginx 监控的服务
   }


   virtual_ipaddress {
     192.168.212.110 # 虚拟ip,也就是解决写死程序的ip怎么能切换的ip,也可扩展,用途广泛。可配置多个。
   }
}

修改从keepalived信息

修改主Nginx服务器keepalived文件, /etc/keepalived/keepalived.conf

bash 复制代码
! Configuration File for keepalived


vrrp_script chk_nginx {
   script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕机以后,自动开启服务
   interval 2 #检测时间间隔
   weight -20 #如果条件成立的话,则权重 -20
}
# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
   state BACKUP #来决定主从
   interface ens33 # 绑定虚拟 IP 的网络接口,根据自己的机器填写
   virtual_router_id 121 # 虚拟路由的 ID 号, 两个节点设置必须一样
   mcast_src_ip 192.168.212.141 #填写本机ip
   priority 100 # 节点优先级,主要比从节点优先级高
   nopreempt # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
   advert_int 1 # 组播信息发送间隔,两个节点设置必须一样,默认 1s
   authentication {
     auth_type PASS
     auth_pass 1111
   }
   # 将 track_script 块加入 instance 配置块
   track_script {
     chk_nginx #执行 Nginx 监控的服务
   }


   virtual_ipaddress {
     192.168.212.110 # 虚拟ip,也就是解决写死程序的ip怎么能切换的ip,也可扩展,用途广泛。可配置多个。
   }
}

Nginx+keepalived实现高可用

写入nginx_check.sh脚本 /etc/keepalived/nginx_check.sh

bash 复制代码
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
   /usr/local/nginx/sbin/nginx
   sleep 2
   if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
     killall keepalived
   fi
fi

该脚本一定要授权。

sh 复制代码
chmod 777 nginx_check.sh
相关推荐
梁萌14 分钟前
Docker中的分层(Layer)
运维·docker·容器
IT 古月方源16 分钟前
关于 VRRP的详解
运维·网络·tcp/ip·网络安全·智能路由器
檀越剑指大厂16 分钟前
【Linux系列】sed命令的深入解析:如何使用sed删除文件内容
linux·运维·服务器
不爱学英文的码字机器44 分钟前
深入理解 Linux 文件时间戳:atime、mtime 和 ctime 的概念及应用
linux·运维·服务器
꧁༺朝花夕逝༻꧂1 小时前
nginx-负载均衡
nginx·负载均衡
沙滩de流沙2 小时前
Spark生态圈
大数据·分布式·spark·scala
迷迭所归处2 小时前
Linux系统 —— 进程控制系列 - 进程的等待:wait 与 waitpid
linux·运维·服务器
Charlie__ZS2 小时前
Docker安装
运维·docker·容器
yulingfeng592 小时前
Centos7 yum 报错“Could not resolve host: mirrorlist.centos.org; Unknown error“
linux·运维·centos
海域云赵从友2 小时前
香港 GPU 服务器托管引领 AI 创新,助力 AI 发展
运维·服务器·人工智能