lua-resty-shdict-server

一个兼容 HTTP 和 Redis 协议的接口,用于调试 ngx.shared API

$ opm get fffonion/lua-resty-shdict-server

名称

lua-resty-shdict-server - 一个兼容 HTTP 和 Redis 协议的接口,用于调试 ngx.shared API

描述

这是一个库,它提供了一个兼容 HTTP 和 Redis 协议的接口,用于调试 ngx.shared.DICT API。

它也可以用作模拟 Redis 服务器(WIP)。

状态

实验性。

概要

目前,在 httpstream 子系统中定义的共享字典彼此不共享,因此我们需要两组配置来调试任一子系统。尽管如此,该模块提供了类似的 API,可以在两个子系统中使用。

http

    lua_shared_dict dogs 10m;
    
    server {
        listen 80;
        
        location =/cli {
            content_by_lua_block {
                require "resty.core"
                local srv = require("resty.shdict.server")
                local s = srv:new("foobar", nil)
                s:serve()
            }
        }
    }

这将设置一个简单的 HTTP 服务器。使用任何 http 客户端(如 curl)向我们配置的位置发出 http 请求。例如

    $ curl "http://host/cli?dict=dogs&cmd=set%20dog%20wow&password=foobar"
    OK
    
    $ curl "http://host/cli?dict=dogs&cmd=get%20dog&password=foobar"
    "wow"

stream

    lua_shared_dict dogs 10m;
    
    server {
        listen 127.0.0.1:18001;
        content_by_lua_block {
            require "resty.core.shdict"
            local srv = require("resty.shdict.server")
            local s = srv:new("foobar", nil)
            s:serve()
        }
    }

这将设置一个简单的 TCP 服务器。使用 telnet 或等效工具进行交互式连接。例如

    $ telnet 127.0.0.1 18001
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    SELECT dogs
    ERR authentication required
    AUTH foobar
    OK
    SELECT dogs
    OK
    SET dog wow
    OK
    GET dog
    "wow"

它还支持 Redis RESP 协议

    $ redis-cli -h 127.0.0.1 -p 18001
    127.0.0.1:18001> get dogs
    (error) ERR authentication required
    127.0.0.1:18001> auth foobar
    OK
    127.0.0.1:18001> set dog wow
    (error) ERR no shdict selected
    127.0.0.1:18001> select dogs
    OK
    127.0.0.1:18001> set dog wow
    OK
    127.0.0.1:18001> get dog
    wow

API

shdict.server:new(password, shdict)

使用password 和预选的共享字典shdict 初始化服务器实例。

如果password 未设置,则服务器是公共的。如果设置了password,则客户端必须调用 auth 命令进行身份验证才能运行其他命令。如果您正在监听非本地接口,请采取适当的安全措施。

如果shdict 未设置,则客户端必须调用 select 命令选择一个共享字典。

shdict.server:serve(mode)

使用名为*mode的处理程序启动服务器。要运行处理程序 serve_stream_redis`,请使用

    shdict.server:serve("stream_redis")

如果mode 未定义,则使用每个子系统的默认处理程序。对于 http,默认处理程序为 serve_http_plain。对于 stream,默认处理程序为 serve_stream_redis

shdict.server:serve_http_plain()

此处理程序接受来自客户端的单个 HTTP 请求,并以纯文本形式发送响应。

shdict.server:serve_http_json()

此处理程序接受来自客户端的单个 HTTP 请求,并以 json 编码文本形式发送响应。

shdict.server:serve_http(output_filter)

此处理程序接受来自客户端的单个 HTTP 请求,并通过 output_filter 格式化发送响应。

如果 output_filter 未定义,则使用 output_plain,此处理程序等效于 serve_http_plain

output_filter 是一个函数,它以表作为参数并返回一个字符串。用户可以定义自己的过滤器并生成所需的输出。

shdict.server:serve_stream_redis()

此处理程序接受内联或 Redis 协议的 TCP 连接。可以使用类似 telnetnc 的纯文本 TCP 客户端或 Redis 兼容的客户端或库来连接到服务器。

命令

基本命令

支持来自 ngx.shared.DICT API 的方法。

一些命令(如 ttlcapacity)需要安装 resty.core。要使用这些命令,请将 require('resty.core') 用于 http 子系统,将 require('resty.core.shdict') 用于 stream 子系统。

方法名称是不区分大小写的。参数用空格分隔。

例如

  • 要使用键 dog 设置值 wow,请使用 SET dog wowsEt dog wow

  • 要使用键 dog 设置值 wow !,请使用 SET dog "wow !"

  • 要使用键 dog 设置值 "wow" !,请使用 SET dog "\"wow\" !"

如果包含 resty.shdict.redis-commands,一些命令将映射到 redis 风格的命令。

  • del 作为 delete 的别名

  • flushall 作为 flush_all 的别名

AUTH

对服务器进行身份验证。

    > AUTH password

如果password 有效,则返回 OK

SELECT

选择一个共享字典。

    > SELECT shdict

如果shdict 找到,则返回 OK

PING

测试与服务器的连接。

    > PING
    PONG

KEYS

此命令需要 resty.shdict.redis-commands 模块。

时间复杂度为 O(3n)。此命令仅用于调试,请不要在生产代码中使用它来搜索键。

返回与pattern 匹配的所有键列表。pattern 是一个 glob 风格的模式。

    > KEYS pattern
    > KEYS do?
    > KEYS do*
    > KEYS do[a-z]

返回找到的所有键的列表。

EVAL

此命令需要 resty.shdict.redis-commands 模块。

在服务器上运行 Lua 脚本。语法与 Redis EVAL 相同。

    > EVAL script numkeys key [key ...] arg [arg ...]
    > EVAL "shdict.call('set', 'dog', 'wow') 0
    (nil)
    > EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"

出于安全原因,仅提供以下 API

  • 函数:asserterrorgetmetatableipairsnextpairspcallselectsetmetatabletonumbertostringunpack

  • 模块:bitmathstringtable

  • ngx.sharedngx.re

  • shdict.callshdict.pcall 用于调用 shdict API

  • zone 作为当前 shdict 实例

此外,还创建了从 redis.callshdict.call 的别名,以方便起见。

已知问题

  • 如果安装了该库,该库将使用 resty.core,其行为将略微不同于 C 实现。例如,使用 resty.core 时,缺失的参数将由 nil 填充,在这种情况下,发出 SET a 等效于 SET a nil

  • 出于性能问题,内联协议(HTTP 内联或 Redis 内联)最多只能接受四个参数。出于此原因,EVAL 可能会因 参数无效 而失败。要解决此问题,请始终使用其他协议(如 Redis RESP 协议)来调用这些命令。

待办事项

  • 将更多 ngx.* API 添加到 EVAL 命令。

  • 添加 INFO 命令。

版权和许可

该模块在 BSD 许可下发布。

版权所有 (C) 2018,由 fffonion <fffonion@gmail.com>。

保留所有权利。

在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用此软件,无论是否修改。

  • 源代码的重新分发必须保留上述版权声明、此条件列表和以下免责声明。

  • 二进制形式的重新分发必须在随分发提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。

本软件由版权持有人和贡献者“按原样”提供,并且任何明示或暗示的保证,包括但不限于适销性保证和适用于特定目的的保证均被排除在外。在任何情况下,版权持有人或贡献者均不对因使用本软件而造成的任何直接、间接、偶然、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;或业务中断)负责,无论损害是基于合同、严格责任或侵权(包括疏忽或其他)的任何理论,即使已被告知可能发生此类损害。

另请参阅

作者

fffonion

许可证

3bsd

依赖项

luajit

版本