服务高可用保障:服务限流,Nginx实现服务限流

一、前言

1.1什么是限流?

限流存在于高可用服务中。
用于高可用的保护手段,主要包括:缓存,降级,限流
限流:只允许指定的事件进入系统,超过的部分将被拒绝服务,排队或者降级处理。

1.2为什么需要限流?

一:服务扛不住压力了
二:因为资源的稀缺或者处于安全防范的目的而采用的自我保护机制,保证有限的资源提供最大的服务能力,按照预期的流量提供服务 ,超过的部分将会拒绝服务,排队或者降级处理

二、按照限流算法分类

2.1.计数器(固定窗口计数器)

通用及最简单的算法,简单逻辑是维护一个固定时间的计数器,如果检测到单位时间过去则记为0,重新计数
在这里插入图片描述

存在的问题
1.没有应对突发的流量的能力:如100的qps,前100ms来了99个,后900ms只能处理一个
2.不准确,在一个窗口内后半段时间来了100个请求,以及在后一个窗口的前半段时间100个请求,等同于在一个窗口内出现了双倍的限流的流量!

2.2 漏铜算法

在这里插入图片描述

水:请求
桶:限流阈值大小
漏的水滴:固定速率,服务的处理速度
实现步骤:
1.将每个请求放入固定的大小的队列进行存储
2.以固定的速率向外流出请求,队列为空则停止流出
3.队列满了则拒绝服务

2.3令牌桶算法

在这里插入图片描述

为了保证网站在遭受流量攻击的时候,仍然能够保障正常用户的访问不受到影响,有必要对网站添加限流措施。通过简单的配置Nginx,可以帮助我们实现这一功能。
优点:令牌桶支持突发流量
因为桶中有多少令牌在等待,就允许有多少突发请求可以执行

实现步骤:
1.以恒定的速率向桶中增加令牌
2.如果令牌满了直接丢弃,如果有请求则获取令牌进行请求
3.如果桶空了,则拒绝执行

三、Nginx实现服务限流

实现服务限流的方式有很多种,下面我主要介绍的是Nginx实现,优点是不用频繁部署jar服务,减少代码编写。提高效率,短时间解决问题

Nginx支持通过以下维度,来对用户的请求进行限制:

  1. 控制访问频率
  2. 控制并发连接数
  3. 控制访问速率
  4. IP黑白名单

3.1超过访问频率就立即拒绝

对应Nginx模块:ngx_http_limit_req_module

# 限流设置,这只是设置流量限制和共享内存区域的参数,但实际上并不限制请求速率。具体的限制需要定义具体的url
limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=10r/s;
# 指定错误码
limit_req_status 429;
 
server {
    location /update_content {        
        proxy_pass http://192.168.211.1:18081;
    }
 
    location /read_content {
        # 使用限流配置
        limit_req zone=contentRateLimit;
        proxy_pass http://192.168.211.1:18081;
    }
}
  • binary_remote_addr:表示基于客户端IP做限流,使用二进制来表示IP地址;
  • zone:定义共享内存区来存储访问信息;
  • contentRateLimit:10m 表示一个大小为10M,名字为contentRateLimit的内存区域; 1M能存储8000个IP地址的访问信息(64位平台);
  • rate:用于设置最大访问速率,rate=10r/s 表示每秒最多处理10个请求。Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求;
  • limit_req_zone:只定义速度限制的相关参数,一般用于http块中,使其可以在多个相关server中使用;
  • limit_req:启用定义的限速参数;
    当存储空间耗尽的时候,如果需要记录新的值,那么就会通过LRU算法移除旧的变量来腾出空间,如果这样腾出来的空间还是不足以接纳新的记录值,那么nginx就会返回状态码503。此外,为了防止内存耗尽,nginx每次创建一个新记录值的时候就会清理掉两个60秒内没被使用过的旧记录值。
    (2) 支持处理突发流量
    超过流量不会立即被拒绝,允许加入一个队列,只有队列满了之后的请求才会被拒绝。如果有时正常流量突然增大,超出的请求将被拒绝,无法处理突发流量,就可以结合 burst 参数使用来解决该问题。

