Nginx的配置使用

Nginx介绍

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx 可以在大多数 Unix Linux OS 上编译运行,并有 Windows 移植版。 Nginx 的1.19.2稳定版已经于2020年8月11日发布,一般情况下,对于新建站点,建议使用最新稳定版作为生产版本,已有站点的升级急迫性不高。Nginx 的源代码使用 2-clause BSD-like license。
Nginx 是一个很强大的高性能Web和反向代理服务,它具有很多非常优越的特性:在连接高并发的情况下,Nginx是Apache服务不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一。能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。
服务器
Nginx作为负载均衡服务:Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务对外进行服务。Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。处理静态文件,索引文件以及自动索引;打开文件描述符缓冲。
无缓存的反向代理加速,简单的负载均衡和容错。FastCGI,简单的负载均衡和容错。模块化的结构。包括 gzipping, byte ranges, chunked responses,以及 SSI-filter 等 filter。如果由 FastCG或其它代理服务器处理单页中存在的多个 SSI,则这项处理可以并行运行,而不需要相互等待。

代理模式

正向代理

正向代理就是代理的客户端,服务端实际不知道发起的是客户端,正向代理服务器位于客户端和服务器之间,为了从服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端需要要进行一些正向代理的设置的,例如vpn。

反向代理

反向代理,客户端对代理是无感知的,客户端不需要任何配置就可以访问,客户端将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

正向代理中,proxy和client同属一个LAN,对server透明;反向代理中,proxy和server同属一个LAN,对client透明。实际上proxy在两种代理中做的事都是代为收发请求和响应,不过从结构上来看正好左右互换了下,所以把后出现的那种代理方式叫成了反向代理。

负载均衡

来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
负载均衡有4层负载均衡模型和7层负载均衡模型,简单来说就是:
负载均衡四层和七层主要是根据d网络的结构来的。一般来说,四层主要是网络层,也就是TCP和UDP的负载均衡(主要是TCP的)。七层是应用层,主要是指HTTP、FTP、HTTPS等的负载均衡,四层负载均衡的典型软件如LVS,七层负载均衡的比较典型软件如haproxy,nginx等。
四层负载均衡:主要在传输层做的负载均衡,简单来说就是比如请求的地址http://ip1:port/,然后直接修改ip1和port1的信息然后转发请求,效率更高;
七层负载均衡:主要是在应用层做的负载均衡,简单来说就是需要最请求的url进行分析,然后进行负载均衡处理,所以性能较四层的低,但是7层负载均衡所带来的扩展是四层负载均衡所达不到的。

常用的命令

防火墙相关:
开放端口列表:firewall-cmd --list-all
添加开放端口:firewall-cmd --add-port=8080/tcp --permanent
重新加载防火墙配置:firewall-cmd --reload
关闭防火墙:systemctl stop firewalld.service
监听列表:netstat -tlnp
安装ab测试工具:yum -y install httpd-tools
apache ab测试(压力测试):ab -kc 1000 -n 1000 http://127.0.0.1/

安装部署

我这里就使用在线安装,安装最新的版本,网上大部分都是源码的安装,安装也比较简单,源码版安装就是需要安装一些依赖的组件,比如GCC,我这里直接在线安装,为了方便研究nginx,直接用在线安装。
在线安装直接在/ect/yum.repos.d/中新建文件nginx.repo,建立一个yum源,内容如下:

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key

我这里使用的是root用户,简单,这不是重点,一般在生产环境中都不会使用root用户来安装nginx,也不会在线安装的,都是源码安装的,我这里不是记录安装,只是为了将nginx的使用记录一下,所以这里就直接在root用户上使用在线安装。
执行命令:yum install -y nginx
安装完成过后在/etc/nginx下就有了文件,并且已经建立了软连接,可以在任何目录执行nginx就可以启动nginx了,目录结构如下:
在这里插入图片描述
这里最重要的是有一个配置文件nginx.conf和一个文件夹conf.d,conf.d是在nginx. conf中通过include导入的一个配置文件目录,在conf.d中可以定制我们个性化的所有的配置文件,大部分是server的配置可以配置到这里,包括负载均衡的配置,modules这个是安装的模块,就是如果需要使用到的module安装过后就出现到这里,在conf.d中的配置文件都是在http域中的,ngixn有那些域呢,大概有main域,events域,http域(包含了server域)
在这里插入图片描述

