1. 程式人生 > 其它 >Ubuntu18.04 安裝Nginx

Ubuntu18.04 安裝Nginx

正向代理和反向代理

正向代理,意思是一個位於客戶端和原始伺服器(origin server)之間的伺服器,為了從原始伺服器取得內容,客戶端向代理髮送一個請求並指定目標(原始伺服器),然後代理向原始伺服器轉交請求並將獲得的內容返回給客戶端。客戶端才能使用正向代理。

反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連線的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。

大家都知道代理一般分為正向代理和反向代理,但為何有這種叫法的區別呢,下圖比較形象的說明:

如圖,代理一般用於跨網之間的訪問,例如內網的客戶端需要訪問外網時通過一個代理server將需要的外網資源通過代理伺服器取回,這種場景下,代理server稱之為正向代理server,作用仍然是一個客戶端,保護和限制真實的客戶端。從結構上來看,客戶端和代理伺服器可以劃為組成一部分,外網的資源server為另一部分。而反向代理一般用於為web服務提供方提供保護,是客戶端直接訪問代理server,代理server作為一個web伺服器,訪問web資源作為自身的資源。從結構上來看,客戶端為一部分,代理伺服器和外網的資源做為另一部分。即為正向代理的reverse,意思是結構上的反轉。

Nginx簡介

Nginx是一個web伺服器也可以用來做負載均衡及反向代理使用

Nginx安裝

sudo apt-get install nginx  # 安裝nginx
sudo apt-get --purge autoremove nginx  # 徹底解除安裝nginx

nginx的基本操作

/etc/init.d/nginx start #啟動
/etc/init.d/nginx reload #重啟
/etc/init.d/nginx stop #停止

sudo service nginx start    # 啟動
sudo service nginx reload   # 過載
sudo service nginx restart  # 重啟
sudo service nginx stop     # 停止

sudo /usr/local/nginx/sbin/nginx -v  # 檢視版本
sudo /usr/local/nginx/sbin/nginx     # 啟動
sudo /usr/local/nginx/sbin/nginx -s stop   # 停止
sudo /usr/local/nginx/sbin/nginx -s reload # 重啟

nginx 簡單配置,django和tornado混合使用

nginx主配置檔案/etc/nginx/nginx.conf中存在以下內容

