0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

怎么用OpenResty搭建高性能服務(wù)端

馬哥Linux運(yùn)維 ? 來源:博客園 ? 作者:smileyqp ? 2021-06-16 09:31 ? 次閱讀

Socket編程

Linux Socket編程領(lǐng)域?yàn)榱颂幚泶罅窟B接請(qǐng)求場(chǎng)景,需要使用非阻塞I/O和復(fù)用,select、poll、epoll是Linux API提供的I/O復(fù)用方式,自從Linux2.6中加入了epoll之后,高性能服務(wù)器領(lǐng)域得到廣泛的應(yīng)用,Nignx就是使用epoll來實(shí)現(xiàn)I/O復(fù)用支持高并發(fā)。

對(duì)于“高性能”服務(wù)端而言,我們所關(guān)注的并不是語言的性能,而是緩存和語言支持異步非阻塞。

緩存

針對(duì)緩存要明白通信速度的快慢順序

內(nèi)存》SSD機(jī)械磁盤

本機(jī)》網(wǎng)絡(luò)

進(jìn)程內(nèi) 》 進(jìn)程間

緩存系統(tǒng)的目標(biāo)是希望在進(jìn)程內(nèi)的命中率是最高的,那么此時(shí)緩存系統(tǒng)整體的效率也是最高的。

異步非阻塞

希望訪問數(shù)據(jù)庫、訪問網(wǎng)絡(luò),訪問一些比較慢的IO設(shè)備時(shí),不要在等待上耗費(fèi)大量時(shí)間。而是使用事件驅(qū)動(dòng)的方式,當(dāng)系統(tǒng)完成某項(xiàng)任務(wù)后再來通知我們。這樣就可以將服務(wù)器CPU的空閑資源,用來服務(wù)客戶端連接。

OpenResty

OpenResty是基于Ngnix和Lua的高性能web平臺(tái),內(nèi)部集成精良的LUa庫、第三方模塊、依賴項(xiàng)。用于方便搭建能夠處理高并發(fā)、擴(kuò)展性極高的動(dòng)態(tài)web應(yīng)用、web服務(wù)、動(dòng)態(tài)網(wǎng)關(guān)??梢允褂肔ua腳本調(diào)用Ngnix支持的C以及Lua模塊,快速構(gòu)建10K~1000K單機(jī)并發(fā)連接的高性能web應(yīng)用系統(tǒng)。OpenResty的目標(biāo)是讓web服務(wù)直接運(yùn)行在Nginx服務(wù)內(nèi)部,利用Ngnix的非阻塞IO模型,對(duì)HTTP客戶端請(qǐng)求和后端DB進(jìn)行一致的高性能響應(yīng)。

OpenResty的出現(xiàn)可以說是顛覆了高性能服務(wù)端的開發(fā)模式。OpenResty實(shí)際上是Nginx+LuaJIT的完美組合。

65bc9f9a-cc67-11eb-9e57-12bb97331649.png

OpenResty工作方式

由于Nginx采用的是master-worker模型,也就是一個(gè)master主進(jìn)程管理多個(gè)worker進(jìn)程,基本的事件處理都是放在worker中,master僅負(fù)責(zé)一些全劇初始化,以及對(duì)worker的管理。在OpenResty中,每個(gè)worker使用一個(gè)LuaVM,每個(gè)請(qǐng)求被分配到worker時(shí),將在這個(gè)LuaVM中創(chuàng)建一個(gè)coroutine協(xié)程。協(xié)程之間數(shù)據(jù)隔離,每個(gè)協(xié)程具有獨(dú)立的全局變量_G。

Lua中的協(xié)程和多線程下的線程類似,都有自己的堆棧、局部變量、指令指針。。。,但是和其他協(xié)程程序共享全局變量等信息。線程和協(xié)程主要不同在于:多處理器的情況下,概念上來說多線程是同時(shí)運(yùn)行多個(gè)線程,而協(xié)程是通過代碼來完成協(xié)程的切換,任何時(shí)刻只有一個(gè)協(xié)程程序在運(yùn)行。并且這個(gè)在運(yùn)行的協(xié)程只有明確被要求掛起時(shí)才會(huì)被掛起。

