Nginx 極簡教程

Nginx 極簡教程

本項目是一個 Nginx 極簡教程,目的在于幫助新手快速入門 Nginx。

examples 目錄中的示例模擬了工作中的一些常用實戰(zhàn)場景灾常,并且都可以通過腳本一鍵式啟動,讓您可以快速看到演示效果。

簡介

什么是 Nginx?

Nginx (engine x) 是一款輕量級的 Web 服務器 着绊、反向代理服務器及電子郵件(IMAP/POP3)代理服務器。

img

什么是反向代理熟尉?

反向代理(Reverse Proxy)方式是指以代理服務器來接受 internet 上的連接請求归露,然后將請求轉發(fā)給內(nèi)部網(wǎng)絡上的服務器,并將從服務器上得到的結果返回給 internet 上請求連接的客戶端斤儿,此時代理服務器對外就表現(xiàn)為一個反向代理服務器剧包。

img

Nginx 入門

詳細安裝方法請參考:Nginx 安裝

nginx 的使用比較簡單,就是幾條命令往果。

常用到的命令如下:

nginx -s stop       快速關閉Nginx疆液,可能不保存相關信息,并迅速終止web服務棚放。
nginx -s quit       平穩(wěn)關閉Nginx枚粘,保存相關信息,有安排的結束web服務飘蚯。
nginx -s reload     因改變了Nginx相關配置馍迄,需要重新加載配置而重載。
nginx -s reopen     重新打開日志文件局骤。
nginx -c filename   為 Nginx 指定一個配置文件攀圈,來代替缺省的。
nginx -t            不運行峦甩,僅僅測試配置文件赘来。nginx 將檢查配置文件的語法的正確性现喳,并嘗試打開配置文件中所引用到的文件。
nginx -v            顯示 nginx 的版本犬辰。
nginx -V            顯示 nginx 的版本嗦篱,編譯器版本和配置參數(shù)。

如果不想每次都敲命令幌缝,可以在 nginx 安裝目錄下新添一個啟動批處理文件startup.bat灸促,雙擊即可運行。內(nèi)容如下:

@echo off
rem 如果啟動前已經(jīng)啟動nginx并記錄下pid文件涵卵,會kill指定進程
nginx.exe -s stop

rem 測試配置文件語法正確性
nginx.exe -t -c conf/nginx.conf

rem 顯示版本信息
nginx.exe -v

rem 按照指定配置去啟動nginx
nginx.exe -c conf/nginx.conf

如果是運行在 Linux 下浴栽,寫一個 shell 腳本,大同小異轿偎。

Nginx 實戰(zhàn)

我始終認為典鸡,各種開發(fā)工具的配置還是結合實戰(zhàn)來講述,會讓人更易理解坏晦。

Http 反向代理

我們先實現(xiàn)一個小目標:不考慮復雜的配置萝玷,僅僅是完成一個 http 反向代理。

nginx.conf 配置文件如下:

注:conf/nginx.conf 是 nginx 的默認配置文件英遭。你也可以使用 nginx -c 指定你的配置文件

#運行用戶
#user somebody;

#啟動進程,通常設置成和cpu的數(shù)量相等
worker_processes  1;

#全局錯誤日志
error_log  D:/Tools/nginx-1.10.1/logs/error.log;
error_log  D:/Tools/nginx-1.10.1/logs/notice.log  notice;
error_log  D:/Tools/nginx-1.10.1/logs/info.log  info;

#PID文件间护,記錄當前啟動的nginx的進程ID
pid        D:/Tools/nginx-1.10.1/logs/nginx.pid;

#工作模式及連接數(shù)上限
events {
    worker_connections 1024;    #單個后臺worker process進程的最大并發(fā)鏈接數(shù)
}

