Nginx中虛擬主機配置

1、Nginx中虛擬主機配置

一、基於域名的虛擬主機配置

一、修改宿主機的hosts文件(系統盤/windows/system32/driver/etc/HOSTS)javascript

linux : vim /etc/hostsphp

格式: ip地址 域名css

eg: 192.168.3.172 www.gerry.comhtml

二、在nginx.conf文件中配置server段前端

server {
  listen 80;
  server_name www.gerry.com; # 域名區分
   
  location / {
      root html/gerry;
      index index.html;
  }
}

server {
  listen 80;
  server_name www.rm.com; # 域名區分
   
  location / {
      root html/rm;
      index index.html;
  }
}

二、基於端口號的虛擬主機配置

一、在nginx.conf文件中配置server段java

server {
  listen 80; # 端口區分
  server_name www.gerry.com;
   
  location / {
      root html/gerry;
      index index.html;
  }
}

server {
  listen 8080; # 端口區分
  server_name www.gerry.com;
   
  location / {
      root html/gerry;
      index index.html;
  }
}

 

三、基於IP的虛擬主機配置

一、添加網卡的IP別名linux

ifconfig ens33:1 192.168.3.202 broadcast 192.168.3.255 netmask 255.255.255.0 up
route add -host 192.168.3.202 dev ens33:1
ifconfig ens33:2 192.168.3.203 broadcast 192.168.3.255 netmask 255.255.255.0 up
route add -host 192.168.3.203 dev ens33:2

從另一臺服務器Ping 192.168.3.202和192.168.3.203兩個IP,若是可以Ping通,則證實配置無誤。可是,經過ifconfig和route配置的IP別名在服 務器重啓後會消失,不過能夠將這兩條ifconng和route命令添加到/etc/rc.local文件中,讓系統開機時自動運行,如下是相關命令:vi /etc/rc.local 在文件末尾增長如下內容,而後保存便可nginx

ifconfig ens33:1 192.168.3.202 broadcast 192.168.3.255 netmask 255.255.255.0 up route add -host 192.168.3.202 dev ens33:1 ifconfig ens33:2 192.168.3.203 broadcast 192.168.3.255 netmask 255.255.255.0 up route add -host 192.168.3.203 dev ens33:2git

二、修改配置文件作以下的Server段配置github

server {
  listen 80;
  server_name 192.168.3.202;
   
  location / {
      root html/host1;
      index index.html;
  }
}

server {
  listen 80;
  server_name 192.168.3.203;
   
  location / {
      root html/host2;
      index index.html;
  }
}

2、nginx中server_name的匹配順序

前提:安裝echo-nginx-module

一、下載https://github.com/openresty/echo-nginx-module並解壓到服務器上

二、進入nginx的安裝目錄,用下列命令進行配置和安裝 ./configure --prefix=/usr/local/nginx --add-module=/usr/local/nginx_modules/echo-nginx-module-master make -j4 && make install

修改hosts配置文件

在Hosts文件中作以下配置:

vim /etc/hosts

127.0.0.1 ddd.cn

127.0.0.1 aaa.cn

一、最高優先級:徹底匹配

首先,在nginx.conf中建立2個server,1個徹底匹配,1個通配符匹配

通配符server放在最前,以證實徹底匹配的優先級與配置順序無關

server {
  listen 80;
  server_name *.cn;
   
  location / {
      default_type text/html;
      echo "通配符在前";
  }
}

server {
  listen 80;
  server_name ddd.cn;
   
  location / {
      default_type text/html;
      echo "徹底匹配";
  }
}

二、第二優先級:通配符在前

server {
  listen 80;
  server_name ddd.*;
   
  location / {
      default_type text/html;
      echo "通配符在後";
  }
}

server {
  listen 80;
  server_name *.cn;
   
  location / {
      default_type text/html;
      echo "通配符在前";
  }
}

三、第三優先級:通配符在後

server {
  listen 80;
  server_name ~^\w+\.cn$;
   
  location / {
      default_type text/html;
      echo "正則匹配";
  }
}

server {
  listen 80;
  server_name ddd.*;
   
  location / {
      default_type text/html;
      echo "通配符在後";
  }
}

