SlideShare une entreprise Scribd logo
1  sur  53
Télécharger pour lire hors ligne
OpenResty 项目模块化最佳实践
更优雅的组织 OpenResty 项目模块
张金政
tianchaijz@gmail.com
December 23, 2017
0
ngx_lua 模块配置指令执行顺序和阶段
https://github.com/openresty/lua-nginx-module
1
一个简单的鉴权网关
-- module access
local _M = {}
function _M.check()
-- ...
end
return _M
2
一个简单的鉴权网关
-- module access
local _M = {}
function _M.check()
-- ...
end
return _M
location / {
access_by_lua_block {
require("mod.access").check()
}
}
2
复杂一点
2
一个复杂的网关
location / {
rewrite_by_lua_block {
if ngx.is_subrequest then
return
end
-- ...
}
access_by_lua_block {
-- module access
-- other features
}
}
3
一个复杂的网关
复杂的模块调用,耦合度高,不灵活
4
缺点
• 模块之间耦合度高
• 模块组织不灵活
• 很多复杂请求不好处理,无法发挥 OpenResty 的威力
5
那么问题来了
增删一个模块
5
其他 location 需要处理类似的逻辑
5
subrequest
5
模块框架
借鉴了 NGINX 的模块机制,将模块调用关系组织
成一个链表
5
对请求分类,将请求处理流程注册到框架中
5
在主请求中进行路由
5
lua-resty-master
102 行 Lua 代码,简单强大
6
模块方法
• new
• run
• exec
• set_type
• next_handler
• export
7
一个简单的鉴权网关
local MODULE = "http.mod.access"
local core = require "resty.master.core"
local function check(r)
-- do check here
return r:next_handler(MODULE)
end
return {
[core.ACCESS_PHASE] = { handler = check }
}
return _M
8
一个简单的鉴权网关
-- lua config
local _M
_M.handlers = {
main = {
"http.mod.access", -- access
},
}
return _M
9
一个简单的鉴权网关
init_worker_by_lua_block {
local config = require "config"
local request = require "resty.master.request"
for typ, hs in pairs(config.handlers) do
request.register(typ, hs)
end
}
10
一个简单的鉴权网关
location / {
access_by_lua_block {
local request = require "resty.master.request"
local r = request.new("main")
r:run(r.ACCESS_PHASE)
}
}
11
新增加的模块只需配置一下
11
一个简单的鉴权网关
-- lua config
local _M
_M.handlers = {
main = {
"http.mod.access", -- access
"http.mod.finalize", -- access
},
}
return _M
12
一个简单的鉴权网关
-- lua config
local _M
_M.handlers = {
main = {
"http.mod.access", -- access
"http.mod.finalize", -- access 只需配置
},
}
return _M
12
一个复杂的网关
-- lua config
local _M
_M.handlers = {
main = {
"http.mod.router", -- rewrite
"http.mod.access", -- access
"http.mod.finalize", -- access
},
["@subrequest"] = {
"http.mod.subrequest" -- rewrite
},
["@bypass"] = {
"http.mod.finalize", -- access
},
["@internal"] = {
-- header_filter
{ "http.mod.common", { [HEADER_FILTER] = true } },
},
}
13
一个复杂的网关
local MODULE = "http.mod.router"
local core = require "resty.master.core"
local function route(r)
if ngx.is_subrequest then
return r:exec("@subrequest")
end
if expr then
return r:exec("@bypass")
end
return r:next_handler(MODULE)
end
return {
[core.REWRITE_PHASE] = { handler = route }
}
14
一个复杂的网关
rewrite_by_lua_block {
local r = require("resty.master.request").new("main")
ngx.ctx.request = r
r:run(r.REWRITE_PHASE)
}
access_by_lua_block {
local r = ngx.ctx.request
r:run(r.ACCESS_PHASE)
}
15
一个复杂的网关
复杂的模块调用,耦合度低,灵活
16
优点
• ngx_lua hooks 都变成了占位符,无任何逻辑
• 配合 ngx.exec 能发挥出 OpenResty 更大的威力
• 项目组织完全配置化
17
为所欲为
只需修改配置
• 增删一个模块
• 其他 location 需要处理类似的逻辑
• subrequest
18
只需修改配置
• 增删一个模块
• 其他 location 需要处理类似的逻辑
• subrequest
这些问题已不存在
18
面向配置编程
18
优点不止这些
让开发者重新审视自己的模块
18
让开发精力集中到项目架构中
18
快乐编程
18
小技巧
小技巧
• 把处理好的 NGINX 变量都放在 request 对象中
• 一个专门的 finalize 模块做请求处理收尾,设置 NGINX 变量
• ngx.exec 时使用 freelist 算法优雅的保存 ngx.ctx 变量
19
优雅的保存 ngx.ctx
local stash_ctx = require("mod.ngx_ctx").stash
local function go(r)
stash_ctx() -- save ngx.ctx
-- r:set_type("fetch")
return ngx.exec("/content")
end
20
优雅的保存 ngx.ctx
local stash_ctx = require("mod.ngx_ctx").stash
local function go(r)
stash_ctx() -- save ngx.ctx
-- r:set_type("fetch")
return ngx.exec("/content")
end
location /content {
content_by_lua_block {
require("mod.ngx_ctx").apply()
local r = ngx.ctx.request
r:run(r.REWRITE_PHASE)
}
}
20
序列化 request 对象
local function serialize(r)
local rdata = {}
for k, v in pairs(r) do
if is_str(k) and string_sub(k, 1, 1) ~= "_"
and not is_func(v) then
rdata[k] = v
end
end
return cmsgpack.pack(rdata)
end
21
使用案例
文件分片
• 优雅的隔离 subrequest
22
视频 seek
• 获取视频元数据 + 视频 seek 后的内容
23
视频 seek
24
CDN 私有请求
将私有请求直接路由到一个没有权限校验的处理流程中
• 绕过鉴权
• 文件预热
• 刷新 URL 转换
25
推而广之
在其他非 OpenResty 项目中尝试使用这种模块机制
25
https://github.com/openresty-fan/lua-resty-master
Questions?
26
广告
26

