1.為什么Nginx里面有的是瀏覽器渲染出的頁面,有的時候就變成下載文件?
這個一個取決于服務(wù)端nginx,一個取決于你瀏覽器。在Nginx服務(wù)端的配置文件目錄下,有一個mime.types文件,內(nèi)容如下
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
Application/JAVAscript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
這里,如text/html格式的字符串就是用來說明數(shù)據(jù)類型的,/前的是主類型,/之后的是該主類型下的子類型。詳細的類型定義在RFC2046中。
Nginx通過服務(wù)器端文件的后綴名來判斷這個文件屬于什么類型,再將該數(shù)據(jù)類型寫入HTTP頭部的Content-Type字段中,發(fā)送給客戶端
比如,當我們打開一個頁面,看到一個PNG格式的圖片的時候,Nginx是這樣發(fā)送格式信息的:
服務(wù)器上有test.png這個文件,后綴名是png;
根據(jù)mime.types,這個文件的數(shù)據(jù)類型應(yīng)該是image/png;
將Content-Type的值設(shè)置為image/png,然后發(fā)送給客戶端。
我們在Chrome瀏覽器中可以看到這個文件返回的頭部信息,并對應(yīng)的宣傳出來,如果不能識別則設(shè)置為下載文件。
2.multi_accept on的作用是什么?能不能通用配置?
這個數(shù)值默認就是on建議采用默認設(shè)置, multi_accept的作用是告訴nginx收到一個新連接通知后接受盡可能多的連接,多個worker按串行方式來處理連接,也就是一個連接只有一個worker被喚醒,其他的處于休眠狀態(tài)
設(shè)置為off后,多個worker按并行方式來處理連接,也就是一個連接會喚醒所有的worker,直到連接分配完畢,沒有取得連接的繼續(xù)休眠。當你的服務(wù)器連接數(shù)不多時,開啟這個參數(shù)會讓負載有一定的降低,但是當服務(wù)器的吞吐量很大時,為了效率,可以關(guān)閉這個參數(shù)。
3.同一臺機器通過進程socket文件快還是通過localhost:9000這個方式快?彼此之間各有什么坑嗎?
這兩個模式不一樣,一般對于程序聯(lián)系更為緊密的,可以使用進程間共享內(nèi)存調(diào)用,這樣效率更高。Socket方式
如果,兩個進程是松耦合的,那么用接口調(diào)用模式更佳。IP:PORT方式
當前,我們對于系統(tǒng)設(shè)計講究松耦合,微服務(wù)的模式,所以版本通過api接口模式調(diào)用更為廣泛應(yīng)用。
4.nginx +Tomcat 后臺服務(wù)響應(yīng)內(nèi)容比較大,日志報"an upstream response is buffered to a temporary file"的warn,通常這種情況需要配置網(wǎng)站的 Proxy Buffer相關(guān)的參數(shù),但proxy buffer相關(guān)的參數(shù),我應(yīng)該配置多大合理
這個buffer緩沖區(qū)設(shè)置是根據(jù)實際的 Response 大小來定,假設(shè)你是這么設(shè)置的:
fastcgi_buffers 8 5K; fastcgi_buffer_size 5K; #那么內(nèi)存的緩存區(qū)最大能緩存的大小是 5K * 8 = 40K,如果Nginx代理的后臺頁面超過這個大小,那就會出現(xiàn)這個錯誤。 #因為,頻繁的寫硬盤會影響性能,所以這個參數(shù)還是值得適當?shù)母鶕?jù)實際情況優(yōu)化的
5.關(guān)于try_files,怎么在生產(chǎn)中真正結(jié)合緩存,代理用?如下例:
server {
...
location {
try_files /app/cache/ $uri @fallback;
index index.html;
}
...
}
我們可以用后臺程序?qū)⒕彺嫘畔⑸傻?document_root/app/cache/目錄下,它將檢測,$document_root/app/cache/index.html 和$document_root$uri是否有靜態(tài)緩存生成的文件存在,如果不存在著內(nèi)部重定向到@fallback(@表示配置文件中預(yù)定義標記點)。
6.nginx在配置https時,如何匹配某個URL地址不做https跳轉(zhuǎn),如下例:
server {
listen 80;
server_name xuliangwei.com;
root /code;
location / {
#如果url不匹配這個則進行跳轉(zhuǎn)https,匹配則走本地的root查詢內(nèi)容
if ($request_uri !~ '^/bgx/') {
return 301 https://$server_name$request_uri;
}
}
}
server {
....
listen 443;
server_name xuliangwei.com;
....
}
7.使用nginx負載均衡時,如何將后端請求超時的服務(wù)器流量平滑的切換到另一臺上。
如果后臺服務(wù)連接超時,Nginx是本身是有機制的,如果出現(xiàn)一個節(jié)點down掉的時候,Nginx會更據(jù)你具體負載均衡的設(shè)置,將請求轉(zhuǎn)移到其他的節(jié)點上,但是,如果后臺服務(wù)連接沒有down掉,但是返回錯誤異常碼了如:504、502、500,這個時候你需要加一個負載均衡的設(shè)置,如下:
proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;
意思是,當其中一臺返回錯誤碼404,500...等錯誤時,可以分配到下一臺服務(wù)器程序繼續(xù)處理,提高平臺訪問成功率。
server {
listen 80;
server_name xuliangwei.com;
location / {
proxy_pass http://node;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
}
8.如何使用nginx的proxy_next_upstream將nginx錯誤頁面返回json
需求是除了404 頁面,其他的錯誤頁面都要返回 json,而且在外界看來是正常的,所以說白了就是后端服務(wù)器返回了我定義的錯誤狀態(tài)碼,需要在nginx這里做一個轉(zhuǎn)換,轉(zhuǎn)換到 200,用戶看到的是200,其實是將錯誤的狀態(tài)碼定向至200,然后再次調(diào)度到/api。
server {
listen 80;
server_name www.bgx.com;
location / {
proxy_intercept_errors on; #反向代理默認不支持自定義錯誤頁面,需要增加該參數(shù)
proxy_set_header Host $host;
proxy_pass http://www_server3_plools;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_next_upstream error timeout http_503 non_idempotent;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#出現(xiàn)500等錯誤都返回給用戶200狀態(tài),并跳轉(zhuǎn)至/api
error_page 500 502 503 504 =200 /api;
location = /api{
default_type application/json;
return 200 '{"retCode":"1001","retMsg":"invoke failed"}';
}
9.負載均衡配置,當掛掉一臺服務(wù)時,不能流暢地切換
需求:在配置負載均衡時,后端三臺web,手動關(guān)閉一個web 服務(wù),當輪詢到這臺關(guān)停的時候,總是要卡頓很久?
#可以如下這兩個參數(shù): proxy_connect_timeout 600; #1分鐘 proxy_read_timeout 600; #1分鐘
10.Nginx如何封掉真實惡意攻擊的IP地址
server {
listen 80;
server_name bgx.com;
location / {
set $allow true;
if ($http_x_forwarded_for ~ "106.121.*.*|106.121.71.120|106.121.74.130"){
set $allow false;
}
if ($allow = false){
return 403;
}
}
}
11.配置Nginx,僅允許公司網(wǎng)絡(luò)地址能訪問公司后臺/admin,其他網(wǎng)絡(luò)訪問返回403錯誤。
server {
listen 80;
server_name bgx.com;
location ~ ^/admin {
set $allow false;
if ($http_x_forwarded_for ~ "36.11.10.254|36.11.10.*"){
set $allow true;
}
if ($allow = false){
return 403;
}
}
}
12.linux系統(tǒng)的65535端口限制是如何來的?
在TCP、UDP協(xié)議的開頭,會分別有16位來存儲源端口號和目標端口號,所以端口個數(shù)是2^16-1=65535個。
TCP端口數(shù)65535的限制,這個是由TCP/IP協(xié)議棧中的第四層運輸層UDP/TCP協(xié)議決定的.在UDP/TCP協(xié)議中源端口和目的端口都只有16位,也就是說端口的取值范圍為0~65535。
13.四層負載均衡與七層負載均衡誤區(qū)?
1.四層負載均衡不受系統(tǒng)套接字限制,可以承載的并發(fā)量可以遠遠超過65535,這是因為四層在OSI協(xié)議中處于較低的層級,其并非在用戶空間,而是在內(nèi)核空間,是由TCP/IP協(xié)議棧處理的!
2.而七層負載均衡是在應(yīng)用層進行負載均衡,應(yīng)用層位于OSI協(xié)議中的最高層,也就是最接近用戶,其維護連接數(shù)要受到系統(tǒng)套接字的限制,Linux默認最多可以使用的套接字就65535個,這是系統(tǒng)的限制……更重要的是每個客戶端請求到達服務(wù)器,服務(wù)器處理的時候都是自最下層往上一次拆封數(shù)據(jù)包的,最上面的應(yīng)用層需要處理更多的工作,因此其必然承載的并發(fā)量不如四層多!
3.但需要注意七層負載均衡可以進行更復雜的控制,比如session會話保持,URL規(guī)則控制等,功能比四層更全面!
至于四層和七層可以處理的并發(fā)量有多大,這個和硬件密切相關(guān),不同配置的服務(wù)器,差異較大,沒有準確的量化指標!
14.如何為Nginx配置錯誤頁面?
當我們只有單臺web服務(wù)器時,需要配置錯誤返回頁面,可以使用error_page來指定。
[root@web01 conf.d]# cat code3.conf
server {
listen 80;
server_name code.oldboy.com;
location / {
root /code;
}
#如服務(wù)器返回如下錯誤狀態(tài)碼,則進行跳轉(zhuǎn),跳轉(zhuǎn)至/404.html
error_page 404 403 /40x.html;
#如服務(wù)器返回如下錯誤狀態(tài)碼,則進行跳轉(zhuǎn),跳轉(zhuǎn)至/50x.html
error_page 500 502 503 504 /50x.html;
#精準匹配訪問
location = /404.html {
root /err;
}
location = /50x.html {
root /err;
}
}
15.如何為nginx反向代理設(shè)置自定義錯誤頁面,包含proxy、fastcgi
#代理的配置
[root@www conf.d]# cat proxy.conf
server {
listen 80;
server_name test.bgx.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_intercept_errors on; #接收后端web4xx,5xx錯誤
error_page 500 502 403 404 = /proxy_error.html; #將后端web拋出的錯誤定向到指定的頁面
}
#如果有請求proxy_error.html文件的則指定到對應(yīng)的目錄
location = /proxy_error.html {
root /code/proxy;
}
}
#后端web節(jié)點配置
[root@www conf.d]# cat web.conf
server {
listen 8080;
server_name test.bgx.com;
root /code/web;
index index.html;
error_page 404 /404.html; #如果代理開啟proxy_intercept_errors則后端web配置error_page無效
}
16.Nginx如何禁止IP直接訪問?
當用戶通過訪問IP或者未知域名訪問你的網(wǎng)站的時候,你希望禁止顯示任何有效內(nèi)容,可以給他返回500,目前國內(nèi)很多機房都要求網(wǎng)站主關(guān)閉空主機頭,防止未備案的域名指向過來造成麻煩。
server {
listen 80;
server_name www.xuliangwei.com # 這里指定自己的域名
}
server{
listen 80 default_server; # 默認優(yōu)先返回
server_name _; # 空主機頭或IP
return 500; # 返回500錯誤
}
也可以將流量集中導入自己的網(wǎng)站,只要做以下跳轉(zhuǎn)設(shè)置就可以
server {
listen 80 default_server;
return 302 https://www.xuliangwei.com;
}
17.Nginx在上傳文件時出現(xiàn)413 Request Entity Too Large,怎么辦?
因為Nginx默認支持上傳1MB的文件,所以超過1MB則會報錯。
#nginx上傳文件大小限制配置語法
Syntax: client_max_body_size size;
Default: client_max_body_size 1m;
Context: http, server, location
允許該server能支持上傳200m的文件,也可以其配置放入http層,所有server都生效。
server {
...
client_max_body_size 200m;
...
}
18.Nginx指定路徑時,root與alias區(qū)別在哪?
root與alias路徑匹配主要區(qū)別在于nginx如何解釋location后面的uri,這會使兩者分別以不同的方式將請求映射到服務(wù)器文件上,alias是一個目錄別名的定義,root則是最上層目錄的定義。
root的處理結(jié)果是:root路徑+location路徑
alias的處理結(jié)果是:使用alias路徑替換location路徑
1.root路徑配置實例: 用戶訪問www.xuliangwei.com/image/test.gif,實際上Nginx會上/code/image/目錄下找去找test.gif文件
server {
listen 80;
server_name www.xuliangwei.com;
location /image/ {
root /code;
}
}
2.alias配置實例: 用戶訪問www.xuliangwei.com/image/test.gif,實際上Nginx會上/code/目錄下找去找test.gif文件。
server {
listen 80;
server_name www.xuliangwei.com;
location /image/ {
alias /code;
}
}
19.為什么通過IP地址訪問Nginx,有時候訪問的不是我想要的頁面呢?
在開始處理一個http請求時,nginx會取出header頭中的Host變量,與nginx.conf中每個server的server_name進行匹配,以此決定到底由哪一個server來處理這個請求。但nginx如配置多個相同的server_name,會導致server_name出現(xiàn)優(yōu)先級訪問沖突。
1.準備nginx對應(yīng)的配置文件
[root@web02 conf.d]# cat code1.conf
server {
listen 80;
server_name localhost code1.bgx.com;
location / {
root /code1;
index index.html;
}
}
[root@web02 conf.d]# cat code2.conf
server {
listen 80;
server_name localhost code2.bgx.com;
location / {
root /code2;
index index.html;
}
}
[root@web02 conf.d]# cat code3.conf
server {
listen 80;
server_name localhost code3.bgx.com;
location / {
root /code3;
index index.html;
}
}
2.準備站點目錄
[root@web02 conf.d]# mkdir /code{1..3} -p
[root@web02 conf.d]# for i in {1..3};do echo "Code$i" > /code$i/index.html;done
[root@web02 conf.d]# cat /code1/index.html
Code1
[root@web02 conf.d]# cat /code2/index.html
Code2
[root@web02 conf.d]# cat /code3/index.html
Code3
3.檢查語法, 并重新加載Nginx
[root@web02 conf.d]# nginx -t nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # 重啟Nginx [root@Nginx ~]# systemctl restart nginx
4.測試訪問效果
#1.當用戶第一次訪問, 由code1.conf返回輸出信息 [root@Nginx ~]# curl localhost Code 1 #2.此時將code1.conf修改為code5.conf后進行重載Nginx [root@Nginx ~]# mv code1.conf code5.conf [root@Nginx ~]# systemctl reload nginx #3.再次訪問時, 由code2.conf返回輸出信息 [root@Nginx ~]# curl localhost Code 2
5.多ServerName優(yōu)先級總結(jié), 在開始處理一個HTTP請求時,Nginx會讀取請求頭中的host,與每個server中的 server_name 進行匹配,來決定用哪一個 server 標簽完成處理這個請求。但有可能一個Host與多個server中的server_name都匹配,這個時候就會更具匹配優(yōu)先級來選擇實際處理的server塊。優(yōu)先級匹配結(jié)果如下:
1.首先選擇所有的字符串完全匹配的server_name。(完全匹配)
2.選擇通配符在前面的server_name,如*.bgx.com
3.選擇通配符在后面的server_name,如bgx.*
4.最后選擇使用正則表達式匹配的server_name
5.如果全部都沒有匹配到,那么將選擇在listen配置項后加入[default_server]的server塊
6.如果沒寫,那么就找到匹配listen端口的第一個Server塊的配置文件
PS注意:當出現(xiàn)多個相同的Server_Name情況下,配置文件排序優(yōu)先使用則會先被調(diào)用,所以生產(chǎn)建議配置相同端口, 不同域名,這樣則不會出現(xiàn)訪問沖突。
20.Nginx Try_files路徑匹配如何使用?
nginx的try_file路徑匹配,按順序檢查文件是否存在
[root@bgx ~]# cat /etc/nginx/conf.d/try_file.conf
server {
listen 80;
server_name try.bgx.com;
root /code;
location / {
try_files $uri /404.html /index.php;
}
}
#1.檢查用戶請求的uri內(nèi)容是否存在本地,存在則解析
#2.如果請求的url不存在,則訪問對應(yīng)站點目錄中的404.html文件
#3.最后交給index.php處理
1.演示環(huán)境準備
[root@Nginx ~]# echo "Try-Page" > /soft/code/index.html [root@Nginx ~]# echo "Tomcat-Page" > /soft/app/Apache-tomcat-9.0.7/webapps/ROOT/index.html #啟動tomcat [root@Nginx ~]# sh /soft/app/apache-tomcat-9.0.7/bin/startup.sh #檢查tomcat端口 [root@Nginx ~]# netstat -lntp|grep 8080 tcp6 0 0 :::8080 :::* LISTEN 104952/java
2.配置Nginx的tryfiles
[root@Nginx ~]# cat /etc/nginx/conf.d/try.conf
server {
listen 80;
server_name try.bgx.com;
root /code;
index index.html;
location / {
try_files $uri @java_page;
}
location @java_page {
proxy_pass http://127.0.0.1:8080;
}
}
#重啟Nginx
[root@Nginx ~]# nginx -s reload
3.測試`tryfiles`
[root@Nginx ~]# curl http://try.bgx.com/index.html
Try-Page
#將/code/index.html文件移走
[root@Nginx ~]# mv /code/{index.html,index.html_bak}
#發(fā)現(xiàn)由Tomcat吐回了請求
[root@Nginx ~]# curl http://try.bgx.com/index.html
Tomcat-Page
21.使用lvs+keepalived可以直接負載到后端的tomcat,nginx也可以負載到后端的tomcat,lvs是4層負載比nginx七層負載效率要高,為什么網(wǎng)上有很多資料要使用lvs+keepalived來負載nginx呢?直接使用lvs+keepalived負載到后端的tomcat不就可以了嗎?
首先nginx是一個靜態(tài)服務(wù)器,通常用來處理靜態(tài)資源,比如你網(wǎng)頁中的html,圖片,css等,這些都屬于靜態(tài)資源,但nginx也可以作為反向代理,將你的動態(tài)資源請求給你分發(fā)到后端的應(yīng)用服務(wù)器(此處就是分發(fā)到你的tomcat),由于nginx的高性能,尤其是處理靜態(tài)資源的高效性!
其實兩種方案都可以,一種是nginx+tomcat,這種通常用于中小型站點,
第二種是lvs+nginx+tomcat,這種適用于大型站點,因為lvs的并發(fā)能力遠遠大于nginx,所以用在最前端,接收用戶請求,后面的nginx可以用于會話保持
兩者是不同的應(yīng)用場景,對于有session保持的場景,LVS是做不到的,因此LVS也替代不了Nginx……但如果你的應(yīng)用不需要更復雜的7層控制,那LVS的性能會遠遠大于nginx!
22.nginx掛維護頁面后,所有用戶訪問網(wǎng)站都會自動跳轉(zhuǎn)至維護頁面。但公司內(nèi)部IP需要能正常訪問網(wǎng)站,不授維護頁面干擾。
1.代碼如下
[root@web01 conf.d]# cat wh.conf
server {
listen 80;
server_name limit.bgx.com;
root /code;
#------------------>
#1.在server層下設(shè)定ip變量值為0
set $ip 0;
#2.如果來源IP是10.0.0.101 102則設(shè)定變量為ip變量為1
#注意如果remote_addr無法獲取真實客戶端IP,請使用$http_x_forwarded_for
if ($remote_addr ~* "10.0.0.101|10.0.0.102") {
set $ip 1;
}
#3.如果ip變量為0,則跳轉(zhuǎn)至/code/wh.html這個頁面,否則不做任何處理
if ($ip = 0) {
rewrite ^(.*)$ /wh.html break;
}
#------------------->如果想針對某個location進行操作,則將如上配置寫入location中即可
location / {
index index.html;
}
}
2.效果展示






