一种轻量的openresty路由设计
在使用openresty开发接口的过程会发现一个问题,那就是接口的地址问题怎么解决,最好一个接口地址对应一个lua文件,也可以在nginx.conf 配置中使用content_by_lua 来编写接口逻辑,显然后者并不合适团队开发,为了解决这个问题,所以出现了很多类似的框架,一个比较好用的就是lusty框架,他可以将url中的某段值自动定义成变量,但是耦合性有点高,当多个接口站点部署在同一个nginx上时,你只能通过修改lusty的目录结构和app.lua文件,显然这不是我想要的结果,在网上找到一段很犀利的ngx配置,简单粗暴,但非常有效。
但出于安全性考虑,决定给访问的接口地址加个白名单功能,不在白名单的地址不允许访问。
将白名单功能抽象成一个app_route.lua文件,在初始化的时候需要载入一个白名单列表,具体的ngx配置如下:
这里加载了一个对应目录的route_config.lua,由于这个config文件内容较小,所以我把内容直接列了出来:
--白名单列表
local whitelist = {
'test1',
'user/login',
'user/register'
}
--路由重写列表
local rewritelist = {
['user/([-_a-zA-Z0-9]+)/login'] = 'user/login',
['user/([a-zA-Z0-9]+)/register'] = 'user/register'
}
return {
whitelist = whitelist,
rewritelist = rewritelist
}
然后在content_by_lua_file 前面加这么一句代码:
你会发现白名单功能就这么完成了,而且多次测试后发现单纯的路由查找功能会比lusty快一倍以上。
当然也支持简单的路由重定向功能,本文只是单纯的技术分享,如果你有更好的建议也可以单独讨论。
文本是原创作品,转载记得写明出处
app_route.lua
local _M = { _VERSION = '0.1' }
local mt = { __index = _M}
local tinsert = table.insert
local tconcat = table.concat
local tonumber = tonumber
local function uritoken(uri)
local ret = {}
for token in uri:gmatch("[^/.]+") do
tinsert(ret,token)
end
return ret
end function _M.new(self,rconfig)
local tab = {}
local routeMap = require(rconfig)
local route_data = {}
local whitelist = routeMap.whitelist
for i=,#whitelist do
local ret = uritoken(whitelist[i])
if #ret > then
tinsert(route_data,tconcat({'^',tconcat(ret,'/'),'$'}))
end
end
local rewritelist = routeMap.rewritelist
local x =
local rewrite_data = {}
local rewrite_urls = {}
for k,v in pairs(rewritelist) do
tinsert(rewrite_data,tconcat({'^(?<z',x,'z>',k,')$'}))
tinsert(rewrite_urls,v)
x = x +
end
tab.rewrite_urls = rewrite_urls
tab.rewrite_pattern = tconcat(rewrite_data,'|')
tab.route_pattern = tconcat(route_data,'|')
return setmetatable(tab, mt)
end function _M.route_verify(self)
local uri = ngx.var.api_path
local ret = uritoken(uri)
uri = tconcat(ret,'/')
ngx.var.api_path = uri
local m = ngx.re.match(uri,self.route_pattern)
if m == nil then
m = ngx.re.match(uri,self.rewrite_pattern)
if m == nil then
ngx.exit()
else
local locant = ngx.re.match(next(m,#m), "^z(\\d+)z")
ngx.var.api_path = self.rewrite_urls[tonumber(locant[])]
end
end
end
return _M
一种轻量的openresty路由设计的更多相关文章
- flutter最简单轻量便捷的路由管理方案NavRouter
大家好,我是CrazyQ1,今天给大家推荐一个路由管理方案,用的非常不错的,叫nav_router. 项目地址是:https://github.com/fluttercandies/nav_route ...
- 实战ELK(4)Metricbeat 轻量型指标采集器
一.介绍 用于从系统和服务收集指标.从 CPU 到内存,从 Redis 到 Nginx,Metricbeat 能够以一种轻量型的方式,输送各种系统和服务统计数据. 1.系统级监控,更简洁(轻量型指标采 ...
- Metricbeat 轻量型指标采集器
一.介绍 用于从系统和服务收集指标.从 CPU 到内存,从 Redis 到 Nginx,Metricbeat 能够以一种轻量型的方式,输送各种系统和服务统计数据. 1.系统级监控,更简洁(轻量型指标采 ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案(续)
本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...
- 动手打造轻量web服务器(二)路由
tomcat启动慢?自己动手打造轻量web服务器(一) 上篇讲了怎么做一个最简单的web服务器,这篇就是在上篇加上URL路由功能(什么是路由?) 首先,根据http获得请求行 val scanner ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案
简单,是因为只有一个类 轻量,是因为整个类代码只有300行 灵活,是因为扩展方式只需要继承重写某个方法即可 补充:修正无法处理可空值类型的bug 首先我将这个类称之为JsonBuilder,我希望它以 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<上篇>
工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...
- Bourbon – 简单轻量的 Sass 混入(Mixins)库
Bourbon 是一个简单易用的 Sass 混入(Mixin)库,无需配置.该混入包含用于支持所有现代浏览器的 CSS3 属性前缀.前缀需要确保在旧的浏览器支持优雅降级.Bourbon 使用 SCSS ...
- Cardinal:一个用于移动项目开发的轻量 CSS 框架
Cardinal 是一个适用于移动项目的 CSS 框架,包含很多有用的默认样式.矢量字体.可重用的模块以及一个简单的响应式模块系统.Cardinal 提供了一种在多种移动设备上实现可伸缩的字体和布局的 ...
随机推荐
- java-常用快捷键
alt+/:代码提示 ctrl+/:代码提示 ctrl+1:快速生成impl代码
- MFC程序实现给对话框加入�背景图片
1.插入一个Bitmap的资源图片,如果资源名称为:IDC_BITMAP1 2.在CXXXDialog::OnPaint()中实现: void CMyDialogDlg::OnPaint() { if ...
- 【Leetcode】Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- QuaZip实现多文件打包
项目需求: 在Goldenfarm客户端中当用户选择了本地场景文件,并进行本地场景文件分析后会产生分析结果,分析结果主要包括:贴图纹理.可渲染层等,其中贴图纹理指出了在场景文件中使用到的贴图或其它文件 ...
- WCF - 消息
SOAP SOAP是Simple Object Access Protocol(简单对象访问协议)的简称 而如今SOAP已经成为了符合W3C制定的SOAP规范的消息 允许您使用 XML 在通过低层 I ...
- windows 进程间通讯方法
Windows平台为我们提供了多种进程间通信的机制,主要包括:注册表方式.共享文件方式.共享内存方式.共享数据段.映射文件方式.管道方式. 剪贴板方式.消息方式.其中注册表方式需要增加注册表表项,而注 ...
- WPF加载Winform窗体时 报错:子控件不能为顶级窗体
一.wpf项目中引用WindowsFormsIntegration和System.Windows.Forms 二.Form1.Designer.cs 的 partial class Form1 设置为 ...
- Oracle笔记-表的管理
3.1创建和管理表在Oracle表中使用的emp,dept,sal都是系统内建好的表,那么在SQL语法中同样支持了表的创建语句,要想创建表,则应先了解下Oracle中最常用的几种数据类型3.1.1常用 ...
- Bash中的$符号
脚本名称:$0 PID:$$ 参数个数:$# 脚本返回值:$? 第x个参数:$x 第10个以上的参数加大括号:${10} 所有参数:$@ #!/bin/bash echo "The prog ...
- Mybatis高级应用
Mybatis是一个半自动的框架.相对于hibernate全自动模式,mybatis为开发人员提供了更加灵活的对sql语句操作的控制能力,有利于dba对相关的sql操作进行优化,同时也方便开发者构建复 ...