Contenu connexe

Tendances

Mysql multi threaded_server_introduction
Mysql multi threaded_server_introductionMysql multi threaded_server_introduction
Mysql multi threaded_server_introductionlazydba
 
在開始工作以前,我以為我會寫扣。
在開始工作以前,我以為我會寫扣。在開始工作以前,我以為我會寫扣。
在開始工作以前,我以為我會寫扣。Chih-Hsuan Kuo
 
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型keelii
 
Golangintro
GolangintroGolangintro
Golangintro理 傅
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)wang hongjiang
 
Analysis of Adobe's RTMFP Protocol
Analysis of Adobe's RTMFP ProtocolAnalysis of Adobe's RTMFP Protocol
Analysis of Adobe's RTMFP ProtocolChangming Sun
 
DNS协议与应用简介
DNS协议与应用简介DNS协议与应用简介
DNS协议与应用简介琛琳 饶
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用琛琳 饶
 
Sql调优clustering factor影响数据删除速度一例
Sql调优clustering factor影响数据删除速度一例Sql调优clustering factor影响数据删除速度一例
Sql调优clustering factor影响数据删除速度一例maclean liu
 
Effective linux.2.(tools)
Effective linux.2.(tools)Effective linux.2.(tools)
Effective linux.2.(tools)wang hongjiang
 
Unix socket
Unix socketUnix socket
Unix socketst900278
 
Linux Network Monitoring
Linux Network MonitoringLinux Network Monitoring
Linux Network MonitoringKenny (netman)
 
Gdb principle
Gdb principleGdb principle
Gdb principlelibfetion
 
部署並執行以太坊智能合約
部署並執行以太坊智能合約部署並執行以太坊智能合約
部署並執行以太坊智能合約Nicholas Lin
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closureswang hongjiang
 
twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹twMVC
 
Mongo db架构之优先方案
Mongo db架构之优先方案Mongo db架构之优先方案
Mongo db架构之优先方案Lucien Li
 
BASH 漏洞深入探討
BASH 漏洞深入探討BASH 漏洞深入探討
BASH 漏洞深入探討Tim Hsu
 
深入浅出Netty l.t
深入浅出Netty   l.t深入浅出Netty   l.t
深入浅出Netty l.toleone
 
Lua gc代码
Lua gc代码Lua gc代码
Lua gc代码Wei Sun
 

Tendances (20)

Mysql multi threaded_server_introduction
Mysql multi threaded_server_introductionMysql multi threaded_server_introduction
Mysql multi threaded_server_introduction
 
在開始工作以前,我以為我會寫扣。
在開始工作以前,我以為我會寫扣。在開始工作以前,我以為我會寫扣。
在開始工作以前,我以為我會寫扣。
 
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型
 
Golangintro
GolangintroGolangintro
Golangintro
 
Effective linux.1.(commandline)
Effective linux.1.(commandline)Effective linux.1.(commandline)
Effective linux.1.(commandline)
 
Analysis of Adobe's RTMFP Protocol
Analysis of Adobe's RTMFP ProtocolAnalysis of Adobe's RTMFP Protocol
Analysis of Adobe's RTMFP Protocol
 
DNS协议与应用简介
DNS协议与应用简介DNS协议与应用简介
DNS协议与应用简介
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用
 
Sql调优clustering factor影响数据删除速度一例
Sql调优clustering factor影响数据删除速度一例Sql调优clustering factor影响数据删除速度一例
Sql调优clustering factor影响数据删除速度一例
 
Effective linux.2.(tools)
Effective linux.2.(tools)Effective linux.2.(tools)
Effective linux.2.(tools)
 
