nginx 反向代理配置(一)

      文章參考:https://blog.csdn.net/physicsdandan/article/details/45667357php

      什麼是代理?html

      代理在普通生活中的意義就是原本應該你作的事情,你讓別人代你作了,那麼那個幫你作的人就是你的代理。和在計算機網絡中代理的概念差很少,前端

原本是要客戶端作的網絡訪問,如今移交給另一臺機器作,那麼那個機器就被稱爲代理服務器,代理服務器幫你訪問。過程以下:node

      正常狀況:linux

      client-(send request)->serverios

      代理狀況:nginx

      client-(send request)->client proxy(send request)->serverweb

      什麼是反向代理?正則表達式

      反向代理在計算機網絡中是指這麼一個過程,通常來講正向代理是客戶端找人來代理把本身的請求轉發給服務器,可是若是是反向代理,找代理的人再也不算法

是客戶端,而是服務端這邊把本身接受的請求轉發給背後的其餘機器。

     反向代理狀況:

     client-(send request)->server proxy(send request)->other server

      下面看一個示例:

#① part start
#運行nginx進程的帳戶
user www;
#
worker_process 1;
error_log /var/log/nginx/error.log
pid /var/run/nginx.pid;

events{
    use epoll;
    worker_connections 1024;
}

http{
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    access_log  /var/log/nginx/access.log  main;
    #
    sendfile        on;
    #
    keepalive_timeout  65;
    gzip  on;

    index   index.html index.htm;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    #② part start
    # 定義上游服務器列表組
    upstream web1 {
        server 127.0.0.1:111 weight=1;
        server 127.0.0.1:222 weight=1;
    }
    upstream web2 {
        server 127.0.0.2:111 weight=1;
        server 127.0.0.2:222 weight=6;
        server 127.0.0.2:333 weight=7;
    }
    #定義一個服務器,其監聽80端口,配置的域名是www.company.com
    server{
        listen 80;
        # using www  domain to access the main website
        server_name www.company.com;
        access_log  /var/log/nginx/www.log

        location / {
            root /home/website_root;

        }
    }
    #③ part start
    #定義第二個服務器,其一樣監聽80端口,可是匹配域名是web.company.com
    server{
        listen 80;
        # using web sub domain to access
        server_name web.company.com;
        access_log  /var/log/nginx/web_access.log

        location / {
            root /home/web2_root;
            proxy_pass http://127.0.0.1:8080/web/;
            proxy_read_timeout 300;
            proxy_connect_timeout 300;
            proxy_redirect     off;

            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host              $http_host;
            proxy_set_header   X-Real-IP         $remote_addr;
        }
    }
    #定義第三個服務器,其一樣監聽80端口,可是匹配域名是web1.company.com,並把請求轉發到web1上游服務
    server{
        listen 80;
        # using web1 sub domain to access
        server_name web1.company.com;
        access_log  /var/log/nginx/web1_access.log

        location / {
            root /home/web1_root;
            proxy_pass http://web1;
            proxy_read_timeout 300;
            proxy_connect_timeout 300;
            proxy_redirect     off;

            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host              $http_host;
            proxy_set_header   X-Real-IP         $remote_addr;
        }
    }
        #定義第三個服務器,其一樣監聽80端口,可是匹配域名是web2.company.com,並把請求轉發到web2上游服務
    server{
        listen 80;
        # using web2 sub domain to access
        server_name web2.company.com;
        access_log  /var/log/nginx/web2_access.log

        location / {
            root /home/web2_root;
            proxy_pass http://web2;
            proxy_read_timeout 300;
            proxy_connect_timeout 300;
            proxy_redirect     off;

            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host              $http_host;
            proxy_set_header   X-Real-IP         $remote_addr;
        }
    }
}

       這個示例都作了什麼?

       1.第一部分,定義了 nginx 通用規則

       2.第二部分,開始定義上游服務器組

       3.第三部分,開始定義 server,並指定如何使用第二部分定義的 upstream

       整體來講上面的示例提供了四個服務,www、web、web一、web2 4個網站,這個例子很適合一臺機器,可是又想避免訪問 url 中帶有端口號,統一使用

