OpenResty使用漏桶算法实现限流

前言

其它项目组需要调用接口,添加接口限流,防止项目被狂掉宕机。生产用了openresty,所以在openresty上添加按接口限流,同时,需按照不同接口有不同的限流规则,使用openresty中内置的漏桶算法方式限流。

漏桶算法

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

通俗解释。

比如设置rate为100,burst为50,即允许1s放进来100个请求,桶大小为50。

那么1s内:

第1-100个请求会访问成功。

第101-150个请求会进入burst。

第150个请求之后的会直接失败返回。

openresty的说明文档:https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/req.md

限流配置

使用OpenResty的漏桶算法进行限流配置,不同接口配置不同的标准,所以测试了两个接口test1和test2

主要分两步:

  1. 添加限流使用的lua脚本
  2. 在反向代理中配置限流的lua脚本

ps: 因为大多数使用情况还是会反向代理,所以直接在反向代理中配置lua

添加lua脚本01和02的区别,仅限于漏桶的参数配置不同

添加lua脚本01

lualib\utils 路径下创建lua脚本

lua脚本内容:

-- utils/limit_req_leaky_bucket.lua
local limit_req = require "resty.limit.req"-- rate:  5/s即为每秒3个请求,增加桶容量为1/s,超过5/s不到(5+1)/s的delay,排队等候
local lim, err = limit_req.new("my_limit_req_store1", 5, 1)
if not lim thenngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)return ngx.exit(500)
endlocal _M = {}function _M.incoming()local key = ngx.var.binary_remote_addrlocal delay, err = lim:incoming(key, true)if not delay thenif err == "rejected" thenreturn ngx.exit(503) -- 超过的请求直接返回503endngx.log(ngx.ERR, "failed to limit req: ", err)return ngx.exit(500)end-- 此方法返回,当前请求需要delay秒后才会被处理,和他前面对请求数-- 所以此处对桶中请求进行延时处理,让其排队等待,就是应用了漏桶算法-- 此处也是与令牌桶的主要区别if delay >= 0.001 thenngx.sleep(delay)end
endreturn _M

添加lua脚本02

lualib\utils 路径下创建lua脚本

lua脚本内容:

-- utils/limit_req_leaky_bucket.lua
local limit_req = require "resty.limit.req"-- rate:  3/s即为每秒3个请求,增加桶容量为1/s,超过3/s不到(3+1)/s的delay,排队等候
local lim, err = limit_req.new("my_limit_req_store2", 3, 1)
if not lim thenngx.log(ngx.ERR, "failed to instantiate a resty.limit.req object: ", err)return ngx.exit(500)
endlocal _M = {}function _M.incoming()local key = ngx.var.binary_remote_addrlocal delay, err = lim:incoming(key, true)if not delay thenif err == "rejected" thenreturn ngx.exit(503) -- 超过的请求直接返回503endngx.log(ngx.ERR, "failed to limit req: ", err)return ngx.exit(500)end-- 此方法返回,当前请求需要delay秒后才会被处理,和他前面对请求数-- 所以此处对桶中请求进行延时处理,让其排队等待,就是应用了漏桶算法-- 此处也是与令牌桶的主要区别if delay >= 0.001 thenngx.sleep(delay)end
endreturn _M

在nginx.conf中添加配置文件

# --- 限流 ---
worker_processes  1;events {worker_connections  1024;
}
# ------------http {# --- 反向代理 ---include       /etc/nginx/conf.d/*.conf;# -----------------------include       mime.types;default_type  application/octet-stream;sendfile        on;#keepalive_timeout  0;keepalive_timeout  65;# --- 限流 ---lua_code_cache on;# 共享内存lua_shared_dict my_limit_req_store1 100M;lua_shared_dict my_limit_req_store2 100M;# -----------# --- 反向代理 ---upstream backend_server {server 127.0.0.1:8080;}# -----------------------server {listen       80;server_name  localhost;#charset koi8-r;#access_log  logs/host.access.log  main;location / {root   html;index  index.html index.htm;}location /test1 {# --- 限流 ---access_by_lua_block {local limit_count = require "utils.limit_req_leaky_bucket1"-- 对于内部重定向或子请求,不进行限制。因为这些并不是真正对外的请求。if ngx.req.is_internal() thenreturnendlimit_count.incoming()}# ------------# --- 反向代理 ---# 如果内容源是反向代理proxy_pass http://backend_server;proxy_set_header Host $host;proxy_redirect off;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_connect_timeout 60;proxy_read_timeout 600;proxy_send_timeout 600;# -----------------------}location /test2 {# --- 限流 ---access_by_lua_block {local limit_count = require "utils.limit_req_leaky_bucket2"-- 对于内部重定向或子请求,不进行限制。因为这些并不是真正对外的请求。if ngx.req.is_internal() thenreturnendlimit_count.incoming()}# ------------# --- 反向代理 ---# 如果内容源是反向代理proxy_pass http://backend_server;proxy_set_header Host $host;proxy_redirect off;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_connect_timeout 60;proxy_read_timeout 600;proxy_send_timeout 600;# -----------------------}}}

