如何在OpenResty里实现代码热更新

所谓「代码热更新」,是指代码发生变化后,不用 reload 或者 graceful restart 进程就能生效。比如有一个聊天服务,连接着一百万个用户的长连接,所谓代码热更新就是在长连接不断的前提下完成代码更新。通过关闭 lua_code_cache 可以实现此目标,但那样的话性能无疑将大打折扣!实际上因为所有的 require 操作都是通过 package.loaded 来加载模块的,所以通过 package.loaded 就可以实现代码热更新,并且基本不影响性能。

继续阅读

手把手教你用OpenResty里的FFI

了解 OpenResty 的人应该知道,OpenResty 原本的 API 都是基于 C 实现的,不过在新版里都已经改成了基于 FFI 实现的,为什么这么做?因为 FFI 在效率上更有优势,除此以外,FFI 还有一个优点是可以很便利的和 C 交互,我们不妨设想一下,C 语言有那么多成熟的库,通过 FFI,我们可以轻而易举的引入到自己的应用中,何乐而不为呢?

继续阅读

一个尾调用相关的诡异报错信息

一个 OpenResty 的接口报错了,我查了一下日志,发现如下报错信息:

bad argument #1 to ‘test’ (string expected, got userdata)

看上去这就是一道送分题啊:无非就是 test 函数的第一个参数类型应该是 string,实际传递的却是 userdata。就当我觉得可以轻而易举解决问题的时候,突然发现 test 函数定义就没有参数,调用的时候也没传参数,真是太诡异了。

继续阅读

关于 Cosocket 的 socket busy 报错

关于 OpenResty 的 cosocket,文档里有如下一段描述:

the cosocket object here is full-duplex, that is, a reader “light thread” and a writer “light thread” can operate on a single cosocket object simultaneously (both “light threads” must belong to the same Lua handler though, see reasons above). But you cannot have two “light threads” both reading (or writing or connecting) the same cosocket, otherwise you might get an error like “socket busy reading” when calling the methods of the cosocket object.

简单点儿说,cosocket 是全双工的,如果同一个 lua handler 有一个读线程和一个写线程的话,那么它们可以同时操作一个 cosocket 对象,但是如果两个线程一起读或者写一个 cosocket 对象的话,那么会触发「socket busy」错误。

继续阅读