include /etc/nginx/conf.d/*.conf;  # 包含/etc/nginx/conf.d 目錄下的所有後綴為.conf的檔案
include /etc/nginx/sites-enabled/*; # 包含/etc/nginx/sites-enabled/ 目錄下的所有檔案

所以可以為專案單獨配置,如:為新專案新增配置檔案vim /etc/nginx/sites-enabled/project_name.conf

upstream tornadoServer{  # 負載均衡
    server 127.0.0.1:7021;
}
upstream djangoServer {  # 負載均衡
    server unix:///home/prject/config/uwsgi.sock;
}
server {
    # the port your site will be served on
    listen     9999;
    # the domain name it will serve for
    server_name 192.168.1.251; # substitute your machine's IP address or FQDN
    charset     utf-8;

    #定義本虛擬主機的訪問日誌
    access_log  /home/prject/config/access.log; # 訪問日誌
    error_log /home/prject/config/error.log; # 錯誤日誌
    
    #把請求方向代理傳給tornado伺服器, /api/v1/aaa 和 /api/v1/bbb
    location ~ ^/api/v1/(aaa|bbb) {  
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://tornadoServer;
    }

    #把請求方向代理傳給django伺服器, /api/v1/ccc 和 /api/v1/ddd
    location ~ ^/api/v1/(ccc|ddd) {
        uwsgi_pass  djangoServer;
        client_max_body_size 100M;
        include    /home/prject/config/uwsgi_params; # the uwsgi_params file you installed
    }
    location /static {
        alias /home/prject/static; # your project's static files - amend as required
    }

    location / {  # 前後端分離,前端location
        root /home/prject/dist;
        index /index.html;
        try_files $uri $uri/ /index.html;
    }
}

開啟外網訪問,配置防火牆

防火牆入門:https://www.cnblogs.com/zhumengke/articles/10273000.html

#sudo ufw allow nginx
sudo ufw allow 80/tcp

Nginx負載均衡配置

Nginx負載均衡的幾種模式

輪詢:每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,就不在分配;

upstream core_tomcat {
    server 192.168.1.253:80      max_fails=3 fail_timeout=30;
    server 192.168.1.252:80      max_fails=3 fail_timeout=30;
 }

權重輪詢:根據後端伺服器效能不通配置輪詢的權重比,權重越高訪問的比重越高;

upstream core_tomcat {
    server 192.168.1.253:80      weight=2  max_fails=3 fail_timeout=30;
    server 192.168.1.252:80      weight=8  max_fails=3 fail_timeout=30;
}

#假如有十個請求,八個會指向第二臺伺服器,兩個指向第一臺;

IP_Hash:根據請求的ip地址hash結果進行分配,第一次分配到A伺服器,後面再請求預設還是分配到A伺服器;可以解決Session失效重新登入問題;

upstream core_tomcat {
  ip_hash;
  server 192.168.1.253:80      max_fails=3 fail_timeout=30;
  server 192.168.1.252:80      max_fails=3 fail_timeout=30;
}

Fair:按後端伺服器的響應時間來分配請求,響應時間短的優先分配;

upstream core_tomcat {
  fair;
  server 192.168.1.253:80      max_fails=3 fail_timeout=30;
  server 192.168.1.252:80      max_fails=3 fail_timeout=30;
}

Url_hash:按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效;

upstream core_tomcat {
  hash  $request_uri;
  server 192.168.1.253:80      max_fails=3 fail_timeout=30;
  server 192.168.1.252:80      max_fails=3 fail_timeout=30;
}

Nginx 配置TCP負載均衡

原文地址:https://www.cnblogs.com/felixzh/p/8377158.html

sudo vim /etc/nginx/nginx.conf
View Code

主要新增配置

stream {
    server {
        listen 8778;
        proxy_pass app;
    }

    upstream app{
        server 127.0.0.1:7021;
        server 127.0.0.1:7022;
        server 127.0.0.1:7023;
    }
}

nginx配置http和https共存

原文標題:Nginx環境下http和https(ssl)共存的方法

原文地址:http://www.abcde.cn/info/show-26-1511-1.html

參考地址:https://help.aliyun.com/document_detail/98728.html?spm=a2c4g.11186623.4.5.106365b0GCGW35

給nginx配置SSL證書之後,https可以正常訪問,http訪問顯示400錯誤,nginx的配置如下:server { listen 80 defa
給nginx配置SSL證書之後,https可以正常訪問,http訪問顯示400錯誤,nginx的配置如下:

server {
    # the port your site will be served on
    listen 80 default backlog=2048;
    listen  443 ssl;

    # the domain name it will serve for
    server_name localhost; # substitute your machine's IP address or FQDN
    #ssl on;   #設定為on啟用SSL功能。
    ssl_certificate /etc/nginx/cert/xxx.pem;   #將domain name.pem替換成您證書的檔名。
    ssl_certificate_key /etc/nginx/cert/xxx.key;   #將domain name.key替換成您證書的金鑰檔名。
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  #使用此加密套件。
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;   #使用該協議進行配置。
    ssl_prefer_server_ciphers on;
    # charset     utf-8;
    #定義本虛擬主機的訪問日誌
    access_log  /home/xxx/config/access.log;
    error_log /home/xxx/config/error.log;
}

http訪問的時候,報錯如下:

400 Bad Request
The plain HTTP requset was sent to HTTPS port. Sorry for the inconvenience.
Please report this message and include the following information to us.
Thank you very much

說是http的請求被髮送到https的埠上去了,所以才會出現這樣的問題。

server {
    listen 80 default backlog=2048;
    listen 443 ssl;
    server_name linuxyan.com;
    root /var/www/html;

    ssl_certificate /usr/local/Tengine/sslcrt/linuxyan.com.crt;
    ssl_certificate_key /usr/local/Tengine/sslcrt/linuxyan.com.key;
}

把ssl on;這行去掉,ssl寫在443埠後面。這樣http和https的連結都可以用,完美解決。

如何找出nginx配置檔案的所在位置?

如果程式在執行中,通常是 /usr/sbin/nginx

# ps -ef | grep nginx 
root     29514     1  0 Mar01 ?        00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 29515 29514  0 Mar01 ?        00:00:00 nginx: worker process
root     30276 28948  0 09:36 pts/1    00:00:00 grep --color=auto nginx

程式並沒有執行

檢視軟體安裝路徑

whereis nginx

查詢執行檔案所在路徑

which nginx

當然還有另外的查詢方法

rpm包安裝的,可以用rpm -qa | grep “軟體或者包的名字”查詢;
yum方法安裝的,可以用yum list installed查詢;

獲取配置檔案位置

通過上面的一些方法,找到了nginx可執行檔案的路徑,就可以通過Nginx自身的功能找到配置檔案的位置了。

# /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

nginx設定301永久重定向

版權宣告:本文為CSDN博主「wzq-blog」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/wzqzhq/article/details/53376501

比如說我的域名有多個,一個主域名www.zq110.com,多個次域名:www.aaa.com www.bbb.com,我想在訪問aaa和bbb時都特定跳轉到www.zq110.com上,這時候我們就用到了301永久重定向。

第一種方法:使用if (條件) {結果}實現

server
{  
    listen 80;
    server_name www.zq110.com www.aaa.com www.bbb.com;
       if ($host != 'www.zq110.com')          ####注意,這裡很嚴格,if後面要有空格,!=兩邊都是空格。
       { 
        rewrite ^/(.*)$ http://www.zq110.com/$1 permanent;
       }

       index,index.php,index.html,index.htm;
       root /data/www;
}

第二種方法(可以單獨為www的次域名分別設定server規則)
因為有一次我使用第一種方法時,經常if錯誤,語法檢測好多次,網上也找了好多方法都無用。於是用了第二個方法:

nginx: [emerg] unknown directive "if" in /usr/local/nginx/conf/nginx.conf:6
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

在總網站下

server
{  
    listen 80;
    server_name www.zq110.com;          ###這裡只設置主域名
    index,index.php,index.html,index.htm;
       root /data/www;
}

server
{ 
    server_name www.aaa.com;            ###次域名aaa的server
    rewrite ^(.*)$ http://www.zq110.com$1 permanent;

}

server
{ 
    server_name www.bbb.com;            ###次域名bbb的server
      rewrite ^(.*)$ http://www.zq110.com$1 permanent;
}

參考網址:

nginx的rewrite應用連結:http://ask.apelearn.com/question/7334
301和302跳轉的區別連結:http://blog.csdn.net/tenfyguo/article/details/5744237#comments

Nginx 配置

作者:DreamTruth來源:掘金
連結:https://juejin.im/post/5c1616186fb9a049a42ef21d

Nginx 配置檔案主要分成四部分:main(全域性設定)、server(主機設定)、upstream(上游伺服器設定,主要為反向代理、負載均衡相關配置)和 location(URL匹配特定位置後的設定)。

  • main 部分設定的指令影響其他所有部分的設定;
  • server 部分的指令主要用於制定虛擬主機域名、IP 和埠號;
  • upstream 的指令用於設定一系列的後端伺服器,設定反向代理及後端伺服器的負載均衡;
  • location 部分用於匹配網頁位置(比如,根目錄“/”,“/images”,等等);

他們之間的關係:server 繼承 main,location 繼承 server;upstream 既不會繼承指令也不會被繼承。

當前 nginx 支援的幾個指令上下文():/etc/nginx/conf.d/default.conf

#定義Nginx執行的使用者和使用者組
user www www; 

#nginx程序數,通常設定成和cpu的數量相等
worker_processes 4; 

#全域性錯誤日誌定義型別,[debug | info | notice | warn | error | crit]
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;


#程序pid檔案
#pid        logs/nginx.pid;


#指定程序可以開啟的最大描述符:數目
#工作模式與連線數上限
##這個指令是指當一個nginx程序開啟的最多檔案描述符數目,理論值應該是最多開啟檔案數(ulimit -n)與nginx程序數相除,但是nginx分配請求並不是那麼均勻,所以最好與ulimit -n 的值保持一致。
#這是因為nginx排程時分配請求到程序並不是那麼的均衡,所以假如填寫10240,總併發量達到3-4萬時就有程序可能超過10240了,這時會返回502錯誤。
worker_rlimit_nofile 65535;


events {
    #參考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型
    #是Linux 2.6以上版本核心中的高效能網路I/O模型,linux建議epoll,如果跑在FreeBSD上面,就用kqueue模型。
    #補充說明:
    #與apache相類,nginx針對不同的作業系統,有不同的事件模型
    #A)標準事件模型
    #Select、poll屬於標準事件模型,如果當前系統不存在更有效的方法,nginx會選擇select或poll
    #B)高效事件模型
    #Kqueue:使用於FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X.使用雙處理器的MacOS X系統使用kqueue可能會造成核心崩潰。
    #Epoll:使用於Linux核心2.6版本及以後的系統。
    #/dev/poll:使用於Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。
    #Eventport:使用於Solaris 10。 為了防止出現核心崩潰的問題, 有必要安裝安全補丁。
    use epoll
    
    
    #單個程序最大連線數(最大連線數=連線數+程序數)
    #根據硬體調整,和前面工作程序配合起來用,儘量大,但是別把cup跑到100%就行。
    worker_connections  1024;
    
    #keepalive 超時時間
    keepalive_timeout 60;
    
    #客戶端請求頭部的緩衝區大小。這個可以根據你的系統分頁大小來設定,一般一個請求頭的大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裡設定為分頁大小。
    #分頁大小可以用命令getconf PAGESIZE 取得。
    #[root@web001 ~]# getconf PAGESIZE
    #但也有client_header_buffer_size超過4k的情況,但是client_header_buffer_size該值必須設定為“系統分頁大小”的整倍數。
    client_header_buffer_size 4k;
    
    #這個將為開啟檔案指定快取,預設是沒有啟用的,max指定快取數量,建議和開啟檔案數一致,inactive是指經過多長時間檔案沒被請求後刪除快取。
    open_file_cache max=65535 inactive=60s;
    
    
    #這個是指多長時間檢查一次快取的有效資訊。
    #語法:open_file_cache_valid time 預設值:open_file_cache_valid 60 使用欄位:http, server, location 這個指令指定了何時需要檢查open_file_cache中快取專案的有效資訊.
    open_file_cache_valid 80s;
    
    
    #open_file_cache指令中的inactive引數時間內檔案的最少使用次數,如果超過這個數字,檔案描述符一直是在快取中開啟的,如上例,如果有一個檔案在inactive時間內一次沒被使用,它將被移除。
    #語法:open_file_cache_min_uses number 預設值:open_file_cache_min_uses 1 使用欄位:http, server, location  這個指令指定了在open_file_cache指令無效的引數中一定的時間範圍內可以使用的最小檔案數,如果使用更大的值,檔案描述符在cache中總是開啟狀態.
    open_file_cache_min_uses 1;
    
    #語法:open_file_cache_errors on | off 預設值:open_file_cache_errors off 使用欄位:http, server, location 這個指令指定是否在搜尋一個檔案是記錄cache錯誤.
    open_file_cache_errors on;
}


#設定http伺服器,利用它的反向代理功能提供負載均衡支援
http{
    #副檔名與檔案型別對映表
    include mime.types;
    
    #預設檔案型別
    default_type application/octet-stream;
    
    #預設編碼
    charset utf-8;
    
    #伺服器名字的hash表大小
    #儲存伺服器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。引數hash bucket size總是等於hash表的大小,並且是一路處理器快取大小的倍數。在減少了在記憶體中的存取次數後,使在處理器中加速查詢hash表鍵值成為可能。如果hash bucket size等於一路處理器快取的大小,那麼在查詢鍵的時候,最壞的情況下在記憶體中查詢的次數為2。第一次是確定儲存單元的地址,第二次是在儲存單元中查詢鍵 值。因此,如果Nginx給出需要增大hash max size 或 hash bucket size的提示,那麼首要的是增大前一個引數的大小.
    server_names_hash_bucket_size 128;
    
    #客戶端請求頭部的緩衝區大小。這個可以根據你的系統分頁大小來設定,一般一個請求的頭部大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裡設定為分頁大小。分頁大小可以用命令getconf PAGESIZE取得。
    client_header_buffer_size 32k;
    
    #客戶請求頭緩衝大小。nginx預設會用client_header_buffer_size這個buffer來讀取header值,如果header過大,它會使用large_client_header_buffers來讀取。
    large_client_header_buffers 4 64k;
    
    #設定通過nginx上傳檔案的大小
    client_max_body_size 8m;
    
    #開啟高效檔案傳輸模式,sendfile指令指定nginx是否呼叫sendfile函式來輸出檔案,對於普通應用設為 on,如果用來進行下載等應用磁碟IO重負載應用,可設定為off,以平衡磁碟與網路I/O處理速度,降低系統的負載。注意:如果圖片顯示不正常把這個改成off。
    #sendfile指令指定 nginx 是否呼叫sendfile 函式(zero copy 方式)來輸出檔案,對於普通應用,必須設為on。如果用來進行下載等應用磁碟IO重負載應用,可設定為off,以平衡磁碟與網路IO處理速度,降低系統uptime。
    sendfile on;
    
     #開啟目錄列表訪問,合適下載伺服器,預設關閉。
    autoindex on;
    
      #此選項允許或禁止使用socke的TCP_CORK的選項,此選項僅在使用sendfile的時候使用
    tcp_nopush on;
     
    tcp_nodelay on;
    
    #長連線超時時間,單位是秒
    keepalive_timeout 120;
    
    #FastCGI相關引數是為了改善網站的效能:減少資源佔用,提高訪問速度。下面引數看字面意思都能理解。
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    
    #gzip模組設定
    gzip on; #開啟gzip壓縮輸出
    gzip_min_length 1k;    #最小壓縮檔案大小
    gzip_buffers 4 16k;    #壓縮緩衝區
    gzip_http_version 1.0; #壓縮版本(預設1.1,前端如果是squid2.5請使用1.0)
    gzip_comp_level 2;     #壓縮等級
    gzip_types text/plain application/x-javascript text/css application/xml;    #壓縮型別,預設就已經包含textml,所以下面就不用再寫了,寫上去也不會有問題,但是會有一個warn。
    gzip_vary on;

    #開啟限制IP連線數的時候需要使用
    #limit_zone crawler $binary_remote_addr 10m;
    
    
    #負載均衡配置
    upstream piao.jd.com {
     
        #upstream的負載均衡,weight是權重,可以根據機器配置定義權重。weigth引數表示權值,權值越高被分配到的機率越大。
        server 192.168.80.121:80 weight=3;
        server 192.168.80.122:80 weight=2;
        server 192.168.80.123:80 weight=3;

        #nginx的upstream目前支援4種方式的分配
        #1、輪詢(預設)
        #每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。
        #2、weight
        #指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況。
        #例如:
        #upstream bakend {
        #    server 192.168.0.14 weight=10;
        #    server 192.168.0.15 weight=10;
        #}
        #2、ip_hash
        #每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。
        #例如:
        #upstream bakend {
        #    ip_hash;
        #    server 192.168.0.14:88;
        #    server 192.168.0.15:80;
        #}
        #3、fair(第三方)
        #按後端伺服器的響應時間來分配請求,響應時間短的優先分配。
        #upstream backend {
        #    server server1;
        #    server server2;
        #    fair;
        #}
        #4、url_hash(第三方)
        #按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取時比較有效。
        #例:在upstream中加入hash語句,server語句中不能寫入weight等其他的引數,hash_method是使用的hash演算法
        #upstream backend {
        #    server squid1:3128;
        #    server squid2:3128;
        #    hash $request_uri;
        #    hash_method crc32;
        #}

        #tips:
        #upstream bakend{#定義負載均衡裝置的Ip及裝置狀態}{
        #    ip_hash;
        #    server 127.0.0.1:9090 down;
        #    server 127.0.0.1:8080 weight=2;
        #    server 127.0.0.1:6060;
        #    server 127.0.0.1:7070 backup;
        #}
        #在需要使用負載均衡的server中增加 proxy_pass http://bakend/;

        #每個裝置的狀態設定為:
        #1.down表示單前的server暫時不參與負載
        #2.weight為weight越大,負載的權重就越大。
        #3.max_fails:允許請求失敗的次數預設為1.當超過最大次數時,返回proxy_next_upstream模組定義的錯誤
        #4.fail_timeout:max_fails次失敗後,暫停的時間。
        #5.backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。

        #nginx支援同時設定多組的負載均衡,用來給不用的server來使用。
        #client_body_in_file_only設定為On 可以講client post過來的資料記錄到檔案中用來做debug
        #client_body_temp_path設定記錄檔案的目錄 可以設定最多3層目錄
        #location對URL進行匹配.可以進行重定向或者進行新的代理 負載均衡
    }
    
    
    #虛擬主機的配置
    server {
        #監聽埠
        listen 80;

        #域名可以有多個,用空格隔開
        server_name www.jd.com jd.com;
        #預設入口檔名稱
        index index.html index.htm index.php;
        root /data/www/jd;

        #對******進行負載均衡
        location ~ .*.(php|php5)?$
        {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
        }
         
        #圖片快取時間設定
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires 10d;
        }
         
        #JS和CSS快取時間設定
        location ~ .*.(js|css)?$
        {
            expires 1h;
        }
         
        #日誌格式設定
        #$remote_addr與$http_x_forwarded_for用以記錄客戶端的ip地址;
        #$remote_user:用來記錄客戶端使用者名稱稱;
        #$time_local: 用來記錄訪問時間與時區;
        #$request: 用來記錄請求的url與http協議;
        #$status: 用來記錄請求狀態;成功是200,
        #$body_bytes_sent :記錄傳送給客戶端檔案主體內容大小;
        #$http_referer:用來記錄從那個頁面連結訪問過來的;
        #$http_user_agent:記錄客戶瀏覽器的相關資訊;
        #通常web伺服器放在反向代理的後面,這樣就不能獲取到客戶的IP地址了,通過$remote_add拿到的IP地址是反向代理伺服器的iP地址。反向代理伺服器在轉發請求的http頭資訊中,可以增加x_forwarded_for資訊,用以記錄原有客戶端的IP地址和原來客戶端的請求的伺服器地址。
        log_format access '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" $http_x_forwarded_for';
         
        #定義本虛擬主機的訪問日誌
        access_log  /usr/local/nginx/logs/host.access.log  main;
        access_log  /usr/local/nginx/logs/host.access.404.log  log404;
         
        #對 "/connect-controller" 啟用反向代理
        location /connect-controller {
            proxy_pass http://127.0.0.1:88; #請注意此處埠號不能與虛擬主機監聽的埠號一樣(也就是server監聽的埠)
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
             
            #後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             
            #以下是一些反向代理的配置,可選。
            proxy_set_header Host $host;

            #允許客戶端請求的最大單檔案位元組數
            client_max_body_size 10m;

            #緩衝區代理緩衝使用者端請求的最大位元組數,
            #如果把它設定為比較大的數值,例如256k,那麼,無論使用firefox還是IE瀏覽器,來提交任意小於256k的圖片,都很正常。如果註釋該指令,使用預設的client_body_buffer_size設定,也就是作業系統頁面大小的兩倍,8k或者16k,問題就出現了。
            #無論使用firefox4.0還是IE8.0,提交一個比較大,200k左右的圖片,都返回500 Internal Server Error錯誤
            client_body_buffer_size 128k;

            #表示使nginx阻止HTTP應答程式碼為400或者更高的應答。
            proxy_intercept_errors on;

            #後端伺服器連線的超時時間_發起握手等候響應超時時間
            #nginx跟後端伺服器連線超時時間(代理連線超時)
            proxy_connect_timeout 90;

            #後端伺服器資料回傳時間(代理髮送超時)
            #後端伺服器資料回傳時間_就是在規定時間之內後端伺服器必須傳完所有的資料
            proxy_send_timeout 90;

            #連線成功後,後端伺服器響應時間(代理接收超時)
            #連線成功後_等候後端伺服器響應時間_其實已經進入後端的排隊之中等候處理(也可以說是後端伺服器處理請求的時間)
            proxy_read_timeout 90;

            #設定代理伺服器(nginx)儲存使用者頭資訊的緩衝區大小
            #設定從被代理伺服器讀取的第一部分應答的緩衝區大小,通常情況下這部分應答中包含一個小的應答頭,預設情況下這個值的大小為指令proxy_buffers中指定的一個緩衝區的大小,不過可以將其設定為更小
            proxy_buffer_size 4k;

            #proxy_buffers緩衝區,網頁平均在32k以下的設定
            #設定用於讀取應答(來自被代理伺服器)的緩衝區數目和大小,預設情況也為分頁大小,根據作業系統的不同可能是4k或者8k
            proxy_buffers 4 32k;

            #高負荷下緩衝大小(proxy_buffers*2)
            proxy_busy_buffers_size 64k;

            #設定在寫入proxy_temp_path時資料的大小,預防一個工作程序在傳遞檔案時阻塞太長
            #設定快取資料夾大小,大於這個值,將從upstream伺服器傳
            proxy_temp_file_write_size 64k;
        }
        
        #本地動靜分離反向代理配置
        #所有jsp的頁面均交由tomcat或resin處理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }
    }
}

訪問日誌、錯誤日誌配置

upstream tornadoTCPServer{
    server 127.0.0.1:7021;
}
server {
    # the port your site will be served on
    listen      80;
    # the domain name it will serve for
    server_name www.baidu.com; # substitute your machine's IP address or FQDN
    charset     utf-8;
    # Django media
    location /media  {
        alias /home/media;  # your Django project's media files - amend as required
    }
    #定義本虛擬主機的訪問日誌
    access_log  /home/config/access.log;
    error_log /home/config/error.log;
    location /static {
        alias /home/static; # your Django project's static files - amend as required
    }
    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  zdCloudPlatform;
        client_max_body_size 100M;
        include    /home/config/uwsgi_params; # the uwsgi_params file you installed
    }
}

location正則

原文地址:https://www.cnblogs.com/IPYQ/p/7889399.html

    location ~ ^/api/v1/(user1|user2) { # 正則匹配  /api/v1/user1/xxx和/api/v1/user2/xxx
        xxx 
    }

一個示例:

location  = / {
  # 精確匹配 / ,主機名後面不能帶任何字串
  [ configuration A ] 
}

location  / {
  # 因為所有的地址都以 / 開頭,所以這條規則將匹配到所有請求
  # 但是正則和最長字串會優先匹配
  [ configuration B ] 
}

location /documents/ {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜尋
  # 只有後面的正則表示式沒有匹配到時,這一條才會採用這一條
  [ configuration C ] 
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜尋
  # 只有後面的正則表示式沒有匹配到時,這一條才會採用這一條
  [ configuration CC ] 
}

location ^~ /images/ {
  # 匹配任何以 /images/ 開頭的地址,匹配符合以後,停止往下搜尋正則,採用這一條。
  [ configuration D ] 
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 結尾的請求
  # 然而,所有請求 /images/ 下的圖片會被 config D 處理,因為 ^~ 到達不了這一條正則
  [ configuration E ] 
}

location /images/ {
  # 字元匹配到 /images/,繼續往下,會發現 ^~ 存在
  [ configuration F ] 
}

location /images/abc {
  # 最長字元匹配到 /images/abc,繼續往下,會發現 ^~ 存在
  # F與G的放置順序是沒有關係的
  [ configuration G ] 
}

location ~ /images/abc/ {
  # 只有去掉 config D 才有效:先最長匹配 config G 開頭的地址,繼續往下搜尋,匹配到這一條正則,採用
    [ configuration H ] 
}

location ~* /js/.*/\.js
  • =開頭表示精確匹配
    如 A 中只匹配根目錄結尾的請求,後面不能帶任何字串。
  • ^~開頭表示uri以某個常規字串開頭,不是正則匹配
  • ~ 開頭表示區分大小寫的正則匹配;
  • ~* 開頭表示不區分大小寫的正則匹配
  • / 通用匹配, 如果沒有其它匹配,任何請求都會匹配到