3.2支持处理突发流量

超过流量不会立即被拒绝,允许加入一个队列,只有队列满了之后的请求才会被拒绝。如果有时正常流量突然增大,超出的请求将被拒绝,无法处理突发流量,就可以结合 burst 参数使用来解决该问题。

# 限流设置,这只是设置流量限制和共享内存区域的参数,但实际上并不限制请求速率。具体的限制需要定义具体的url
limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=10r/s;
 
server {
    location /update_content {        
        proxy_pass http://192.168.211.1:18081;
    }
 
    location /read_content {
        # 使用限流配置
        limit_req zone=contentRateLimit burst=4 nodelay;
        proxy_pass http://192.168.211.1:18081;
    }
}
  • burst :表示在超过设定的处理速率后能额外处理的请求数。burst=4表示有4个请求到达,Nginx
    会处理第一个请求,剩余3个请求将放入队列,然后每隔100ms从队列中获取一个请求进行处理。若请求数大于4,将拒绝处理多余的请求,直接返回503。排队中的请求虽然每100ms会处理一个,但却需要等待
    较长的处理时间。所以burst 往往结合 nodelay 一起使用,以实现削峰填谷的效果;
  • nodelay :假设我们的流量是 2,1,4,0,2
    ,正常的请求会存在峰值和谷值,代表每秒的请求数。这样当流控为2r/s,burst=4
    nodelay时,在第3秒请求数为4时(峰值),仍然允许直接处理4个请求,但是后续的请求会被拦截,保证总流量不超过2r/s,因此,当第四秒请求数为0时,就起到了削峰填谷的作用。假设流量是2,1,4,4,4
    ,峰值持续的时间比较长,那么从第二个峰值开始,就会被真的流控,被拒绝或进行排队,这样即使被处理,也会延迟稍高!

3.3控制并发连接数

Nginx内置的limit_conn_zone和limit_conn指令,提供了通过限制ip连接数来控制流量的能力。

其中只有当服务器正在处理请求并且已经读取了整个请求头时,才会计算为有效连接。
对应Nginx模块:ngx_http_limit_conn_module
(1) 控制每个IP的连接数

limit_conn_zone $binary_remote_addr zone=perip:10m;
 
server {       
 
    location /brand {
        # 同一个地址只允许连接2次
        limit_conn perip 2;
        proxy_pass http://192.168.211.1:18081;
    }
     
}

limit_conn_zone $binary_remote_addr zone=perip:10m :表示根据用户的IP地址来进行限制,设置共享内存大小为10M。

limit_conn perip 2 :表示同一个地址只允许连接2次。

(2) 控制与服务器的连接总数

# 根据server_name来限制,存储内存大小10M
limit_conn_zone $server_name zone=perserver:10m;
 
server {
 
    listen 80;
    server_name xx.com;
      
    location / {
        # 限制与服务器的总连接数
        limit_conn perserver 100;
        root   html;
        index  index.html index.htm;
    }
}

limit_conn_zone $server_name zone=perserver:10m :表示根据用户访问的server_name来进行限制,设置共享内存大小为10M。

limit_conn perserver 100 :表示同一个server只允许连接100次。

3.4控制访问速率

设置http请求传输多少字节后开始限速。
对应Nginx模块:ngx_http_core_module

location /flv/ {
    limit_rate_after 500k;
    # 带宽限制,对单个连接限速
    limit_rate       50k;
}

limit_rate_after 500k :表示传输的前500k数据不限速,500k之后再进行限速。

limit_rate 50k :对单个连接限速为50k/s。如果一个客户端发起两个连接,就是50k * 2。

3.5黑白名单

配置固定IP为黑名单,访问时会返回403 Forbidden。
nginx 是按照自上而下的顺序进行匹配,匹配到一个就不往下继续了,如遇到 return 指令时 return 指令还是会生效。