nginx的常用命令
nginx:启动nginx
nginx -t :修改了nginx.conf配置文件过后,可以通过nginx -t对修改的配置文件进行检查,检查配置文件是否有错误,比如下面:
在这里插入图片描述
输出有两行,看到ok和successful就代表配置文件是ok的
nginx -s reload:可以认为是重启,其实不是重启,就是从新加载配置文件,也可以理解的重启,就是重新加载配置文件,在nginx中大部分的操作都是修改配置,修改了直接执行这个命令,让配置生效。
nginx -s stop:停机,将nginx直接停止,这个时候如果有请求正在处理,nginx是不管的,直接会停止,所以这个命令是有风险的
nginx -s quit:这个命令和stop一样都是停止nginx服务器,但是唯一 区别就是quit这个会将目前所接受的请求处理完成再去停机,可以叫做优雅停机。

nginx.conf

这里先大概看下nginx的配置文件,nginx有很多功能,我这里只简单记录下一些常用的配置,后续如果有用到其他的,可以去网络下找下资源

#表示nginx使用的用户是哪个,我这里用的用户是 root
user  root;
#工作进程有几个,这里的工作进程是一个
worker_processes  1;
#可以定义一个nginx的错误日志存放的地方,方便nginx在报错的时候,比如404,找不到页面的这种错误去看error日志,可以很方便的定位错误的地方
error_log  /var/log/nginx/error.log warn;
#pid就是进程号,任何程序运行成功都会有一个进程存在 ,我们经常强制停止一个程序,就是通过kill去杀掉这个进程,所以nginx这里将它启动的进程号放入了一个文件中,这样的好处就是如果有多个进程
#需要杀掉这个进程,就 可以 不用ps,然后再去杀,可以直接kill -9 cat /var/run/nginx.pid,将nginx全部停止
pid        /var/run/nginx.pid;

#上面的配置就叫做main域,可以叫做全局配置域


#这个是Nginx 事件驱动相关的配置指令域,这里默认定义了一个参数worker_connections  ,工作进程的连接数默认1024
events {
    worker_connections  1024;
}