#設定http服務器,利用它的反向代理功能提供負載均衡支持
http {
    #設定mime類型(郵件支持類型),類型由mime.types文件定義
    include       D:/Tools/nginx-1.10.1/conf/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    D:/Tools/nginx-1.10.1/logs/access.log main;
    rewrite_log     on;

    #sendfile 指令指定 nginx 是否調(diào)用 sendfile 函數(shù)(zero copy 方式)來輸出文件挖诸,對于普通應用汁尺,
    #必須設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設置為 off多律,以平衡磁盤與網(wǎng)絡I/O處理速度痴突,降低系統(tǒng)的uptime.
    sendfile        on;
    #tcp_nopush     on;

    #連接超時時間
    keepalive_timeout  120;
    tcp_nodelay        on;

    #gzip壓縮開關
    #gzip  on;

    #設定實際的服務器列表
    upstream zp_server1{
        server 127.0.0.1:8089;
    }

    #HTTP服務器
    server {
        #監(jiān)聽80端口,80端口是知名端口號狼荞,用于HTTP協(xié)議
        listen       80;

        #定義使用www.xx.com訪問
        server_name  www.helloworld.com;

        #首頁
        index index.html

        #指向webapp的目錄
        root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp;

        #編碼格式
        charset utf-8;

        #代理配置參數(shù)
        proxy_connect_timeout 180;
        proxy_send_timeout 180;
        proxy_read_timeout 180;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarder-For $remote_addr;

        #反向代理的路徑(和upstream綁定)辽装,location 后面設置映射的路徑
        location / {
            proxy_pass http://zp_server1;
        }

        #靜態(tài)文件,nginx自己處理
        location ~ ^/(images|javascript|js|css|flash|media|static)/ {
            root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;
            #過期30天相味,靜態(tài)文件不怎么更新拾积,過期可以設大一點,如果頻繁更新丰涉,則可以設置得小一點拓巧。
            expires 30d;
        }

        #設定查看Nginx狀態(tài)的地址
        location /NginxStatus {
            stub_status           on;
            access_log            on;
            auth_basic            "NginxStatus";
            auth_basic_user_file  conf/htpasswd;
        }

        #禁止訪問 .htxxx 文件
        location ~ /\.ht {
            deny all;
        }

        #錯誤處理頁面(可選擇性配置)
        #error_page   404              /404.html;
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   html;
        #}
    }
}

好了,讓我們來試試吧:

  1. 啟動 webapp一死,注意啟動綁定的端口要和 nginx 中的 upstream 設置的端口保持一致肛度。
  2. 更改 host:在 C:\Windows\System32\drivers\etc 目錄下的 host 文件中添加一條 DNS 記錄
127.0.0.1 www.helloworld.com
  1. 啟動前文中 startup.bat 的命令
  2. 在瀏覽器中訪問 www.helloworld.com,不出意外投慈,已經(jīng)可以訪問了承耿。

Https 反向代理

一些對安全性要求比較高的站點冠骄,可能會使用 HTTPS(一種使用 ssl 通信標準的安全 HTTP 協(xié)議)。

這里不科普 HTTP 協(xié)議和 SSL 標準加袋。但是凛辣,使用 nginx 配置 https 需要知道幾點:

  • HTTPS 的固定端口號是 443,不同于 HTTP 的 80 端口
  • SSL 標準需要引入安全證書锁荔,所以在 nginx.conf 中你需要指定證書和它對應的 key

其他和 http 反向代理基本一樣蟀给,只是在 Server 部分配置有些不同蝙砌。

  #HTTP服務器
  server {
      #監(jiān)聽443端口阳堕。443為知名端口號,主要用于HTTPS協(xié)議
      listen       443 ssl;

      #定義使用www.xx.com訪問
      server_name  www.helloworld.com;

      #ssl證書文件位置(常見證書文件格式為:crt/pem)
      ssl_certificate      cert.pem;
      #ssl證書key位置
      ssl_certificate_key  cert.key;

      #ssl配置參數(shù)(選擇性配置)
      ssl_session_cache    shared:SSL:1m;
      ssl_session_timeout  5m;
      #數(shù)字簽名择克,此處使用MD5
      ssl_ciphers  HIGH:!aNULL:!MD5;
      ssl_prefer_server_ciphers  on;

      location / {
          root   /root;
          index  index.html index.htm;
      }
  }

負載均衡

前面的例子中恬总,代理僅僅指向一個服務器。

