nginx 簡(jiǎn)介
nginx 是一個(gè)高性能的 http 服務(wù)器,代碼完全用C語(yǔ)言編寫绑警,能夠支持高達(dá)50,000個(gè)并發(fā)連接數(shù)的響應(yīng)侦高。與其它 http 服務(wù)器相比,nginx 具有以下幾個(gè)特性:
- nginx 可以在大部分 Linux OS 上編譯運(yùn)行液斜,并且可以比較簡(jiǎn)單地在 Windows 上移植。
- nginx 可以提供很方便的反向代理功能叠穆。
- nginx 可以輕松完成負(fù)載均衡服務(wù)
由于業(yè)務(wù)需求少漆,我學(xué)習(xí) nginx 主要是希望將 nginx 作為反向代理服務(wù)器進(jìn)行使用, 并希望它能提供負(fù)載均衡功能
nginx 在 Windows 中運(yùn)行
為了方便嘗試硼被,目前準(zhǔn)備簡(jiǎn)單地在 Windows 上配置使用即可示损,下載地址為 http://nginx.org/en/docs/windows.html 下載后解壓,運(yùn)行 nginx.exe 或者運(yùn)行命令行嚷硫,在解壓目錄中輸入 start nginx 即可運(yùn)行检访。
檢查 nginx 進(jìn)程可以使用 tasklist 指令:
tasklist /fi "imagename eq nginx.exe"
映像名稱 PID 會(huì)話名 會(huì)話# 內(nèi)存使用
========================= ======== ================ =========== ============
nginx.exe 6516 Console 1 444 K
nginx.exe 33104 Console 1 820 K
其中一個(gè)進(jìn)程是 master 進(jìn)程,另外一個(gè)是 worker 進(jìn)程仔掸。
另外一些簡(jiǎn)單命令有:
nginx -s stop 快速停止nginx
nginx -s quit 優(yōu)雅退出
nginx -s reload 如果改變配置文件脆贵,開啟新的worker進(jìn)程以運(yùn)行新的配置
nginx -s reopen 重新打開log文件
nginx 使用
nginx 常用功能
- 代理服務(wù)器
- 負(fù)載均衡
- web 緩存
nginx 配置文件結(jié)構(gòu)
./conf/nginx.conf
worker_processes 1; #全局塊
events{ #events塊
worker_connections 1024;
}
http #http塊
{
include mime.types; #http全局塊
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80; #server全局塊
server_name localhost;
location / { #location塊
root html;
index index.html index.htm;
}
location [PATTERN]
{
...
}
}
server
{
...
}
}
配置文件參數(shù)的詳解可以查看 http://tengine.taobao.org/book/chapter_02.html#id6
在 http://www.nginx.cn/doc/ 中也列出了幾個(gè)配置文件的例子可以參考:
- 兩個(gè)虛擬主機(jī)(純靜態(tài)-html 支持) - Two Virtual Hosts, Serving Static Files
http {
server {
listen 80;
server_name www.domain1.com;
access_log logs/domain1.access.log main;
location / {
index index.html;
root /var/www/domain1.com/htdocs;
}
}
server {
listen 80;
server_name www.domain2.com;
access_log logs/domain2.access.log main;
location / {
index index.html;
root /var/www/domain2.com/htdocs;
}
}
}
反向代理
原理+實(shí)踐
反向代理概念
反向代理(Reverse Proxy)方式是指以代理服務(wù)器來接受Internet上的連接請(qǐng)求,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器起暮;并將從服務(wù)器上得到的結(jié)果返回給Internet上請(qǐng)求連接的客戶端卖氨,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)服務(wù)器。
通常的代理服務(wù)器,只用于代理內(nèi)部網(wǎng)絡(luò)對(duì)Internet的連接請(qǐng)求筒捺,客戶機(jī)必須指定代理服務(wù)器,并將本來要直接發(fā)送到Web服務(wù)器上的http請(qǐng)求發(fā)送到代理服務(wù)器中柏腻。當(dāng)一個(gè)代理服務(wù)器能夠代理外部網(wǎng)絡(luò)上的主機(jī),訪問內(nèi)部網(wǎng)絡(luò)時(shí)系吭,這種代理服務(wù)的方式稱為反向代理服務(wù)五嫂。
可以看出,使用反向代理服務(wù)器的好處有:
- 代理服務(wù)器可以在安全數(shù)據(jù)庫(kù)和可能共計(jì)的惡意節(jié)點(diǎn)中提供一道屏障肯尺,提高系統(tǒng)安全性
- 可以將用戶請(qǐng)求的 http 服務(wù)重定向?yàn)?https 沃缘, 提高用戶安全性
- 使得負(fù)載均衡功能可以方便應(yīng)用
反向代理服務(wù)器配置
較為基本的反向代理服務(wù)器配置相對(duì)簡(jiǎn)單,主要是運(yùn)用 HttpProxy 模塊则吟,下面給出一份基礎(chǔ)模板可以參考:
#設(shè)定負(fù)載均衡的服務(wù)器列表
#weigth參數(shù)表示權(quán)值孩灯,權(quán)值越高被分配到的幾率越大
upstream test{
server ip0:8080 weight=1;
server ip1:8080 weight=1;
}
server {
#偵聽的80端口
listen 80;
server_name localhost;
location / {
index index.html;
proxy_pass http://test; #設(shè)置代理
#以下是一些反向代理的配置可刪除
proxy_redirect off;
#后端的Web服務(wù)器可以通過X-Forwarded-For獲取用戶真實(shí)IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 90;
proxy_send_timeout 150;
proxy_read_timeout 150;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
反向代理動(dòng)態(tài)服務(wù)發(fā)現(xiàn):
了解了反向代理配置后,仍然是無法成功運(yùn)用在目標(biāo)系統(tǒng)中逾滥,因?yàn)槟繕?biāo)系統(tǒng)要求服務(wù)具有伸縮性,即可以動(dòng)態(tài)增加服務(wù)內(nèi)容败匹,或者增加服務(wù)器寨昙。因此需要代理服務(wù)器也能動(dòng)態(tài)發(fā)現(xiàn)服務(wù)。
使用etcd+confd管理nginx配置 則是一個(gè)可行的嘗試, 利用etcd動(dòng)態(tài)發(fā)現(xiàn)服務(wù)掀亩,然后用confd監(jiān)聽etcd的變化舔哪,從而改變配置文件。
生成配置的方式為:
通過API將配置寫入etcd槽棍,confd注冊(cè)監(jiān)控etcd的key為/nginx/捉蚤,只要發(fā)生變化就通知 confd 根據(jù)模板生成配置。confd 默認(rèn)的配置路徑為 /etc/confd/炼七,創(chuàng)建 conf.d 和 template 兩個(gè)目錄缆巧,分別存放配置資源和配置模板。
confd 的安裝地址為 https://github.com/kelseyhightower/confd豌拙, 看了一下也包含了對(duì) Windows 系統(tǒng)的支持陕悬, 但是做的比較粗糙,在 Windows系統(tǒng)中查找配置文件仍然是從 /etc/confd 中尋找:WARNING Cannot load template resources: confdir '/etc/confd' does not exist
按傅, 因此還是建議在 Linux 系統(tǒng)下運(yùn)行捉超。
nginx 的配置模板需要?jiǎng)討B(tài)寫入,因此需要修改(這里只討論增減服務(wù)器):
upstream www_{{getv "/nginx/https/www/server/server_name"}} {
{{range getvs "/nginx/https/www/upstream/*"}}server {{.}};{{end}}
}
server {
server_name {{getv "/nginx/https/www/server/server_name"}}:443;
location / {
proxy_pass http://www_{{getv "/nginx/https/www/server/server_name"}};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
}
但是目前仍然有問題唯绍,就是配置文件生成之后拼岳,如何能夠動(dòng)態(tài)加載,加載方式有如下幾種:
- dns動(dòng)態(tài)解析:改變dns配置
- 動(dòng)態(tài)模板解析: 使用jinja2况芒、mako的模板引擎惜纸,動(dòng)態(tài)的根據(jù)你提供變量渲染配置
- 服務(wù)發(fā)現(xiàn)模式:
- 前面2個(gè)都有比較大的限制,并且需要reload的話,nginx新老配置交替的時(shí)候會(huì)掉15%左右的qps堪簿, 因此頻繁reload方式并不建議痊乾,服務(wù)發(fā)現(xiàn)模式有些時(shí)候可以不按照reload方式進(jìn)行:
在github中的不少nginx服務(wù)發(fā)現(xiàn)的實(shí)現(xiàn),他們不會(huì)新開進(jìn)程椭更,而是在在master進(jìn)程中注冊(cè)一個(gè)定時(shí)器哪审,該事件會(huì)觸發(fā)watch,當(dāng)發(fā)現(xiàn)version的版本號(hào)發(fā)生變更時(shí)虑瀑,就知道主機(jī)列表發(fā)生了變化湿滓,進(jìn)而重載配置. 那么如何讓worker進(jìn)程也使用新的配置? 這時(shí)候可能不會(huì)使用共享變量舌狗,因?yàn)樽x寫都要加鎖叽奥,及其影響速度. 所以每個(gè)worker都會(huì)緩存一份location upstream的配置,每個(gè)worker也會(huì)有個(gè)定時(shí)器痛侍,他的事件共享內(nèi)存的upstream有無變化…
-
可以基于 Redis 動(dòng)態(tài)路由: 第一次請(qǐng)求時(shí)朝氓,從 Redis 獲取路由地址,放入本地緩存中主届,并設(shè)置有效時(shí)間赵哲,后續(xù)請(qǐng)求直接從本地緩存中獲取,如果本地緩存失效君丁,則從 Redis 中請(qǐng)求枫夺。
但沒有考慮 redis 數(shù)據(jù)與本地緩存數(shù)據(jù)不一致問題。
而且不管如何動(dòng)態(tài)更新绘闷,一個(gè)關(guān)鍵問題是橡庞,nginx 的最小單位是 IP 地址 + 端口, 而目標(biāo)系統(tǒng)的最小單位是服務(wù)印蔗。因此相對(duì)難以應(yīng)用扒最。但本次探索不失為一個(gè)有價(jià)值的嘗試。