四、listen配置項中default的影響

server {
  listen 80;
  server_name ~^\w+\.cn$;
   
  location / {
      default_type text/html;
      echo "正則匹配";
  }
}

server {
  listen 80;
  server_name dddd.xxx;
   
  location / {
      default_type text/html;
      echo "不匹配";
  }
}

server {
  listen 80 default;
  server_name haha.xxx;
   
  location / {
      default_type text/html;
      echo "不匹配找Listen Default";
  }
}

五、驗證default的做用域

server {
    listen 80 default;
    server_name *.cn;
    
    location / {
        default_type text/html;
        echo "通配符在前";
    }
}

server {
    listen 80;
    server_name ddd.cn;
    
    location / {
        default_type text/html;
        echo "徹底匹配";
    }
}

結論: default關鍵字在全部server段下面的server_name都匹配不上的時候纔有效果

六、驗證沒有匹配成功也沒有default的狀況

server {
    listen 80;
    server_name haha.cn;
    
    location / {
        default_type text/html;
        echo "不匹配,通配符在前";
    }
}

server {
    listen 80;
    server_name heihei.cn;
    
    location / {
        default_type text/html;
        echo "不匹配,通配符在後";
    }
}

結論: 在請求的server_name 都不匹配也沒有default關鍵字狀況下,會根據配置文件的順序選擇配置文件中第一虛擬主機。

3、日誌的配置

http {
    include       mime.types;
    default_type  application/octet-stream;
	# 定義日誌的格式
    log_format  main  '$remote_addr - [$time_iso8601] - $msec - $status - $request_time - $body_bytes_sent - "$http_host" - "$request" - "$http_referer" - "$http_user_agent" - "$http_x_forwarded_for"';

  #設置日誌默認存儲目錄
    access_log  logs/access.log  main;
    error_log   logs/error.log;
}

====== 內置的變量 ===============
$remote_addr, $http_x_forwarded_for(反向) 記錄客戶端IP地址
$remote_user 記錄客戶端用戶名稱
$request 記錄請求的URL和HTTP協議
$status 記錄請求狀態
$body_bytes_sent 發送給客戶端的字節數,不包括響應頭的大小; 該變量與Apache模塊mod_log_config裏的「%B」參數兼容。
$bytes_sent 發送給客戶端的總字節數。
$connection 鏈接的序列號。
$connection_requests 當前經過一個鏈接得到的請求數量。
$msec 日誌寫入時間。單位爲秒,精度是毫秒。
$pipe 若是請求是經過HTTP流水線(pipelined)發送,pipe值爲「p」,不然爲「.」。
$http_referer 記錄從哪一個頁面連接訪問過來的
$http_user_agent 記錄客戶端瀏覽器相關信息
$request_length 請求的長度(包括請求行,請求頭和請求正文)。
$request_time 請求處理時間,單位爲秒,精度毫秒; 從讀入客戶端的第一個字節開始,直到把最後一個字符發送給客戶端後進行日誌寫入爲止。
$time_iso8601 ISO8601標準格式下的本地時間。
$time_local 通用日誌格式下的本地時間。

4、nginx配置location(html location重定向)