但是肚邢,網(wǎng)站在實際運營過程中壹堰,大部分都是以集群的方式運行,這時需要使用負載均衡來分流骡湖。

nginx 也可以實現(xiàn)簡單的負載均衡功能贱纠。

img

假設這樣一個應用場景:將應用部署在 192.168.1.11:80、192.168.1.12:80响蕴、192.168.1.13:80 三臺 linux 環(huán)境的服務器上谆焊。網(wǎng)站域名叫 www.helloworld.com,公網(wǎng) IP 為 192.168.1.11浦夷。在公網(wǎng) IP 所在的服務器上部署 nginx辖试,對所有請求做負載均衡處理(下面例子中使用的是加權輪詢策略)。

nginx.conf 配置如下:

http {
     #設定mime類型,類型由mime.type文件定義
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #設定日志格式
    access_log    /var/log/nginx/access.log;

    #設定負載均衡的服務器列表
    upstream load_balance_server {
        #weigth參數(shù)表示權值劈狐,權值越高被分配到的幾率越大
        server 192.168.1.11:80   weight=5;
        server 192.168.1.12:80   weight=1;
        server 192.168.1.13:80   weight=6;
    }

   #HTTP服務器
   server {
        #偵聽80端口
        listen       80;

        #定義使用www.xx.com訪問
        server_name  www.helloworld.com;

        #對所有請求進行負載均衡請求
        location / {
            root        /root;                 #定義服務器的默認網(wǎng)站根目錄位置
            index       index.html index.htm;  #定義首頁索引文件的名稱
            proxy_pass  http://load_balance_server ;#請求轉向load_balance_server 定義的服務器列表

            #以下是一些反向代理的配置(可選擇性配置)
            #proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            #后端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_connect_timeout 90;          #nginx跟后端服務器連接超時時間(代理連接超時)
            proxy_send_timeout 90;             #后端服務器數(shù)據(jù)回傳時間(代理發(fā)送超時)
            proxy_read_timeout 90;             #連接成功后罐孝,后端服務器響應時間(代理接收超時)
            proxy_buffer_size 4k;              #設置代理服務器(nginx)保存用戶頭信息的緩沖區(qū)大小
            proxy_buffers 4 32k;               #proxy_buffers緩沖區(qū),網(wǎng)頁平均在32k以下的話肥缔,這樣設置
            proxy_busy_buffers_size 64k;       #高負荷下緩沖大辛ぁ(proxy_buffers*2)
            proxy_temp_file_write_size 64k;    #設定緩存文件夾大小,大于這個值续膳,將從upstream服務器傳

            client_max_body_size 10m;          #允許客戶端請求的最大單文件字節(jié)數(shù)
            client_body_buffer_size 128k;      #緩沖區(qū)代理緩沖用戶端請求的最大字節(jié)數(shù)
        }
    }
}

負載均衡策略

Nginx 提供了多種負載均衡策略改艇,讓我們來一一了解一下:

負載均衡策略在各種分布式系統(tǒng)中基本上原理一致,對于原理有興趣姑宽,不妨參考 負載均衡

輪詢
upstream bck_testing_01 {
  # 默認所有服務器權重為 1
  server 192.168.250.220:8080
  server 192.168.250.221:8080
  server 192.168.250.222:8080
}
加權輪詢
upstream bck_testing_01 {
  server 192.168.250.220:8080   weight=3
  server 192.168.250.221:8080              # default weight=1
  server 192.168.250.222:8080              # default weight=1
}
最少連接
upstream bck_testing_01 {
  least_conn;

  # with default weight for all (weight=1)
  server 192.168.250.220:8080
  server 192.168.250.221:8080
  server 192.168.250.222:8080
}
加權最少連接
upstream bck_testing_01 {
  least_conn;

  server 192.168.250.220:8080   weight=3
  server 192.168.250.221:8080              # default weight=1
  server 192.168.250.222:8080              # default weight=1
}
IP Hash
upstream bck_testing_01 {

  ip_hash;

  # with default weight for all (weight=1)
  server 192.168.250.220:8080
  server 192.168.250.221:8080
  server 192.168.250.222:8080

}
普通 Hash
upstream bck_testing_01 {

  hash $request_uri;

  # with default weight for all (weight=1)
  server 192.168.250.220:8080
  server 192.168.250.221:8080
  server 192.168.250.222:8080

}