順序 no優先順序:
(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)

上面的匹配結果
按照上面的location寫法,以下的匹配示例成立:

  • / -> config A
    精確完全匹配,即使/index.html也匹配不了
  • /downloads/download.html -> config B
    匹配B以後,往下沒有任何匹配,採用B
  • /images/1.gif -> configuration D
    匹配到F,往下匹配到D,停止往下
  • /images/abc/def -> config D
    最長匹配到G,往下匹配D,停止往下
    你可以看到 任何以/images/開頭的都會匹配到D並停止,FG寫在這裡是沒有任何意義的,H是永遠輪不到的,這裡只是為了說明匹配順序
  • /documents/document.html -> config C
    匹配到C,往下沒有任何匹配,採用C
  • /documents/1.jpg -> configuration E
    匹配到C,往下正則匹配到E
  • /documents/Abc.jpg -> config CC
    最長匹配到C,往下正則順序匹配到CC,不會往下到E

URL擷取

server {
    listen      80;
    server_name www.test.com;

    # 情形A
    # 訪問 http://www.test.com/testa/aaaa
    # 後端的request_uri為: /testa/aaaa
    location ^~ /testa/ {
        proxy_pass http://127.0.0.1:8801;
    }
    
    # 情形B
    # 訪問 http://www.test.com/testb/bbbb
    # 後端的request_uri為: /bbbb
    location ^~ /testb/ {
        proxy_pass http://127.0.0.1:8801/;
    }

    # 情形C
    # 下面這段location是正確的
    location ~ /testc {
        proxy_pass http://127.0.0.1:8801;
    }

    # 情形D
    # 下面這段location是錯誤的
    #
    # nginx -t 時,會報如下錯誤: 
    #
    # nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular 
    # expression, or inside named location, or inside "if" statement, or inside 
    # "limit_except" block in /opt/app/nginx/conf/vhost/test.conf:17
    # 
    # 當location為正則表示式時,proxy_pass 不能包含URI部分。本例中包含了"/"
    location ~ /testd {
        proxy_pass http://127.0.0.1:8801/;   # 記住,location為正則表示式時,不能這樣寫!!!
    }

    # 情形E
    # 訪問 http://www.test.com/ccc/bbbb
    # 後端的request_uri為: /aaa/ccc/bbbb
    location /ccc/ {
        proxy_pass http://127.0.0.1:8801/aaa$request_uri;
    }

    # 情形F
    # 訪問 http://www.test.com/namea/ddd
    # 後端的request_uri為: /yongfu?namea=ddd
    location /namea/ {
        rewrite    /namea/([^/]+) /yongfu?namea=$1 break;
        proxy_pass http://127.0.0.1:8801;
    }

    # 情形G
    # 訪問 http://www.test.com/nameb/eee
    # 後端的request_uri為: /yongfu?nameb=eee
    location /nameb/ {
        rewrite    /nameb/([^/]+) /yongfu?nameb=$1 break;
        proxy_pass http://127.0.0.1:8801/;
    }

    access_log /data/logs/www/www.test.com.log;
}

