Nginx扩展之Openresty

Posted WebArtisan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx扩展之Openresty相关的知识,希望对你有一定的参考价值。

nginx模块

在前面文章nginx编译安装中我们提到,nginx模块是提前编译进去的,所以如果要基于nginx做扩展开发,就要相对比较熟悉nginx代码结构和编译过程。

虽然未来nginx版本即使支持动态链接库,使用C语言写nginx扩展门槛也同样高。

复习一下,查询编译安装nginx模块信息,使用-V参数即可

nginx -V
nginx version: openresty/1.19.3.2
built by gcc 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
built with OpenSSL 1.1.1k 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx ... --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-compat --with-stream --with-http_ssl_module

可以看到在configure arguments中详细列出了我们当前nginx中已经编译进去的模块。

Openresty

使用C并且重新编译nginx,对于我们基于nginx做业务开发,造成了诸多不便,开发测试、上线更新相对麻烦。Openresty的解决方式是首先使用C写了lua-nginx-module,将luajit嵌入了nginx中,打开了扩展的大门,然后业务开发模块可以使用lua脚本语言来开发。

openresty的官方解释为一个基于nginx的可编写脚本的Web平台,除了核心的lua-nginx-moduleopenresty还包含维护了非常多lua编写的第三方模块,开箱即用,很方便我们做业务定制开发。

安装Openresty

官方推荐安装方式为通过软件源二进制包安装,因为编译lua-nginx-module还是非常麻烦的,对于我们使用lua快速实现业务来说,这块精力可以不花,如果要深入openresty可以尝试完全从源码编译安装。

# add the yum repo:
wget https://openresty.org/package/centos/openresty.repo
sudo mv openresty.repo /etc/yum.repos.d/

# update the yum index:
sudo yum check-update

sudo yum install openresty

通过官方源安装openresty非常简单,而且安装之后所有文件都在/usr/local/openresty下面,非常简洁:

$ ls -al
总用量 64
drwxr-xr-x 10 root root 4096 6月 3 11:46 .
drwxr-xr-x. 16 root root 4096 6月 3 11:46 ..
drwxr-xr-x 2 root root 4096 6月 3 11:46 bin
-rw-r--r-- 1 root root 22924 6月 1 13:11 COPYRIGHT
drwxr-xr-x 6 root root 4096 6月 3 11:46 luajit
drwxr-xr-x 5 root root 4096 6月 3 11:46 lualib
drwxr-xr-x 6 root root 4096 6月 3 11:46 nginx
drwxr-xr-x 4 root root 4096 6月 3 11:46 openssl111
drwxr-xr-x 3 root root 4096 6月 3 11:46 pcre
drwxr-xr-x 3 root root 4096 6月 3 11:46 site
drwxr-xr-x 3 root root 4096 6月 3 11:46 zlib

注意到这个目录下有opensslpcre两个目录,回顾我们编译安装nginx提到的依赖,可见openresty的源已经帮我们解决好了这个依赖,统一放到当前目录下。

启动Openresty

安装完openresty我们完全可以使用openresty命令替换nginx命令,所有的参数都一样,准备一个conf文件启动。

# mkdir -p /tmp/nginx/logs
# /tmp/nginx/demo.conf

worker_processes 1;

error_log logs/error.log debug;

events {
worker_connections 1024;
}

daemon off;

http {

server {
listen 9090;
location / {
content_by_lua_block {
ngx.say("hello world")
}
}
}

}

# openresty -p /tmp/nginx -c /tmp/nginx/demo.conf

另起终端测试

curl -v http://127.0.0.1:9090
* Trying 127.0.0.1:9090...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 9090 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:9090
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: openresty/1.19.3.2
< Date: Fri, 18 Jun 2021 09:04:56 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
<
hello world
* Connection #0 to host 127.0.0.1 left intact

Lua扩展编写

在上面demo.conf中我们已经实现了openresty lua的hello world,值得注意的是我们使用了一个content_by_lua_block指令,这个指令是lua-nginx-module提供的,意思为这个location响应内容通过执行lua产生。

在介绍更多指令之前我们先看一下lua-nginx-module的在nginx中的的流程图:

图中从上到下描述了lua-nginx-module可作用的:启动初始化lua、处理请求rewrite/access、产生响应、记录日志阶段,以及对应阶段可使用的指令。

每一个阶段的*_by_lua指令后面,我们可以引用我们的lua脚本,或者直接写片段的lua代码。对应的我们可以在lua脚本中实现请求当前阶段的业务逻辑,比如可以在access阶段做安全认证等逻辑。

更多指令: https://github.com/openresty/lua-nginx-module#directives 。

openresty除了实现lua-nginx-module开启了执行lua脚本能力外,还将许多nginx api直接封装进了lua,我们在实现业务逻辑的时候在脚本中可以直接使用,比如在上面demo.conf中我们调用的ngx.say(),便是一个类似print的api。

更多nginx lua api: https://github.com/openresty/lua-nginx-module#nginx-api-for-lua 。

总结

总的来说,使用openresty来做基于nginx的业务开发,门槛已经大大降低了,几乎不用去熟悉nginx的代码和数据结构。了解lua-nginx-module提供的指令、封装好的api、在nginx中的作用流程,是入坑的开始。

相关项目

  • ingress-nginx-controller

kubernetes社区官方基于lua能力实现的ingress-controller,使用lua主要解决动态upstream的问题。https://github.com/kubernetes/ingress-nginx

  • kong

基于nginx+lua实现的api-gateway。https://github.com/kong/kong


以上是关于Nginx扩展之Openresty的主要内容,如果未能解决你的问题,请参考以下文章

OpenResty(nginx扩展)实现防cc攻击

分布式实战:Nginx缓存之OpenResty部署

OpenResty(nginx扩展)实现防cc攻击

并发编程之缓存:OpenResty+lua实现一级缓存

Kong 如何在 NGINX 和 OpenResty 上工作

OpenResty--------企业级理论实践篇