日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

nginx动态配置及服务发现那些事

發布時間:2024/2/28 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nginx动态配置及服务发现那些事 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

標題, ?《閑聊nginx動態配置及服務發現的那些事》 …

?

這次的準備閑聊關于nginx服務發現的話題, ?按照我以往寫文章的性子,估計會遷移一些主題. ?畢竟單純聊nginx和動態服務發現沒啥意思,因我以前的文章有大量的涉及到。

?

?

該文章寫的有些亂,歡迎來噴 ! 另外文章后續不斷更新中,請到原文地址查看更新. ? ?http://xiaorui.cc/?p=3855

?

nginx upstream相關

我這里就不再精細的講述nginx的源碼, 畢竟我自己也只是粗略看了點nginx的底層代碼. ?nginx的動態配置肯定是繞不過upstream模塊的運作了,他主要的驅動是xxx_pass,比如最常用的proxy_pass, uwsgi_pass。upstream相關配置結構的建立,并不一定是非要配置upstream這個指令才會去做,有時proxy_pass直接就是跟一個ip地址或域名, 他其實隱式的調用upstream 。

?

那么一個具體的request過程如何跟upstream配置怎么關聯起來的?

首先是通過peer.init函數指針初始化,然后根據round robbin算法選擇ngx_http_upstream_init_round_robin_peer,每種算法鎖出發的函數不一樣,這是廢話。 從配置上看,凡是請求到location /xxx的request請求,他們都關聯到同一個upstream配置,但是既然大家公用一個結構,那么需不需要互斥呢?如果大家都要修改其中的某個成員… ? ?

實際上,nginx中一個請求不會中多個進程中同時處理,一個request生老病死都在一個worker內。 ?每個nginx worker都會監聽自己相關的epoll fd事件。 當一個worker爭取到了nginx listen fd accept的鎖,那么他就可以接收新的request請求,這個請求的創建出的fd會壓到他本進程的事件里。 我想說的是,他不會逃到worker里, 因為也沒這個必要這么實現,跨多進程傳遞socket本身是個很蛋疼的實現.

nginx relaod相關

那么nginx upstrem闡述完了,我們再聊聊nginx -s reload. ??

當你增刪改upstream配置的時候,如何讓nginx不停服務的重載配置? nginx -s reload. ?reload的實現相對好理解,-s的作用是向master進程發送信號。 其實是SIGHUP信號的封裝,也就是說我們可以直接通過kill向nginx的pid發送SIGHUP信號來完成reload操作。?
master通過ngx_signal_handler處理信號,見到reload就重置ngx_reconfigure = 1.

?

?

1

2

3

4

casengx_signal_value(NGX_RECONFIGURE_SIGNAL):??

????ngx_reconfigure = 1;??

????action = ", reconfiguring";??

break;??

?

這樣當ngx_master_process_cycle的for循環中檢測到ngx_reconfigure ==1,就開始做重加載配置的操作,通過ngx_start_worker_processes開啟新進程,而之前的進程則通過ngx_signal_worker_processes來發送信號進行“優雅”的關閉. ?所謂優雅的關閉, 就是讓當前真正處理請求的進程等到處理完之后再退出,當然進程不能再次參與accept鎖的爭奪了. ?這樣新的請求會拿到listen accept鎖,可建立reqeust連接.

如何保證已經建連的連接 ? ??

如果是短連接,那么在請求完之后,worker會主動發送close(),后面就把fd事件給踢掉。 ?

那么長連接會怎么辦? ?這個時候長連接是有兩種的, 前者是是client 跟 nginx proxy的連接,后者是proxy跟后端服務的連接,比如nginx –> tornado 就屬于后者.

?

nginx proxy主要就是給client提供服務,在對外請求完畢的情況下,右面的連接可有可無了, ?當然我們還是操作proxy給后端服務發送close()關閉連接 。 如果發生異常進程退出,后端經過keepalive timeout后進行回收資源.?

前者的連接就有點意思了, ?當你的請求是http1.1長連接時候,不管是單次請求或者是stream這種流式請求,都會在請求完之后退出。 那么對于客戶端有什么影響? ?客戶端會收到fin的tcp關閉請求,配合nginx關閉連接之后. 當你再次訪問nginx的時候,才會重建一個連接…?

?

什么是nginx的動態配置?

到此為止, nginx reload 和 upstream 都過了一遍. ?那么動態配置又是什么? 我們什么時候需要動態配置? ?

我認為nginx的動態配置可以有這么幾種方法.

一種是dns動態解析 ,一種是模板渲染, 一種服務發現動態配置重載. ??

碰巧,這幾種配置我都有在線上用過,我不會單純的說誰更好,誰更差,因為每個動態配置方法都有他的應用場景. ?比如dns動態解析非常適合依賴域名來辨識主機的集群服務,多用在類aws、阿里云這樣的云服務. ? 模板動態配置方法更適合那種大型的運維平臺管理體系. ? ?服務發現配置適合那種docker化的服務, 或者類似的微服務框架體系.