server {
    listen      8801;
    server_name www.test.com;
    
    root        /data/www/test;
    index       index.php index.html;

    rewrite ^(.*)$ /test.php?u=$1 last;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    access_log /data/logs/www/www.test.com.8801.log;
}

實際使用建議

所以實際使用中,個人覺得至少有三個匹配規則定義,如下:
#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裡是直接轉發給後端應用伺服器了,也可以是一個靜態首頁
# 第一個必選規則
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二個必選規則是處理靜態檔案請求,這是nginx作為http伺服器的強項
# 有兩種配置模式,目錄匹配或字尾匹配,任選其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三個規則就是通用規則,用來轉發動態請求到後端應用伺服器
#非靜態檔案請求就預設是動態請求,自己根據實際把握
#畢竟目前的一些框架的流行,帶.php,.jsp字尾的情況很少了
location / {
    proxy_pass http://tomcat:8080/
}

http://tengine.taobao.org/book/chapter_02.html
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

Rewrite規則

rewrite功能就是,使用nginx提供的全域性變數或自己設定的變數,結合正則表示式和標誌位實現url重寫以及重定向。rewrite只能放在server{},location{},if{}中,並且只能對域名後邊的除去傳遞的引數外的字串起作用,例如http://seanlook.com/a/we/index.php?id=1&u=str只對/a/we/index.php重寫。語法rewrite regex replacement [flag];

