lua-resty-ffiOpenResty/Nginx 通用接口

联合创作 · 2023-09-19 05:04

lua-resty-ffi提供了一个通用高效的接口,使得你可以使用Go,Python,Java和Rust为 OpenResty/Nginx 直接开发你想要的功能。


众所周知,OpenResty使用的lua和C,生态很弱,很多重造的轮子也缺乏维护,以至于跟外围生态系统互通时,巧妇难为无米之炊。


特色:



  • 非阻塞,以协程的方式运行

  • 简单可扩展的接口,支持任何符合C ABI的语言

  • 一劳永逸,无需再编写任何C或者lua的模块来开发新功能

  • 高性能,比unix domain socket要快

  • 通用的java、python加载器

  • 可使用任何你喜欢的消息序列化格式


最简单的实例:


使用golang开发一个echo功能。


创建文件:​echo.go


package main

/*
#cgo LDFLAGS: -shared
#include <string.h>
void* ngx_http_lua_ffi_task_poll(void *p);
char* ngx_http_lua_ffi_get_req(void *tsk, int *len);
void ngx_http_lua_ffi_respond(void *tsk, int rc, char* rsp, int rsp_len);
*/
import "C"
import (
"log"
"unsafe"
)

//export libffi_init
func libffi_init(cfg_cstr *C.char, tq unsafe.Pointer) C.int {
log.Println("start go echo runtime")
go func() {
for {
task := C.ngx_http_lua_ffi_task_poll(tq)
if task == nil {
break
}
var rlen C.int
r := C.ngx_http_lua_ffi_get_req(task, &rlen)
res := C.malloc(C.ulong(rlen))
C.memcpy(res, unsafe.Pointer(r), C.ulong(rlen))
C.ngx_http_lua_ffi_respond(task, 0, (*C.char)(res), rlen)
}
log.Println("exit go echo runtime")
}()
return 0
}

func main() {}

 


创建文件:nginx.conf


daemon off;
error_log /dev/stderr info;
worker_processes auto;
env LD_LIBRARY_PATH;

events {}

http {
server {
listen 20000;

location /echo {
content_by_lua_block {
local demo = ngx.load_ffi("ffi_go_echo")
local ok, res = demo:echo("foobar")
assert(ok)
assert(res == "foobar")

demo:__unload()
ok, res = demo:echo("foobar")
assert(not ok)
ngx.log(ngx.ERR, res)

ngx.say("ok")
}
}
}
}

运行:


​go build -buildmode=c-shared -o libffi_go_echo.so echo.go
LD_LIBRARY_PATH=$(PWD) $(NGINX_BIN) -p $(PWD) -c nginx.conf
curl localhost:20000/echo

 

浏览 52
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报