openresty入门

最近调研日志大数据分析相关的架构,接触到openresty项目,它的作用是通过lua语法写nginx扩展,从而基于nginx进程实现高性能的轻量业务处理。

这个openresty的优势就是内嵌在nginx里,简单不复杂的业务逻辑可以直接写在里面,就避免再去开发独立的服务了。

参考

我很久以前做过lua+c,但是现在已经忘的一干二净了。

幸亏有一位360公司的同学总结了一份教程,通过学习教程可以直接上手openresty:《OpenResty 最佳实践》

实践

我的目标是接收客户端上报的一些统计日志,然后写到磁盘文件中去。

openresty框架提供了输出nginx error log的方法,但是将业务统计日志打印到error log里,会增加后续从error log中提取统计日志的额外工作。

因此,我需要自己封装日志输出方法,把统计日志单独输出到一个目录下,与nginx error日志完全隔离开来。

DEMO地址:https://github.com/owenliang/log-analyze/tree/master/openresty

nginx配置接口地址与lua处理脚本

对外暴露了/collect接口,内部指令含义如下:

  1. set_by_lua_block:相当于Nginx的set,可以用lua脚本动态设置一个nginx变量(var);我这里是为后面的lua脚本指定了统计日志的保存目录,也就是将日志保存在nginx工作目录下的collect子目录中。
  2. content_by_lua_file:相当于处理Nginx收到的请求,这里主要是把上报的日志进行一些规范化。
  3. log_by_lua_file:Nginx专门给扩展打印日志的一个回调时机,此时应答已经发回给了调用者,所以不会影响请求的响应时间。

content_by_lua_file

读取请求body,做一些格式解析,最后将要输出的统计日志保存到nginx.ctx变量中。

nginx.ctx是请求的上下文,可以在log_by_lua_file阶段提取出来,从而打印统计日志到文件中。

log_by_lua_file

在这个阶段,就是遍历content_by_lua_file保存的日志数组,逐条调用Log模块输出到文件中去。

log模块是我自己开发的日志模块,接下来看一下实现。

封装log模块

在模块里通过file保存了当前打开的日志文件句柄,每小时都会切换到新的文件继续输出日志。

连续的多个请求不需要重复打开文件,因为openresty提供的lua执行虚拟环境(VM)是全局唯一的,就是说上述log模块是一次加载、持久缓存的。

所以我们完全可以在模块内保存局部变量file、file_path等,供当前连接的后续请求以及其他连接的请求共享,这一点在开发时需要特别注意,避免写出不可以共享执行的代码。

最后

上述流程在collect目录下生成了统计日志:https://github.com/owenliang/log-analyze/tree/master/openresty/collect

openrestsy项目在源码中内置了nginx,lua,只需要下载源码一键编译即可。

为了使用openresty,我们应该直接使用它编译的nginx环境,若希望和现有线上nginx做结合,建议直接替换线上nginx或者做nginx反向代理到openresty nginx。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~