OpenResty 官網(wǎng):http://openresty.org/ ?OpenResty? - 中文官方站 http://openresty.org/cn/
OpenResty 是一個(gè)nginx和它的各種三方模塊的一個(gè)打包而成的軟件平臺(tái)。最重要的一點(diǎn)是它將lua/luajit打包了進(jìn)來(lái),使得我們可以使用lua腳本來(lái)進(jìn)行web的開(kāi)發(fā)。有了lua,我們可以借助于nginx的異步非阻塞的功能,達(dá)到使用 lua 異步并發(fā)訪問(wèn)后端的 MySQL, PostgreSQL, Memcached, Redis等等服務(wù)。特別是特有的 ngx.location.capture_multi 功能讓人印象深刻,其可以達(dá)到極大的減少瀏覽器的http連接數(shù)量,并且可以異步并發(fā)的訪問(wèn)后臺(tái) Java/PHP/Python 等等接口。OpenResty 架構(gòu)的web可以輕松超越Node.js的性能,并且對(duì)后端語(yǔ)言沒(méi)有限制,你可以使用Java/PHP/Python等等各種語(yǔ)言。OpenResty(nginx+lua)可以替代node.js的前端渲染的功能。
火云邪神語(yǔ)錄:天下武功,無(wú)堅(jiān)不破,唯快不破!Nginx的看家本領(lǐng)就是速度,Lua的拿手好戲亦是速度,這兩者的結(jié)合在速度上無(wú)疑有基因上的優(yōu)勢(shì)。
最先將Nginx,Lua組合到一起的是OpenResty,它有一個(gè)ngx_lua模塊,將Lua嵌入到了Nginx里面;隨后Tengine也包含了ngx_lua模塊。至于二者的區(qū)別:OpenResty是Nginx的Bundle;而Tengine則是Nginx的Fork。值得一提的是,OpenResty和Tengine均是國(guó)人自己創(chuàng)建的項(xiàng)目,前者主要由春哥和曉哲開(kāi)發(fā),后者主要由淘寶打理。
至于OpenResty和Tengine孰優(yōu)孰劣,留給大家自己判斷,如下資料可供參考:
ngx_openresty: an Nginx ecosystem glued by Lua
淘寶網(wǎng)Nginx應(yīng)用、定制與開(kāi)發(fā)實(shí)戰(zhàn)
推薦看看春哥在Tech-Club上關(guān)于『由Lua粘合的Nginx生態(tài)環(huán)境』的演講實(shí)錄,有料!
安裝
需要最新版的Nginx,LuaJIT,ngx_devel_kit,ngx_lua等安裝文件。
安裝Lua或者LuaJIT都是可以的,但是出于效率的考慮,推薦安裝LuaJIT。
詳細(xì)參考:Nginx與Lua | 火丁筆記 https://huoding.com/2012/08/31/156
OpenResty (aka. ngx_openresty) is a full-fledged web application server by bundling the standard?Nginx?core, lots of?3rd-party Nginx modules, as well as most of their external dependencies.
By taking advantage of various well-designed Nginx modules, OpenResty effectively turns the nginx server into a powerful web app server, in which the web developers?can use the Lua programming language to script various existing nginx C modules and Lua modules?and construct extremely high-performance web applications that are capable to handle 10K+ connections.
OpenResty aims to run your server-side web app completely in the Nginx server, leveraging Nginx's event model to?do non-blocking I/O not only with the HTTP clients,?but also with remote backends like MySQL, PostgreSQL, Memcached, and Redis.
1. 安裝OpenResty
先安裝依賴(lài):yum install readline-devel pcre-devel openssl-devel gcc
解壓: tar zxvf ngx_openresty-1.9.3.1.tar.gz
建立一個(gè)軟連接:ln -s ngx_openresty-1.9.3.1 openresty
進(jìn)入目錄:cd openresty
編譯:
./configure \
? ? ? ? ? ? --with-cc-opt="-I/usr/local/include" \
? ? ? ? ? ? --with-ld-opt="-L/usr/local/lib" \
? ? ? ? ? ? --prefix=/opt/openresty
... ...
Configuration summary
? + using system PCRE library
? + using system OpenSSL library
? + md5: using OpenSSL library
? + sha1: using OpenSSL library
? + using system zlib library
? nginx path prefix: "/opt/openresty/nginx"
? nginx binary file: "/opt/openresty/nginx/sbin/nginx"
? nginx configuration prefix: "/opt/openresty/nginx/conf"
? nginx configuration file: "/opt/openresty/nginx/conf/nginx.conf"
? nginx pid file: "/opt/openresty/nginx/logs/nginx.pid"
? nginx error log file: "/opt/openresty/nginx/logs/error.log"
? nginx http access log file: "/opt/openresty/nginx/logs/access.log"
? nginx http client request body temporary files: "client_body_temp"
? nginx http proxy temporary files: "proxy_temp"
? nginx http fastcgi temporary files: "fastcgi_temp"
? nginx http uwsgi temporary files: "uwsgi_temp"
? nginx http scgi temporary files: "scgi_temp"
其中 --prefix=/opt/openresty 指定了安裝目錄,不指定的話默認(rèn)會(huì)安裝到 /usr/local/openresty 目錄下。
編譯安裝: make && make install
[root@localhost src]# cd /opt/openresty/
[root@localhost openresty]# ls
bin? luajit? lualib? nginx
可以看到 /opt/openresty 目錄下四個(gè)文件夾,其中包括了 luajit,nginx。
啟動(dòng)openresty: /opt/openresty/nginx/sbin/nginx -c /opt/openresty/nginx/conf/nginx.conf -p /opt/openresty/nginx/
[root@localhost src]# ps -elf|grep nginx
1 S root? ? ? 2076? ? 1? 0? 80? 0 - 34999 -? ? ? 21:24 ?? ? ? ? 00:00:00 nginx: master process /opt/openresty/nginx/sbin/nginx -c /opt/openresty/nginx/conf/nginx.conf -p /opt/openresty/nginx/
5 S nobody? ? 2077? 2076? 0? 80? 0 - 35045 -? ? ? 21:24 ?? ? ? ? 00:00:00 nginx: worker process? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
0 S root? ? ? 2079? 1678? 0? 80? 0 -? 1088 -? ? ? 21:24 pts/1? ? 00:00:00 grep nginx
驗(yàn)證可以訪問(wèn): curl 127.0.0.1
2. content_by_lua 和 content_by_lua_file
nginx 如何嵌入 lua 腳本。方法就是在nginx的配置文件nginx.conf 中使用 content_by_lua 或者 cotent_by_lua_file 指令:
1) content_by_lua 一般在很簡(jiǎn)單的lua腳本時(shí)使用:
? ? ? ? location /lua {
? ? ? ? ? ? ? ? set $test "hello, world.";
? ? ? ? ? ? ? ? content_by_lua '
? ? ? ? ? ? ? ? ? ? ? ? ngx.header.content_type = "text/plain";
? ? ? ? ? ? ? ? ? ? ? ? ngx.say(ngx.var.test);
? ? ? ? ? ? ? ? ';
? ? ? ? }
訪問(wèn) http://localhost/lua 可以看到輸出到頁(yè)面的??hello, world.
2)cotent_by_lua_file 適應(yīng)于復(fù)雜的 lua 腳本,專(zhuān)門(mén)放入一個(gè)文件中:
? ? ? ? location /lua2 {
? ? ? ? ? ? #lua_code_cache off;
? ? ? ? ? ? content_by_lua_file lua/hello.lua;
? ? ? ? }
路徑相對(duì)于 /opt/openresty/nginx
[root@localhost lua]# pwd
/opt/openresty/nginx/lua
[root@localhost lua]# cat hello.lua
ngx.say('hello ngx_lua!!!!');
本例子中 hello.lua 只包含一句: ngx.say('hello ngx_lua!!!!');
訪問(wèn) /lua2 :
[root@localhost lua]# curl localhost/lua
hello ngx_lua!!!!
可以看到訪問(wèn)成功。
在 nginx.conf 文件的 server {.. ...} 中加入?lua_code_cache off;?可以方便調(diào)試lua腳本,修改lua腳本之后,不需要 reload nginx.
openresty 中的 nginx 嵌入 luajit 的原理:
每一個(gè)nginx的進(jìn)程中都嵌入了一個(gè) luajit的虛擬機(jī),來(lái)執(zhí)行l(wèi)ua腳本。nginx將lua腳本的執(zhí)行交給了luajit vm.
3. ngx_lua 的指令 和 API
上面我們說(shuō)到 nginx 嵌入 lua 腳本可以使用 content_by_lua 和 content_by_lua_file,它們其實(shí)是指令(Directives),類(lèi)似的指令還有很多,
具體參見(jiàn):https://www.nginx.com/resources/wiki/modules/lua/#directives
這些指令都是 nginx 訪問(wèn) lua 腳本的入口。
ngx_lua API:
指令是 nginx 訪問(wèn) lua 腳本的入口。那么lua腳本如何調(diào)用nginx中的函數(shù)呢?就是通過(guò) ngx_lua 的API 。
具體介紹參見(jiàn):https://www.nginx.com/resources/wiki/modules/lua/#nginx-api-for-lua
The various?*_by_lua?and?*_by_lua_file?configuration?directives?serve as gateways?to the Lua API within the?nginx.conf?file. The?NGINX Lua API described below can only be called within the user Lua code?run in the context of these configuration directives.
The API is exposed to Lua in the form of two standard packages?ngx?and?ndk. These packages are in the default global scope within ngx_lua and are always available within ngx_lua directives.
其實(shí)nginx和Lua的交互開(kāi)發(fā)主要就是指令和API,當(dāng)然還有l(wèi)ua腳本的語(yǔ)法。指令是nginx訪問(wèn)lua的入口,API是lua調(diào)用nginx的函數(shù),lua是腳本編程語(yǔ)言。
指令其實(shí)很簡(jiǎn)單,所以主要就是熟悉ngx_lua的 API 和Lua語(yǔ)法。
4. lua 訪問(wèn) redis
lua-resty-redis 模塊:https://github.com/openresty/lua-resty-redis (有文檔可以參考)
在nginx.conf中加入:
? ? ? ? location /redis_test{
? ? ? ? ? ? content_by_lua_file lua/redis_test.lua;
? ? ? ? }
redis_test.lua 內(nèi)容:
[root@localhost lua]# cat redis_test.lua
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
? ? ? ? ngx.say("failed to connect: ", err)
? ? ? ? return
end
ngx.say("set result: ", ok)
local res, err = red:get("dog")
if not res then
? ? ? ? ngx.say("failed to get doy: ", err)
? ? ? ? return
end
if res == ngx.null then
? ? ? ? ngx.say("dog not found.")
? ? ? ? return
end
ngx.say("dog: ", res)
[root@localhost lua]#
訪問(wèn):
[root@localhost lua]# curl localhost/redis_test
set result: 1
dog: an animal
[root@localhost lua]#
我們看到訪問(wèn)成功。
5. lua 訪問(wèn)mysql
openresty的mysql模塊:lua-resty-mysql :https://github.com/openresty/lua-resty-mysql(有文檔可以參考)
在nginx.conf加入如下配置:
? ? ? ? location /mysql_test {
? ? ? ? ? ? content_by_lua_file lua/mysql_test.lua;
? ? ? ? }
mysql_test.lua腳本內(nèi)容:
[root@localhost lua]# pwd
/opt/openresty/nginx/lua
[root@localhost lua]# cat mysql_test.lua
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
? ? ? ? ngx.say("failed to instantiate mysql: ", err)
? ? ? ? return
end
db:set_timeout(1000)
local ok, err, errno, sqlstate = db:connect{
? ? ? ? host = "127.0.0.1",
? ? ? ? port = 3306,
? ? ? ? database = "ngx_lua",
? ? ? ? user = "root",
? ? ? ? password="digdeep",
? ? ? ? max_packet_size = 1024 * 1024
}
if not ok then
? ? ? ? ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate)
? ? ? ? return
end
ngx.say("connected to mysql.")
local res, err, errno, sqlstate = db:query("drop table if exists cats")
if not res then
? ? ? ? ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
? ? ? ? return
end
res, err, errno, sqlstate = db:query("create table cats " .. "(id int not null primary key auto_increment, "
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .. "name varchar(30))")
if not res then
? ? ? ? ngx.say("bad result: ", err, ": ", errno, ": ", sqlstate, ".")
? ? ? ? return
end
ngx.say("table cats created.")
res, err, errno, sqlstate = db:query("insert into cats(name) " .. "values (\'Bob\'),(\'\'),(null)")
if not res then
? ? ? ? ngx.say("bad request: ", err, ": ", errno, ": ", sqlstate, ".")
? ? ? ? return
end
ngx.say(res.affected_rows, " rows inserted into table cats ", "(last insert id: ", res.insert_id, ")")
res, err, errno, sqlstate = db:query("select * from cats order by id asc", 10)
if not res then
? ? ? ? ngx.say("bad result ", err, ": ", errno, ": ", sqlstate, ".")
? ? ? ? return
end
local cjson = require "cjson"
ngx.say("result: ", cjson.encode(res))
local ok, err = db:set_keepalive(1000, 100)
if not ok then
? ? ? ? ngx.say("failed to set keepalive: ", err)
? ? ? ? return
end
測(cè)試:
[root@localhost lua]# curl localhost/mysql_test
connected to mysql.
table cats created.
3 rows inserted into table cats (last insert id: 1)
result: [{"name":"Bob","id":1},{"name":"","id":2},{"name":null,"id":3}]
測(cè)試通過(guò)。
5. lua 的 capture 和 capture_multi(子查詢(xún))
capture_multi 是 openresty 一個(gè)十分強(qiáng)大的功能。它能極大的減少前端瀏覽器發(fā)送的http請(qǐng)求的數(shù)量,突破了瀏覽器對(duì)于同一個(gè)服務(wù)器并發(fā)請(qǐng)求數(shù)量的限制,因?yàn)樗梢詫⑶岸说亩鄠€(gè)http請(qǐng)求減少為只要一個(gè)http請(qǐng)求到nginx,然后nginx使用capture_multi特性,對(duì)后端發(fā)起多個(gè)異步并發(fā)請(qǐng)求,然后統(tǒng)一將結(jié)果返回給前端。下面看一個(gè)例子:
首先在nginx.conf中加入下面的 location 配置,并且配置好 nginx 訪問(wèn) php 的配置:
? ? ? ? location /capture {
? ? ? ? ? ? content_by_lua_file lua/capture.lua;
? ? ? ? ? ? #access_by_lua_file lua/capture.lua;
? ? ? ? }
? ? ? ? location ~ \.php$ {
? ? ? ? ? ? root? ? ? ? ? html;
? ? ? ? ? ? fastcgi_pass? 127.0.0.1:9000;
? ? ? ? ? ? fastcgi_index? index.php;
? ? ? ? ? ? fastcgi_param? SCRIPT_FILENAME? $document_root$fastcgi_script_name;
? ? ? ? ? ? include? ? ? ? fastcgi_params;
? ? ? ? }
capture.lua 的代碼如下:
[root@localhost lua]# pwd
/opt/openresty/nginx/lua
[root@localhost lua]# cat capture.lua
local res1,res2,res3,res4 = ngx.location.capture_multi{
? ? ? ? {"/mysql_test", {args="t=1&id=1"}},
? ? ? ? {"/redis_test", {args="t=2&id=2"}},
? ? ? ? {"/lua", {args="t=3&id=3"}},
? ? ? ? {"/index.php", {args="t=3&id=3"}},
}
ngx.header.content_type="text/plain"
ngx.say(res1.body)
ngx.say(res2.body)
ngx.say(res3.body)
ngx.say(res4.truncated)
ngx.say(res4.status)
ngx.say(res4.header["Set-Cookie"])
--ngx.say(res4.body)
index.php 代碼:
[root@localhost html]# pwd
/opt/openresty/nginx/html
[root@localhost html]# cat index.php
<?php
? ? ? ? echo phpinfo();
?>
訪問(wèn):
[root@localhost html]# curl localhost/capture
connected to mysql.
table cats created.
3 rows inserted into table cats (last insert id: 1)
result: [{"name":"Bob","id":1},{"name":"","id":2},{"name":null,"id":3}]
set result: 1
dog: an animal
hello ngx_lua!!!!
false
200
nil
可以看到訪問(wèn)成功了。/mysql_test,/redis_test,?/lua,?/index.php 四個(gè)請(qǐng)求的結(jié)果都輸出了。
注意:
ngx.location.capture_multi{... ...} 中的多個(gè)異步并發(fā)請(qǐng)求可以是 nginx.conf 中配置的 location(比如 /mysql_test, /redis_test, /lua),也可以不是 location配置的路徑,比如 index.php 就不是。index.php 就是一個(gè)簡(jiǎn)單的后臺(tái)php 腳本。當(dāng)然也可以是一個(gè) java 實(shí)現(xiàn)的后臺(tái)接口。
6. openresty的緩存 lua_shared_dict
定義一個(gè)緩存:
在nginx的配置文件 nginx.conf 的 http 端下面加入指令:
lua_shared_dict ngx_cache 128m;
就定義了一個(gè) 名稱(chēng)為 ngx_cache 大小為128m的內(nèi)存用于緩存,注意該緩存是所有nginx work process所共享的。
在lua腳本中訪問(wèn)緩存:
local ngx_cache = ngx.shared.ngx_cache
local value = ngx_cache:get(key)
local succ, err, forcible = ngx_cache:set(key, value, exptime)
下面測(cè)試一下,首先在 nginx.conf的server端中加入:
? ? ? ? location /cache {
? ? ? ? ? ? content_by_lua_file lua/cache.lua;
? ? ? ? }
然后編寫(xiě) cache.lua 腳本:
[root@localhost lua]# cat cache.lua
local redis = require "resty.redis"
local red = redis:new()
function set_to_cache(key, value, exptime)
? ? ? ? if not exptime then
? ? ? ? ? ? ? ? exptime = 0
? ? ? ? end
? ? ? ? local ngx_cache = ngx.shared.ngx_cache
? ? ? ? local succ, err, forcible = ngx_cache:set(key, value, exptime)
? ? ? ? return succ
end
function get_from_cache(key)
? ? ? ? local ngx_cache = ngx.shared.ngx_cache;
? ? ? ? local value = ngx_cache:get(key)
? ? ? ? if not value then
? ? ? ? ? ? ? ? value = get_from_redis(key)
? ? ? ? ? ? ? ? set_to_cache(key, value)
? ? ? ? ? ? ? ? return value
? ? ? ? end
? ? ? ? ngx.say("get from cache.")
? ? ? ? return value
end
function get_from_redis(key)
? ? ? ? red:set_timeout(1000)
? ? ? ? local ok, err = red:connect("127.0.0.1", 6379)
? ? ? ? if not ok then
? ? ? ? ? ? ? ? ngx.say("failed to connect: ", err)
? ? ? ? ? ? ? ? return
? ? ? ? end
? ? ? ? local res, err = red:get(key)
? ? ? ? if not res then
? ? ? ? ? ? ? ? ngx.say("failed to get doy: ", err)
? ? ? ? ? ? ? ? return ngx.null
? ? ? ? end
? ? ? ? ngx.say("get from redis.")
? ? ? ? return res
end
function set_to_redis(key, value)
? ? ? ? red:set_timeout(1000)
? ? ? ? local ok, err = red:connect("127.0.0.1", 6379)
? ? ? ? if not ok then
? ? ? ? ? ? ? ? ngx.say("failed to connect: ", err)
? ? ? ? ? ? ? ? return
? ? ? ? end
? ? ? ? local ok, err = red:set(key, value)
? ? ? ? if not ok then
? ? ? ? ? ? ? ? ngx.say("failed to set to redis: ", err)
? ? ? ? ? ? ? ? return
? ? ? ? end
? ? ? ? return ok
end
set_to_redis('dog', "Bob")
local rs = get_from_cache('dog')
ngx.say(rs)
測(cè)試:
[root@localhost ~]# curl localhost/cache
get from redis.
Bob
[root@localhost ~]# curl localhost/cache
get from cache.
Bob
[root@localhost ~]# curl localhost/cache
get from cache.
Bob
第一次從 redis中獲取,以后每次都從cache中獲取。
可以使用 ab 測(cè)試一下rps(Requests per second):
ab -n 1000 -c 100 -k http://127.0.0.1/cache
7. 解決緩存失效風(fēng)暴 lua-resty-lock
緩存失效風(fēng)暴是指緩存因?yàn)闀r(shí)間過(guò)期而失效時(shí),會(huì)導(dǎo)致所有的請(qǐng)求都去訪問(wèn) 后臺(tái)的redis或者mysql,而導(dǎo)致CPU性能即刻增長(zhǎng)的現(xiàn)象。所以關(guān)鍵是當(dāng)緩存失效時(shí),用lock保證只有一個(gè)線程去訪問(wèn)后臺(tái)的redis或者mysql,然后更新緩存。需要使用到 lua-resty-lock 模塊的加鎖、解鎖功能。
lua-resty-lock 文檔:https://github.com/openresty/lua-resty-lock
首先在nginx.conf 的 http 端下面加入指令:
lua_shared_dict ngx_cache 128m;? ? # cache
lua_shared_dict cache_lock 100k;? ? # lock for cache
然后在nginx.conf的server端中加入:
? ? ? ? location /cache_lock {
? ? ? ? ? ? content_by_lua_file lua/cache_lock.lua;
? ? ? ? }
cache_lock.lua代碼:
cat cache_lock.lua
local redis = require "resty.redis"
local resty_lock = require "resty.lock"
local red = redis:new()
function set_to_cache(key, value, exptime)
? ? if not exptime then
? ? ? ? exptime = 0
? ? end
? ? local ngx_cache = ngx.shared.ngx_cache
? ? local succ, err, forcible = ngx_cache:set(key, value, exptime)
? ? return succ
end
function get_from_cache(key)
? ? local ngx_cache = ngx.shared.ngx_cache;
? ? local value = ngx_cache:get(key)
? ? if not value then
? ? ? ? value = get_from_redis(key)
? ? ? ? set_to_cache(key, value)
? ? ? ? return value
? ? end
? ? ngx.say("get from cache.")
? ? return value
end
function get_from_redis(key)
? ? red:set_timeout(1000)
? ? -- lock , then get cache
? ? local lock, err = resty_lock:new("cache_lock")
? ? if not lock then
? ? ? ? return fail("failed to create lock: ", err)
? ? end
? ? local elapsed, err = lock:lock("lock_cache_key")
? ? if not elapsed then
? ? ? ? ngx.log(log.ERR, "failed to acquire the lock: ", err)
? ? end
? ? ngx.sleep(5)
? ? local ok, err = red:connect("127.0.0.1", 6379)
? ? if not ok then
? ? ? ? ngx.say("failed to connect: ", err)
? ? ? ? --unlock
? ? ? ? local ok, err = lock:unlock()
? ? ? ? if not ok then
? ? ? ? ? ? return fail("failed to unlock: ", err)
? ? ? ? end
? ? ? ? return
? ? end
? ? local res, err = red:get(key)
? ? if not res then
? ? ? ? ngx.say("failed to get doy: ", err)
? ? ? ? --unlock
? ? ? ? local ok, err = lock:unlock()
? ? ? ? if not ok then
? ? ? ? ? ? return fail("failed to unlock: ", err)
? ? ? ? end
? ? ? ? return ngx.null
? ? end
? ? --unlock
? ? local ok, err = lock:unlock()
? ? if not ok then
? ? ? ? return fail("failed to unlock: ", err)
? ? end
? ? ngx.say("get from redis.")
? ? return res
end
function set_to_redis(key, value)
? ? red:set_timeout(1000)
? ? local ok, err = red:connect("127.0.0.1", 6379)
? ? if not ok then
? ? ? ? ngx.say("failed to connect: ", err)
? ? ? ? return
? ? end
? ? local ok, err = red:set(key, value)
? ? if not ok then
? ? ? ? ngx.say("failed to set to redis: ", err)
? ? ? ? return
? ? end
? ? return ok
end
local rs = get_from_cache('dog')
ngx.say(rs)
測(cè)試:
[root@localhost lua]# curl localhost/cache_lock
get from cache.
Bob
[root@localhost lua]# curl localhost/cache_lock
get from cache.
Bob
7. openresty 執(zhí)行階段
nginx的執(zhí)行階段分成了很多個(gè)階段,所以第三方模塊就可以在某個(gè)適當(dāng)?shù)碾A段加入一些處理。openresty進(jìn)行了簡(jiǎn)化成了7個(gè)階段:
7個(gè)階段的執(zhí)行順序如下:
set_by_lua: 流程分支判斷,判斷變量初始哈
rewrite_by_lua: 用lua腳本實(shí)現(xiàn)nginx rewrite
access_by_lua: ip準(zhǔn)入,是否能合法性訪問(wèn),防火墻
content_by_lua: 內(nèi)存生成
header_filter_by_lua:過(guò)濾http頭信息,增加頭信息
body_filter_by_lua: 內(nèi)容大小寫(xiě),內(nèi)容加密
log_by_lua: 本地/遠(yuǎn)程記錄日志
但是其實(shí)我們可以只用 content_by_lua,所有功能都在該階段完成,也是可以的。
總結(jié):
OpenResty??是一個(gè)基于?Nginx?與 Lua 的高性能 Web 平臺(tái),其內(nèi)部集成了大量精良的 Lua 庫(kù)、第三方模塊以及大多數(shù)的依賴(lài)項(xiàng)。用于方便地搭建能夠處理超高并發(fā)、擴(kuò)展性極高的動(dòng)態(tài) Web 應(yīng)用、Web 服務(wù)和動(dòng)態(tài)網(wǎng)關(guān)。
OpenResty??通過(guò)匯聚各種設(shè)計(jì)精良的?Nginx?模塊(主要由 OpenResty 團(tuán)隊(duì)自主開(kāi)發(fā)),從而將?Nginx有效地變成一個(gè)強(qiáng)大的通用 Web 應(yīng)用平臺(tái)。這樣,Web 開(kāi)發(fā)人員和系統(tǒng)工程師可以使用 Lua 腳本語(yǔ)言調(diào)動(dòng)?Nginx?支持的各種 C 以及 Lua 模塊,快速構(gòu)造出足以勝任 10K 乃至 1000K 以上單機(jī)并發(fā)連接的高性能 Web 應(yīng)用系統(tǒng)。
OpenResty??的目標(biāo)是讓你的Web服務(wù)直接跑在?Nginx?服務(wù)內(nèi)部,充分利用?Nginx?的非阻塞 I/O 模型,不僅僅對(duì) HTTP 客戶端請(qǐng)求,甚至于對(duì)遠(yuǎn)程后端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進(jìn)行一致的高性能響應(yīng)。
參考?組件?可以知道 OpenResty??中包含了多少軟件。
參考?上路?學(xué)習(xí)如何從最簡(jiǎn)單的 hello world 開(kāi)始使用 OpenResty??開(kāi)發(fā) HTTP 業(yè)務(wù),或前往?下載?直接獲取 OpenResty??的源代碼包開(kāi)始體驗(yàn)。
---------------------
作者:天府云創(chuàng)
來(lái)源:CSDN
原文:https://blog.csdn.net/enweitech/article/details/78519398
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!