Categories
程式開發

Nginx-技術專題-技術介紹


Nginx 介紹

Nginx 是一個高性能的 HTTP 和反向代理 web 服務器,同時也提供了 IMAP/POP3/SMTP 服務。

Nginx 是由伊戈爾·賽索耶夫為俄羅斯訪問量第二的 Rambler.ru 站點開發的,第一個公開版本 0.1.0 發佈於 2004 年 10 月 4 日。

Nginx 特點是佔有內存少,並發能力強。

事實上 nginx 的並發能力確實在同類型的網頁服務器中表現較好,一般來說,如果我們在項目中引入了 Nginx ,我們的項目架構可能是這樣:

Nginx-技術專題-技術介紹 1

這樣的架構中, Nginx 所代表的角色叫做負載均衡服務器或者反向代理服務器,所有請求首先到達Nginx 上,再由Nginx 根據提前配置好的轉發規則,將客戶端發來的請求轉發到某個Tomcat上去。

那麼這裡涉及到兩個概念:

負載均衡服務器

就是進行請求轉發,降低某一個服務器的壓力。負載均衡策略很多,也有很多層,對於一些大型網站基本上從DNS 就開始負載均衡,負載均衡有硬件和軟件之分,各自代表分別是F5 和Nginx (目前Nginx 已經被F5 收購),早些年,也可以使用Apache 來做負載均衡,但是效率不如Nginx ,所以現在主流方案是Nginx 。

反向代理服務器

另一個概念是反向代理服務器,得先說正向代理,看下面一張圖:

Nginx-技術專題-技術介紹 2

在這個過程中,Google 並不知道真正訪問它的客戶端是誰,它只知道這個中間服務器在訪問它。因此,這裡的代理,實際上是中間服務器代理了客戶端,這種代理叫做正向代理。

那麼什麼是反向代理呢?看下面一張圖:

Nginx-技術專題-技術介紹 3

在這個過程中,10086 這個號碼相當於是一個代理,真正提供服務的,是話務員,但是對於客戶來說,他不關心到底是哪一個話務員提供的服務,只需要記得10086 這個號碼就行了。

所有的請求打到10086 上,再由10086 將請求轉發給某一個話務員去處理。因此,在這裡,10086 就相當於是一個代理,只不過它代理的是話務員而不是客戶端,這種代理稱之為反向代理。

Nginx 優勢

Nginx 有著非常廣泛的使用,隨便舉幾點:

Nginx 做靜態資源服務器“:Java 中的資源可以分為動態和靜態,動態需要經過Tomcat 解析之後,才能返回給瀏覽器,例如JSP 頁面、Freemarker 頁面、控制器返回的JSON 數據等,都算作動態資源,動態資源經過了Tomcat 處理,速度必然降低。對於靜態資源,例如圖片、HTML、JS、CSS 等資源,這種資源可以不必經過Tomcat 解析,當客戶端請求這些資源時,之間將資源返回給客戶端就行了。此時,可以使用Nginx 搭建靜態資源服務器,將靜態資源直接返回給客戶端。Nginx 做負載均衡服務器,無論是使用Dubbo 還是Spirng Cloud ,除了使用各自自帶的負載均衡策略之外,也都可以使用Nginx 做負載均衡服務器。支持高並發、內存消耗少、成本低廉、配置簡單、運行穩定等。

Nginx 安裝

由於基本上都是在Linux 上使用Nginx,因此松哥這裡主要向大家展示CentOS 7 安裝Nginx:

首先下載Nginx

然後解壓下載的目錄,進入解壓目錄中,在編譯安裝之前,需要安裝兩個依賴:

然後開始編譯安裝:裝好之後,默認安裝位置在:

進入到該目錄的 sbin 目錄下,執行 nginx 即可啟動 Nginx :

Nginx-技術專題-技術介紹 4

Nginx 啟動成功之後,在瀏覽器中直接訪問Nginx 地址:

Nginx-技術專題-技術介紹 5

看到如上頁面,表示Nginx 已經安裝成功了。

如果修改了Nginx 配置,則可以通過如下命令重新加載Nginx 配置文件:

Nginx搭建靜態資源web服務器

Nginx默認會訪問index.html頁面.

例如,如下圖配置, 當訪問http://172.16.204.5:90/“時, 默認會訪問安裝目錄下的mine_html目錄中的index.html文件.

Nginx-技術專題-技術介紹 6

設置Nginx的gzip壓縮:

Nginx-技術專題-技術介紹 7

Nginx支持訪問文件樹

效果如下(如果訪問的url路徑下有index.html, 默認還是會跳到index.html頁面):

Nginx-技術專題-技術介紹 8

要達到上圖中的效果,Nginx的配置文件需要添加如下設置:

Nginx-技術專題-技術介紹 9

添加上圖中的配置後, 客戶端訪問http://172.16.204.5:90/“時, 會以樹的格式展示mine_html中的所有文件. 使用這種方式可以很好的共享靜態資源.

在生產環境中

公網的帶寬是有限的, 並發情況下各個客戶端會爭搶帶寬資源, 為了防止訪問大的靜態資源對其他用戶造成影響, 可以設置nginx響應的帶寬. 例如如下圖設置, nginx給客戶端響應時會以每秒1k的速度響應.

