OpenResty? 是一個基于 Nginx 與 Lua 的高性能 Web 平臺,其內(nèi)部集成了大量精良的 Lua 庫、第三方模塊以及大多數(shù)的依賴項。用于方便地搭建能夠處理超高并發(fā)、擴(kuò)展性極高的動態(tài) Web 應(yīng)用、Web 服務(wù)和動態(tài)網(wǎng)關(guān)。Web 開發(fā)人員和系統(tǒng)工程師可以使用 Lua 腳本語言調(diào)動 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 模型,不僅僅對 HTTP 客戶端請求,甚至于對遠(yuǎn)程后端諸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都進(jìn)行一致的高性能響應(yīng)。
下載安裝
以下操作指令摘抄自O(shè)penResty官網(wǎng),不做贅述。
sudo yum -y install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum -y install openresty
sudo yum -y install openresty-resty
安裝完成之后,我們進(jìn)入OpenResty所在目錄
cd /usr/local/openresty
ll

測試用例
- 創(chuàng)建測試用lua文件
cd /usr/local/openresty/lualib
mkdir test
cd test
vim test.lua
--用于接收前端數(shù)據(jù)的對象
local args=nil
--獲取前端的請求方式 并獲取傳遞的參數(shù)
local request_method = ngx.var.request_method
--判斷是get請求還是post請求并分別拿出相應(yīng)的數(shù)據(jù)
if"GET" == request_method then
args = ngx.req.get_uri_args()
elseif "POST" == request_method then
ngx.req.read_body()
args = ngx.req.get_post_args()
--兼容請求使用post請求,但是傳參以get方式傳造成的無法獲取到數(shù)據(jù)的bug
if (args == nil or args.data == null) then
args = ngx.req.get_uri_args()
end
end
--獲取前端傳遞的name值
local name = args.name
--響應(yīng)前端
ngx.say("linux hello:"..name)
- 配置nginx
openresty內(nèi)置nginx,使用openresty需要使用它內(nèi)部的nginx。
cd /usr/local/openresty/nginx/conf
vim nginx.conf
最終測試配置為
#user nobody;
worker_processes 2;
events {
use epoll;
worker_connections 150000;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /luatest
{
default_type text/html;
content_by_lua_file /usr/local/openresty/lualib/test/test.lua;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
AB壓力測試
安裝httpd-tools
yum -y install httpd-tools
試一把1w并發(fā),10w請求

提示
Too many open files (24)打開的文件太多了
查看允許打開的文件數(shù)
ulimit -a
修改允許打開的文件數(shù)
ulimit -n 204800

繼續(xù)試1w并發(fā),10w請求,出現(xiàn)
apr_socket_recv: Connection reset by peer (104)問題
apr_socket_recv這個是操作系統(tǒng)內(nèi)核的一個參數(shù),在高并發(fā)的情況下,內(nèi)核會認(rèn)為系統(tǒng)受到了
SYN flood(一種利用TCP協(xié)議缺陷,發(fā)送大量偽造的TCP連接請求,從而使得被攻擊方資源耗盡(CPU滿負(fù)荷或內(nèi)存不足)的攻擊方式)攻擊,導(dǎo)致未完成退出測試,所以在應(yīng)用服務(wù)武器上設(shè)置下這個參數(shù)為0禁用系統(tǒng)保護(hù)
進(jìn)入管理配置文件
vim /etc/sysctl.conf
#添加如下一行
net.ipv4.tcp_syncookies = 0
#保存退出后執(zhí)行
sysctl -p
擴(kuò)展(未測試)
net.ipv4.tcp_syncookies = 0
#此參數(shù)是為了防止洪水攻擊的,但對于大并發(fā)系統(tǒng),要禁用此設(shè)置
net.ipv4.tcp_max_syn_backlog
#參數(shù)決定了SYN_RECV狀態(tài)隊列的數(shù)量,一般默認(rèn)值為512或者1024,即超過這個數(shù)量,系統(tǒng)將不再接受新的TCP連接請求,一定程度上可以防止系統(tǒng)資源耗盡??筛鶕?jù)情況增加該值以接受更多的連接請求。
net.ipv4.tcp_tw_recycle
#參數(shù)決定是否加速TIME_WAIT的sockets的回收,默認(rèn)為0。
net.ipv4.tcp_tw_reuse
#參數(shù)決定是否可將TIME_WAIT狀態(tài)的sockets用于新的TCP連接,默認(rèn)為0。
net.ipv4.tcp_max_tw_buckets
好了,現(xiàn)在可以正常測試了
- 1w并發(fā)10w請求
ab -c 10000 -n 100000 127.0.0.1/luatest
結(jié)果:
#服務(wù)器信息,ip,端口
Server Software: openresty/1.13.6.2
Server Hostname: 127.0.0.1
Server Port: 80
#文檔/接口,響應(yīng)數(shù)據(jù)大小
Document Path: /luatest
Document Length: 541 bytes
#壓力測試的結(jié)果報表
#并發(fā)請求數(shù)
Concurrency Level: 10000
#測試耗時
Time taken for tests: 11.361 seconds
#完成請求數(shù)
Complete requests: 100000
#失敗請求數(shù)
Failed requests: 9
(Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
Write errors: 0
Non-2xx responses: 100000
#總網(wǎng)絡(luò)傳輸量
Total transferred: 73096724 bytes
#HTML內(nèi)容傳輸量
HTML transferred: 54096922 bytes
#吞吐量,平均每秒處理請求數(shù)
Requests per second: 8801.77 [#/sec] (mean)
#前端請求平均時間
Time per request: 1136.135 [ms] (mean)
#服務(wù)平均處理請求的時間
Time per request: 0.114 [ms] (mean, across all concurrent requests)
#網(wǎng)絡(luò)傳輸速度。對于大文件的請求測試,這個值很容易成為系統(tǒng)瓶頸所在。
Transfer rate: 6283.01 [Kbytes/sec] received
#時間消耗報表針對請求平均等待時間`Time per request`的細(xì)化分析,只是了解
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 304 884.1 14 7055
Processing: 3 35 65.5 23 11029
Waiting: 0 29 63.4 18 11029
Total: 6 339 902.2 36 11226
#請求時間分布,50%的請求在36毫秒內(nèi)處理完畢。90%的請求在1077毫秒內(nèi)處理完畢,最長響應(yīng)時間為11226毫秒
Percentage of the requests served within a certain time (ms)
50% 36
66% 61
75% 101
80% 171
90% 1077
95% 1197
98% 3160
99% 3235
100% 11226 (longest request)
提取部分參數(shù)稍微總結(jié)下:
吞吐量(每秒處理的請求數(shù)):8801.77
驗證:吞吐量(8801.77) * 測試耗時 (11.361) 約等于10W
用戶平均等待時間:1136.135
服務(wù)器平均處理時間:0.114
驗證:由于服務(wù)器并發(fā)量為1W,那用戶前端響應(yīng)時間,應(yīng)該接近服務(wù)器平均處理時間 * 1w,0.114*10000=1140,1136.135約等于1140
90%的請求在1077ms內(nèi)完成,最長的請求耗時11226毫秒。
網(wǎng)絡(luò)傳輸速度:6283.01kb
- 2w并發(fā)10w請求
ab -c 20000 -n 100000 127.0.0.1/luatest
這里簡單分析標(biāo)出重要數(shù)據(jù)

總結(jié)
這里主要測試openresty(實際上是nginx)平臺的并發(fā)能力,用于測試的電腦,為2核4G的筆記本,2W的并發(fā)沒有什么壓力,可惜AB測試有上限,不太方便做極限測試。
簡單來說,OpenResty提供了一種Nginx處理請求,lua腳本處理邏輯(操作MySQL,Redis等)的一種平臺響應(yīng)模式。我們知道Lua 是一種輕量小巧的腳本語言,用標(biāo)準(zhǔn)C語言編寫。它的執(zhí)行效率無疑比java高的多。
特點
- 充分利用Nginx的并發(fā)能力和lua的執(zhí)行效率,分擔(dān)了Tomcat等Web應(yīng)用服務(wù)器的壓力。
- lua屬于腳本語言,更新版本只需要更新修改Lua腳本之后,重啟Nginx即可完成更新發(fā)布。
- 不適合開發(fā)復(fù)雜業(yè)務(wù)邏輯
適用 - 高并發(fā),高頻率調(diào)用的,并且主要目的用于獲取數(shù)據(jù)的接口適用lua編寫(比如首頁的展示數(shù)據(jù))。
- 請求過濾攔截(商城秒殺,商品完了之后的請求攔截)