×
关于Socket 编程发展OpenResty 简介Lua 入门Lua 简介Lua 环境搭建基础数据类型表达式控制结构if/elsewhilerepeatforbreak,returnLua函数函数的定义函数的参数函数返回值全动态函数调用模块String 库Table 库日期时间函数数学库函数文件操作

Lua 高阶

元表面向对象编程局部变量判断数组大小非空判断正则表达式不用标准库虚变量抵制使用 module() 定义模块调用代码前先定义函数点号与冒号操作符的区别module 是邪恶的FFI什么是 JITNginxNginx 新手起步location 匹配规则if 是邪恶的静态文件服务日志反向代理负载均衡陷阱和常见错误

OpenResty

环境搭建Windows 平台CentOS 平台Ubuntu 平台Mac OS X 平台Hello World与其他 location 配合获取 uri 参数获取请求 body输出响应体日志输出简单API Server框架使用 Nginx 内置绑定变量子查询不同阶段共享变量防止 SQL 注入如何发起新 HTTP 请求

LuaRestyRedisLibrary

访问有授权验证的 Redisselect+set_keepalive 组合操作引起的数据读写错误redis 接口的二次封装(简化建连、拆连等细节)redis 接口的二次封装(发布订阅)pipeline 压缩请求数量script 压缩复杂请求动态生成的 lua-resty-redis 模块方法LuaCjsonLibraryjson解析的异常捕获稀疏数组空table编码为array还是objectPostgresNginxModule调用方式简介不支持事务超时健康监测SQL注入LuaNginxModule执行阶段概念正确的记录日志热装载代码阻塞操作缓存sleep定时任务禁止某些终端访问请求返回后继续执行调试请求中断后的处理我的 lua 代码需要调优么变量的共享范围动态限速shared.dict 非队列性质正确使用长链接如何引用第三方 resty 库body 在 location 中的传递典型应用场景怎样理解 cosocket如何安全启动唯一实例的 timer如何正确的解析域名使用动态 DNS 来完成 HTTP 请求LuaRestyLock缓存失效风暴

stream_lua_module

balancer_by_lua

OpenResty 与 SSL

HTTPS 时代动态加载证书和 OCSP staplingTLS session resumption测试代码静态分析单元测试代码覆盖率API 测试性能测试持续集成灰度发布Web 服务API的设计数据合法性检测协议无痛升级代码规范连接池C10K 编程TIME_WAIT 问题与 Docker 使用的网络瓶颈火焰图什么时候使用如何定位问题

OpenResty 周边

如何添加自己的lua api

零碎知识点记录

2016-7 月汇总如何在后台开启轻量级线程来定时更新共享内存一个 openresty 内存“泄漏”问题用 do-end 整理你的代码lua 中如何 continue调用 FFI 出现 "table overflow"如何定位 openresty 崩溃 bug

调用 FFI 出现 "table overflow"


Question:

  1. 首先安装 uuid 模块(ubuntu/debian请安装:sudo apt-get install uuid uuid-dev 两个模块)
  2. FFI 调用,代码示例:
local ffi = require 'ffi'

ffi.cdef[[
typedef unsigned char uuid_t[16];
void uuid_generate(uuid_t out);
void uuid_unparse(const uuid_t uu, char *out);
]]

local uuid = ffi.load('libuuid')

if uuid then
    local uuid_t   = ffi.new("uuid_t")
    local uuid_out = ffi.new("char[64]")
    uuid.uuid_generate(uuid_t)
    uuid.uuid_unparse(uuid_t, uuid_out)
    result = ffi.string(uuid_out)
    print(result)
end

当使用这个的时候刚开始不会出现错误,但是运行一段时间后就会出现 table overflow, 第二天早上回来看到的,请问遇到过这样的情况么?

Answer:

貌似这里每请求都调用 ffi.cdef?建议把 ngx_ffi.lua 实现为一个真正的 Lua 模块,这样就可以享受只加载一次的好处:

http://wiki.nginx.org/HttpLuaModule#Data_Sharing_within_an_Nginx_Worker

你遇见的 table overflow 的错误很容易通过下面这个独立的 Lua 脚本复现:

-- test.lua
local ffi = require "ffi"
while true do
    ffi.cdef[[
    typedef struct { void* ev_ptr; void* char_ptr; } bif_result;
    ]]
end

命令行上的执行结果如下:

$ /usr/local/openresty/luajit/bin/luajit-2.0.0-beta10 test.lua
/usr/local/openresty/luajit/bin/luajit-2.0.0-beta10: table overflow
stack traceback:
        [C]: in function 'cdef'
        a.lua:6: in main chunk
        [C]: ?

所以只要把 ffi.cdef 移出循环就不会溢出了。(而在你的场景中,则是把 ffi.cdef 调用移进 Lua 模块加载代码。)

可以参考一下 lua-resty-string 库中的 resty.md5 模块的实现:

https://github.com/agentzh/lua-resty-string/blob/master/lib/resty/md5.lua

根据下面链接完成整理

https://groups.google.com/forum/#!topic/openresty/zGxwOqUN4fc


分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)