Nginx-技術專題-技術介紹 10

Nginx緩存服務器上的靜態文件

Nginx緩存的優點

Nginx-技術專題-技術介紹 11

如圖所示,nginx緩存,可以在一定程度上,減少源服務器的處理請求壓力。

因為靜態文件(比如css,js, 圖片)中,很多都是不經常更新的。 nginx使用proxy_cache將用戶的請求緩存到本地一個目錄。下一個相同請求可以直接調取緩存文件,就不用去請求服務器了。

畢竟,IO密集型服務的處理是nginx的強項。

如何進行設置

先上個栗子:

http{
proxy_connect_timeout 10;
proxy_read_timeout 180;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 96k;
proxy_temp_file_write_size 96k;
proxy_temp_path /tmp/temp_dir;
proxy_cache_path /tmp/cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=10g;
server {
listen 80 default_server;
server_name localhost;
root /mnt/blog/;
location / {
}
#要缓存文件的后缀,可以在以下设置。
location ~ .*.(gif|jpg|png|css|js)(.*) {
proxy_pass http://ip地址:90;
proxy_redirect off;
proxy_set_header Host $host;
proxy_cache cache_one;
proxy_cache_valid 200 302 24h;
proxy_cache_valid 301 30d;
proxy_cache_valid any 5m;
expires 90d;
add_header wall "hey!guys!give me a star.";
}
}
# 无nginx缓存的blog端口
server {
listen 90;
server_name localhost;
root /mnt/blog/;
location / {
}
}
}

因為我是在一台服務器上做試驗,所以用了兩個端口80和90進行模擬兩台服務器之間的交互。

80端口對接的是普通的域名(http://wangxiaokai.vip)訪問。 90端口負責處理80端口代理過來的資源訪問。

相當於90端口是源服務器,80端口是nginx反向緩存代理服務器。

接下來講一下配置項:

http層設置

proxy_connect_timeout 10;
proxy_read_timeout 180;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 96k;
proxy_temp_file_write_size 96k;
proxy_temp_path /tmp/temp_dir;
proxy_cache_path /tmp/cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=10g;

proxy_connect_timeout 服務器連接的超時時間proxy_read_timeout 連接成功後,等候後端服務器響應時間proxy_send_timeout 後端服務器數據回傳時間proxy_buffer_size 緩衝區的大小proxy_buffers 每個連接設置緩衝區的數量為number,每塊緩衝區的大小為sizeproxy_busy_buffers_size開啟緩衝響應的功能以後,在沒有讀到全部響應的情況下,寫緩衝到達一定大小時,nginx一定會向客戶端發送響應,直到緩衝小於此值。 proxy_temp_file_write_size 設置nginx每次寫數據到臨時文件的size(大小)限制proxy_temp_path 從後端服務器接收的臨時文件的存放路徑proxy_cache_path 設置緩存的路徑和其他參數。被緩存的數據如果在inactive參數(當前為1天)指定的時間內未被訪問,就會被從緩存中移除

server層設置

反向緩存代理服務器

server {
listen 80 default_server;
server_name localhost;
root /mnt/blog/;
location / {
}
#要缓存文件的后缀,可以在以下设置。
location ~ .*.(gif|jpg|png|css|js)(.*) {
proxy_pass http://ip地址:90;
proxy_redirect off;
proxy_set_header Host $host;
proxy_cache cache_one;
proxy_cache_valid 200 302 24h;
proxy_cache_valid 301 30d;
proxy_cache_valid any 5m;
expires 90d;
add_header wall "hey!guys!give me a star.";
}
}

proxy_pass nginx緩存裡拿不到資源,向該地址轉發請求,拿到新的資源,並進行緩存proxy_redirect 設置後端服務器“Location”響應頭和“Refresh”響應頭的替換文本proxy_set_header 允許重新定義或者添加發往後端服務器的請求頭proxy_cache 指定用於頁面緩存的共享內存,對應http層設置的keys_zoneproxy_cache_valid 為不同​​的響應狀態碼設置不同的緩存時間expires 緩存時間

這裡我設置了圖片、css、js靜態資源進行緩存。

當用戶輸入http://wangxiaokai.vip域名時,解析得到ip:port的訪問地址。 port默認為80。所以頁面請求會被當前server截取到,進行請求處理。

當解析到上述文件名結尾的靜態資源,會到緩存區獲取靜態資源。

如果獲取到對應資源,則直接返回數據。

如果獲取不到,則將請求轉發給proxy_pass指向的地址進行處理。

源服務器

server {
listen 90;
server_name localhost;
root /mnt/blog/;
location / {
}
}

這裡直接處理90端口接受到的請求,到服務器本地目錄/mnt/blog下抓取資源進行響應。

如何驗證緩存是否有效

細心的讀者應該發現,我在第二段栗子裡,留了個彩蛋 add_header wall “hey!guys!give me a star.”。

add_header

是用於在報頭設置自定義的信息。

所以,如果緩存有效的話,那麼靜態資源返回的報頭,一定會帶上這個信息。

訪問http://wangxiaokai.vip結果如下:

Nginx-技術專題-技術介紹 12