域名方式訪問。4個網站都監聽 80 端口,可是分配不一樣的二級域名便可。這就須要 nginx 反向代理,具體如何實現,咱們從新舉一個例子,以下所示:

       (1) 只有一臺服務器,一個 IP,一個域名 www.xsgzs.com

       (2) 這臺服務器上有多個應用運行在不一樣端口,如:

           127.0.0.1:4000 運行着一個 博客應用

           127.0.0.1:3009 運行着一個博客後臺管理系統

           咱們不指望在訪問的 url 中攜帶有端口號,統一使用域名方式訪問,能夠爲運行在不一樣端口號的應用分配二級域名,同時把二級域名都解析到 80 端口,

可是轉發到不一樣的端口去,但願訪問  www.blog.xsgzs.com 能訪問到 127.0.0.1:4000 ,訪問 www.admin.xsgzs.com 能訪問到 127.0.0.1:3009 

       具體步驟:

       (1) 在 nginx.conf 文件新增 upstream server(上游服務器)

upstream blog.xsgzs {
      server 127.0.0.1:4000
}

upstream admin.xsgzs {
      server 127.0.0.1:3009
}

  (2) 在配置文件中添加 server,都監聽 80 端口

server {      
                              listen      80;      
                              server_name www.blog.xsgzs.com;      
                              location / {      
                                          proxy_pass http://blog.xsgzs;      
                              }      
                              error_page  500 502 503 504  /50x.html;    
                              location = /50x.html {        
                                              root  html;      
                              }
 }

 server {      
                              listen      80;      
                              server_name www.admin.xsgzs.com;      
                              location / {      
                                      proxy_pass http://admin.xsgzs;      
                              }      
                              error_page  500 502 503 504  /50x.html;    
                              location = /50x.html {        
                                          root  html;      
                                }
 }

       爲何須要反向代理?

       做爲服務端代理,天然是一臺機器處理不過來了,須要轉發、分散請求給其餘服務器作。下面列出一些適用場景:

       1.負載均衡:

       上面的例子1中 web1 和 web2 上游服務器組都使用了負載均衡,把請求轉發向一組服務器。具體轉發給哪臺服務器,nginx 提供了多種負載均衡策略,上面使用的是加權方式

       2.一個域名,多個網站。 如上面的例2

       3.反向代理另外一個做用就是隱藏後面的真實服務,以此達到必定的安全性

       仔細講解各個模塊

       nginx 配置文件主要分爲六個區域

(1) main 全局設置
(2) events (nginx 工做模式)
(3) http (http設置)
(4) server (主機設置)
(5) location (URL匹配)
(6) upstream (負載均衡服務器設置)

  main 模塊(全局設置)

       下面是一個 main 區域,它是一個全局設置

user nobody nobody;
worker_processes 2;
error_log  /usr/local/var/log/nginx/error.log  notice;
worker_rlimit_nofile 1024;

  user 用來設置運行 nginx 服務器的用戶或用戶組,語法格式:

user user [group]

  user , 指定能夠運行 nginx 服務器的用戶

       group,可選項,指定能夠運行 nginx 服務器的用戶組

       注:只有被指定的用戶或用戶組纔有權限啓動 nginx 進程,若是是其餘用戶 (test_user) 嘗試啓動 nginx 進程,將會報錯

nginx: [emerg] getpwnam("test_user") failed (2:No such file or directory) in /Nginx/conf/nginx.conf:2

  從上面的報錯信息中能夠知道,nginx 沒法運行的緣由是查找 test_user 失敗,引發錯誤的緣由在 nginx.conf 文件第二行即

配置運行 nginx 服務器的用戶或用戶組

        若是但願全部的用戶或用戶組都有權限啓動 nginx 進程,有兩種方式:一是將此行指令註釋掉、而是將用戶或用戶組設置

爲 nobody,這也是 user 指令的默認值

        worker_processes  用來指定 nginx 要開啓的子進程數目

        worker prcocess 是 nginx 服務器實現併發處理的關鍵所在,從理論上來講,worker process 的值越大,能夠支持的併發處理量越大,但實際上它還要受到來自軟件自己、

