美文网首页API网关Kong实践笔记
Kong[nginx]-17 玩转rewrite(),动态返回图

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

作者: 国服最坑开发 | 来源:发表于2019-08-22 16:22 被阅读40次

    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专题目录


    相关文章

      网友评论

        本文标题:Kong[nginx]-17 玩转rewrite(),动态返回图

        本文链接:https://www.haomeiwen.com/subject/ejinsctx.html