匹配指定的請求uri(請求uri不包含查詢字符串,如http://localhost:8080/test?id=10,請求uri是/test)

語法形式

location [ = | ~ | ~* | ^~ | @] /uri/ { configuration }

location = /uri =開頭表示精確前綴匹配,只有徹底匹配才能生效。

location ^~ /uri ^~開頭表示普通字符串匹配上之後再也不進行正則匹配。

location ~ pattern ~開頭表示區分大小寫的正則匹配。

location ~* pattern ~*開頭表示不區分大小寫的正則匹配。

location /uri 不帶任何修飾符,表示前綴匹配。(通常匹配,最長命中匹配)

location /uri/aaa/bbb 最長命中匹配

location / 通用匹配,任何未匹配到其餘location的請求都會匹配到。

注意:正則匹配會根據匹配順序,找到第一個匹配的正則表達式後將中止搜索。普通字符串匹配則無視順序,只會選擇最精確的匹配。

一、location經常使用匹配

  • = :精準匹配

  • ~ :正則匹配

  • ~* :正則匹配,不區分大小寫

  • ^~ : 普通字符匹配, ^~ 的含義是若是命中,則不會再進行任何的正則匹配(關閉正則匹配)

  • 前面沒有任何修飾: 普通字符匹配

二、location匹配順序

  1. 精確匹配

  2. 普通匹配

  3. 正則匹配

精準匹配

location =/test/index.html {
	root gerry/host2;
	index index.html;
}

普通匹配

location /test {
	root gerry/host1;
	index index.html;
}

# 最長命中匹配
location /test/aaa {
	root gerry/host1;
	index index.html;
}


# root 和 alias 區別
location /test {
	root gerry/host1;
	index index.html;
}


location /kkk/ {
	alias /usr/local/nginx/gerry/host1/;
	index index.html;
}

正則匹配

##正則匹配
location ~ /test/.+\.html$ {
	root gerry/host1;
}

location ~ /test/.+\.js$ {
	root gerry/host1;
}

## 關閉正則匹配
location ^~ /test {
	root gerry/host2;
	index index.html;
}

## 忽略大小寫匹配
location ~* /.+\.HTML$ {
	root gerry/html;
	index index.html;
}

三、location匹配規則流程

A、判斷是否精準匹配,若是匹配,直接返回結果並結束搜索匹配過程。 B、判斷是否普通匹配,若是匹配,看是否包含^~前綴,包含則返回,不然記錄匹配結果,(若是匹配到多個location時返回或記錄最長匹配的那個) C、判斷是否正則匹配,按配置文件裏的正則表達式的順序,由上到下開始匹配,一旦匹配成功,直接返回結果,並結束搜索匹配過程。 D、若是正則匹配沒有匹配到結果,則返回步驟B記錄的匹配結果。

注意:

A、多個普通匹配的location時,和location的順序無關,老是匹配全部的location,而後取匹配最長的location做爲結果

B、多個正則匹配的location時,和順序有關,從上到下依次匹配,一旦匹配成功便結束,直接返回結果。

四、經常使用配置指令alias、root

一、alias——別名配置,用於訪問文件系統,在匹配到location配置的URL路徑後,指向alias配置的路徑,如:

location /test/ {

alias /usr/local/; ## 文件路徑必須爲絕對路徑

}

請求/test/1.jpg(省略了協議和域名),將會返回文件/usr/local/1.jpg。

若是alias配置在正則匹配的location內,則正則表達式中必須包含捕獲語句(也就是括號()),並且alias配置中也要引用這些捕獲值。如:

location ~* /img/(.+.(gif|png|jpeg) {

alias /usr/local/images/$1;

}

請求中只要能匹配到正則,好比/img/flower.png 或者 /resource/img/flower.png,都會轉換爲請求/usr/local/images/flower.png

二、root——根路徑配置,用於訪問文件系統,在匹配到location配置的URL路徑後,指向root配置的路徑,並把請求路徑附加到其後,如:

location /test/ {

root /usr/local/;

}

請求/test/1.jpg,將會返回文件/usr/local/test/1.jpg。

5、Nginx的Rewrite

一、rewrite的介紹

一、Rewrite經過ngx_http_rewrite_module模塊支持url重寫、支持if判斷,但不支持else

二、rewrite功能就是,使用nginx提供的全局變量或本身設置的變量,結合正則表達式和標誌位實現url重寫以及重定向

三、rewrite只能放在server{},location{},if{}中,而且只能對域名後邊的除去傳遞的參數外的字符串起做用

http://www.gerry.com/test/v1/10

http://www.gerry.com/test?version=1&id=10

二、經常使用指令

If 空格 (條件) {設定條件進行重寫}

條件的語法:

  1. 「=」 來判斷相等,用於字符比較

  2. 「~」 用正則來匹配(表示區分大小寫),「~*」 不區分大小寫

  3. 「-f -d -e」 來判斷是否爲文件、目錄、是否存在

return 指令

語法:return code;

中止處理並返回指定狀態碼給客戶端。

if ($request_uri ~ *.sh ){

return 403

}

set指令

set variable value;

定義一個變量並賦值,能夠是文本、變量或者文本變量混合體

rewrite指令

語法:rewrite regex replacement [flag]{last / break/ redirect 返回臨時301/ permanent 返回永久302}

last: 中止處理後續的rewrite指令集、 而後對當前重寫的uri在rewrite指令集上從新查找

break: 中止處理後續的rewrite指令集 ,並不會從新查找

三、實例講解

執門搜索

這個規則的目的是爲了執行搜索,搜索URL中包含的關鍵字。

 

加了問號和不加問號區別?
URI:/search/some-search-keywords/zhangsan?name=zhangsan

/search.do?p=some-search-keywords&name=zhangsan&name=zhangsan           不加問號。

/search.do?p=some-search-keywords&name=zhangsan                          加問號。

熱門搜索

請求的URL	//hqidi.com/search/some-search-keywords
重寫後URL	//hqidi.com/search.do?p=some-search-keywords
重寫規則	        rewrite ^/search/(.*)$ /search.do?p=$1?;

用戶我的資料頁面

大多數運行訪問者註冊的動態網站都提供一個能夠查看我的資料的頁面,這個頁面的URL包含用戶的UID和用戶名

請求的URL	//hqidi.com/user/47/dige
重寫後URL	//hqidi.com/user.do?id=47&name=dige
重寫規則	        rewrite ^/user/([0-9]+)/(.+)$ /user.do?id=$1&name=$2?;

多個參數

有些網站對字符串參數使用不一樣的語法,例如 經過斜線「/」來分隔非命名參數

請求的URL	//hqidi.com/index.php/param1/param2/param3
重寫後URL	//hqidi.com/index.php?p1=param1&p2=param2&p3=param3
重寫規則	        rewrite ^/index.do/(.*)/(.*)/(.*)$ /index.do?p1=$1&p2=$2&p3=$3?;

相似百科的格式

這種格式特色,一個前綴目錄,後跟文章名稱

請求的URL	//hqidi.com/wiki/some-keywords
重寫後URL	//hqidi.com/wiki/index.do?title=some-keywords
重寫規則	        rewrite ^/wiki/(.*)$ /wiki/index.do?title=$1?;

論壇

論壇通常用到兩個參數,一個話題標識(topic)一個出發點(starting post)

請求的URL	//hqidi.com/topic-1234-50-some-keywords.html
重寫後URL	//hqidi.com/viewtopic.do?topic=1234&start=50
重寫規則        	rewrite ^/topic-([0-9]+)-([0-9]+)-(.*)\.html$ viewtopic.do?topic=$1&start=$2?;

新網站的文章

這種URL結構的特色,由一個文章標識符,後跟一個斜線,和一個關鍵字列表組成。

請求的URL	//hqidi.com/88/future
重寫後URL	//hqidi.com/atricle.php?id=88
重寫規則	        rewrite ^/([0-9]+)/.*$ /aticle.do?id=$1?;

最後一個問號

若被替換的URI中含有參數(相似/app/test.php?id=5之類的URI),默認狀況下參數會被自動附加到替換串上,能夠經過在替換串的末尾加上?標記來解決這一問題。

rewrite ^/users/(.*)$ /show?user=$1? last;

比較一個加上?標記和不加?標記的URL跳轉區別:

rewrite ^/test(.*)$ //hqidi.com/home premanent;

訪問//hqidi.com/test?id=5 通過301跳轉後的URL地址爲 //hqidi.com/home?id=5

rewrite ^/test(.*)$ //hqidi.com/home? premanent;

訪問//hqidi.com/test?id=5 通過301跳轉後的URL地址爲 //hqidi.com/home

6、瀏覽器本地緩存配置

語法:expires 60 s|m|h|d

動靜分離效果:

server {
    listen 80;
    server_name localhost;
    location / {
        root html;
        index index.html;
    }
    
    location ~ \.(png|jpg|js|css|gif)$ {
        root html/images;
        expires 5m;
    }
}

7、Gzip壓縮策略

瀏覽器請求 -> 告訴服務端當前瀏覽器能夠支持壓縮類型->服務端會把內容根據瀏覽器所支持的壓縮策略去進行壓縮返回

->瀏覽器拿到數據之後解碼; 常見的壓縮方式:gzip、deflate 、sdch

Gzip on|off 是否開啓gzip壓縮 Gzip_buffers 4 16k

設置系統獲取幾個單位的緩存用於存儲gzip的壓縮結果數據流。4 16k表明以16k爲單位,安裝原始數據大小以16k爲單位的4倍申請內存。

Gzip_comp_level[1-9] 壓縮級別, 級別越高,壓縮越小,可是會佔用CPU資源 Gzip_disable #正則匹配UA 表示什麼樣的瀏覽器不進行gzip Gzip_min_length 開始壓縮的最小長度(小於多少就不作壓縮)

Gzip_http_version 1.0|1.1 表示開始壓縮的http協議版本 Gzip_proxied (nginx 作前端代理時啓用該選項,表示不管後端服務器的headers頭返回什麼信息,都無條件啓用壓縮) Gzip_type text/pliain,application/xml 對那些類型的文件作壓縮 (conf/mime.conf) Gzip_vary on|off 是否傳輸gzip壓縮標識

server {
    listen 80;
    server_name localhost;
    gzip on;
    gzip_buffers 4 16K;
    gzip_comp_level 7;
    gzip_min_length 500;
    gzip_types text/css text/xml text/javascript;
    
    location / {
        root html;
        index index.html;
    }
    
    location ~ \.(png|jpg|js|css|gif)$ {
        root html/images;
        expires 5m;
    }
}

注意點

  1. 圖片、mp3這樣的二進制文件,不必作壓縮處理,由於這類文件壓縮比很小,壓縮過程會耗費CPU資源

  2. 過小的文件不必壓縮,由於壓縮之後會增長一些頭信息,反而致使文件變大

  3. Nginx默認只對text/html進行壓縮 ,若是要對html以外的內容進行壓縮傳輸,咱們須要手動來配置

8、Nginx反向代理

location {proxy_pass}

server {
    listen 80;
    server_name www.gerry.com;
    
    location =/s {
        proxy_pass http://www.baidu.com;
    }
}

Proxy_pass 既能夠是ip地址,也能夠是域名,同時還能夠指定端口

Proxy_pass指定的地址攜帶了URI,看咱們前面的配置【/web】,那麼這裏的URI將會替換請求URI中匹配location參數部分;如上代碼將會訪問到http://www.baidu.com/web

9、負載均衡

upstream是Nginx的HTTP Upstream模塊,這個模塊經過一個簡單的調度算法來實現客戶端IP到後端服務器的負載均衡

一、Upstream經常使用參數介紹

語法:server address [parameters]

其中關鍵字server必選。 address也必選,能夠是主機名、域名、ip或unix socket,也能夠指定端口號。 parameters是可選參數,能夠是以下參數:

down:表示當前server已停用

backup:表示當前server是備用服務器,只有其它非backup後端服務器都掛掉了或者很忙纔會分配到請求

weight:表示當前server負載權重,權重越大被請求概率越大。默認是1

max_failsfail_timeout通常會關聯使用,若是某臺server在fail_timeout時間內出現了max_fails次鏈接失敗,那麼Nginx會認爲其已經掛掉了,從而在fail_timeout時間內再也不去請求它,fail_timeout默認是10s,max_fails默認是1,即默認狀況是隻要發生錯誤就認爲服務器掛掉了,若是將max_fails設置爲0,則表示取消這項檢查。

upstream tomcatserver {
    server 192.168.3.220:8080;
    server 192.168.3.222:8080 weigth=4;
}

二、ups支持的調度算法

在作負載均衡前,咱們首先須要定義一個 Server 組用來表示全部存在的後臺服務:

http {
    upstream backend {
        server backend1.example.com weight=5;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
}

而後,咱們須要把流量重定向到上一步定義的 backend 上去, 咱們能夠經過指定 proxy_pass 的值來完成這一操做:

    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
    
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

這裏咱們將全部的流量重定向到 http://backend , 這將這個 NGINX 實例上的全部流量重定向到以前定義的 backend 上去。

負載均衡算法

當沒有指定任何信息時, NGINX 默認使用了 Round Robin(輪詢)算法來重定向流量。其實 NGINX 提供了多種算法來作負載均衡,下面咱們來介紹一下:

一、Round Robin (輪詢)

在沒有指定 weight(權重) 的狀況下,Round Robin 會將全部請求均勻地分發給全部後臺服務實例:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
}

這裏咱們沒有指定權重,因此兩個後臺服務會收到等量的請求。可是,當指定了權重以後,NGINX 就會將權重考慮在內:

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
}

在 NGINX 中,weight 默認被設置爲 1。這裏咱們用一開始的配置舉例, backend1.example.com 的權重被設置爲 5,另外一個的權重沒設置,因此是默認值 1。咱們也沒有設置輪詢算法,因此這時候 NGINX 會以 5:1 的比例轉發請求,即 6 個請求中, 5 個被放到了 backend1.example.com 上, 有一個被髮到了 backend2.example.com 上。

二、Least Connections(最少鏈接算法)

在這個模式下,一個請求會被 NGINX 轉發到當前活躍請求數量最少的服務實例上:

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}