操做系統自己資源和能力、硬件設備(如:CPU 和 磁盤驅動器)等制約,其語法格式:

worker_processes number | auto

  number,來指定 nginx 要開啓的子進程數目

       auto,nginx 自動檢測

       在默認配置文件中,number = 1,啓動 nginx 服務器以後,使用如下命令能夠看到此時的 nginx 除了主進程 master process 以外還生成了一個 worker process,在這裏我將

number 指定爲 4 ,除了主進程 master process 以外還生成了 4 個 worker process

        在這裏還有一點須要注意的地方:

        worker_processes 指的是操做系統啓動多少個工做進程運行 nginx,注意這裏說的是工做進程(worker process)。在 nginx 運行的時候,會啓動兩種進程,一種進程是 master pro

cess(主進程),一種是 worker process(工做進程)。主進程負責監控端口,協調工做進程的工做狀態,分配工做任務,工做進程負責進行任務處理,通常這個參數要和操做系統 CPU 內

核數成倍數。

        error_log 關於錯誤日誌的配置能夠參考這一篇文章:https://www.cnblogs.com/leeyongbard/p/10880356.html

        worker_rlimit_nofile 用來設定一個 nginx worker process (工做進程),可打開最大文件數

        events 模塊

        events 模塊用來指定 nginx 的工做模式以及每個 worker process 同時開啓的最大鏈接數,以下:

events {
    use epoll; #Linux平臺
    worker_connections  1024;
}

  use 用來指定 nginx 的工做模式,nginx 支持的工做模式有:select、poll、Kqueue、epoll、rtsig 和 /dev/poll,select 和 poll 是標準的工做模式,Kqueue 和 epoll 是

高效的工做模式,不一樣的是 epoll 是用在 linux 平臺,而 Kqueue 是用在 BSD 系統,而 mac 基於 BSD ,因此 mac 上的 nginx 工做模式是 Kqueue ,epoll 是 Linux 上nginx

工做模式的首選  

       worker_connections 用來設置容許每個 worker process 同時開啓的最大鏈接數,即接收前端的最大請求數。最大客戶端鏈接數由 worker_processes 和 worker_conn

ectios決定,即 max_clients = worker_processes * worker_connections ,在做爲反向代理時,max_clients = worker_processes * worker_connections/4。注意,一個進程建

立一個鏈接後,進程將打開一個文件副本。因此,worker_connections 的 number 值還受到操做系統設定的,進程最大可打開文件數

其語法格式:

worker_connections number

  設置 nginx 進程最大可打開文件數(不能超過系統級別設定的進程可打開最大文件數)

       1.更改系統級別 "進程可打開最大文件數"

          首先須要要有 root 權限,修改 /etc/security/limits.conf

          在主配置文件中添加下面兩句

* soft nofile 327680
* hard nofile 327680

  soft 表示應用軟件級別限制的最大可打開文件數,hard 表示操做系統級別限制的最大可打開文件數,"*" 表示對全部用戶都生效

       保存配置不會當即生效,須要經過 ulimit 命令 或 重啓系統

ulimit -n 327680

  執行命令後,經過 ulimit -a 查看修改是否生效

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63704
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 327680
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63704
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

  注意,open files 這一項變化了表示修改生效

       2. 修改 nginx 軟件級別的 "進程最大可打開文件數"

          第一步只是修改了操做系統級別的 "進程最大可打開文件數",做爲 nginx 來講,咱們還須要對這個軟件進行修改,打開 nginx.conf 主配置文件,修改 worker_rlimit_nofile 屬性

          修改完成以後,須要重啓 nginx 配置才能生效

       3.驗證 nginx 的 "進程最大可打開文件數" 是否生效

          在 Linux 中,全部的進程都會有一個臨時的核心配置文件描述,存放位置:/pro/進程號/limit

          咱們能夠看到,nginx worker process 的進程號分別是:487二、487三、487四、4875,咱們選擇其中一個查看其核心配置信息:

          能夠看到 Max open files 分別是65535,更改配置信息後,重啓 nginx,如上所示方式查看是否生效

         http 模塊

        http 模塊能夠說是最核心的模塊了,它主要負責 HTTP 服務器相關屬性的配置,它裏面的 server、upstream 相當重要,下面看一個簡單的 http 模塊配置

