关于 Openresty 的两三事
http://lua.ren/topic/135/%E5%85%B3%E4%BA%8E-openresty-%E7%9A%84%E4%B8%A4%E4%B8%89%E4%BA%8B
基础原理 Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,基本的事件处理都是放在 woker 中,master 负责一些全局初始化,以及对 worker 的管理。
每个 woker 使用一个 LuaVM,当请求被分配到 woker 时,将在这个 LuaVM 里创建一个 coroutine。协程之间数据隔离,每个协程具有独立的全局变量 _G。
关于 LUACODECACHE 关闭 luacodecache 时,require 的处理方式是每次都强制重新加载和解析,也就是说,你对代码的任何修改的效果,都将在上传后立即体现。
开启 luacodecache 时,在同一个 LuaVM 中,模块将在首次加载并解析后被缓存,之后再次 require 将直接返回缓存的内容。换句话说,同一 worker 上的所有请求将共享已加载的模块,任意一个请求对于模块属性的修改,都将影响到同一 worker 上的其他请求。
不应使用模块级的局部变量以及模块属性,存放任何请求级的数据。否则在 luacodecache 开启时,会造成请求间相互影响和数据竞争,产生不可预知的异常状况。
关闭 luacodecache 会极大的降低性能,在生产环境中应开启 luacodecache 。
虽然开发环境中关闭 luacodecache 会有一些便利性,但我强烈建议开启 luacodecache ,与线上保持一致,以减少不必要的差异性问题和额外测试需求。
开启 luacodecache 时,可用 nginx -s reload 或 kill -HUP masterPID 方式热重载代码,无需重启 Nginx。
关于 PATH 和 CPATH OpenResty 会将它的 lib 目录加入 package.path 和 package.cpath,但你的项目目录需要自己处理。
在入口文件中,将项目目录加入 package.path 和 package.cpath 是不可取的。因为 luacodecache 开启时,package 模块是同一 worker 上所有请求共享的,如果无条件追加,package.path 和 package.cpath 将不断变长,并最终导致内存溢出。
以下是我采用的解决方案:
None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
关于 LUA-RESTY-MYSQL 和 LUA-RESTY-REDIS 不应使用模块级的局部变量以及模块属性,存放 resty.mysql 和 resty.redis 实例。否则,在 luacodecache 开启时,同一 worker 的所有请求将共享该实例,造成数据竞争问题。建议将 resty.mysql 和 resty.redis 实例存放到 ngx.ctx 中。
不能在 require 过程中实例化 resty.mysql 和 resty.redis 实例,否则会报错。例如,模块返回一个 function,此 function 直接或间接调用实例化 resty.mysql 和 resty.redis 的代码,将会导致报错。
在首次查询时实例化是一个比较好的解决方案:
None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
|
使用 setkeepalive(maxidletimeout, poolsize) 替代 close() 将启用连接池特性。set_keepalive 的意思可以理解为,保持连接,并将连接归还到连接池内。这样在下次连接时,会首先会尝试从连接池获取连接,获取不成功才会创建新的连接。在高并发下,连接池能大大的减少连接 MySQL 和 Redis 的次数,明显的提升性能。
使用模块缓存静态数据 利用 luacodecache 开启时模块会被缓存的特性,我们可以使用模块来缓存静态数据,其效率接近于将数据缓存在内存中。
存储方法:
None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
读取方法:
None
1 2 3 4 5 6 7 8 9 10 |
|
清理方法:
None
1 2 3 4 |
|
关于 OPENRESTY 的两三事 火星梅梅 | 5 八月, 2013 | OpenResty, 爱 Coding | 2条评论 基础原理 Nginx 采用的是 master-worker 模型,一个 master 进程管理多个 worker 进程,基本的事件处理都是放在 woker 中,master 负责一些全局初始化,以及对 worker 的管理。
每个 woker 使用一个 LuaVM,当请求被分配到 woker 时,将在这个 LuaVM 里创建一个 coroutine。协程之间数据隔离,每个协程具有独立的全局变量 _G。
关于 LUACODECACHE 关闭 luacodecache 时,require 的处理方式是每次都强制重新加载和解析,也就是说,你对代码的任何修改的效果,都将在上传后立即体现。
开启 luacodecache 时,在同一个 LuaVM 中,模块将在首次加载并解析后被缓存,之后再次 require 将直接返回缓存的内容。换句话说,同一 worker 上的所有请求将共享已加载的模块,任意一个请求对于模块属性的修改,都将影响到同一 worker 上的其他请求。
不应使用模块级的局部变量以及模块属性,存放任何请求级的数据。否则在 luacodecache 开启时,会造成请求间相互影响和数据竞争,产生不可预知的异常状况。
关闭 luacodecache 会极大的降低性能,在生产环境中应开启 luacodecache 。
虽然开发环境中关闭 luacodecache 会有一些便利性,但我强烈建议开启 luacodecache ,与线上保持一致,以减少不必要的差异性问题和额外测试需求。
开启 luacodecache 时,可用 nginx -s reload 或 kill -HUP masterPID 方式热重载代码,无需重启 Nginx。
关于 PATH 和 CPATH OpenResty 会将它的 lib 目录加入 package.path 和 package.cpath,但你的项目目录需要自己处理。
在入口文件中,将项目目录加入 package.path 和 package.cpath 是不可取的。因为 luacodecache 开启时,package 模块是同一 worker 上所有请求共享的,如果无条件追加,package.path 和 package.cpath 将不断变长,并最终导致内存溢出。
以下是我采用的解决方案:
None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
关于 LUA-RESTY-MYSQL 和 LUA-RESTY-REDIS 不应使用模块级的局部变量以及模块属性,存放 resty.mysql 和 resty.redis 实例。否则,在 luacodecache 开启时,同一 worker 的所有请求将共享该实例,造成数据竞争问题。建议将 resty.mysql 和 resty.redis 实例存放到 ngx.ctx 中。
不能在 require 过程中实例化 resty.mysql 和 resty.redis 实例,否则会报错。例如,模块返回一个 function,此 function 直接或间接调用实例化 resty.mysql 和 resty.redis 的代码,将会导致报错。
在首次查询时实例化是一个比较好的解决方案:
None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
|
使用 setkeepalive(maxidletimeout, poolsize) 替代 close() 将启用连接池特性。set_keepalive 的意思可以理解为,保持连接,并将连接归还到连接池内。这样在下次连接时,会首先会尝试从连接池获取连接,获取不成功才会创建新的连接。在高并发下,连接池能大大的减少连接 MySQL 和 Redis 的次数,明显的提升性能。
使用模块缓存静态数据 利用 luacodecache 开启时模块会被缓存的特性,我们可以使用模块来缓存静态数据,其效率接近于将数据缓存在内存中。
存储方法:
None
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
读取方法:
None
1 2 3 4 5 6 7 8 9 10 |
|
清理方法:
None
1 2 3 4 |
|
数据存储 _G
请求级 table 变量,生命周期为本次请求,可存储请求级任意 Lua 数据。
NGX.CTX
请求级 table 变量,生命周期为本次请求,可存储请求级任意 Lua 数据。
NGX.SHARED.DICT
全局级 key-value 字典,使用共享内存实现,实现了读写锁,所有请求均可安全读写。 value 只能为布尔值、数字和字符串。Reload Nginx 时不会受影响,只有当 Nginx 被关闭时才会丢失。
模块属性和模块级局部变量
worker 级变量,同一 worker 的所有请求共享,没有读写锁,多个请求同时写入时不安全。
多谢原作者的分享: http://zivn.me/?p=157
关于 Openresty 的两三事相关推荐
- OpenResty搭建高性能服务端
Socket编程 Linux Socket编程领域为了处理大量连接请求场景,需要使用非阻塞I/O和复用,select.poll.epoll是Linux API提供的I/O复用方式,自从Linux2.6 ...
- OpenResty中的upstream healthcheck功能沉思录
综述 healthcheck功能本质上还是个定时器,去定期检查指定upstream组的状态,它发送指定的http请求并解析响应码,去探测upstream中每个peer的存活状态,再结合历史请求记录来判 ...
- OpenResty学习中的几个小例子汇总
1.测试lua或是LuaJIT的版本号 如果使用的是标准 Lua,访问 /lua-version 应当返回响应体 Lua 5.1 如果是 LuaJIT 则应当返回类似 LuaJIT 2.0.2 这样的 ...
- 在CentOS 6.9 x86_64的OpenResty 1.13.6.1上使用基于Redis实现动态路由示例
下面是我阅读春哥OpenResty官网主页中"Dynamic Routing Based On Redis"一节的实操记录,整理如下. https://openresty.org/ ...
- 在CentOS 6.9 x86_64的OpenResty 1.13.6.1上使用LuaRocks示例
下面是我阅读春哥OpenResty官网主页中"Using LuaRocks"一节的实操记录,整理如下. https://openresty.org/cn/using-luarock ...
- 在CentOS 6.9 x86_64上玩转OpenResty 1.13.6.1中的resty-cli模块
resty-cli是OpenResty中命令行工具的集合,其中resty工具是最有用的. 安装好OpenResty之后,resty-cli就会默认安装,以我的安装为例,参见博文 http://blog ...
- OpenResty中遇到Can't locate Time/HiRes.pm in @INC问题的解决方法
今天在研究resty这个命令行工具时,执行 resty -h 出现下面的报错 Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local ...
- 在CentOS 6.9 x86_64上搭建全功能的OpenResty 1.13.6.1笔记
好久没有玩OpenResty,这段时间机会难得,赶紧实践一下.下面是我在rMBP的CentOS 6.9 x86_64虚拟机上安装目前最新版OpenResty 1.13.6.1的笔记. OpenRest ...
- 在Ubuntu 14.04 64bit上安装OpenResty 1.9.7.4
为了自己的ThinkPad T420上面的Ubuntu可以使用openresty开发,我特地记录一下安装过程: 安装依赖包 apt-get install libreadline-dev libncu ...
最新文章
- Python 来分析,堪比“唐探系列”!B站9.5分好评如潮!
- python中非怎么表示_Python中非英语文本的标记化
- 图灵直播——听胡阳老师和大家聊聊《Python Web开发者的破局之道》
- Android使用ViewPager实现左右滑动效果
- 是时候好好去学门脚本语言了
- 结构方程模型-调节(干扰)效应检验(一)
- H5版俄罗斯方块(3)---游戏的AI算法
- 开发环境ubuntu16.04常用工具和设置(git、ssh、python、sh、java、Maven、mysql、postgresql)
- 推荐几本学习MySQL的好书
- 大数据 | 致敬科比的篮球生涯。
- opencv实现电子试卷图片中对号、错误的检测
- feedburner怎么用_在FeedSky和FeedBurner中无缝切换
- 安装ie9提示未能完成安装_ie9无法安装的原因以及安装步骤【图文教程】
- 第一讲:PN结的形成
- 浙江更新了小学3年级到9年级信息技术课,小学开始学编程
- 深度 | 巨头都在追逐的眼球追踪技术,究竟能带来什么?
- Linux环境创建oracle数据库
- Because an app is obscuring a permission request, Settings can't verify your response
- nodemcu写入HTML,(一)nodemcu进阶:从Web浏览器控制LED
- 思科VTP协议及其配置
热门文章
- python describe函数_Python基础知识点梳理2,推荐收藏
- 注释和特殊字符(HTML)
- input 禁止输入特殊字符
- OpenRowSet导入Excel大批量数据
- 一起来学SpringBoot | 第二篇:SpringBoot配置详解
- 网络爬虫随记:2018-03-12启(refreshing)
- Requirejs常用配置和应用
- arch linux windows,windows+Archlinux双系统安装指南(一)
- mysql 命令 字符集_MySQL的字符集操作命令总结
- Learnopengl