参考

http://www.guanshanw.com/post/67951.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

epoll的并发服务器(TCP服务器与客户端通信)

服务器&#xff1a; #include<myhead.h> #define IP "192.168.250.100" #define PORT 8888 /* typedef union epoll_data {void *ptr;int fd;uint32_t u32;uint64_t u64; } epoll_data_t;struct epoll_event {uint32_t events; …

计算机视觉与深度学习-图像分割-视觉识别任务02-目标检测-【北邮鲁鹏】

目录标题 参考目标检测定义深度学习对目标检测的作用单目标检测多任务框架多任务损失预训练模型姿态估计 多目标检测问题滑动窗口&#xff08;Sliding Window&#xff09;滑动窗口缺点 AdaBoost&#xff08;Adaptive Boosting&#xff09;参考 区域建议 selective search 思想慢…

Spring Cloud Eureka:服务注册与发现

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Spring Cloud Eureka&#xff1a;服务注册与发现 Spring Cloud Eureka是Spring Cloud生态系统中的一个组件&#xff0c;它是用于实现服务注册与发现的服务治理组件。在…

pytorch迁移学习训练图像分类

pytorch迁移学习训练图像分类 一、环境配置二、迁移学习关键代码三、完整代码四、结果对比 代码和图片等资源均来源于哔哩哔哩up主&#xff1a;同济子豪兄 讲解视频&#xff1a;Pytorch迁移学习训练自己的图像分类模型 一、环境配置 1&#xff0c;安装所需的包 pip install …

Leetcode算法入门与数组丨5. 数组二分查找

文章目录 1 二分查找算法2 二分查找细节3 二分查找两种思路3.1 直接法3.2 排除法 1 二分查找算法 二分查找算法是一种常用的查找算法&#xff0c;也被称为折半查找算法。它适用于有序数组的查找&#xff0c;并通过将待查找区间不断缩小一半的方式来快速定位目标值。 算法思想…

【ArcGIS】基本概念-矢量空间分析

栅格数据与矢量数据 1.1 栅格数据 栅格图是一个规则的阵列&#xff0c;包含着一定数量的像元或者栅格 常用的栅格图格式有&#xff1a;tif&#xff0c;png&#xff0c;jpeg/jpg等 1.2 矢量数据 矢量图是由一组描述点、线、面&#xff0c;以及它们的色彩、位置的数据&#x…

堆内存与栈内存

文章目录 1. 栈内存2. 堆内存3. 区别和联系参考资料 1. 栈内存 栈内存是为线程留出的临时空间 每个线程都有一个固定大小的栈空间&#xff0c;而且栈空间存储的数据只能由当前线程访问&#xff0c;所以它是线程安全的。栈空间的分配和回收是由系统来做的&#xff0c;我们不需…

如何玩转CSDN AI工具集

前言 人工智能生成内容&#xff08;AIGC&#xff09;是当下最具有前景的技术领域之一。AI能够以惊人的速度和准确度生成各种类型的内容&#xff0c;完成文章翻译、代码生成、AI对话、插图创作等工作&#xff0c;带来了许多令人兴奋的机遇。 本文将介绍CSDN AI工具集的基本使用…

「大数据-0」虚拟机VMware安装、配置、使用、创建虚拟机集群教程

目录 一、下载VMware Wworkstation Pro 16 二、安装VMware Wworkstation Pro 16 三、检查与设置VMware的网卡 1. 检查 2. 设置VMware网段 四、在VMware上安装Linux虚拟机 五、对安装好的虚拟机进行设置 1. 打开设置 2. 设置中文 3. 修改字体大小 4. 修改终端字体大小 5. 关闭虚…