http{
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /usr/local/var/log/nginx/access.log  main;
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  10;
    #gzip  on;
    upstream myproject {
        .....
    }
    server {
        ....
    }
}

  說一下每一個配置項的具體含義

       include:nginx 服務器做爲 web 服務器,必須可以識別前端請求過來的資源類型,include mime.types 用來設置 nginx 所能識別的文件類型,mime.types 在

nginx 主配置文件同級目錄下

       default_type:設置默認的類型爲二進制流,也就是當請求的資源類型在 mime.types 裏面未定義時默認使用該類型

       access_log、log_format 能夠參考這篇文章:https://www.cnblogs.com/leeyongbard/p/10880356.html

       sendfile 用於開啓高效的文件傳輸模式。將 tcp_nopush、tcp_nodelay 設置爲 on 用於防止網絡阻塞

       keepalive_timeout:用於設置與用戶創建鏈接以後,nginx 服務器能夠保持這些鏈接一段時間

       server 模塊

       server 模塊是 http 模塊的子模塊,主要用於定義一個虛擬主機,下面先看一個簡單的 server 是如何作的?

server {
        listen       8080;
        server_name  localhost 192.168.12.10 www.yangyi.com;
        # 全局定義,若是都是這一個目錄,這樣定義最簡單。
        root   /Users/yangyi/www;
        index  index.php index.html index.htm; 
        charset utf-8;
        access_log  usr/local/var/log/host.access.log  main;
        error_log  usr/local/var/log/host.error.log  error;
        ....
}

  server,標誌定義虛擬主機開始

       listen,指定虛擬主機的服務端口

       server_name,用來指定 IP 地址或 域名,多個域名之間用空格分開

       root,配置請求的根目錄

               web 服務器在接收到網絡請求後,須要在服務端指定的根目錄中尋找請求的資源。在 nginx 服務器中 root 指令就是設置這個根目錄的,其語法爲:

root path

               path 爲 nginx 服務器接收到請求後查找資源的根目錄。root 指令能夠在 http,server,location 塊中均可以配置,多數狀況下 root 指令是配置在 location

               塊中,看一個簡單的示例

location /data/
{
        root     /locationtest1;
}

        當 location 塊接收到 /data/index.html 的請求時,將會在 /locationtest1/data/ 目錄下尋找 index.html 響應請求

         index,用於設定只輸入域名時訪問的默認首頁地址,有個前後順序:index.php、index.html、index.htm 若是沒有開啓目錄瀏覽權限,又找不到這些默認首頁,則會報 403 

         charset,設置網頁的默認編碼格式

         access_log,error_log 這裏再也不說

         location 模塊

         location 模塊也是一個很是重要且經常使用的模塊,根據字面意思就能夠知道主要用於定位,定位 URL,解析 URL,它提供了很是強大的正則匹配功能,也支持條件判斷匹配

         在 nginx 官方文檔中定義的 location 語法爲:

location [ = | ~ | ~* | ^~] uri {
    ................
    ................ 
}

    其中,uri 是待匹配的請求字符串,能夠是不含正則表達式的字符串,如,/myserver.php,也能夠是包含正則表達式的字符串,如,.php$(表示以 .php 結尾)

         不包含正則表達式的 uri -> 標準 uri

         包含正則表達式的 uri -> 正則 uri

         方括號裏面的部分是可選項,在介紹四種標識以前先了解下若是不添加此選項時,nginx 服務器是如何在 server 塊中搜索並使用 location 塊和 uri 實現和請求字符串匹配的

         在不添加此選項時,nginx 服務器會在 server 塊的多個 location 塊中搜索是否有和標準 uri 匹配的請求字符串,若是有多個能夠匹配,就記錄匹配度最高的一個。而後再用

         location 塊中的正則 uri 和請求字符串匹配,當正則 uri 匹配成功以後,結束搜索,使用此 location 塊處理請求。若是正則 uri 匹配失敗,就是用上面匹配度最高的 location

         塊處理此請求。

         四種標識(=、~、~*、^~)