server {
    listen 8080;
    server_name _;
 
    location / {
        allow 192.168.135.1;
        deny all;
        return 200 "$remote_addr 正常访问 3";
    }
}
# 屏蔽单个ip访问
deny IP;
# 允许单个ip访问
allow IP;
# 屏蔽所有ip访问
deny all;
# 允许所有ip访问
allow all;
# 屏蔽整个段即从123.0.0.1到123.255.255.254访问的命令
deny 123.0.0.0/8
# 屏蔽IP段即从123.45.0.1到123.45.255.254访问的命令
deny 124.45.0.0/16
# 屏蔽IP段即从123.45.6.1到123.45.6.254访问的命令
deny 123.45.6.0/24
 
# 也可以通过配置文件来配置
include blockip.conf;

动态黑白名单:也可以采用Lua+Redis实现,将黑名单存入到Redis缓存,每次执行请求时,通过lua脚本先获取用户IP,匹配IP是否属于黑名单,如果是,则不让请求,如果不是,则放行。

 /**
     * provide by zym
     * 0 error(s), 0 warning(s)
     */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/23009.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国内行业垂直型SaaS公司有哪些?发展前景如何?

01 国内行业垂直型SaaS公司有哪些? 根据艾瑞咨询测算,2021年中国企业级应用软件市场规模达到2592亿元,SaaS在其中占比达到28.1%。 在企业数字化转型的全景图中,SaaS扮演着应用场景层面的关键作用,往往是企业特定环节数…

ChatGPT系列学习(1)transformer基本原理讲解

文章目录 1. 简介1.1. 发展史 2. Transformer 整体结构3. 名词解释3.1. token 4. transformer输入4.1. 单词 Embedding4.2. 位置Embedding4.3. Transformer Embedding层实现 5. Attention结构5.1. 简介5.2. Self Attention(自注意力机制)5.2.1. 简介5.2.…

mysql 库的操作

文章目录 mysql 库的操作1. 创建数据库创建数据库案例 2. 字符集和校验规则查看系统默认的字符集合校验规则查看数据库支持的字符集查看数据库支持的字符集较验规则校验规则对数据库的影响 3. 操作数据库查看数据库显示创建语句修改数据库删除数据库查看数据库连接情况 mysql 库…

uniapp内使用 mescroll

前言 在使用uniapp开发项目的过程中,在很多场景里都需要下拉刷新和上拉加载,而 mescroll.js 则是一个非常精致的下拉刷新和上拉加载 js 框架。 官网地址:mescroll 介绍 mescroll.js 是在 H5端 运行的下拉刷新和上拉加载插件,时…

Leetcode 1679. K 和数对的最大数目 双指针法

https://leetcode.cn/problems/max-number-of-k-sum-pairs/ 给你一个整数数组 nums 和一个整数 k 。 每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。 返回你可以对数组执行的最大操作数。 示例 1: 输入&#xff1…

【云计算与虚拟化】第五章—— vCenter Server 5.5 的高级功能(三)

第五章—— vCenter Server 5.5 的高级功能(三) 1.使用vsphere client 登陆vcenter服务器,创建一个群集,名称为自己的学号,(截图) 2.针对该群集打开HA功能(截图) 3.接入控制策略选择…

使用Python复制某文件夹下子文件夹名为数据文件夹下的所有以DD开头的文件夹到桌面...

点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 楼阁玲珑五云起,其中绰约多仙子。 大家好,我是皮皮。 一、前言 前几天在Python最强王者群【魏哥】问了一个Python自动化办公处理…

单模光纤二维模场分布的MATLAB仿真

在上一篇文章中,我们介绍了单模光纤的一维模场分布,能看出沿着径向的光场分布情况,并分析能量的分布 这一篇中,我们绘制光纤横截面上的二维光场分布:代码如下: clear close all V 2.4000; U 1.6453; W …

Netty和Tomcat的区别、性能对比