第一種, dns動態解析

我們通常在配置nginx upstream的時候都會使用ip地址. 對于那種依賴域名的集群服務,非常適合這樣的配置. ?因為你修改了一組域名的配置,你如果nginx域名來解析, 就不再重新配置了。 這個dns服務器肯定不能是公網. 內網必須配置一個高性能的dns服務,比如dnsmasq, bind. 另外我們需要注意dns緩存的問題, nginx默認會根據dns server返回的ttl來設置記錄的失效時間, 推薦配置成5s . ?如果ttl太小,dns也會成為一個瓶頸點.?

dns的缺點也明顯,那就是ip級別,很多時候一臺服務器我們會開N個port, ?動態的域名只能跟蹤ip的級別, 這樣顯得很不靈活。 ?由于nginx dns動態解析多適用于云主機環境,云主機一般是一兩個核,所以這是可以接受的.?

如果你使用skydns的化,也可以實現我們后面講述的動態服務發現.?

我們可以簡單的配置dns模式.:

?

1

2

3

4

5

resolver 10.0.0.1;

set $blog http://service-123.xiaorui.cc;

location / {

????proxy_pass $blog;

}

?

也可以配置更加的豐富. ? 我這邊用的是tengine。

?

?

1

2

3

4

5

6

7

8

9

10

upstream backend {

????dynamic_resolve fallback=stale fail_timeout=30s;

?

????server a.com;

????server b.com;

}

?

server {

????proxy_pass http://backend;

}

?

?

nginx plus版的配置. ?相對來說,nginx plus的功能更加豐富點,但是需要收費,我在free期間測試過該功能,通過.?

?

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#xiaorui.cc

?

resolver 10.0.0.1;

?

upstream xiaorui.cc {

????zone upstream_dynamic 64k;

????server backend2.example.com:8080 fail_timeout=5s slow_start=30s;

????server backend3.example.com??????resolve;

????server backend4.example.com??????service=http resolve;

}

?

server {

????location / {

????????proxy_pass http://xiaorui.cc;

????????health_check;

????}

}

?

另外可以使用nginx的dns加強版插件. https://github.com/GUI/nginx-upstream-dynamic-servers

?

第二種,動態模板解析

我在上面有說過動態模板解析的場景一般是那種運維平臺系統, 我曾經在全網集群調度平臺,智能dns管理系統中使用過這種方法, 他的優點在于系統的集中式管理,本身來說這種管理方式只是把手動的操作變成自動化而已,但這種配置方式相當的穩定,只是每次渲染模板后都需要nginx -s reload. ??

另外他的開發成本還是不低的,小公司hold不住的,一般各大公司的運維平臺多使用這種方式. ?

簡單說下他的實現,比如python語言,我們可以使用jinja2、mako的模板引擎,動態的根據你提供變量渲染配置.?

?

第三種,服務發現模式.

服務發現是這次的重點,博客里有聊過etcd、zookeeper、consul 這三種服務發現的使用及坑. ? 那么跟nginx是怎么實現的動態加載配置? 他跟nginx -s reload不一樣, reload會重新開一組進程來接收請求,讓老進程完事后再退出. ? ?切記,如果你線上流量較大,不要頻繁的reload, ? 因為nginx新老配置交替的時候會掉15%左右的qps .

?

? ? ?其實并不一定要按照reload的路子走,我們可以針對nginx進行改造。 讓他可以主動去拉取最新的服務發現里的主機. ?在github中的不少nginx服務發現的實現,他們不會新開進程,而是在在master進程中注冊一個定時器,該事件會觸發watch,當發現version的版本號發生變更時,就知道主機列表發生了變化,進而重載配置. ? 那么如何讓worker進程也使用新的配置? ?這時候可能不會使用共享變量,因為讀寫都要加鎖,及其影響速度. ?所以每個worker都會緩存一份location upstream的配置,每個worker也會有個定時器,他的事件共享內存的upstream有無變化… ??

?

優點是什么? ?服務發現模式特別適合微服務,更片面的說 docker服務化. ? ?因為docker可以更加彈性的擴展縮減集群的計算架構. ? ?當docker容器起來后,直接給consul注冊一個槽位,間隔性的發送健康心跳. ?我們不需要管nginx的配置,nginx會自己動態的重載最新的配置. ? ? 當我們把docker容器干掉了,由于consul有配置過期自動清理記錄,很大程度保證consul服務發現列表的 “純潔性” . ?

?

一個nginx consul的場景圖:

?

?

下圖是etcd的服務發現流程. ? 服務的提供者會注冊到服務注冊中心上,請求者在請求之前會訪問一次注冊中心,從里面取出主機記錄才會進一步訪問.?

?

nginx服務發現的模塊, ?https://github.com/weibocom/nginx-upsync-module

?

轉自:

?http://xiaorui.cc/?p=3855

?

總結

以上是生活随笔為你收集整理的nginx动态配置及服务发现那些事的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。