隨着現代web開發的發展,restful,先後端分離,前端js框架的應用愈來愈廣泛。不少web應用請求的接口可能根本就存在於不一樣的服務器,相似於微信,支付寶等等。這其中就會存在跨域的問題。簡單來講,跨域就是瀏覽器爲了防止黑客可以隨意改變表單的請求地址的一種安全防禦。若是黑客能夠隨意將一個表單的請求地址改爲其控制的服務器地址,在返回一個能夠獲取用戶填寫信息的頁面,就會形成用戶信息泄露。這種瀏覽器跨域防禦跟如今的開發模式又有相悖的地方。筆者最初使用nginx 就是爲了解決先後端分離帶來的跨域問題。前端
nginx是一個高性能的http/反向代理服務器,也能夠用於郵件服務。具備反向代理/負載均衡的功能。起源於俄羅斯的一個大型網站,如今國內新浪、16三、騰訊、Discuz、豆瓣都有使用。nginx
筆者會記錄學習nginx的過程,畢竟不少東西的學習光靠百度百科遠遠不夠。web
一. nginx爲何具備高性能編程
nginx在啓動後,服務器會出現至少兩個進程(具體看配置),也能夠當作是兩類進程,一個是master,一個是workers,兩者是管理與被管理的關係。 master進程可以將接收到的http請求合理的分配到works進程中去。因此通常的http請求實際上是跟master進程通訊,master進程保證每一個請求只被一個works執行,至於master分配請求與worker處理請求的機制這裏不作表述。後端
那麼,nginx採用這種進程模型有什麼好處呢?固然,好處確定會不少了。首先,對於每一個worker進程來講,獨立的進程,不須要加鎖,因此省掉了鎖帶 來的開銷,同時在編程以及問題查找時,也會方便不少。其次,採用獨立的進程,可讓互相之間不會影響,一個進程退出後,其它進程還在工做,服務不會中 斷,master進程則很快啓動新的worker進程。固然,worker進程的異常退出,確定是程序有bug了,異常退出,會致使當前worker上的 全部請求失敗,不過不會影響到全部請求,因此下降了風險。固然,好處還有不少,你們能夠慢慢體會。 跨域
nginx提供一種異步非阻塞的機制。當一個請求經過master到達worker時,操做系統 提供select/poll/epoll/kqueue這樣的系統調用,當請求發現對應的接口還沒有準備好(這裏的未準備好有多種緣由,可能沒有響應,正在初始化,正在創建鏈接等),這個時候請求放到內核中,不佔用CPU的內存,同時 select/poll/epoll/kqueue這樣的系統調用 監聽該請求的目標是否準備好,這個時候該worker進程能夠接收另外的請求來處理,若是前面的請求目標被監聽到準備好時,worker在調用回,這樣使得CPU處於一種高效的使用狀態而不用開闢對於的線程佔用內存空間。數組
固然,這裏的併發請求,是指未處理完的請求,線程只有一個,因此同時能處理的請求固然只有一個了,只是在請求間進行不斷地切換而已,切換也是由於異步事件 未準備好,而主動讓出的。這裏的切換是沒有任何代價,你能夠理解爲循環處理多個準備好的事件,事實上就是這樣的。與多線程相比,這種事件處理方式是有很大 的優點的,不須要建立線程,每一個請求佔用的內存也不多,沒有上下文切換,事件處理很是的輕量級。併發數再多也不會致使無謂的資源浪費(上下文切換)。更多 的併發數,只是會佔用更多的內存而已。 我以前有對鏈接數進行過測試,在24G內存的機器上,處理的併發請求數達到過200萬。如今的網絡服務器基本都採用這種方式,這也是nginx性能高效的 主要緣由。瀏覽器
nginx在實現時,是經過一個鏈接池來管理的,每一個worker進程都有一個獨立的鏈接池,鏈接池的大小是 worker_connections。這裏的鏈接池裏面保存的其實不是真實的鏈接,它只是一個worker_connections大小的一個 ngx_connection_t結構的數組。而且,nginx會經過一個鏈表free_connections來保存全部的空閒 ngx_connection_t,每次獲取一個鏈接時,就從空閒鏈接鏈表中獲取一個,用完後,再放回空閒鏈接鏈表裏面。安全
在這裏,不少人會誤解worker_connections這個參數的意思,認爲這個值就是nginx所能創建鏈接的最大值。其實否則,這個值是表 示每一個worker進程所能創建鏈接的最大值,因此,一個nginx能創建的最大鏈接數,應該是worker_connections * worker_processes。固然,這裏說的是最大鏈接數,對於HTTP請求本地資源來講,可以支持的最大併發數量是 worker_connections * worker_processes,而若是是HTTP做爲反向代理來講,最大併發數量應該是worker_connections * worker_processes/2。由於做爲反向代理服務器,每一個併發會創建與客戶端的鏈接和與後端服務的鏈接,會佔用兩個鏈接。服務器
(未完待續)