Kong[nginx]-17 玩转rewrite(),动态返回图片资源


KONG专题目录


0x00 场景

一般我们在提供图片资源下载服务的时候 ,直接使用nginxalias 指令就可以很好的实现这个功能.

但是, 现在有这样的需求:

通过访问一个带参数的URL, 要求服务器能够动态返回相应的图片资源(比如有些参数值不存在的时候,使用默认值).
换句话说, 这样的URL, 可以直接写在htmlsrc标签内使用, 能够正常显示图片.

0x01 思路

对于这样的需求, 我们当然可以用万能的Spring Boot 去开发一个后端服务去搞.
但是, 作为一个酷爱折腾,而且对性能有极度要求的后端开发, 我们断然选择了kong插件的形式去解决这个问题.

  • 静态图片服务
    首先想到的就是服务端的重定向指令,
    那么首先我们先要有一套对外服务的静态图片请求服务,这个比较容易实现.

  • 插件逻辑

    • 解析请求路由和参数
    • 过滤或重写参数, 组合得到要重定向的路由
    • 重定向请求(向客户端返回图片)
0x02 静态资源访问服务

这里的配置方法, 完全参考nginx配置思路即可.

  • 添加 kong_nginx 的静态访问路由

kong中更新kong_nginx.conf方法不熟悉的同学,请翻看以前的文章,这里不(jiu)再(shi)赘(tai)述(lan).

cd /usr/local/share/lua/5.1/kong/templates
vim nginx_kong.lua

找到 location = /kong_error_handler 这一行, 在它的上面添加下面的配置:

        location /static/ {
                alias /opt/share/static/;
        }

修改完成后, 记得 kong restart

  • 复制图片文件夹
    把图片文件夹复制到/opt/share/static目录后, 完成配置.

图片目录

请求图片URL: http://aaa.com/static/T00001/en/desc.png

访问图片
0x03 插件编写

我们期待结果是, 请求http://aaa.com/get_image?key=T00001&lang=en&desc.png这样的URL也能返回上面的图片.

  • 背景调查
    因为我们要用到rewrite(),所以先去查看一下官方文档,
    可以了解到, 我们需要开发一个全局插件.
    那么, 我们必需在这个插件里, 过滤一下请求路由(因为每一个请求都会在这个插件里执行)
官方说明
  • 代码实现
    我们新建一个插件,命名为 image-request, 插件代码如下:
-- handler.lua
-- handler.lua
local BasePlugin   = require "kong.plugins.base_plugin"

local CCHandler    = BasePlugin:extend()

CCHandler.VERSION  = "1.0.0"
CCHandler.PRIORITY = 10

function CCHandler:rewrite(config)

    if kong.request.get_path() == '/get_image' then
        -- 取URL参数
        local key      = kong.request.get_query_arg('key') or '-'
        local lang     = kong.request.get_query_arg('lang') or 'en'
        local filename = kong.request.get_query_arg('filename') or 'desc.png'

        -- 读取插件配置参数
        local dic      = {}
        for _, v in ipairs(config.guide_settings) do
            local _key, _lang = string.match(v, "^([^:]+):(.*)$")
            dic[_key]         = _lang
        end
        
        -- 如果key不存在的话, 返回404
        local _lang = dic[key]
        if _lang == nil then
            return kong.response.exit(404, "404 not found",
                    {
                        ["Content-Type"] = "text/plain",
                    })
        end

        -- 读取多语言信息,如果配置项里不存在的话,使用默认值 : en
        if string.find(_lang, lang) == nil then
            lang = 'en'
        end

        -- 拼接字符串
        local _img_url = '/static/' .. key .. '/' .. lang .. '/' .. filename
        ngx.req.set_uri(_img_url, true)
    end
end

return CCHandler

看注释理解起来, 问题不大.
如果有需要的话, 可以把/get_image也写到插件配置里, 那样更灵活.

-- schema.lua
local typedefs     = require "kong.db.schema.typedefs"
-- 定义输入类型为 字符串 数组, 意为可以输入多个字符串

local colon_string_array = {
  type = "array",
  default = {},
  elements = { type = "string", match = "^[^:]+:.*$" },
}


return {
  name   = "image-request",
  fields = {
    { protocols = typedefs.protocols_http },
    { config = {
      type   = "record",
      fields = {
        -- 插件配置页
        { guide_settings = colon_string_array }
      },
    },
    },
  },
}

插件参数guide_settings用于配置已经支持的key和语言信息.

0x04 启用插件
  • 修改 /etc/kong/kong.conf
vim /etc/kong/kong.conf
### 找到 plugins 这一行,添加插件名称 image-request
plugins = bundled, image-request
### 重启kong
kong restart 
  • 配置插件
    添加全局插件 , 并配置参数 T00001:en,记得要按回车
添加插件
0x05 验证

这里是测试链接, 主要以key关键信息, 后面两个字段都有默认值.

0x06 小结

本文实现内容并不复杂, 笔者最开始天真的以为在access()下执行ngx.req.set_uri()操作应该就可以了, 然并卵.

最后还是查看了相关文档后, 才找到正确的方向.
看来, 各个生命周期做什么事情, 还是应该事先多了解一下比较好


KONG专题目录


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容

  • Kong 是 Mashape 开源的高性能高可用 API 网关和 API 管理服务层。它基于 OpenResty ...
    meng_philip123阅读 9,032评论 0 6
  • 配置加载 Kong的默认配置在 /etc/kong/kong.conf.default 。如果你通过一个官方的安装...
    DreamsonMa阅读 54,773评论 0 16
  • 有些人一辈子也吃不到苦,有些人一辈子也吃不到甜,也许这也就是命运吧,但是你要努力的改变一些命运,让苦变成甜。让甜变...
    天朗气清A阅读 349评论 0 0
  • 1、持久化 持久化分为RDB持久化和AOF,前者是生成快照,如果数据改动大时该持久化效率高;后者记录命令,数据量大...
    xuyouxin1阅读 840评论 0 1
  • 1.他 “晶晶?晶晶!” 当我再次睁眼,没有牛魔王,没有二当家那个猪头,连晶晶,你也不见了。 我踉跄着走出洞口,薄...
    归桦阅读 1,249评论 10 11