关于老板让我用 Openresty 实现的各种奇怪需求以及实现
本文主要介绍最近整理的用Openresty处理的一些需求或功能,当然这都是领导时不时给我提出来需求,有些需求个人感觉还是怪怪的,不过领导的话不能不听不是?
关于Openresty网上有很多介绍,他的普通用法和Nginx几乎一样没什么特别的。高级功能的话,Openresty比Nginx支持更多的模块,还支持Lua、JavaScript作为脚本语言实现更高级的功能。
需求一、URL 重写
这个需求还算比较常见,就是把一个 url 转换成另一种形式,举个例子:
领导:你来把
https://www.example.com/article/xxxxx这个 url 给我转后端的https://www.example.com/api/article/xxxxx一个接口上。我:为啥不直接请求后端接口?
领导:
/api/一看就是后端接口,要让用户看起来像是直接访问一个页面。
这个小需求可以直接用rewrite实现,先看下rewrite的用法:
rewrite
其中最后一个参数:
last: 表示在匹配完本条规则后还会继续向下找其他 location;break:表示匹配完本条规则后就直接返回;redirect:会返回 302 临时重定向,地址栏的地址会发生变化,爬虫不会更新 url。permanent:会返回 301 永久重定向,地址栏的地址会发生变化,爬虫会更新 url。
需求实现
我只要拿到 uri,因为前缀是一样的,所以只需要把 uri 后面的 xxxxx 解析出来就好了,rewrite之后,直接break。直接在server块里加上下面这块代码,轻轻松松实现。
需求二、URL 重写+参数名转换
这个需求,跟上一个基本类型,只是多了一个参数转变的过程。
领导:你来把
https://www.example.com/article/xxxxx?id=yyyyy这个 url 给我转后端的https://www.example.com/api/article/xxxxx一个接口上,然后把 id 这个参数给我变成articleId。我:直接用
articleId不行吗?领导:不行。
好吧,继续干活,这个需求可以分为两步,第一步把url用rewrite重写和上面的一样,第二步把参数换一个名字。
参数获取
在 nginx 中可以使用$arg_XXX来获取请求的参数,例如https://www.example.com/article/xxxxx?id=yyyyy这个请求,在 nginx 中可以直接使用$arg_id获取id这个参数。
需求实现
知道怎么拿到参数后,实现就简单了,在第一示例的代码基础上改改就可以了。
需求三、域名过滤
这个需求是说,服务器接收好多请求,这些请求有不同的域名,要过滤需要的域名请求。
领导:咱们目前的服务器是别的组不用的,现在还有其他域名请求会进来,你判断下如果是咱们的域名就继续执行,如果不是咱们的,直接返回 404。
我:哦。
if AND OR 判断
这个需求理解是如果是A域名或者是B域名,请求继续,如果都不是则返回 404,但 nginx 虽然支持if判断,但是并不支持AND、 OR这样的操作,只能换一种方式实现。
实现思路为:我设置一个字符串,如果不是A域名我追加一个字符,如果不是B域名我再追加一个字符,如果这个字符串为等于一个值那么就返回 404。
需求实现
刚才已经分析完了,直接上代码吧,在server块里,加上下面这个代码即可。
需求四、配置 CORS 指定 Origin
这个需求是跨域设置,不能设置为*,只允许特定的域名请求,添加信任域名。
领导:给咱们网站接口设置下允许哪些域名可以访问。
我:你后端不能做吗?
领导:后端还不得写代码吗。
我:。。。。。。
map 指令
这个map的含义简单理解为,map匹配一个字符串作为key,按照映射关系把value的值赋值给$variable这个变量。
需求实现
既然不能用*设置允许所有跨域访问,只能定义一个白名单了,最终实现如下:
需求五、参数值转换
这天领导又给我来了个震惊我的需求:把一个请求的参数值按照一定的规则动态换成数据库里的另一个值。
领导:你看这个
url,https://www.example.com/api/user/info?openId=xxxx,在 Openresty 中把这个 openId 给我换成数据库里的主键 id,然后用 id 参数传给我,就是变为https://www.example.com/api/user/info?id=yyyy。我:你没开玩笑?
领导:我像在开玩笑吗?下午给我。
解决思路
既然没开玩笑,那就想办法呗。用Openresty连数据库?额,不太好。
从官网找了找,也没有找到好办法,那只能写个脚本了。
先判断是这个url,先内部发送个请求根据openId查询对应id,再把id拼接到url继续处理后续逻辑。
需求实现
先写个lua脚本,从脚本中根据openId查询出对应id是多少,然后再把 id 参数拼接上,重新请求接口。
相当于中间经过了一层中转,因为是服务内部请求,所以性能影响不是很大,来看下代码实现。
lua 脚本 user_api.lua
openresty配置如下,需要加上access_by_lua_file,对应的值为 lua 脚本的路径。
后记
这些都是领导提出的一些需求,你以为就这些吗?不不不,这只是冰山一角,后续会再介绍其他需求,以及解决方案。










评论