網(wǎng)站有多個 webapp 的配置

當一個網(wǎng)站功能越來越豐富時遣耍,往往需要將一些功能相對獨立的模塊剝離出來,獨立維護炮车。這樣的話舵变,通常酣溃,會有多個 webapp。

舉個例子:假如 www.helloworld.com 站點有好幾個 webapp纪隙,finance(金融)赊豌、product(產(chǎn)品)、admin(用戶中心)绵咱。訪問這些應用的方式通過上下文(context)來進行區(qū)分:

www.helloworld.com/finance/

www.helloworld.com/product/

www.helloworld.com/admin/

我們知道碘饼,http 的默認端口號是 80,如果在一臺服務器上同時啟動這 3 個 webapp 應用悲伶,都用 80 端口艾恼,肯定是不成的。所以麸锉,這三個應用需要分別綁定不同的端口號钠绍。

那么,問題來了花沉,用戶在實際訪問 www.helloworld.com 站點時莺丑,訪問不同 webapp埃仪,總不會還帶著對應的端口號去訪問吧。所以,你再次需要用到反向代理來做處理洪鸭。

配置也不難皮仁,來看看怎么做吧:

http {
    #此處省略一些基本配置

    upstream product_server{
        server www.helloworld.com:8081;
    }

    upstream admin_server{
        server www.helloworld.com:8082;
    }

    upstream finance_server{
        server www.helloworld.com:8083;
    }

    server {
        #此處省略一些基本配置
        #默認指向product的server
        location / {
            proxy_pass http://product_server;
        }

        location /product/{
            proxy_pass http://product_server;
        }

        location /admin/ {
            proxy_pass http://admin_server;
        }

        location /finance/ {
            proxy_pass http://finance_server;
        }
    }
}

靜態(tài)站點

有時候知市,我們需要配置靜態(tài)站點(即 html 文件和一堆靜態(tài)資源)量瓜。

舉例來說:如果所有的靜態(tài)資源都放在了 /app/dist 目錄下,我們只需要在 nginx.conf 中指定首頁以及這個站點的 host 即可晦雨。

配置如下:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    gzip on;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png;
    gzip_vary on;

    server {
        listen       80;
        server_name  static.zp.cn;

        location / {
            root /app/dist;
            index index.html;
            #轉發(fā)任何請求到 index.html
        }
    }
}

然后架曹,添加 HOST:

127.0.0.1 static.zp.cn

此時,在本地瀏覽器訪問 static.zp.cn 闹瞧,就可以訪問靜態(tài)站點了绑雄。

搭建文件服務器

有時候,團隊需要歸檔一些數(shù)據(jù)或資料奥邮,那么文件服務器必不可少万牺。使用 Nginx 可以非常快速便捷的搭建一個簡易的文件服務洽腺。

Nginx 中的配置要點:

  • 將 autoindex 開啟可以顯示目錄脚粟,默認不開啟。
  • 將 autoindex_exact_size 開啟可以顯示文件的大小蘸朋。
  • 將 autoindex_localtime 開啟可以顯示文件的修改時間核无。
  • root 用來設置開放為文件服務的根路徑。
  • charset 設置為 charset utf-8,gbk;藕坯,可以避免中文亂碼問題(windows 服務器下設置后团南,依然亂碼噪沙,本人暫時沒有找到解決方法)。

一個最簡化的配置如下:

autoindex on;# 顯示目錄
autoindex_exact_size on;# 顯示文件大小
autoindex_localtime on;# 顯示文件時間

server {
    charset      utf-8,gbk; # windows 服務器下設置后吐根,依然亂碼正歼,暫時無解
    listen       9050 default_server;
    listen       [::]:9050 default_server;
    server_name  _;
    root         /share/fs;
}

解決跨域

