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

 

浏览 8
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

编辑 分享
举报