文章目录 一、Netty和Tomcat有什么区别?二、为什么Netty受欢迎?三、Netty为什么并发高 ? 一、Netty和Tomcat有什么区别? Netty和Tomcat最大的区别就在于通信协议,Tomcat是基于Http协议的,他的实质是一个基…

代码随想录算法训练营day52 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组

代码随想录算法训练营day52 | 300.最长递增子序列,674. 最长连续递增序列,718. 最长重复子数组 300.最长递增子序列解法一:动态规划 674. 最长连续递增序列解法一:动态规划解法二:双指针法 718. 最长重复子数组解法一&…

SQL案例-高校信息管理系统实现要求

SQL案例-高校信息管理系统实现要求 (1) 建表 stuInfo(学生信息表) 字段名称数据类型说明stuName字符学生姓名,该列必填,要考虑姓氏可能是两个字的,如欧阳俊雄stuNo字符学号,该列必填,学号不能重复,且必须…

算法|1.二分及其扩展

算法|1.二分及其扩展 1、有序数组中找到num 题意:给定有序数组,在有序数组中找到指定数字,找到返回true,找不到返回false. 解题思路: 数组有序查找指定元素使用二分法L指针初始值设为0,R指针初始值设为…

IOC初始化 IOC启动阶段 (Spring容器的启动流程)

[toc](IOC初始化 IOC启动阶段 (Spring容器的启动流程)) IOC初始化 IOC启动阶段 (Spring容器的启动流程) Resource定位过程:这个过程是指定位BeanDefinition的资源,也就是配置文件(如xml)的位置,并将其封装成Resource对…

拥抱新时代的Java

原文链接 拥抱新时代的Java Java作为面向对象编程的王牌语言,曾经风靡一时,在Web领域是绝对的老大。随着时间的推移,一些新的编程范式不断的涌现,如函数式编程,响应式编程,以及对函数的全力支持&#xff0…

node.js+vue房屋租赁管理系统z0g8w

本系统主要包括以下功能模块:租户、出租人、房源信息、预约看房、合同信息等模块。 其中设计的主要功能如下: (1)用户的注册和登录本系统,登录到系统的首页。 (2)用户可以发布自己的房源信息…

强化学习:值迭代和策略迭代

值迭代 通过上一章的学习,我们知道了贝尔曼最优方程的求解实际上分两部分,一是给定一个初始值 v k v_k vk​ 找到最优策略 π k 1 π_{k1} πk1​ ,二是更新 v k 1 v_{k1} vk1​   下面,我们将详细剖析这个算法&#xff0…

RabbitMQ

处理问题 服务异步调用 两个服务调用时,我们可以通过传统的HTTP方式,让服务A直接去调用服务B的接口,但是这种方式是同步的方式,虽然可以采用SpringBoot提供的Async注解实现异步调用,但是这种方式无法确保请求一定回访…

从Redisson的RedissonSemaphore引发的信号量实际含义的思考

Semaphore到底该如何使用 事情的起因是最近在看redisson的源码&#xff0c;刚好看到了RedissonSemaphore的acquire/release实现。 public RFuture<Void> releaseAsync(int permits) {if (permits < 0) {throw new IllegalArgumentException("Permits amount ca…

ThingsBoard教程(五十):规则节点解析 创建关系节点Create Relation Node,删除关系节点 Delete Relation Node

创建关系节点 Create Relation Node Since TB Version 2.2.1 根据类型和方向,从所选实体创建到消息发起方的关系。 以下消息发起方类型被允许:资产、设备、实体视图、客户、租、仪表板。 通过元数据键模式查找目标实体,然后在源实体和目标实体之间创建关系。 如果选择的…

ASP.NET Core 使用Filter和Redis实现接口防重

背景 日常开发中&#xff0c;经常需要对一些响应不是很快的关键业务接口增加防重功能&#xff0c;即短时间内收到的多个相同的请求&#xff0c;只处理一个&#xff0c;其余不处理&#xff0c;避免产生脏数据。 这和幂等性&#xff08;idempotency&#xff09;稍微有点区别&am…
最新文章