pip pip3安装库时都指向python2的库

当在python3的环境下使用pip3安装库时&#xff0c;发现居然都指向了python2的库 pip -V pip3 -V安装命令更改为&#xff1a; python3 -m pip install <package>

【操作系统笔记】内存寻址

物理寻址 主存&#xff08;内存&#xff09; 计算机主存也可以称为物理内存&#xff0c;内存可以看成由若干个连续字节大小的单元组成的数组每个字节都有一个唯一的物理地址&#xff08;Physical Address&#xff09;CPU访问内存前&#xff0c;先拿到内存地址&#xff0c;然后…

【数据结构】二叉树的链式实现及遍历

文章目录 一、二叉树的遍历1、前序遍历2、中序遍历3、后序遍历4、层序遍历 二、二叉树结点个数及高度1、二叉树节点个数2、二叉树叶子节点个数3、二叉树第k层节点个数4、二叉树查找值为x的节点 三、二叉树创建及销毁1、通过前序遍历数组创建二叉树2、二叉树的销毁3、判断是否为…

Pytest单元测试框架 —— Pytest+Allure+Jenkins的应用

一、简介 pytestallurejenkins进行接口测试、生成测试报告、结合jenkins进行集成。 pytest是python的一种单元测试框架&#xff0c;与python自带的unittest测试框架类似&#xff0c;但是比unittest框架使用起来更简洁&#xff0c;效率更高 allure-pytest是python的一个第三方…

IMX6ULL移植篇-Linux内核源码文件表

一. Linux内核源码目录 我们在分析 Linux 之前&#xff0c;一定要先在 Ubuntu 中编译一下 Linux &#xff0c;因为编译过程会生成一些文件&#xff0c;而生成的这些恰恰是分析 Linux 不可或缺的文件。 二. Linux内核源码重要文件含义 编译后的 Linux内核源码重要的文件…

9.20(复习9.19,9.17,9.13)

1.混合分片式水平分片&#xff0c;垂直分片和导出分片的混合 2.关联挖掘是用于发现数据库中数据间的关联习惯 3.提取游标&#xff1a; FETCH ABSOLUTE 4.修改触发器 ALTER TRIGGER 4.无共享结构被认为是支持并行数据库系统最好并行结构 5.数据库镜像分为 高可用操作模式…

修改接口,字段的内容允许清空,避免歧义,参数校验:@NotNull

1. 问题描述 修改接口&#xff0c;字段的内容允许清空&#xff0c;是否应该做参数校验&#xff1f;如何做参数校验&#xff1f; 2. 说明 2.1. 需要对字段进行校验。 因为不校验&#xff0c;字段可能不传&#xff0c;或者字段的值为null&#xff1b;这样无法判断出&#xff…

【Linux基础】第27讲 Linux 查找和过滤命令(二)——grep命令

Grep命令 grep是根据文件的内容进行查找&#xff0c;会对文件的每一行按照给定的模式&#xff08;patter&#xff09;进行匹配查找 基本格式&#xff1a; grep [options]范围 [options] 主要参数 -c: 只输出匹配行的计数 -i : 不区分大小写 -n: 显示匹配行及行号 -w: 显示整个…

[Linux入门]---文本编辑器vim使用

文章目录 1.Linux编辑器-vim使用2.vim的基本概念4.vim正常模式命令集从正常模式进入插入模式从插入模式转换为命令模式移动光标删除文字复制替换撤销更改跳至指定行 5.vim末行模式命令集5.总结 1.Linux编辑器-vim使用 vi/vim作为Linux开发工具之一&#xff0c;从它的键盘操作图…

驱动开发练习,platform实现如下功能

实验要求 驱动代码 #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/mod_devicetable.h> #include <linux/of_gpio.h> #include <linux/unistd.h> #include <linux/interrupt…

PDCA循环

目录 1.认识PDCA&#xff1a; 2.PDCA循环的经典案例 3.PDCA的四个阶段和八个步骤 4.PDCA循环的优缺点&#xff1a; 5.案例 6.其他作用 1.认识PDCA&#xff1a; PDCA循环最早由美国质量统计控制之父Shewhat&#xff08;休哈特&#xff09;提出的PDS&#xff08;Plan Do Se…