Nginx是俄羅斯人用c++編寫的十分輕量級的HTTP服務(wù)器,同時也能作為郵件服務(wù)器、反向代理服務(wù)器、靜態(tài)資源服務(wù)器筝蚕。
簡介
- Nginx以事件驅(qū)動的方式編寫,所以有非常好的性能铺坞,同時也是一個非常高效的反向代理起宽、負載平衡。其擁有匹配Lighttpd的性能济榨,同時還沒有Lighttpd的內(nèi)存泄漏問題坯沪。
- Nginx專為性能優(yōu)化而開發(fā),性能是其最重要的考量,實現(xiàn)上非常注重效率 擒滑。它支持內(nèi)核Poll模型腐晾,能經(jīng)受高負載的考驗,有報告表明能支持高達 50,000個并發(fā)連接數(shù)。
- Nginx具有很高的穩(wěn)定性丐一。其它HTTP服務(wù)器藻糖,當遇到訪問的峰值,或者有人惡意發(fā)起慢速連接時库车,也很可能會導致服務(wù)器物理內(nèi)存耗盡頻繁交換巨柒,失去響應(yīng),只能重啟服務(wù)器。例如當前apache一旦上到200個以上進程洋满,web響應(yīng)速度就明顯非常緩慢了晶乔。而Nginx采取了分階段資源分配技術(shù),使得它的CPU與內(nèi)存占用率非常低牺勾。nginx官方表示保持10,000個沒有活動的連接正罢,它只占2.5M內(nèi)存,所以類似DOS這樣的攻擊對nginx來說基本上是毫無用處的驻民。就穩(wěn)定性而言,nginx比lighthttpd更勝一籌腺怯。
- Nginx支持熱部署。它的啟動特別容易, 并且?guī)缀蹩梢宰龅?*24不間斷運行川无,即使運行數(shù)個月也不需要重新啟動。你還能夠在不間斷服務(wù)的情況下虑乖,對軟件版本進行進行升級懦趋。
- ……
HTTP基礎(chǔ)功能:
- 處理靜態(tài)文件,索引文件以及自動索引疹味;
- 反向代理加速(無緩存)仅叫;
- FastCGI,簡單的負載均衡和容錯糙捺;
- 模塊化的結(jié)構(gòu)诫咱。過濾器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI過濾器中洪灯,到同一個 proxy 或者 FastCGI 的多個子請求并發(fā)處理坎缭;
- SSL 和 TLS SNI 支持;
基本概念:
1.正向代理:
用戶訪問代理服務(wù)器签钩。網(wǎng)站對用戶不透明掏呼。對用戶服務(wù)。
2.反向代理:
用戶訪問反向代理服務(wù)器铅檩。但是用戶不知道訪問的是反向代理服務(wù)器多個站點中的哪一個站點憎夷。對服務(wù)器服務(wù)。
3.負載均衡
nginx 的 upstream目前支持 4 種方式的分配
1)昧旨、輪詢(默認):每個請求按時間順序逐一分配到不同的后端服務(wù)器拾给,如果后端服務(wù)器down掉,能自動剔除兔沃。
2)蒋得、weight:指定輪詢幾率,weight和訪問比率成正比粘拾,用于后端服務(wù)器性能不均的情況窄锅。
2)、ip_hash :每個請求按訪問ip的hash結(jié)果分配,這樣每個訪客固定訪問一個后端服務(wù)器入偷,可以解決session的問題追驴。
3)、fair(第三方):按后端服務(wù)器的響應(yīng)時間來分配請求疏之,響應(yīng)時間短的優(yōu)先分配殿雪。
4)、url_hash(第三方)
4.異步非阻塞
和node類似Nginx 采用了異步非阻塞的方式來處理請求锋爪。Nginx 采用的是多 worker 的方式來處理請求丙曙,每個 worker 里面只有一個主線程,每個worker線程都繼承了高并發(fā)的特性其骄。
想想 apache 的常用工作方式(apache 也有異步非阻塞版本亏镰,但因其與自帶某些模塊沖突,所以不常用)拯爽,每個請求會獨占一個工作線程索抓,當并發(fā)數(shù)上到幾千時,就同時有幾千的線程在處理請求了毯炮。這對操作系統(tǒng)來說逼肯,是個不小的挑戰(zhàn),線程帶來的內(nèi)存占用非常大桃煎,線程的上下文切換帶來的 cpu 開銷很大篮幢,自然性能就上不去了,而這些開銷完全是沒有意義的为迈。
命令
1.安裝
osx 用homebrew
brew install nginx
2.nginx命令
命令 | 注釋 | |
---|---|---|
nginx | 啟動nginx三椿,按照默認路徑 | |
nginx -t | 測試配置正確性、也可查詢默認配置路徑 | |
nignx -c 路徑 | 按照指定路徑[啟動 | ...] |
nginx -s reload | 平滑重啟 | |
nginx -s stop | 停止nginx | |
nginx -v | 顯示 nginx 的版本 | |
nginx -V | nginx 的版本葫辐,編譯器版本和配置參數(shù)赋续。 |
3.nginx信號
啟動nginx后會根據(jù)配置生成一個master進程和多個worker進程(由參數(shù)worker_processes配置,一般為機器cpu核數(shù))master 來管理 worker 進程另患,所以我們只需要與 master 進程通信就行了纽乱。master 進程會接收來自外界發(fā)來的信號,再根據(jù)信號做不同的事情昆箕。所以我們要控制 Nginx鸦列,只需要通過 kill 向 master 進程發(fā)送信號就行了,例如:
kill -HUP pid
//平滑重啟nginx
//pid是nginx的進程
//若在nginx.conf配置了pid文件存放路徑則該文件存放的就是Nginx主進程號
//可用路徑代替pid 鹏倘,例如: '/usr/nginx/logs/nginx.pid'
master進程:
信號 | 注釋 |
---|---|
TERM, INT | 快速關(guān)閉 |
QUIT | 從容關(guān)閉 |
HUP | 重載配置 \ 用新的配置開始新的工作進程 \ 從容關(guān)閉舊的工作進程 |
USR1 | 重新打開日志文件 |
USR2 | 平滑升級可執(zhí)行程序薯嗤。 |
WINCH | 從容關(guān)閉工作進程 |
worker進程:
信號 | 注釋 |
---|---|
TERM, INT | 快速關(guān)閉 |
QUIT | 從容關(guān)閉 |
USR1 | 重新打開日志文件 |
conf配置
基本參數(shù)
#運行用戶
user nobody;
#啟動進程,通常設(shè)置成和cpu的數(shù)量相等
worker_processes 2;
#nginx pid進程號存儲地址
pid logs/nginx.pid;
events {
#ulimit -n 一個進程所能夠打開的文件的最大數(shù)
#反向代理,最大并發(fā)數(shù) worker_connections * worker_processes/2
worker_connections 1024;
}
負載均衡
在http節(jié)點里添加:
#定義負載均衡設(shè)備的 Ip及設(shè)備狀態(tài)
upstream myServer {
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup;
ip_hash;
}
在需要使用負載的Server節(jié)點下添加
proxy_pass http://myServer;
upstream 每個設(shè)備的狀態(tài):
- down :表示單前的server暫時不參與負載
- weight :默認為1.weight越大纤泵,負載的權(quán)重就越大骆姐。
- max_fails :允許請求失敗的次數(shù)默認為1.當超過最大次數(shù)時镜粤,返回proxy_next_upstream 模塊定義的錯誤
- fail_timeout:max_fails 次失敗后,暫停的時間玻褪。
- backup: 其它所有的非backup機器down或者忙的時候肉渴,請求backup機器。所以這臺機器壓力會最輕带射。
ip_hash
使用負載均衡服務(wù)器一多就會出現(xiàn)一個問題同规,那怎么實現(xiàn)多臺服務(wù)器之間session的共享。其中一個方案就是ip_hash窟社。nginx中的ip_hash能夠?qū)⒛硞€ip的請求定向到同一臺后端券勺,這樣一來這個ip下的某個客戶端和某個后端就能建立起穩(wěn)固的session;
nginx 編程
1.nginx變量
Nginx 變量的創(chuàng)建和賦值操作發(fā)生在全然不同的時間階段。Nginx 變量的創(chuàng)建只能發(fā)生在 Nginx 配置加載的時候灿里,或者說 Nginx 啟動的時候关炼;而賦值操作則只會發(fā)生在請求實際處理的時候。這意味著不創(chuàng)建而直接使用變量會導致啟動失敗匣吊,同時也意味著我們無法在請求處理時動態(tài)地創(chuàng)建新的 Nginx 變量盗扒。
server {
listen 8080;
location /foo {
echo "foo = [$foo]";
}
location /bar {
set $foo 32;
echo "foo = [$foo]";
}
}
我們使用了標準 ngx_rewrite 模塊的 set 配置指令對變量 $a 進行了賦值操作。特別地缀去,我們把字符串 hello world 賦給了它。
這里我們使用第三方 ngx_echo 模塊的 echo 配置指令將 $foo 變量的值作為當前請求的響應(yīng)體輸出甸祭。
我們用curl訪問地址:
$ curl 'http://localhost:8080/foo' //foo = []
$ curl 'http://localhost:8080/bar' //foo = [32]
2.Nginx 內(nèi)建變量
例如由 ngx_http_core 模塊提供的內(nèi)建變量 $uri缕碎,可以用來獲取當前請求的 URI(經(jīng)過解碼,并且不含請求參數(shù))池户,而 $request_uri 則用來獲取請求最原始的 URI (未經(jīng)解碼咏雌,并且包含請求參數(shù))。但是大部分內(nèi)建變量類似保留值不可被賦值校焦。
location /test {
echo "uri = $uri";
echo "request_uri = $request_uri";
echo "name: $arg_name";//name不區(qū)分大小寫
}
$ curl "http://localhost:8080/test?Name=aaa"
:uri = /test
:request_uri = /test
:name: aaa
$ curl "http://localhost:8080/test?a=3&b=4"
:uri = /test
:request_uri = /test?a=3&b=4
:name:
也有一些內(nèi)建變量是支持改寫的赊抖,其中一個例子是 $args. 這個變量在讀取時返回當前請求的 URL 參數(shù)串(即請求 URL 中問號后面的部分,如果有的話)寨典,而在賦值時可以直接修改參數(shù)串:
location /test {
set $orig_a $arg_a;
set $args "a=5";
echo "original a: $orig_a";
echo "a: $arg_a";
}
$ curl 'http://localhost:8080/test?a=3'
:original a: 3
:a: 5
原本$arg_a應(yīng)該返回參數(shù)a=3氛雪,但是訪問時賦值了$args 'a=5',所以取$arg_a時返回了5耸成;
參考鏈接:
http://www.ttlsa.com/nginx/nginx-tutorial-from-entry-to-the-master-ttlsa/
https://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
http://wiki.jikexueyuan.com/project/nginx/nginx-framework.html