根據(jù)實(shí)際測(cè)試,OpenResty性能接近于Nginx 性能之王c module,甚至超過。

OpenResty 架構(gòu)

負(fù)載均衡

LVS+HAProxy將流量轉(zhuǎn)發(fā)給核心Nginx1和Nginx2,即實(shí)現(xiàn)了流量的負(fù)載均衡。

單機(jī)閉環(huán)

所有想要的數(shù)據(jù)都能從本服務(wù)器直接獲取,大多數(shù)時(shí)候無需通過網(wǎng)絡(luò)或去其他服務(wù)器獲取。

分布式閉環(huán)

單機(jī)閉環(huán)會(huì)遇到2個(gè)主要問題

1.數(shù)據(jù)不一致

例如沒有主從架構(gòu)導(dǎo)致不同服務(wù)器數(shù)據(jù)不一致

2.遇到存儲(chǔ)瓶頸

磁盤或內(nèi)存遇到天花板

解決數(shù)據(jù)不一致比較好的辦法是采用主從或分布式集中存儲(chǔ),而遇到存儲(chǔ)瓶頸就需要進(jìn)行按業(yè)務(wù)鍵進(jìn)行分片,將數(shù)據(jù)分散到多臺(tái)服務(wù)器。

接入網(wǎng)關(guān)

接入網(wǎng)關(guān)又叫接入層,即接收流量的入口,在入口處做如下事情:

65fa836e-cc67-11eb-9e57-12bb97331649.png

接入網(wǎng)關(guān)

OpenResty環(huán)境搭建

http://openresty.org

http://openresty.org/cn/download.html

安裝前準(zhǔn)備,必須安裝perl、libpcre、libssl庫。

# 從系統(tǒng)路徑中查看必備庫是否已經(jīng)安裝

$ sudo ldconfig -v

# 安裝必備庫

$ sudo apt install libpcre3-dev libssl-dev perl make build-essential curl libreadline-dev libncurses5-dev

下載并解壓OpenResty后進(jìn)入其目錄

$ wget https://openresty.org/download/ngx_openresty-1.13.6.1.tar.gz

$ tar -zxvf ngx_openresty-1.13.6.1.tar.gz

$ mv openresty-1.13.6.1 openresty

$ cd openresty

$ 。/configure

默認(rèn)會(huì)被安裝到/usr/local/openresty目錄下

# 編譯并安裝

$ sudo make && make install

$ cd /usr/local/openresty

啟動(dòng)Nginx

$ sudo /usr/local/openresty/nginx/sbin/nginx

$ ps -ef | grep nginx

$ service nginx status

Nginx啟動(dòng)若出現(xiàn)

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

nginx: [emerg] still could not bind()

說明80端口并占用,查看80端口被占用的端口并重啟。原因在于nginx先監(jiān)聽了ipv4的80端口之后又監(jiān)聽了ipv6的80端口,于是就重復(fù)占用了。

$ sudo netstat -ntlp | grep 80

$ sudo killall -9 nginx

重新編輯Nginx配置文件

$ sudo vim /etc/nginx/conf/nginx.conf

listen 80;

listen [::]:80 ipv6only=on default_server;

使用curl工具或在瀏覽器訪問默認(rèn)80端口

$ curl 127.0.0.1

瀏覽器輸入http://127.0.0.1/

將Nginx工具配置到當(dāng)前用戶的系統(tǒng)環(huán)境變量中

$ sudo vim ~/.bashrc

export PATH=$PATH:/usr/local/openresty/nginx/sbin

$ source ~。/bashrc

$ cd ~

$ nginx -s reload

nginx: [alert] kill(12267, 1) failed (1: Operation not permitted)

開發(fā)文檔

https://www.nginx.com/resources/wiki/modules/lua/

ubuntu 安裝 vcode 或 sublime text 編輯器

content_by_lua

$ vim /usr/local/openresty/nginx/conf/nginx.conf

location /test {

default_type text/html;

content_by_lua ‘ngx.say(“hello openresty”)’;

}

