靜态資源web服務
Nginx作為儲存靜态資源的web服務,對靜态資源直接做出響應。減少後端伺服器的負載壓力。
基礎配置
配置實踐
# 先把上一節的配置備份下來
cd /etc/nginx/conf.d
mv auth_basic.conf auth_basic.conf.bak
# 從備份目錄恢複一個初始配置并改名
cp /opt/backup/default.conf static.conf
# 修改配置
vi static.conf
# 配置如下
server {
...
# 開啟sendfile,提高網絡包的傳輸效率
sendfile on;
# 配置圖檔資源的路徑
location ~ .*\.(jpg|gif|png)$ {
root /opt/app/code/images;
}
# 配置txt|xml資源的路徑
location ~ .*\.(txt|xml)$ {
root /opt/app/code/doc;
}
# 配置html網頁資源路徑
location ~ .*\.(html|htm)$ {
root /opt/app/code;
}
}
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 重載配置
systemctl reload nginx.service
# 我們準備了一個圖檔資源
[[email protected] conf.d]# cd /opt/app/code/images
[[email protected] images]# ls
react.jpg
驗證結果

開啟壓縮
開啟壓縮,可以加快資源響應速度,同時節省網絡帶寬資源。
配置實踐
cd /etc/nginx/conf.d
# 修改配置
vi static.conf
# 配置如下
server {
...
#開啟sendfile,提高網絡包的傳輸效率
sendfile on;
#配置圖檔資源的路徑
location ~ .*\.(jpg|gif|png)$ {
#開啟壓縮
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types image/jpeg image/gif image/png;
root /opt/app/code/images;
}
#配置txt|xml資源的路徑
location ~ .*\.(txt|xml)$ {
#開啟壓縮
gzip on;
gzip_http_version 1.1;
gzip_comp_level 1;
gzip_types text/plain application/xml;
root /opt/app/code/doc;
}
# 配置html網頁資源路徑
location ~ .*\.(html|htm)$ {
root /opt/app/code;
}
}
# 驗證配置,先不重載配置
nginx -tc /etc/nginx/nginx.conf
相比圖檔,用檔案來示範壓縮,壓縮效果會更好:
cd /opt/app/code/doc
# 直接把nginx通路日志拷貝到靜态資源目錄
cp /var/log/nginx/access.log access.txt
chmod 777 access.txt
在重載配置之前,我們先通路一次http://39.104.93.171/access.txt
# access.log輸出如下:
39.104.93.171 115.198.157.60 - admin [03/Feb/2018:21:51:23 +0800] "GET /access.txt HTTP/1.1" 200 20626 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" "-"
可以看到傳輸内容大小是20626。
# 然後我們重載配置
systemctl reload nginx.service
浏覽器清空緩存(避免304影響)後再次通路http://39.104.93.171/access.txt
# access.log輸出如下:
39.104.93.171 115.198.157.60 - admin [03/Feb/2018:21:58:56 +0800] "GET /access.txt HTTP/1.1" 200 1895 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" "-"
可以看到傳輸資料大小已經被壓縮到隻有1895了。
跨域通路
浏覽器基于安全考慮,采用同源政策,限制了跨域通路。然而企業内部站點之間通常會有跨域通路的需求。尤其是現在前後端分離的方式,前端采用諸如React或Vue等MVVM架構開發純Ajax的SPA應用時,頁面間的路由是前端控制,前端同學往往要求相關伺服器開放跨域通路。
我準備了另外一台伺服器:39.104.116.91,有如下頁面,通過ajax跨域請求本nginx伺服器的html資源:
<!DOCTYPE HTML>
<html >
<head>
<title>測試ajax跨域通路</title>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.ajax({
type: "GET",
url: "http://39.104.93.171/someone.html",
success: function(data) {
alert("跨域通路成功!");
},
error: function(data) {
alert("跨域通路失敗!");
}
});
});
</script>
</head>
<body>測試跨域通路</body>
</html>
那麼,我們要在目前nginx伺服器上,配置允許39.104.116.91的跨域通路。
配置參考
cd /etc/nginx/conf.d
# 修改配置
vi static.conf
# 配置如下
server {
...
#開啟sendfile,提高網絡包的傳輸效率
sendfile on;
#配置圖檔資源的路徑
location ~ .*\.(jpg|gif|png)$ {
#開啟壓縮
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types image/jpeg image/gif image/png;
root /opt/app/code/images;
}
#配置txt|xml資源的路徑
location ~ .*\.(txt|xml)$ {
#開啟壓縮
gzip on;
gzip_http_version 1.1;
gzip_comp_level 1;
gzip_types text/plain application/xml;
root /opt/app/code/doc;
}
# 配置html網頁資源路徑
location ~ .*\.(html|htm)$ {
#允許http://39.104.116.91跨域通路
add_header Access-Control-Allow-Origin http://39.104.116.91;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
root /opt/app/code;
}
}
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 重載配置
systemctl reload nginx.service
防盜鍊
防盜鍊,簡單來說就是你可以直接通路該資源,但是不能将我的資源連結放到你自己的伺服器上讓别人通路,尤其是圖檔或視訊這種比較大的檔案,容易導緻伺服器響應很慢,并且影響帶寬。
配置實踐
cd /etc/nginx/conf.d
# 修改配置
vi static.conf
# 配置如下
server {
...
#開啟sendfile,提高網絡包的傳輸效率
sendfile on;
#配置圖檔資源的路徑
location ~ .*\.(jpg|gif|png)$ {
#開啟壓縮
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types image/jpeg image/gif image/png;
# 防盜鍊
valid_referers none blocked *.zhutx.com server_names ~\.google\. ~\.baidu\.;
if ($invalid_referer) {
return 403;
}
root /opt/app/code/images;
}
...
}
valid_referers指定了合法的來源'referer', 他決定了内置變量$invalid_referer的值。
valid_referers文法
valid_referers none | blocked | server_names | string ...;
參數 | 說明 |
---|---|
none | “Referer” 來源頭部為空的情況 |
blocked | “Referer”來源頭部不為空,但是裡面的值被代理或者防火牆删除了,這些值都不以http://或者https://開頭 |
server_names | “Referer”來源頭部包含目前的server_names(目前域名) |
arbitrary string | 任意字元串,定義伺服器名或者可選的URI字首。主機名可以使用*開頭或者結尾,在檢測來源頭部這個過程中,來源域名中的主機端口将會被忽略掉 |
regular expression | 正規表達式 |
是以,我們的防盜鍊配置,在以下情況下可以合法通路圖檔:
- 直接在浏覽器輸入你的圖檔位址。符合none這個規則;
- 來自*.zhutx.com的通路;
- 來自谷歌和百度的通路(SEO優化);
如果不合法,那麼$invalid_referer等于1,會在if語句中傳回一個403給使用者。
網頁緩存
配置實踐
cd /etc/nginx/conf.d
# 修改配置
vi static.conf
# 配置如下
server {
...
location ~ .*\.(html|htm)$ {
# 協商用戶端,應答時維護Cache-Control和Expires頭資訊
expires 24h;
add_header Access-Control-Allow-Origin http://39.104.116.91;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
root /opt/app/code;
}
...
}
代理服務
正向代理
正向代理即用戶端代理。用戶端通過主動設定代理服務,進而将對目标的通路委托給有權通路的代理伺服器去通路。翻牆就是這種場景。
Nginx可以做正向代理伺服器
配置參考
# 先将上節内容備份下來
cd /etc/nginx/conf.d
mv static.conf static.conf.bak
# 從備份目錄恢複初始配置并改名
cp /opt/backup/default.conf zx_proxy.conf
# 修改配置
vi zx_proxy.conf
# 配置如下
server {
...
# 可能會涉及到DNS域名解析
resolver 8.8.8.8;
location / {
# 原封不動的讓自己轉發用戶端的請求
proxy_pass http://$http_host$request_uri;
}
}
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 重載配置
systemctl reload nginx.service
驗證結果
我的chrome浏覽器,安裝了SwitchySharp插件,配置Nginx代理如下:
接下來我通路了http://www.ttlsa.com/
通路正常,觀察Nginx的access.log的輸出日志:
www.ttlsa.com 115.198.157.60 - - [04/Feb/2018:11:13:40 +0800] "GET http://www.ttlsa.com/ HTTP/1.1" 200 18758 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" "-"
可見,我們對目标網站的通路,已經由Nginx代理了。
反向代理
反向代理即服務端代理。對用戶端隐藏真實伺服器位址。
配置參考
# 先把之前的配置備份下來
cd /etc/nginx/conf.d
mv zx_proxy.conf zx_proxy.conf.bak
# 從備份目錄恢複一個原始配置并改名
cp /opt/backup/default.conf fx_proxy.conf
# 編輯配置
vi fx_proxy.conf
# 配置如下
#我們增加這個server,端口8080,充當示範Real Server
server {
listen 8080;
server_name localhost;
location / {
root /opt/app/code;
}
}
server {
location / {
#把請求代理到本機8080端口
proxy_pass http://127.0.0.1:8080;
#引入代理相關通用配置
include proxy_params;
}
}
# 其他代理通用配置獨立出去,友善複用
vi /etc/nginx/proxy_params
# default就可以了。除非傳回301的場景,可能需要改寫
proxy_redirect defalut;
#配置header資訊,讓Real Server了解實際用戶端資訊
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
#一些代理逾時設定
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
#代理緩沖區設定
proxy_buffer_size 32k;
proxy_buffering on;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 由于這次增加了一個server端口要啟動,是以重新開機nginx服務
systemctl restart nginx.service
# 驗證8080端口已啟動
netstat -lnp | grep 8080
# 顯示如下
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 22091/nginx: master
驗證結果
# 建立反向代理結果示範頁面
cd /opt/app/code
vi test_fx_proxy.conf
<!DOCTYPE HTML>
<html >
<head>
<title>反向代理測試</title>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
</head>
<body>反向代理通路成功了</body>
</html>
然後通路:
以下是本次通路的access.log輸出:
39.104.93.171 127.0.0.1 - - [04/Feb/2018:11:37:12 +0800] "GET /test_fx_proxy.html HTTP/1.0" 200 235 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" "-"
39.104.93.171 115.198.157.60 - - [04/Feb/2018:11:37:12 +0800] "GET /test_fx_proxy.html HTTP/1.1" 200 235 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" "-"
可以看到2次請求,先是80端口的server收到使用者請求,經反向代理後,Real Server收到了這個請求。
代理WebSocket的配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:8010;
}
server {
listen 8020;
access_log /var/log/nginx/test_websocket.access.log main;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
負載均衡服務
負載均衡技術可讓多個後端伺服器共同分擔請求壓力,解決大量并發通路服務問題。
參考配置
# 先備份反向代理配置
cd /etc/nginx/conf.d
mv fx_proxy.conf fx_proxy.conf.bak
# 從備份目錄恢複一個初始配置并改名
cp /opt/backup/default.conf load_balance.conf
# 修改配置
vi load_balance.conf
#配置如下
server{
listen 8001;
server_name localhost;
location / {
root /opt/app/code/server_8001;
}
}
server{
listen 8002;
server_name localhost;
location / {
root /opt/app/code/server_8002;
}
}
server{
listen 8003;
server_name localhost;
location / {
root /opt/app/code/server_8003;
}
}
server{
listen 8004;
server_name localhost;
location / {
root /opt/app/code/server_8004;
}
}
upstream backend {
server localhost:8001;
server localhost:8002;
server localhost:8003 down;
server localhost:8004 backup;
}
server {
...
location / {
# 代理到upstream組
proxy_pass http://backend;
include proxy_params;
}
}
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 重載服務
systemctl reload nginx.service
# 可以看到4個端口都已就緒
[[email protected] conf.d]# netstat -lnp | grep 8001
tcp 0 0 0.0.0.0:8001 0.0.0.0:* LISTEN 22091/nginx: master
[[email protected] conf.d]# netstat -lnp | grep 8002
tcp 0 0 0.0.0.0:8002 0.0.0.0:* LISTEN 22091/nginx: master
[[email protected] conf.d]# netstat -lnp | grep 8003
tcp 0 0 0.0.0.0:8003 0.0.0.0:* LISTEN 22091/nginx: master
[[email protected] conf.d]# netstat -lnp | grep 8004
tcp 0 0 0.0.0.0:8004 0.0.0.0:* LISTEN 22091/nginx: master
接下來我們按照4個server的配置,建立各自的測試結果頁面:
cd /opt/app/code
mkdir server_8001 server_8002 server_8003 server_8004
cd server_8001
vi test_load_balance.html
<!DOCTYPE HTML>
<html >
<head>
<title>負載均衡測試頁</title>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
</head>
<body>my port is 8001</body>
</html>
同樣的建立其他3個test_load_balance.html,隻是顯示port不同。
驗證結果
我們嘗試多次請求http://39.104.93.171/test_loa...
結果始終處于下面兩個頁面之間變換:
我們DROP掉8001和8002
iptables -I INPUT -p tcp --dport 8001 -j DROP
iptables -I INPUT -p tcp --dport 8002 -j DROP
再嘗試多次請求http://39.104.93.171/test_loa...
這回頁面始終顯示:
upstream的server參數
參數 | 說明 |
---|---|
down | 不參與負載均衡 |
backup | 預留的備份伺服器。當沒有其他節點提供服務時,它才提供服務 |
max_fails | 允許請求失敗的次數 |
fail_timeout | 經過max_fails失敗後,服務暫停的時間 |
max_conns | 限制最大接收的連接配接數 |
上面示範時,8003是指定了down,實驗結果也驗證了它沒參與負載均衡。8004指定了backup,我們用iptables指令DROP了8001和8002後,已沒有其他節點對外提供服務了,是以backup開始接收請求。
其他參數可以自行嘗試。
負載均衡排程算法
方式 | 說明 |
---|---|
輪詢 | 按順序逐一配置設定給不同的後端伺服器 |
權重輪詢 | weight值越大,配置設定到的幾率越大 |
ip_hash | 同一IP固定通路同一個後端伺服器 |
least_conn | 哪個連接配接數少就發哪個機器 |
url_hash | 按url參數的hash結果來配置設定 |
hash關鍵數值 | hash自定義的key |
# 負載均衡算法-權重輪詢
upstream backend {
server localhost:8001 weight=5;
server localhost:8002;
server localhost:8003 down;
server localhost:8004 backup;
}
# 負載均衡算法-最少連接配接數
upstream backend {
least_conn;
server localhost:8001;
server localhost:8002;
server localhost:8003 down;
server localhost:8004;
}
# 負載均衡算法-IP HASH
upstream backend {
ip_hash;
server localhost:8001;
server localhost:8002;
server localhost:8003 down;
server localhost:8004;
}
# 負載均衡算法-URL HASH
upstream backend {
url_hash;
server localhost:8001;
server localhost:8002;
server localhost:8003 down;
server localhost:8004;
}
當配置負載均衡算法為IP HASH或URL HASH時,便不再接受backup的server,不然無法通過配置校驗。不過由于backup違背了算法本身,是以這也在情理之中。
緩存服務
我們大緻可以把緩存分為 用戶端緩存、代理緩存和服務端緩存3類。
Nginx作為緩存服務,可以減少後端伺服器的壓力,當再次去通路之前通路過的資料時,在nginx前端就能拿到。是代理緩存。
參考配置
# 備份之前的配置
cd /etc/nginx/conf.d
mv load_balance.conf load_balance.conf.bak
# 從備份目錄初始一份配置并改名
cp /opt/backup/default.conf cache.conf
# 修改配置
vi cache.conf
...
#定義用于存放緩存檔案的空間
#/opt/app/cache 緩存檔案存放目錄
#keys_zone=my_cache:10m,緩存空間命名為my_cache,10m大概可以存8萬個左右的緩存key了
#inactive=60m,超60分鐘沒有通路的緩存自動清理
proxy_cache_path /opt/app/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
...
if ($request_uri ~ ^/(login|register|password)) {
set $cookie_nocache 1;
}
location / {
# 緩存
proxy_cache my_cache;
# 基于代理
proxy_pass http://backend;
# 緩存過期周期配置,傳回200 304狀态的,緩存12小時過期
proxy_cache_valid 200 304 12h;
# 其他的緩存10分鐘過期
proxy_cache_valid any 10m;
# 緩存key
#proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_key $host$uri$is_args$args;
#配置不緩存的請求
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
proxy_no_cache $http_pragma $http_authorization;
# 增加一個頭資訊給用戶端,表示緩存是否命中
add_header Nginx-Cache "$upstream_cache_status";
# 後端伺服器某一台傳回不正常,則代理到下一台
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
include proxy_params;
}
}
清理緩存
方式一:rm -rf 清空緩存目錄。會清空所有緩存
方式二:第三方擴充子產品ngx_cache_purge,可以清理指定緩存
緩存命中分析
在上面緩存的配置中,我們添加了Nginx-Cache這個響應頭部資訊
add_header Nginx-Cache "$upstream_cache_status";
關于$upstream_cache_status,有如下幾個值:
狀态 | 意義 |
---|---|
MISS | 緩存未命中,請求被傳送到背景處理 |
HIT | 緩存命中 |
EXPIRED | 緩存過期,請求被傳送到背景處理 |
UPDATING | 正在更新緩存,将使用舊的應答 |
STALE | 後端得到過期的應答 |
是以,我們可以分析nginx通路日志,hit次數/總請求次數就是緩存命中率
# 修改log_format,輸出$upstream_cache_status
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$upstream_cache_status"';
# 用awk指令統計
awk '{if($NF=="\"HIT\""){hit++}}END{printf "%.2f",hit/NR}' /var/log/nginx/access.log
大檔案分割請求
ngx_http_slice_module子產品是一個分割請求轉換成子請求,每個傳回一定範圍内響應的濾波器。該過濾器提供了更有效的大響應緩存。
該子產品不是預設生成的,它應該使用--with-http_slice_module配置參數啟用。
如果你按Nginx筆記(一)Nginx安裝的方式安裝Nginx,那麼該子產品預設已經編譯進來。可以用nginx -V指令驗證。
配置示例
#定義用于存放緩存檔案的空間
#/opt/app/cache 緩存檔案存放目錄
#keys_zone=my_cache:10m,緩存空間命名為my_cache,10m大概可以存8萬個左右的緩存key了
#inactive=60m,超60分鐘沒有通路的緩存自動清理
proxy_cache_path /opt/app/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
location ~ \.apk$ {
slice 5m;
proxy_cache my_cache;
proxy_cache_key $uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
proxy_cache_valid 200 206 1h;
proxy_pass http://localhost:8999;
}
在這個例子中,響應被分割成5兆位元組的可緩存切片。
安全連結校驗
ngx_http_secure_link_module用于檢查請求連結的真僞,保護資源免受未經授權的通路
該子產品不是預設生成的,它應該使用--with-http_secure_link_module配置參數啟用。
如果你按Nginx筆記(一)Nginx安裝的方式安裝Nginx,那麼該子產品預設已經編譯進來。可以用nginx -V指令驗證。
實際應用中,如需要對下載下傳連結進行合法性校驗,過期校驗。
我們用shell腳本模拟服務端生成一個下載下傳連結:
vim md5url.sh
輸入以下内容
#!/bin/sh
#
download_file="/download/file.img"
expires=$(date -d "2019-02-12 00:00:00" +%s)
secret="123456"
# 我們用過期時間+下載下傳url,加上密鑰,生成md5。後面nginx配置的md5校驗規則亦如此
md5=$(echo -n "${expires}${download_file} ${secret}"|openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)
servername="116.62.156.235"
echo "${servername}${download_file}?md5=${md5}&expires=${expires}"
執行sh md5url.sh,生成連結如下:
116.62.156.235/download/file.img?md5=kD4hdQLA-psd_QzPSzyrdA&expires=1549900800
我們在/opt/app/code下事先放一個下載下傳檔案/download/file.img
nginx配置示例
server {
listen 80;
server_name localhost;
root /opt/app/code;
location / {
# 提取請求參數md5和expires
secure_link $arg_md5,$arg_expires;
# secure_link_md5定義的表達式MD5哈希值與請求參數中提取的md5值比較
secure_link_md5 "$secure_link_expires$uri 123456";
# 如果md5不相同,則該$secure_link變量設定為空字元串
if ($secure_link = "") {
return 403;
}
# 如果md5相同,則檢查是否過期。如果已過期,則該$secure_link變量設定為0
if ($secure_link = "0") {
return 410;
}
}
}
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 重載服務
systemctl reload nginx.service
通路生成的連結,便成功下載下傳檔案。當修改請求md5值,或者過期通路,便會顯示403頁面
geoip
基于IP位址比對MaxMind GeoIP二進制檔案,讀取IP所在地域資訊,包括國家以及城市資訊
當需要為國内與國外使用者提供不同的通路界面,如國内使用者代理到簡體中文的位址,國外使用者代理到英文版位址;
再比如國内使用者,需要基于使用者所在城市提供本地化的服務,如通路58同城,網頁預設就處于這個城市版面;
這些都可以通過ngx_http_geoip_module子產品來實作。
該子產品不是預設生成的,它應該使用--with-http_geoip_module配置參數啟用
# 安裝nginx的geoip子產品
yum install nginx-module-geoip
# 檢視已安裝的庫
cd /etc/nginx/modules
ls
ngx_http_geoip_module-debug.so ngx_http_geoip_module.so ngx_stream_geoip_module-debug.so ngx_stream_geoip_module.so
cd ..
# 非預設編譯進來的,是以load進來
vim nginx.conf
load_module "modules/ngx_http_geoip_module.so";
load_module "modules/ngx_stream_geoip_module.so";
mkdir geoip
cd geoip
下載下傳地域資訊
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoIP.dat.gz
gunzip GeoLiteCity.dat.gz
cd ../conf.d
nginx配置示例
vim test_geo.conf
geoip_country /etc/nginx/geoip/GeoIP.dat;
geoip_city /etc/nginx/geoip/GeoLiteCity.dat;
server {
listen 80;
server_name localhost;
location / {
if ($geoip_country_code != CN) {
return 403;
}
root /usr/share/nginx/html;
index index.html index.htm;
}
location /myip {
default_type text/plain;
return 200 "$remote_addr $geoip_country_name $geoip_country_code $geoip_city";
}
}
# 校驗配置
nginx -tc /etc/nginx/nginx.conf
# 重載服務
systemctl reload nginx.service
當通路/myip時,我們簡單顯示了下本地出口ip以及國家名稱,國家編碼,以及城市編号。
HTTPS服務
動靜分離
分離資源,減少不必要的請求消耗,減少請求延時。
參考配置
# 備份之前的配置
cd /etc/nginx/conf.d
mv cache.conf cache.conf.bak
# 從備份目錄初始一份配置并改名
cp /opt/backup/default.conf dynamic_static.conf
# 修改配置
vi dynamic_static.conf
# 配置如下
upstream java_api {
#事先在本機啟動了tomcat負責接收jsp請求
server 127.0.0.1:8080;
}
server {
...
# 根目錄也可以配置在location外面
root /opt/app/code;
# 動态的請求代理給backend
location ~ \.jsp$ {
proxy_pass http://java_api;
index index.html index.htm;
}
# 靜态請求自己處理
location ~ \.(jpg|png|gif)$ {
expires 1h;
gzip on;
}
location / {
index index.html index.htm
}
}
rewrite
以下場景都可以使用到Nginx的rewrite功能:
- URL重寫以适配後端的接口設計;
- 網站更新時候,對于部分老使用者繼續提供老版本的服務;
- 簡化前端url,友善SEO優化;
- 維護時挂維護頁面;
- 僞靜态,僞裝真實url。
參考配置
vi /etc/nginx/conf.d/default.conf
server {
...
root /opt/app/code;
location ~ ^/break {
# 比對/break,尋到root目錄下的/test目錄去,如果沒有找到則404
rewrite ^/break /test/ break;
}
location ~ ^/last {
# 比對/last,内轉/test/請求
rewrite ^/last /test/ last;
# 302臨時重定向,讓用戶端浏覽器重新通路/test
#rewrite ^/last /test/ redirect;
}
location ~ ^/imooc {
# 臨時性重定向 302,
#rewrite ^/imooc http://www.imooc.com/ permanent;
# 永久性重定向 301,下次将不再經過nginx而直接跳轉目标
rewrite ^/imooc http://www.imooc.com/ redirect;
}
location /test/ {
default_type application/json;
return 200 '{"status":"success"}'
}
location / {
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html break;
# 以Chrome浏覽器通路/nginx路徑,跳轉到慕課網nginx位址
#if ($http_user_agent ~* Chrome) {
# rewrite ^/nginx http://conding.imooc.com/class/121.html break;
#}
# 不存在該檔案,則重定向到百度
#if (!-f $request_filename) {
# rewrite ^/(.*)$ http://www.baidu.com/$1 redirect;
#}
index index.html index.htm
}
}
rewrite規則優先級
- 執行server塊的rewrite指令
- 執行location比對
- 執行標明的location中的rewrite
優雅的rewrite規則規則
server {
listen 80;
server_name www.nginx.org nginx.org;
if ($http_host = nginx.org) {
rewrite (.*) http://www.nginx.org$1;
}
}
可以改成:
server {
listen 80;
server_name nginx.org;
rewrite ^ http://www.nginx.org$request_uri?;
}
server {
listen 80;
server_name www.nginx.org;
}