1. =,用於標準 uri 前,要求請求字符串和 uri 嚴格匹配。若是匹配成功,就中止向下繼續搜索並當即使用該 location 塊處理請求
2,~,用於表示 uri 包含正則表達式,並區分大小寫
3,~*,用於表示 uri 包含正則表達式,而且不區分大小寫
4,^~,用於標準 uri 前,要求 nginx 服務器找到和請求字符串匹配度最高的標準 uri 後,當即使用該 location 快處理請求,再也不使用 location 塊的正則 uri 和請求字符串作匹配

    注意:

咱們知道瀏覽器傳送 uri 時,會對一部分 uri 進行編碼,好比,空格會被編碼成 "%20",問號會被編碼成 '%3f"等,"^"有一個特色,它會對 uri 中的這些符號作編碼處理,如,若是 location 塊接收到的 uri 是 /html/%20/data,則當 nginx 服務器搜索到配置爲 /html//data 的 location 塊時就能夠匹配成功

  upstream 模塊

       upstream 模塊負責負載均衡,目前 nginx 的負載均衡支持 4 種方式:

       1,輪詢(默認)

            每一個請求按照時間順序逐一分配到不一樣後端服務器,若是後端服務器 down 掉,則自動剔除,使用戶訪問不受影響

       2,weight(指定輪詢權重)

            weight 的值越大分配到的訪問機率越高,主要用於後端每臺服務器性能不均衡的狀況下,或僅僅在主從狀況下設置不一樣的權值,達到有效合理的利用主機資源。

upstream bakend {
        server 192.168.0.14 weight=10;
        server 192.168.0.15 weight=10;
}

  3,ip_hash

             每一個請求按照訪問 ip 的哈希結果分配,使來自同一個 ip 的訪客固定訪問一臺後端服務器

upstream bakend {
       ip_hash;
       server 192.168.0.14:88;
       server 192.168.0.15:80;
}

  4,fair 

            比 weight、ip_hash 更加智能的負載均衡算法,fair 能夠根據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端服務器的響應時間來分配請求,響應時間

的優先分配。nginx 自己並不支持 fair,若是要使用這種調度算法,則須要安裝 upstream_fair 模塊。

upstream backend {
        server server1;
        server server2;
        fair;
}

  4,url_hash

            按照訪問 url 的哈希結果分配,使每個 url 定向到後端某一臺服務器,能夠進一步提升後端緩存服務器的效率,不過 nginx 自己是不支持這種調度算法的,須要安裝

nginx 的 hash 軟件包

例:在upstream中加入hash語句,server語句中不能寫入weight等其餘的參數,hash_method是使用的hash算法
upstream backend {
        server squid1:3128;
        server squid2:3128;
        hash $request_uri;
        hash_method crc32;
}

  在 nginx 的 upstream 模塊,能夠設置每臺後端服務器在負載均衡中的調度狀態,經常使用的狀態:

1,down,表示當前機器暫時不參與負載均衡
2,backup,預留的備份機器。當其餘全部的非 backup 機器出現故障或忙的時候,纔會請求 backup 機器,由於此臺機器的訪問壓力最小
3,max_fails,容許請求的失敗次數,默認爲 1,當超過最大次數時,返回 proxy_next_upstream 模塊定義的錯誤
4,fail_timeout,請求失敗超時時間,在經歷了 max_fails 次失敗後,暫停服務的時間。max_fails 和 fail_timeout 能夠一塊兒使用

  下面看一個簡單的 upstream 模塊配置:

       1,在 http 節點下添加 upstream 節點

upstream linuxidc {
      server 10.0.6.108:7080;
      server 10.0.0.85:8980;
}

  2,將 server 節點下的 location 節點中的 proxy_pass 配置爲:http:// + upstream名稱

location / {
      root hml;
      index index.html index.htm;
      proxy_pass http://linuxidc;
}

  如今負載均衡初步完成了,upstream 按照輪詢(默認)方式進行負載均衡。

相關文章
相關標籤/搜索