如果相對域名或引數字串起作用,可以使用全域性變數匹配,也可以使用proxy_pass反向代理。

表明看rewrite和location功能有點像,都能實現跳轉,主要區別在於rewrite是在同一域名內更改獲取資源的路徑,而location是對一類路徑做控制訪問或反向代理,可以proxy_pass到其他機器。很多情況下rewrite也會寫在location裡,它們的執行順序是:

  1. 執行server塊的rewrite指令
  2. 執行location匹配
  3. 執行選定的location中的rewrite指令

如果其中某步URI被重寫,則重新迴圈執行1-3,直到找到真實存在的檔案;迴圈超過10次,則返回500 Internal Server Error錯誤。

flag標誌位

  • last: 相當於Apache的[L]標記,表示完成rewrite
  • break: 停止執行當前虛擬主機的後續rewrite指令集
  • redirect: 返回302臨時重定向,位址列會顯示跳轉後的地址
  • permanent: 返回301永久重定向,位址列會顯示跳轉後的地址

因為301和302不能簡單的只返回狀態碼,還必須有重定向的URL,這就是return指令無法返回301,302的原因了。這裡 last 和 break 區別有點難以理解:

  1. last一般寫在server和if中,而break一般使用在location中
  2. last不終止重寫後的url匹配,即新的url會再從server走一遍匹配流程,而break終止重寫後的匹配
  3. break和last都能組織繼續執行後面的rewrite指令