咱們用 least_conn 來指定最少鏈接優先算法, NGINX 會優先轉發請求到現有鏈接數少的那一個服務實例上。

三、IP Hash (IP 哈希)

在 IP Hash 模式下,NGINX 會根據發送請求的 IP 地址的 hash 值來決定將這個請求轉發給哪一個後端服務實例。被 hash 的 IP 地址要麼是 IPv4 地址的前三個 16 進制數或者是整個 IPv6 地址。使用這個模式的負載均衡模式能夠保證來自同一個 IP 的請求被轉發到同一個服務實例上。固然,這種方法在某一個後端實例發生故障時候會致使一些節點的訪問出現問題。

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}

若是某一臺服務器出現故障或者沒法進行服務,咱們能夠給它標記上 down,這樣以前被轉發到這臺服務器上的請求就會從新進行 hash 計算並轉發到新的服務實例上:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}

四、Generic Hash(通用哈希)

這個模式容許管理員自定義 hash 函數的輸入,好比:

upstream backend {
    hash $reqeust_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

在這個例子中,咱們以請求中所帶的 url 爲 hash 的輸入。 注意到這裏在 hash 那一行的最後加入了 consistent 這個關鍵詞。這個關鍵詞會使用一種新的 hash 算法 ketama, 該算法會讓管理員添加或刪除某個服務實例的時候,只有一小部分的請求會被轉發到與以前不一樣的服務實例上去,其餘請求仍然會被轉發到原有的服務實例上去。

五、Random (隨機算法)

顧名思義,每一個請求都被隨機發送到某個服務實例上去:

upstream backend {
    random;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    server backend4.example.com;
}

Random 模式還提供了一個參數 two,當這個參數被指定時,NGINX 會先隨機地選擇兩個服務器(考慮 weight),而後用如下幾種方法選擇其中的一個服務器:

1. least_conn: 最少鏈接數
2. least_time=header(NGINX PLUS only): 接收到 response header 的最短平均時間
3. least_time=last_byte(NGINX PLUS only): 接收到完整請求的最短平均時間

咱們能夠參考下面的一個例子:

upstream backend {
    random two least_time=last_byte;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    server backend4.example.com;
}

當環境中有多個負載均衡服務器在向後端服務轉發請求時,咱們能夠考慮使用 Random 模式,在只有單個負載均衡服務器時,通常不建議使用 Random 模式。

六、Least Time (NGINX PLUS only)

這是一個 NGINX PLUS (NGINX 的付費版) 纔有的模式,能夠將請求優先轉發給平均響應時間較短的服務實例,它也有三個模式:

1. header: 從服務器接收到第一個字節的時間
2. last_byte: 從服務器接收到完整的 response 的時間
3. last_byte inflight: 從服務器接收到完整地 response 的時間(考慮不完整的請求)

例子以下:

upstream backend {
    least_time header;
    server backend1.example.com;
    server  backend2.example.com;
}

總結

NGINX 提供了多種負載均衡模式,在實際使用中,須要根據實際業務需求去作嘗試,分析日誌來找到最適合當前場景的複雜均衡模式。

相關文章
相關標籤/搜索