利用 Nginx 進行反向代理和負載均衡

Nginx簡介

Nginx(發音同engine x)是一個網頁服務器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的協議鏈接,以及一個負載均衡器和一個HTTP緩存。與舊版本(<=2.2)的Apache不同,nginx不採用每客戶機一線程的設計模型,而是充分使用異步邏輯(這一點與NodeJS採取了相同的做法,支持高併發,Nginx在官方測試的結果中,能夠支持五萬個平行連接,而在實際的運作中,是可以支持二萬至四萬個平行鏈接),削減了上下文調度開銷,所以併發服務能力更強。整體採用模塊化設計,有豐富的模塊庫和第三方模塊庫,配置靈活。

Nginx的配置文件

使用Nginx的方法就是寫配置文件,配置文件能完全控制Nginx,使Nginx按照我們的需求進行運行,所以配置文件的每一項的是幹啥的對我們來說就很重要了,具體配置文件各項的含義請參考 nginx.conf配置文件詳解,我這裏就不贅述了。

反向代理

準備工作

什麼是反向代理?按照我的理解,反向代理是相對於正向代理來說的,因爲他們都是代理,所以我先來解釋一下什麼是代理。所謂代理,就是在客戶端和服務端之間強行添加了一層,用來實現流量轉發的功能,粗略的框圖如下:

+----------------+         +---------------+        +--------------+
|                |         |               |        |              |
|                |         |               |        |              |
|                |  http   |               | http   |              |
|    client      <--------->    proxy      <-------->   server     |
|                |  https  |               | https  |              |
|                |         |               |        |              |
|                |         |               |        |              |
+----------------+         +---------------+        +--------------+

所謂正向代理,是用於代理客戶端的。舉個很簡單的例子:你直接在大陸地區訪問google.com肯定是訪問不了的,原因大家都知道,現在假如你有一臺在美國的主機A,並且能夠正常訪問,那麼你可以將瀏覽器對google.com的請求先轉發給服務器A,服務器A收到請求後,扮演客戶端的角色,發起對google.com的請求,服務器A收到響應後,又扮演服務端,將此響應原封不動的返回給你,自此,一次正向代理順利完成。

反向代理顧名思義是用來代理服務端的。我們也舉個簡單的例子來說明:我們知道google.com沒秒鐘要處理如洪水般的網絡請求,這些請求如果僅僅讓一臺單一的服務器處理,肯定是處理不過來的,我們自然而然的想到讓多臺服務器來處理這些請求,減少每臺服務器的壓力。但是現在有一個問題,多個服務器那就產生了多個IP,一般的,google.com只能解析到某個固定的IP(爲了方便描述,我們暫且這樣認爲。實際情況下,通過設置也是可以讓同一個域名解析到多個IP的),因爲現在存在多個Server,我的一個google.com就不能解析到這些服務器上,而且用多個二級域名比如server1.google.comserver2.google.com等等也給用戶造成了使用上的不便(一萬臺服務器,你咋不上天呢?),那該怎麼辦呢?通過反向代理可以很好的解決這個問題。爲此,我繪製了下面的示意圖:

                                                                   +-------------------+
                                                                   |                   |
                                                            +------>   server 1        |
+-------------+                                             |      |                   |
|             +----------+                                  |      |                   |
|  client 1   |          |                                  |      +-------------------+
|             |          |                                  |
+-------------+          |                                  |
                         |         +------------------+     |      +-------------------+
                         |         |                  |     |      |                   |
+-------------+          |         |                  |     |      |   server 2        |
|             |          |         |                  +------------>                   |
|  clent 2    +-------------------->  reverse proxy   |     |      |                   |
|             |          |         |                  |     |      +-------------------+
+-------------+          |         |                  |     |
                         |         |                  |     |               .
      .                  |         |                  |     |               .
      .                  |         +------------------+     |               .
      .                  |                                  |
                         |                                  |      +--------------------+
+-------------+          |                                  |      |                    |
|             |          |                                  |      |   server m         |
|  client n   +----------+                                  +------>                    |
|             |                                                    |                    |
+-------------+                                                    +--------------------+

而本文的豬腳——Nginx就是幹這個事的。

配置反向代理

  1. 我們利用 http-server 啓動一個本地server。

    1
    http-server -p 3000

    然後在所在的文件夾裏新建一個index.html,輸入hello, nginx

  2. 配置host文件
    Linux爲例:

    1
    sudo vim /etc/hosts

    然後在裏面添加一條記錄:

    1
    test.com 127.0.0.1
  3. 配置nginx.conf
    http裏面添加:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #本地http-server開啓的server,命名爲node-server,監聽3000端口
    upstream node-server{
    server 127.0.0.1:3000;
    }
    # NGINX 虛擬主機,監聽80端口
    server {
    listen 80;
    server_name test.com;
    access_log /var/log/nginx/node-server;
    # Gzip Compression
    gzip on;
    gzip_comp_level 6;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_buffers 16 8k;
    # 反向代理 node-server
    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    # 代理的地址
    proxy_pass http://node-server;
    proxy_redirect off;
    }
    }
  4. 啓動Nginx
    Linux爲例:

    1
    sudo service nginx start

5.測試
 
可以看到,對於用戶的請求,我們成功反向代理到127.0.0.1:3000上!

負載均衡

負載均衡,這個名稱聽起來刁刁的有木有!其實嘛,也就那回事,不要被這牛逼哄哄的名詞嚇住了。之前我們分析了google.com是怎麼對請求進行分流的,現在我們就來小小的試驗一下。

  1. 另開啓一個本地server

    1
    http-server -p 3001

    在此server的根目錄下新建index.html,輸入’hello, nginx (server 2)’

  2. 配置nginx.conf
    修改之前的配置爲:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #本地http-server開啓的server,命名爲node-server,監聽3000和3001端口
    upstream node-server{
    # weight表示權重,數值越大,表示被分配到這個server的機率越大,這裏我們讓其相等。
    server 127.0.0.1:3000 weight=1;
    server 127.0.0.1:3001 weight=1;
    }
    # NGINX 虛擬主機,監聽80端口
    server {
    listen 80;
    server_name test.com;
    access_log /var/log/nginx/node-server;
    # Gzip Compression
    gzip on;
    gzip_comp_level 6;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_buffers 16 8k;
    # 反向代理 node-server
    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    # 代理的地址
    proxy_pass http://node-server;
    proxy_redirect off;
    }
    }
  3. 重啓Nginx
    Linux爲例:

    1
    sudo nginx -s reload

    或者

    1
    sudo service nginx restart
  4. 測試
     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章