if指令與全域性變數

if判斷指令
語法為if(condition){...},對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行,if條件(conditon)可以是如下任何內容:

  • 當表示式只是一個變數時,如果值為空或任何以0開頭的字串都會當做false
  • 直接比較變數和內容時,使用=!=
  • ~正則表示式匹配,~*不區分大小寫的匹配,!~區分大小寫的不匹配

-f!-f用來判斷是否存在檔案
-d!-d用來判斷是否存在目錄
-e!-e用來判斷是否存在檔案或目錄
-x!-x用來判斷檔案是否可執行

例如:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite請求到/msid/目錄下

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
 } //如果cookie匹配正則,設定變數$id等於正則引用部分

if ($request_method = POST) {
    return 405;
} //如果提交方法為POST,則返回狀態405(Method not allowed)。return不能返回301,302

if ($slow) {
    limit_rate 10k;
} //限速,$slow可以通過 set 指令設定

if (!-f $request_filename){
    break;
    proxy_pass  http://127.0.0.1; 
} //如果請求的檔名不存在,則反向代理到localhost 。這裡的break也是停止rewrite檢查

if ($args ~ post=140){
    rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com

location ~* \.(gif|jpg|png|swf|flv)$ {
    valid_referers none blocked www.jefflei.com www.leizhenfang.com;
    if ($invalid_referer) {
        return 404;
    } //防盜鏈
}

rewrite例項

例1:

http {
    # 定義image日誌格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 開啟重寫日誌
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重寫規則資訊
                error_log logs/rewrite.log notice; 
                # 注意這裡要用‘’單引號引起來,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面這條規則後面加上“last”引數,否則下面的set指令不會執行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定針對圖片的日誌格式,來分析圖片型別和大小
                access_log logs/images.log mian;
                root /data/images;
                # 應用前面定義的變數。判斷首先檔案在不在,不在再判斷目錄在不在,如果還不在就跳轉到最後一個url裡
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 圖片不存在返回特定的資訊
                return 404 "image not found\n";
        }
}

