openresty简介
- 官网地址 http://openresty.org/
- 介绍 OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项。 OpenResty 通过汇聚各种设计精良的 Nginx 模块, 从而将 Nginx 有效的变成一个强大的 Web 应用服务器, 这样, Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种C以及Lua 模块, 快速构造出足以胜任 10K 并发连接响应的超高性能Web 应用系统. OpenResty 的目标是让你的Web服务直接跑在 Nginx 服务内部, 充分利用 Nginx 的非阻塞 I/O 模型, 不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL,PostgreSQL,Memcaches 以及 Redis 等都进行一致的高性能响应.
编译安装
下载编译安装包
wget http://openresty.org/download/ngx_openresty-1.7.10.2.tar.gz
解压之后进入解压目录进行编译参数配置
./configure --prefix=/data/soft/openresty --user=nginx --group=nginx
以上编译参数可根据自己的实际需求调整,./configure --help 查看参数 make & make install 编译安装
安装后的目录介绍
Nginx对请求的多阶段处理
了解openresty之前,我们先熟悉下nginx对请求的处理过程。 nginx接收到客户端的请求之后,对请求的处理,是分阶段的,总共有11个
- NGX_HTTP_POST_READ_PHASE 接收完请求之后的第一个处理阶段,位于uri重写之前,很少使用
- NGX_HTTP_SERVER_REWRITE_PHASE server级别的重写,处理位于server块内和location之外的重写指令 比如 index(位于server 块内) 指令 比如 try_files(位于server块内) 指令(在nginx里面也是推荐使用try_files,等效于if-rewrite)
- NGX_HTTP_FIND_CONFIG_PHASE 查找location配置,该阶段使用上一阶段重写后的uri,查找对应的location 该阶段可能会被执行多次
- NGX_HTTP_REWRITE_PHASE location级别的uri重写,该阶段执行location的基本重写命令 如 rewrite trye_files
- NGX_HTTP_POST_REWRITE_PHASE location重写的最后一个阶段,检查上一阶段是否有uri重写,如果有,跳转到合适的阶段 nginx 限制了最大重写次数10次
- NGX_HTTP_PREACCESS_PHASE 访问权限控制的前一阶段,该阶段在权限控制阶段之前,一般也用于访问控制,比如限制访问频率,链接数等
- NGX_HTTP_ACCESS_PHASE 访问权限控制阶段,比如基于ip黑白名单的权限控制,基于用户名密码的权限控制等;
- NGX_HTTP_POST_ACCESS_PHASE 访问权限控制的后一阶段,该阶段根据权限控制阶段的执行结果进行相应处理
- NGX_HTTP_TRY_FILES_PHASE(特殊,顺序不固定) try_files指令的处理阶段,如果没有配置try_files指令,则该阶段被跳过
- NGX_HTTP_CONTENT_PHASE 内容生成阶段,该阶段产生响应,并发送到客户端
- NGX_HTTP_LOG_PHASE 日志记录阶段,该阶段记录访问日志
按照大类分:POST_READ阶段,SERVER_REWRITE阶段,FIND_CONFIG阶段,REWRITE阶段,POST_REWRITE阶段,PREACCESS阶段,ACCESS阶段,POST_ACCESS阶段,TRY_FILES阶段,CONTENT阶段,LOG阶段
因为openresty里面集成了很多模块,实际上就是在不同的处理阶段注册相应的函数,lua模块的加入让nginx本身有了处理lua脚本的能力
为什么openresty快
nginx对请求的处理模式是异步非阻塞的,通过参数配置的优化(linux 内核参数优化),可以达到10万左右的并发处理能力 openresty基于nginx,加上了很多第三方模块,主要是lua,能够使得nginx在内部处理lua的脚本, lua虽然是脚本语言,但是lua的性能很好,尤其是基于lua-jit的运行
这个图片是nginx php-fpm的模型,当nginx接收到php请求,就会转交给php-fpm
php-fpm接收到请求要进行一系列初始化工作,完了执行脚本,之后释放本次请求分配的资源,执行一些回收操作
openresty接收到动态请求,用lua去处理,直接是在nginx内部,后续的一些动作没有,而且lua-jit是非常高效的,因此openresty快是情理之中
由于lua和nginx结合的如此紧密,使得我们可以在nginx请求的各个阶段灵活的处理
openresty常用参数或者接口
github地址 https://github.com/openresty/lua-nginx-module
nginx.conf中可以使用的执行lua的指令
- lua_package_path(http) 设置运行查找库文件的目录 ;;默认地址
- lua_package_cpath(http)
- lua_code_cache(http, server, location, location if) 开启之后对性能提升非常明显,线上开启
- init_by_lua init_by_lua_file(http)
- init_worker_by_lua init_worker_by_file(http)
- set_by_lua set_by_lua_file(server, server if, location, location if)
- content_by_lua content_by_lua_file content_by_block(location, location if)
- rewrite_by_lua rewrite_by_lua_file(http, server, location, location if)
- access_by_lua access_by_lua_file
- header_filter_by_lua header_filter_by_lua_file
- body_filter_by_lua body_filter_by_lua_file
- log_by_lua log_by_lua_file
- lua_shared_dict lua_shared_dict dogs 10m;
lua中可以使用的nginx api
- ngx.arg (set_by_lua, body_filter_by_lua**)
- ngx.var.VARIABLE(set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua*)
- print[ngx.log(NOTICE,...]
- ngx.ctx(nit_worker_by_lua, set_by_lua, rewrite_by_lua, access_by_lua, content_by_lua, header_filter_by_lua, body_filter_by_lua, log_by_lua, ngx.timer.**)
- ngx.location.capture
- ngx.header.HEADER
- ngx.req.start_time
- ngx.req.get_method
- ngx.req.read_body
- ngx.redirect
- ngx.print ngx.say ngx.log ngx.eof
- ngx.now ngx.utctime
- ngx.shared.DICT
- ngx.timer.at
实际应用案例
- 使用 resty.memcached访问操作memcache
- 使用 resty.mysql访问 msyql
注意要点
- 尽量在声明变量时使用local,使用ngx.var ngx.print等的时候也尽量设定为本地变量
- 错误处理需要使用pcall 包装要执行的代码
- 使用require加载模块
- 请求返回可以继续执行任务(fastcgi_finish, ngx.eof())
- 尾调用
- 连接池使用
- 数组下标1 #aa 可以获取数组大小,但是千万不要使用
- ....