Unix socket
Unix socketUnix socket
Unix socket
 
Linux Network Monitoring
Linux Network MonitoringLinux Network Monitoring
Linux Network Monitoring
 
Gdb principle
Gdb principleGdb principle
Gdb principle
 
部署並執行以太坊智能合約
部署並執行以太坊智能合約部署並執行以太坊智能合約
部署並執行以太坊智能合約
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
 
twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹twMVC#43 C#10 新功能介紹
twMVC#43 C#10 新功能介紹
 
Mongo db架构之优先方案
Mongo db架构之优先方案Mongo db架构之优先方案
Mongo db架构之优先方案
 
BASH 漏洞深入探討
BASH 漏洞深入探討BASH 漏洞深入探討
BASH 漏洞深入探討
 
深入浅出Netty l.t
深入浅出Netty   l.t深入浅出Netty   l.t
深入浅出Netty l.t
 
Lua gc代码
Lua gc代码Lua gc代码
Lua gc代码
 

Similaire à OpenResty 项目模块化最佳实践

高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕ideawu
 
2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江thinkinlamp
 
2011 06-12-lamp-mysql
2011 06-12-lamp-mysql2011 06-12-lamp-mysql
2011 06-12-lamp-mysqlpwesh
 
Mysql handlersocket
Mysql handlersocketMysql handlersocket
Mysql handlersocketpwesh
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍gowell
 
Mysql proxy+mysql-mmm
Mysql proxy+mysql-mmmMysql proxy+mysql-mmm
Mysql proxy+mysql-mmmYiwei Ma
 
Nginx使用和模块开发
Nginx使用和模块开发Nginx使用和模块开发
Nginx使用和模块开发qingpiao1983
 
181201_CoAP_coding365
181201_CoAP_coding365181201_CoAP_coding365
181201_CoAP_coding365Peter Yi
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践yiditushe
 
twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC
 
Nginx+常见应用技术指南
Nginx+常见应用技术指南Nginx+常见应用技术指南
Nginx+常见应用技术指南andy54321
 
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境均民 戴
 
使用kslite支持第三方内容开发
使用kslite支持第三方内容开发使用kslite支持第三方内容开发
使用kslite支持第三方内容开发leneli
 
Kissy模块化实践
Kissy模块化实践Kissy模块化实践
Kissy模块化实践yiming he
 
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUGYingSiang Geng
 
康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)Yiwei Ma
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识yiditushe
 
iOS中Lua脚本的应用
iOS中Lua脚本的应用iOS中Lua脚本的应用
iOS中Lua脚本的应用Proteas Wang
 
Mongodb
MongodbMongodb
Mongodbbj
 
配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制maclean liu
 

Similaire à OpenResty 项目模块化最佳实践 (20)

高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕
 
2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江2011 06-12-lamp-mysql-顾春江
2011 06-12-lamp-mysql-顾春江
 
2011 06-12-lamp-mysql
2011 06-12-lamp-mysql2011 06-12-lamp-mysql
2011 06-12-lamp-mysql
 
Mysql handlersocket
Mysql handlersocketMysql handlersocket
Mysql handlersocket
 
Lua 语言介绍
Lua 语言介绍Lua 语言介绍
Lua 语言介绍
 
Mysql proxy+mysql-mmm
Mysql proxy+mysql-mmmMysql proxy+mysql-mmm
Mysql proxy+mysql-mmm
 
Nginx使用和模块开发
Nginx使用和模块开发Nginx使用和模块开发
Nginx使用和模块开发
 
181201_CoAP_coding365
181201_CoAP_coding365181201_CoAP_coding365
181201_CoAP_coding365
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
 
twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧
 
Nginx+常见应用技术指南
Nginx+常见应用技术指南Nginx+常见应用技术指南
Nginx+常见应用技术指南
 
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
COSCUP 2016 Workshop: 用 Docker 架設班級 git-it 練習環境
 
使用kslite支持第三方内容开发
使用kslite支持第三方内容开发使用kslite支持第三方内容开发
使用kslite支持第三方内容开发
 
Kissy模块化实践
Kissy模块化实践Kissy模块化实践
Kissy模块化实践
 
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
探索 ISTIO 新型 DATA PLANE 架構 AMBIENT MESH - GOLANG TAIWAN GATHERING #77 X CNTUG
 
康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)康盛创想项目部Linux 服务器部署标准(最新版)
康盛创想项目部Linux 服务器部署标准(最新版)
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识
 
iOS中Lua脚本的应用
iOS中Lua脚本的应用iOS中Lua脚本的应用
iOS中Lua脚本的应用
 
Mongodb
MongodbMongodb
Mongodb
 
配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制配置Oracle 10g 双向流复制
配置Oracle 10g 双向流复制
 

OpenResty 项目模块化最佳实践