對形如/images/ef/uh7b3/test.png的請求,重寫到/data?file=test.png,於是匹配到location /data,先看/data/images/test.png檔案存不存在,如果存在則正常響應,如果不存在則重寫tryfiles到新的image404 location,直接返回404狀態碼。

例2:

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

對形如/images/bla_500x400.jpg的檔案請求,重寫到/resizer/bla.jpg?width=500&height=400地址,並會繼續嘗試匹配location。

這個location

location ~ ^/(.+)\.3gp\.zip$ {
   # access_by_lua_file  "/opt/pro/nginx/lua/zip_access.lua";
    rewrite_by_lua_file "/opt/pro/nginx/lua/zip_access.lua";
}

匹配http://192.168.75.80:8092/20160614/mobi/vod/ts01/TVM/video/3gp/TVM/HuNanHD/2016/04/27/80a4b71a-c000-46fa-916b-70d9e2445635/Q350/Q350.3gp.zip?&end=5

\.代表. 其中\是轉義字元。 單獨的.代表匹配除換行符以外的任意字元 +匹配重複1次或更多次

全域性變數

下面是可以用作if判斷的全域性變數

  • $args: #這個變數等於請求行中的引數,同$query_string
  • $content_length: 請求頭中的Content-length欄位。
  • $content_type: 請求頭中的Content-Type欄位。
  • $document_root: 當前請求在root指令中指定的值。
  • $host: 請求主機頭欄位,否則為伺服器名稱。
  • $http_user_agent: 客戶端agent資訊
  • $http_cookie: 客戶端cookie資訊
  • $limit_rate: 這個變數可以限制連線速率。
  • $request_method: 客戶端請求的動作,通常為GET或POST。
  • $remote_addr: 客戶端的IP地址。
  • $remote_port: 客戶端的埠。
  • $remote_user: 已經經過Auth Basic Module驗證的使用者名稱。
  • $request_filename: 當前請求的檔案路徑,由root或alias指令與URI請求生成。
  • $scheme: HTTP方法(如http,https)。
  • $server_protocol: 請求使用的協議,通常是HTTP/1.0或HTTP/1.1。
  • $server_addr: 伺服器地址,在完成一次系統呼叫後可以確定這個值。
  • $server_name: 伺服器名稱。
  • $server_port: 請求到達伺服器的埠號。
  • $request_uri: 包含請求引數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。
  • $uri: 不帶請求引數的當前URI,$uri不包含主機名,如”/foo/bar.html”。
  • $document_uri: 與$uri相同。