web 領域開發(fā)中,經(jīng)常采用前后端分離模式拷橘。這種模式下局义,前端和后端分別是獨立的 web 應用程序,例如:后端是 Java 程序冗疮,前端是 React 或 Vue 應用萄唇。

各自獨立的 web app 在互相訪問時,勢必存在跨域問題赌厅。解決跨域問題一般有兩種思路:

  1. CORS

在后端服務器設置 HTTP 響應頭穷绵,把你需要允許訪問的域名加入 Access-Control-Allow-Origin 中。

  1. jsonp

把后端根據(jù)請求特愿,構造 json 數(shù)據(jù),并返回勾缭,前端用 jsonp 跨域揍障。

這兩種思路,本文不展開討論俩由。

需要說明的是毒嫡,nginx 根據(jù)第一種思路,也提供了一種解決跨域的解決方案幻梯。

舉例:www.helloworld.com 網(wǎng)站是由一個前端 app 兜畸,一個后端 app 組成的。前端端口號為 9000碘梢, 后端端口號為 8080咬摇。

前端和后端如果使用 http 進行交互時,請求會被拒絕煞躬,因為存在跨域問題肛鹏。來看看,nginx 是怎么解決的吧:

首先恩沛,在 enable-cors.conf 文件中設置 cors :

# allow origin list
set $ACAO '*';

# set single origin
if ($http_origin ~* (www.helloworld.com)$) {
  set $ACAO $http_origin;
}

if ($cors = "trueget") {
    add_header 'Access-Control-Allow-Origin' "$http_origin";
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}

if ($request_method = 'OPTIONS') {
  set $cors "${cors}options";
}

if ($request_method = 'GET') {
  set $cors "${cors}get";
}

if ($request_method = 'POST') {
  set $cors "${cors}post";
}

接下來在扰,在你的服務器中 include enable-cors.conf 來引入跨域配置:

# ----------------------------------------------------
# 此文件為項目 nginx 配置片段
# 可以直接在 nginx config 中 include(推薦)
# 或者 copy 到現(xiàn)有 nginx 中,自行配置
# www.helloworld.com 域名需配合 dns hosts 進行配置
# 其中雷客,api 開啟了 cors芒珠,需配合本目錄下另一份配置文件
# ----------------------------------------------------
upstream front_server{
  server www.helloworld.com:9000;
}
upstream api_server{
  server www.helloworld.com:8080;
}

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

  location ~ ^/api/ {
    include enable-cors.conf;
    proxy_pass http://api_server;
    rewrite "^/api/(.*)$" /$1 break;
  }

  location ~ ^/ {
    proxy_pass http://front_server;
  }
}

到此,就完成了搅裙。

參考

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末皱卓,一起剝皮案震驚了整個濱河市总放,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌好爬,老刑警劉巖局雄,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異存炮,居然都是意外死亡炬搭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門穆桂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宫盔,“玉大人,你說我怎么就攤上這事享完∽瓢牛” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵般又,是天一觀的道長彼绷。 經(jīng)常有香客問我,道長茴迁,這世上最難降的妖魔是什么寄悯? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮堕义,結果婚禮上猜旬,老公的妹妹穿的比我還像新娘。我一直安慰自己倦卖,他們只是感情好洒擦,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怕膛,像睡著了一般熟嫩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘉竟,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天邦危,我揣著相機與錄音,去河邊找鬼舍扰。 笑死倦蚪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的边苹。 我是一名探鬼主播陵且,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了慕购?” 一聲冷哼從身側響起聊疲,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沪悲,沒想到半個月后获洲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡殿如,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年贡珊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涉馁。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡门岔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烤送,到底是詐尸還是另有隱情寒随,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布帮坚,位于F島的核電站妻往,受9級特大地震影響,放射性物質發(fā)生泄漏叶沛。R本人自食惡果不足惜蒲讯,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灰署。 院中可真熱鬧,春花似錦局嘁、人聲如沸溉箕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肴茄。三九已至,卻和暖如春但指,著一層夾襖步出監(jiān)牢的瞬間寡痰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工棋凳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拦坠,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓剩岳,卻偏偏與公主長得像贞滨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拍棕,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容