Openresty实现访问限流

基本概念 Nginx:高性能、高并发的Web服务器,拥有丰富的第三方模块。 Lua:一种轻量级、可嵌入式的脚本语言。 Ngx_lua:Nginx的一个模块,将Lua嵌入到Nginx中,这样就可以使用Lua编写应用脚本,部署到Nginx中运行,即Nginx变成了一个Web容器,这样开发人员就可以使用Lua语言开发高性能Web应用了。 引用官网的一个描述: OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。 应用场景 在 Lua 中混合处理不同 Nginx 模块输出(proxy, drizzle, postgres, Redis, memcached 等)。 在请求真正到达上游服务之前,Lua 中处理复杂的准入控制和安全检查。 比较随意的控制应答头(通过 Lua)。 从外部存储中获取后端信息,并用这些信息来实时选择哪一个后端来完成业务访问。 在内容 handler 中随意编写复杂的 web 应用,同步编写异步访问后端数据库和其他存储。 在 rewrite 阶段,通过 Lua 完成非常复杂的处理。 在 Nginx 子查询、location 调用中,通过 Lua 实现高级缓存机制。 对外暴露强劲的 Lua 语言,允许使用各种 Nginx 模块,自由拼合没有任何限制。该模块的脚本有充分的灵活性,同时提供的性能水平与本地 C 语言程序无论是在 CPU 时间方面以及内存占用差距非常小。所有这些都要求 LuaJIT 2.x 是启用的。其他脚本语言实现通常很难满足这一性能水平。 LuaNginxModule的执行阶段 set_by_lua*: 流程分支处理判断变量初始化 rewrite_by_lua*: 转发、重定向、缓存等功能(例如特定请求代理到外网) access_by_lua*: IP 准入、接口权限等情况集中处理(例如配合 iptable 完成简单防火墙) content_by_lua*: 内容生成 header_filter_by_lua*: 响应头部过滤处理(例如添加头部信息) body_filter_by_lua*: 响应体过滤处理(例如完成应答内容统一成大写) log_by_lua*: 会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其他机器) 限流的实现 由于近期工作中所负责的项目是开发App和一个前后端分离的管理系统的数据接口(统一采用jwt作为身份认证方式),且第一期已经接近尾声,因此除了做一些php代码层面的缓存优化之外,想到了需要学习一下除了bloomfilter之外的防止缓存穿透的办法(直接在web服务器层面通过redis动态限制访问频率,优点,性能损耗小,全程没有php参与),碰巧网上看到了Openresty,又是基于nginx(熟悉的配方),又能解决当下遇到的问题(神奇的味道),于是经过了几天的学习,也参考了一些其他博客中类似的实现,现记录下本人目前动态限流的实现过程 ...

March 2, 2019 · 7 min · 1477 words