例:http://localhost:88/test1/test2/test.php
hostlocalhosthost:localhostserver_port:88
$request_uri:http://localhost:88/test1/test2/test.php
documenturi/test1/test2/test.phpdocumenturi:/test1/test2/test.phpdocument_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

常用正則

  • .: 匹配除換行符以外的任意字元
  • ?: 重複0次或1次
  • +: 重複1次或更多次
  • *: 重複0次或更多次
  • \d:匹配數字
  • ^: 匹配字串的開始
  • $: 匹配字串的介紹
  • {n}: 重複n次
  • {n,}: 重複n次或更多次
  • [c]: 匹配單個字元c
  • [a-z]: 匹配a-z小寫字母的任意一個

小括號()之間匹配的內容,可以在後面通過$1來引用,$2表示的是前面第二個()裡的內容。正則裡面容易讓人困惑的是\轉義特殊字元。

問題彙總

1、檢視伺服器是否啟動,埠沒有開啟可能時nginx配置的問題,埠開啟可能時專案配置的問題

root@ubuntu:/etc/nginx/sites-enabled# netstat -nlp | grep 9999
tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 7683/nginx -g daemo

2、埠開啟,檢視nginx訪問日誌

root@ubuntu:/home/project/config# tail -f access.log 
192.168.1.218 - - [31/Aug/2019:12:00:30 +0800] "GET / HTTP/1.1" 502 584 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"

檢視錯誤日誌,本次是因為許可權不夠

root@ubuntu:/home/project/config# tail -f error.log 
2019/08/31 12:00:30 [crit] 7685#7685: *1 connect() to unix:///home/project/config/uwsgi.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.1.218, server: 192.168.1.251, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:///home/project/config/uwsgi.sock:", host: "192.168.1.251:9999"

解決方式:

chmod 777 -R project
sudo service nginx start

靜態檔案url地址http://server_ip:9998/static/index.js被301重定向到: http://server_ip/static/index.js/

nginx配置

    location /static {
        alias /home/prject/static; # your Django project's static files 
    }

修改為

 location ~ ^/static/(media|other) {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        # 把請求方向代理傳給tornado伺服器,負載均衡
        proxy_pass http://tornadoServer;
 }