#这里是http域,http域配置了http的一些基本的参数和规则
http {
    #include  /etc/nginx/mime.types表示该http域支持的那些媒体类型,这个是必须要定义的,定义好了以后就会默认支持这些媒体类型,mime.types是一个文件,nginx在安装目录下会有这个文件
    #定义了支持的媒体类型,可以修改
    include       /etc/nginx/mime.types;
    #默认的类型
    default_type  application/octet-stream;

   #日志的格式,nginx这里有一个默认的日志格式,这个可以根据自己的需求去修改日志模板
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    #这个是访问日志的配置,和error的一样,就是需要在一个地方来存放这个访问日志,这里配置到http域中是全局生效的,但是我们可以配置到指定的server域中,server域是包含在http域中的
    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;
   #这个是长连接保存连接的超时时间
    keepalive_timeout  65;
   #gzip是表示是否采用静态资源压缩的开关,如果配置到这里,那么这个http域默认都是启用静态资源压缩
    #gzip  on;
    #这个就比较重要了,配置文件到这里,我们都还没有看到一个server的配置,所以nginx这里给我们定义了一个目录conf.d,只要你在conf.d中配置的**.conf文件都会被加载,所以我一般喜欢把
    #server和负载均衡的配置文件放到这个目录,而nginx.conf这里就配置一些全局通用的配置
    include /etc/nginx/conf.d/*.conf;
}

nginx的配置指令可以分为两大类:指令块与单个指令。指令块就是像events,http,server等,单独指令就是像root html;这样的。
指令块可以嵌套,http块中可以嵌套server指令,server块中可以嵌套location指令,指令可以同时出现在不同的指令块,如root指令可以同时出现在http、server和location指令块,在location中定义的指令会覆盖server,http的指令。作用范围受大括号限制。

Nginx应用

启动nginx

在root的任何地方直接执行nginx,然后ps看下,可以看到有2个进程比较重要,如下图:
在这里插入图片描述
master process是管理进程,二worker process是工作经常,master管理工作进程的,工作进程可以配置多个,在nginx.conf中可以进行配置,在idea中新建一个spring boot的项目,就提供了一个简单的接口如下:

@RestController
@RequestMapping("/index")
public class IndexController {

    @RequestMapping("/test")
    public String test(){
        System.out.println("0000000000");

        return "test";
    }
}

提供的这个接口的访问是8100端口,所以在nginx中需要配置这个反向代理,我们在conf.d中新建一个1001.conf的配置文件,1001表示我要开启1001端口来反向代理后端的这个spring boot项目,在1001.conf中添加如下内容:

server{
    listen 1001;
    server_name 192.168.153.130;
    location / {
     proxy_pass http://192.168.2.3:8100;
   }
}

192.168.153.130是nginx服务器的地址,而192.168.2.3:8100是spring boot服务的地址,配置好了以后,可以直接启动ngixn,然后访问得到结果如下:
在这里插入图片描述
证明是通过nginx代理出去的,所以这就是一个简单的nginx代理的例子,可以通过nginx进行正向代理和反向代理,那么想象一个场景,就是在微服务中,nginx可以对应的是一个getway服务,那么这个getway服务可能做了集群,那么在后端集群中,nginx要能够做负载均衡,否则的话后端的服务集群,如果通过nginx就没有办法达到服务的负载均衡,很显然,nginx肯定是支持的。

负载均衡测试

nginx的负载均衡配置非常简单,需要一个模块upstream,在upstream中配置了,在反向代理中进行配置即可,我先将spring boot服务启动两个来测试,分别启动8100和8200
在这里插入图片描述
然后,nginx中用1002.conf配置文件来配置这个负载均衡的测试,配置如下:

upstream springboot{
  server 192.168.2.3:8100;
  server 192.168.2.3:8200;
}

server{
  listen 1002;
  server_name 192.168.153.130;
  location / {
   proxy_pass http://springboot;
  }
}

然后打开页面访问10次,发现8100和8200每个服务各接受了5次,所以nginx默认是轮训,其实就是两台依次访问,轮训一圈过后又开始轮训的模式,nginx默认提供了4种模式,第二种模式就是权重的模式,配置也非常简单,直接家weight就可以设置权重了,比如

upstream springboot{
  server 192.168.2.3:8100 weight=40;
  server 192.168.2.3:8200 weight=60;
}

这个时候8100和8200就是2比3的比例,可以根据配置的权重进行请求负载,第三种模式我感觉不是用来做负载的,第三种就是ip_hash,什么意思呢?我们知道在后端的服务中,比如用户登录的时候访问的是服务1,但是进行登录操作的时候访问的是服务2了,但是session是保存在服务1里面在,所以这个时候在请求服务2的时候就需要让你去登录,因为是session是在服务器1,当然了在后端的技术中,现在有很多的解决方案来解决session共享问题,比如记录到redis,记录到数据库等等,但是nginx作为一个优秀的反向代理服务器,肯定也是解决的,所以第三种ip_hash就是用来解决session共享问题,意思就是说如果你登录的时候使用的是ip1服务,那么就会为这个客户端请求的这个ip生成一个ip的hash,如果后面还是这个ip来访问,那么就一直转发到第一次登录的后端服务器上,就是这么简单,为了解决session共享问题,配置非常简单,只需要在upstream中进行配置就可以了。

upstream springboot{
   ip_hash; 
  server 192.168.2.3:8100 weight=40;
  server 192.168.2.3:8200 weight=60;
}

配置这么一句话就可以了,这样配置以后,如果ip1第一次访问的是8100,那么后面 的请求都会转发到8100,不会去到8200,ip_hash是nginx会给请求的ip地址做一个hash算法,具体的hash算法需要去看nginx的源码,nginx会固定分配一台机器给这个ip使用,一直保持不变,好像是在超时过后会重新分配hash,但是基本上会一直转发到这台服务器,所以nginx针对ip_hash其实做的解决的就是session共享问题,但是如果说应用的session是有更好的解决办法的话,你可以使用nginx的也可以不使用,nginx的这个简单的应用场景就在于比如你就是一台单体应用,需要通过nginx做负载,那么后端的应用部署了多台,以为应用比较老,也不太想去修改相关的session存放机制,就可以采用nginx的这个ip_hash算法的方式来解决session共享问题。
还有一种负载均衡的分配算法就是最少连接分配算法,什么意思呢?就是说后端服务对接nginx的配置了5台,nginx需要做负载均衡的时候可以配置最少连接分配算法,就会选择这5台中目前连接处理最少的服务做转发处理,比如我的8100和8200,目前8100接受了5个连接,而8200只有一个连接正在处理,这个时候就会去选择8200进行转发处理。配置也非常简单,将ip_hash修改成为least_conn就可了

upstream springboot{
#1.根据权重配置,默认的是轮训
      #server 192.168.93.1:8100 weight=40;
      #server  192.168.93.1:8200 weight=60;
#2.ip_hash,用来解决session共享问题
     #ip_hash;
     #server 192.168.93.1:8100;
     #server 192.168.93.1:8200;
#3.最小连接数,就是说选取连接数最少的一台服务
     least_conn;
     server 192.168.93.1:8100;
     server 192.168.93.1:8200;
}

访问控制

nginx提供了一种机制类似于白名单和黑名单的机制,如果启用了黑名单,那么在黑名单上的请求ip都会被限制,如果启用了白名单,那么只有在白名单内的ip才能通过

http { 
   #也可以配置在server和location块中
    #限制192.168.40.150这个ip访问
    deny 192.168.40.150;#黑名单  报403  也可以配置网段和all
    allow 192.168.40.151;#白名单 
}

多虚拟主机配置

基于ip、端口、域名
在这里插入图片描述

静态资源压缩

静态资源压缩主要用于在静态资源的请求过程中,资源过于庞大,启用了静态资源压缩,性能将能够大大提升,这里主要关注下如何看静态资源压缩的配置

server{
   listen 1002;
   server_name 192.168.93.10;
   location /static {
       gzip on;
       gzip_http_version 1.1;
       gzip_comp_level 4;#压缩等级,数字越小压缩率越高,cpu消耗越大
       gzip_types text/plain application/javascript text/css image/png;#支持压缩的文件格式
       root /usr/nginx/html1;#配置了root以后,就是说访问的路径/url是在root配置的文件夹里面去找(root+uri)
       index index.html;
  }
}

gzip=on就开启静态资源压缩,off为关闭,开启过后大的静态资源比如html就会进行压缩。

状态页

状态页主要是开启一个端口可以监控nginx的状态信息,连接信息,处理信息,可以作为nginx的一个监控入口来使用

server {
    listen 1003;
    location / {
        stub_status on;#开启状态页功能
        access_log off;#关闭访客日志功能
    }
}
访问 localhost:1003页面显示:
Active connections: 2    #活动链接数
server accepts handled requests
 555 555 1024 
Reading: 0 Writing: 1 Waiting: 1

server: nginx启动后一共处理的请求数
accepts handled :nginx启动后创建的握手数
requests:nginx一共处理的请求数
reading:nginx读取到客户端的headers数量
writing:nginx响应给客户端的headers数量
Waiting:nginx处理完毕请求之后,等待下一次请求驻留的连接数(active-(Reading+Writing))

身份认证

身份认证主要用于在应用中的有些页面是需要进行授权认证的用户才能进行访问,不是系统的登录认证,是登录过后可能还需要用户进行认证的一些页面才能放开权限访问,比如像一些二次授权的访问控制,nginx这里也提供了一种认证授权的模式,就是需要使用到httpd-tools,需要先提前安装,yum install -y httpd-tools执行安装,安装完成过后就可以生成一个认证用户信息

htpasswd -bc /usr/nginx/security/auth.user bml 123456
其中bml是用户,密码是123456

将这些认证加入到一些访问页面,比如我这里看状态页,也就是nginx的监控信息,需要认证授权才能访问,配置如下:

server{
 listen 1003;
 server_name 192.168.93.10;
 location / {
  auth_basic "auth_access";
  auth_basic_user_file /usr/nginx/security/auth.user;
  stub_status on;
  access_log off;
 }
}

然后访问1003端口出现
在这里插入图片描述
输入密码过后:
在这里插入图片描述

location匹配

location表达式类型
如果直接写一个路径,则匹配该路径下的
~ 表示执行一个正则匹配,区分大小写
~* 表示执行一个正则匹配,不区分大小写
^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location。
= 进行普通字符精确匹配。也就是完全匹配。
优先级
等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
常规字符串匹配类型。按前缀匹配。
root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root的处理结果是:root路径+location路径
alias的处理结果是:使用alias路径替换location路径
alias是一个目录别名的定义,root则是最上层目录的定义。
还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无。

url重写

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如http://luban.com/a/we/index.jsp?id=1&u=str 只对/a/we/index.php重写。语法rewrite regex replacement [flag];
如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。
表明看rewrite和location功能有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。很多情况下rewrite也会写在location里,它们的执行顺序是:
执行server块的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误
rewrite 规则 定向路径 重写类型;
用在server和location模块,if模块

server {
    # 访问 /last.html 的时候,页面内容重写到 /index.html 中
    rewrite /last.html /index.html last;
    # 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配
    rewrite /break.html /index.html break;
    # 访问 /redirect.html 的时候,页面直接302定向到 /index.html中
    rewrite /redirect.html /index.html redirect;
    # 访问 /permanent.html 的时候,页面直接301定向到 /index.html中
    rewrite /permanent.html /index.html permanent;
    # 把 /html/*.html => /post/*.html ,301定向
    rewrite ^/html/(.+?).html$ /post/$1.html permanent;
    # 把 /search/key => /search.html?keyword=key
    rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;
}

规则:可以是字符串或者正则来表示想匹配的目标url
定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用$index来表示正则里的捕获分组
重写类型:
last :相当于Apache里德(L)标记,表示完成rewrite,浏览器地址栏URL地址不变
break;本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏URL地址不变
redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
last和break的区别
因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:
last一般写在server和if中,而break一般使用在location中
last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
break和last都能阻止继续执行后面的rewrite指令
在location里一旦返回break则直接生效并停止后续的匹配location

server {
    location / {
        rewrite /last/ /q.html last;
        rewrite /break/ /q.html break;
    }
    location = /q.html {
        return 400;
    }
}	

访问/last/时重写到/q.html,然后使用新的uri再匹配,正好匹配到locatoin = /q.html然后返回了400
访问/break时重写到/q.html,由于返回了break,则直接停止了

server {
    # 用 xxoo_admin 来掩饰 admin
    location / {
        # 使用break拿一旦匹配成功则忽略后续location
        rewrite /xxoo_admin /admin break;
    }
    # 访问真实地址直接报没权限
    location /admin {
        return 403;
    }
}

比如:

server{
  listen 1004;
  server_name 192.168.93.10;
  location / {
   rewrite /tmpadmin/demo /admin/demo  break;
    proxy_pass http://192.168.93.1:8100;
 }
 location /admin {
  return 403;
 }
}

然后访问/admin直接报403的错误
在这里插入图片描述
然后访问tmpadmin,就可以正常访问:
在这里插入图片描述

限流

nginx也是提供了限流方案的,因为目前的nginx或者大部分的后端应用都是依赖于阻塞式的IO,阻塞式的IO就是客户端根本不知道你服务端最大能够接受到多少个连接,能够处理多少请求,所以如果服务端只能同时处理100个请求,这个时候你发200个过来,服务器肯定会崩溃的,所以在nginx层面,也提供了一些限流的方案,一是控制速率,二是控制并发连接数。
控制速率
正常限流
漏桶算法(leaky bucket)
在 nginx.conf http 中添加限流配置:
格式:limit_req_zone key zone rate

http {
    limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=10r/s;
}
server {
    location / {
        limit_req zone=myRateLimit;
        proxy_pass http://my_upstream;
    }
}

key :定义限流对象,binary_remote_addr 是一种key,表示基于 remote_addr(客户端IP) 来做限流,binary_ 的目的是压缩内存占用量。
zone:定义共享内存区来存储访问信息, myRateLimit:10m 表示一个大小为10M,名字为myRateLimit的内存区域。1M能存储16000 IP地址的访问信息,10M可以存储16W IP地址访问信息。
rate 用于设置最大访问速率,rate=10r/s 表示每秒最多处理10个请求。Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续100毫秒内又有请求到达,将拒绝处理该请求。
突发限流
突然限流就是在比如已经达到了限流的条件过后,这个时候还有大量的过来,那么可以在原来限流的基础上再新开一定的请求,就类似于信用卡提额类似

server {
    location / {
        limit_req zone=myRateLimit burst=20 nodelay;
        proxy_pass http://my_upstream;
    }
}

burst表示在超过设定的处理速率后能额外处理的请求数。当 rate=10r/s 时,将1s拆成10份,即每100ms可处理1个请求。
此处,burst=20 ,若同时有21个请求到达,Nginx 会处理第一个请求,剩余20个请求将放入队列,然后每隔100ms从队列中获取一个请求进行处理。若请求数大于21,将拒绝处理多余的请求,直接返回503.
不过,单独使用 burst 参数并不实用。假设 burst=50 ,rate依然为10r/s,排队中的50个请求虽然每100ms会处理一个,但第50个请求却需要等待 50 * 100ms即 5s,这么长的处理时间自然难以接受。
因此,burst 往往结合 nodelay 一起使用。
nodelay 针对的是 burst 参数,burst=20 nodelay 表示这20个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=20 相当于缓存队列中占了20个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放。
这就达到了速率稳定,但突然流量也能正常处理的效果。
控制并发连接数

http{
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
}
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) 同时能处理并发连接的总数。
需要注意的是:只有当 request header 被后端server处理后,这个连接才进行计数。
设置白名单

http配置
geo $limit {
    default 1;
    10.0.0.0/8 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_key zone=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进行限流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值