# 重啟Nginx

$ /usr/local/openresty/nginx/sbin/nginx -s reload

# 瀏覽器訪問 127.0.0.1/test

content_by_lua_file

$ vim nginx.conf

location /test {

content_by_lua_file ‘html/test.lua’;

}

$ vim 。。/html/test.lua

ngx.say(“hello lua”)

$ sudo /usr/local/nginx/sbin/nginx -s reload

$ curl 127.0.0.1/test

hello lua

為避免每次修改都需要重啟Nginx,可在Nginx的server選項(xiàng)中配置lua_code_cache選項(xiàng)。

$ vim nginx.conf

server{

lua_code_cache off;

location /test{

content_by_lua_file ‘html/test.lua’;

}

}

$ sudo /usr/local/openresty/nginx/sbin/nginx -s reload

nginx: [alert] lua_code_cache is off; this will hurt performance in /usr/local/openresty/nginx/conf/nginx.conf:48

注意lua_code_cache off;是會(huì)引擎Nginx的性能的,在生產(chǎn)環(huán)境中是需要將其開啟的。

小節(jié)

在OpenResty中開發(fā)是分為兩步的,第一步是修改Nginx配置,第二步是使用Lua開發(fā)自己的腳本。

OpenResty入門

參考資料

OpenResty最佳實(shí)踐

Nginx Lua

創(chuàng)建工作目錄

OpenResty安裝之后就有配置文件及相關(guān)目錄,為了工作目錄和安裝目錄互不干擾,另外創(chuàng)建OpenResty工作目錄,并另寫配置。

$ mkdir -p ~/openresty/test/logs ~/openresty/test/conf

$ vim ~/openresty/test/conf/nginx.conf

# 設(shè)置Nginx worker工作進(jìn)程數(shù)量,即CPU核數(shù)。

worker_processes 1;

# 設(shè)置錯(cuò)誤日志文件路徑

error_log logs/error.log;

# 配置Nginx服務(wù)器與用戶的網(wǎng)絡(luò)連接

events{

# 設(shè)置每個(gè)工作進(jìn)程的最大連接數(shù)

worker_connections 10224;

}

http{

# 虛擬機(jī)主機(jī)塊定義

server{

# 監(jiān)聽端口

listen 8001;

# 配置請(qǐng)求的路由

location /{

default_type text/html;

content_by_lua_block{

ngx.say(“hello world”);

}

}

}

}

$ nginx -p ~/openresty/test

$ curl 127.0.0.1:8001

hello world

$ vim nginx.conf

location /test{

content_by_lua_file “l(fā)ua/test.lua”;

}

$ cd 。。 && mkdir lua && cd lua

$ vim test.lua

local args = ngx.req.get_uri_args()

local salt = args.salt

if not salt then

ngx.exit(ngx.HTTP_BAD_REQUEST)

end

local md5str = ngx.md5(ngx.time()。.salt)

ngx.say(md5str)

$ sudo /usr/local/openresty/nginx/sbin/nginx -s reload

$ curl -i 127.0.0.1/test?salt=lua

HTTP/1.1 200 OK

Server: openresty/1.13.6.2

Date: Sun, 27 Jan 2019 1017 GMT

Content-Type: application/octet-stream

Transfer-Encoding: chunked

Connection: keep-alive

b55b77f75e46b96b11778ca7edfe8d55

若代碼中出現(xiàn)錯(cuò)誤則需要直接查看Nginx的錯(cuò)誤日志進(jìn)行查看

$ vim nginx/logs/error.log

2019/01/27 1715 [error] 15764#0: *6 failed to load external Lua file “/usr/local/openresty/nginx/test.lua”: cannot open /usr/local/openresty/nginx/test.lua: No such file or.。。

Windows系統(tǒng)下查看Nginx進(jìn)程

λ tasklist /fi “imagename eq nginx.exe”

映像名稱 PID 會(huì)話名 會(huì)話# 內(nèi)存使用

========================= ======== ================ =========== ============

nginx.exe 9072 Console 1 7,840 K

nginx.exe 7692 Console 1 12,304 K

nginx.exe 8120 Console 1 7,840 K

nginx.exe 4552 Console 1 12,188 K

nginx.exe 9588 Console 1 7,828 K

nginx.exe 6256 Console 1 12,216 K

nginx.exe 7308 Console 1 7,828 K

nginx.exe 10192 Console 1 12,212 K

λ taskkill /im nginx.exe /f

成功: 已終止進(jìn)程 “nginx.exe”,其 PID 為 9072。

ngx lua API

參考資料

NGINX API for Lua

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207900
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8700

    瀏覽量

    84539
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1461

    瀏覽量

    61489
  • SSD
    SSD
    +關(guān)注

    關(guān)注

    20

    文章

    2791

    瀏覽量

    116647

原文標(biāo)題:OpenResty搭建高性能服務(wù)端

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用NS1串口服務(wù)器HTTP模式上傳服務(wù)器數(shù)據(jù)

    HTTP協(xié)議工作于客戶-服務(wù)端架構(gòu)之上。瀏覽器作為HTTP客戶通過URL向HTTP服務(wù)端即Web服務(wù)器發(fā)送所有請(qǐng)求。Web
    的頭像 發(fā)表于 08-30 12:36 ?119次閱讀
    使用NS1串口<b class='flag-5'>服務(wù)</b>器HTTP模式上傳<b class='flag-5'>服務(wù)</b>器數(shù)據(jù)

    求助,在IR615中可以選用哪種vpn協(xié)議?如何進(jìn)行配置?

    現(xiàn)有多臺(tái)IR615路由器,希望將其配置為vpn客戶,連接云服務(wù)器的vpn服務(wù)端 工程師遠(yuǎn)程連接云服務(wù)器對(duì)IR615進(jìn)行管理 在IR615中可以選用哪種vpn協(xié)議?如何進(jìn)行配置?
    發(fā)表于 07-25 07:53

    請(qǐng)問ESP32作為藍(lán)牙服務(wù)端如何修改MTU?

    我們的工程把esp32當(dāng)作藍(lán)牙服務(wù)端讓電腦去連,由于一些老電腦上沒有藍(lán)牙,要用外置藍(lán)牙驅(qū)動(dòng),默認(rèn)MTU只有23,但是說明上驅(qū)動(dòng)是支持最大mtu的,所以有什么辦法可以通過服務(wù)端去修改mtu嗎
    發(fā)表于 06-27 07:47

    請(qǐng)問esp_local_ctrl中服務(wù)端如何主動(dòng)發(fā)消息?

    請(qǐng)問,在wifi本地控制例程esp_local_ctrl中,設(shè)備作為服務(wù)端在客戶沒有請(qǐng)求的情況下,如何主動(dòng)發(fā)送消息給客戶呢?
    發(fā)表于 06-06 06:11

    服務(wù)端測(cè)試包括什么類型

    服務(wù)端測(cè)試是確保軟件系統(tǒng)在服務(wù)器端正常運(yùn)行和滿足性能要求的重要環(huán)節(jié)。本文將詳細(xì)介紹服務(wù)端測(cè)試的類型、方法和最佳實(shí)踐。 1. 服務(wù)端測(cè)試的定義
    的頭像 發(fā)表于 05-30 16:03 ?400次閱讀

    服務(wù)端測(cè)試是web測(cè)試嗎為什么

    客戶請(qǐng)求、執(zhí)行業(yè)務(wù)邏輯、與數(shù)據(jù)庫交互等。服務(wù)端測(cè)試的目的是確保服務(wù)器端的軟件組件能夠按照預(yù)期工作,沒有錯(cuò)誤,并且能夠滿足性能要求。 服務(wù)端
    的頭像 發(fā)表于 05-30 15:30 ?428次閱讀

    服務(wù)端測(cè)試和客戶測(cè)試區(qū)別在哪

    主要針對(duì)服務(wù)器端的軟件進(jìn)行測(cè)試,包括服務(wù)器端的應(yīng)用程序、數(shù)據(jù)庫、中間件等。服務(wù)端測(cè)試的目的是確保服務(wù)器端軟件的穩(wěn)定性、性能、安全性和可靠性。
    的頭像 發(fā)表于 05-30 15:27 ?1406次閱讀

    服務(wù)端的測(cè)試主要是測(cè)什么內(nèi)容

    服務(wù)端測(cè)試是軟件開發(fā)過程中的一個(gè)重要環(huán)節(jié),主要目的是確保服務(wù)端程序的穩(wěn)定性、性能、安全性和可靠性。 功能測(cè)試 功能測(cè)試是服務(wù)端測(cè)試的基礎(chǔ),主要驗(yàn)證
    的頭像 發(fā)表于 05-30 15:24 ?2554次閱讀

    PLC采用HTTP協(xié)議JSON文件對(duì)接MES等服務(wù)系統(tǒng)平臺(tái)

    文件的字段與PLC寄存器地址,配置URL即可。支持POST/GET/PUT等多種方法。智能網(wǎng)關(guān)IGT-DSER可同時(shí)作為HTTP協(xié)議的客戶服務(wù)端。作為客戶通訊時(shí)將JSON文件提交給HTTP
    發(fā)表于 03-25 14:25

    lwip stm407作為服務(wù)端 pc連接不上怎么解決?

    lwip stm407作為服務(wù)端 pc連接不上
    發(fā)表于 03-20 06:32

    ?PLC從HTTP服務(wù)端獲取JSON文件,解析數(shù)據(jù)到寄存器

    智能網(wǎng)關(guān)IGT-DSER集成了多種PLC協(xié)議,方便實(shí)現(xiàn)各種PLC與HTTP服務(wù)端之間通訊。通過網(wǎng)關(guān)的參數(shù)配置軟件綁定JSON文件的字段與PLC寄存器地址,配置URL,即可采用POST命令,將JSON
    發(fā)表于 01-24 09:47

    PLC通過智能網(wǎng)關(guān),與OPCUA服務(wù)端通訊,實(shí)現(xiàn)標(biāo)簽數(shù)據(jù)讀寫

    是采用西門子S7-200 SMART通過IGT-DSER智能網(wǎng)關(guān)跟OPCUA的服務(wù)端之間通訊,以下是相關(guān)操作步驟。首先通過參數(shù)設(shè)置軟(在附件中)選擇功能與驅(qū)動(dòng)類型,如下圖左邊功能選第三項(xiàng),右邊的驅(qū)動(dòng)選擇
    發(fā)表于 01-02 16:41

    嵌入式學(xué)習(xí)——ElfBoard ELF1板卡 TFTP服務(wù)搭建和使用

    Bootloader中實(shí)現(xiàn)了網(wǎng)卡驅(qū)動(dòng)和TFTP客戶,就可以使用TFTP進(jìn)行傳輸內(nèi)核。使用TFTP協(xié)議傳輸文件,還需要在主機(jī)安裝TFTP服務(wù)端,可以在 Linux系統(tǒng)下實(shí)現(xiàn),也可以在Windows系統(tǒng)下實(shí)現(xiàn),下面
    發(fā)表于 11-23 09:48

    Java SpringBoot項(xiàng)目:Node服務(wù)端搭建

    玩歸玩,鬧歸鬧,別拿 C 開玩笑!這里不推薦大家把 Node 服務(wù)作為 C 服務(wù),畢竟它是單線程多任務(wù) 機(jī)制。這一特性是 Javascript 語言設(shè)計(jì)之初,就決定了它的使命 -
    的頭像 發(fā)表于 11-02 14:56 ?781次閱讀
    Java SpringBoot項(xiàng)目:Node<b class='flag-5'>服務(wù)端</b><b class='flag-5'>搭建</b>

    存儲(chǔ)服務(wù)器怎么搭建?

      搭建存儲(chǔ)服務(wù)器需要根據(jù)我們的需求和環(huán)境選擇合適的硬件和軟件,并進(jìn)行相應(yīng)的配置。那么存儲(chǔ)服務(wù)器怎么搭建?
    的頭像 發(fā)表于 10-31 16:51 ?2579次閱讀