前言
Nginx是一款自由的、開源的、高性能的HTTP服務器和 反向代理 服務器;同時也是一個IMAP、POP3、SMTP代理服務器;Nginx可以作為一個HTTP服務器進行網站的發布處理,另外Nginx可以作為反向代理進行負載均衡的實作,
- Nginx使用基于事件驅動架構,使得其可以支持數以百萬級別的TCP連接
- 高度的模塊化和自由軟體許可證使得第三方模塊層出不窮(開源)
- Nginx是一個跨平臺服務器,可以運行在Linux,Windows,FreeBSD,Solaris,AIX,Mac OS等作業系統上
- 穩定性極高
Nginx 解決高并發
- Nginx高并發原理( 多行程+epoll實作高并發 )
- Nginx 在啟動后,會有一個 master 行程和多個相互獨立的 worker 行程,
- 每個子行程只有一個執行緒(協程),采用的 IO多路復用模型epoll,實作高并發,
epoll能實作高并發原理
- epoll() 中內核則維護一個鏈表,epoll_wait 方法可以獲取到鏈表長度,不為0就知道檔案描述符準備好了,
- 在內核實作中 epoll 是根據每個 sockfd 上面的與設備驅動程式建立起來的回呼函式實作的,
- 某個 sockfd 上的事件發生時,與它對應的回呼函式就會被呼叫,來把這個 sockfd 加入鏈表,其他處于“空閑的”狀態的則不會,
- epoll上面鏈表中獲取檔案描述,這里使用記憶體映射(mmap)技術, 避免了復制大量檔案描述符帶來的開銷
記憶體映射(mmap):記憶體映射檔案,是由一個檔案到一塊記憶體的映射,將不必再對檔案執行I/O操作
nginx和apache比較
nginx相對于apache的優點
- 輕量級,同樣起web 服務,比apache 占用更少的記憶體及資源
- 抗并發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的,在高并發下nginx 能保持低資源低消耗高性能
- 高度模塊化的設計,撰寫模塊相對簡單,社區活躍,各種高性能模塊出品迅速啊
apache 相對于nginx 的優點
- apache 更為成熟,少 bug ,穩定性好
- rewrite ,比nginx 的rewrite 強大
- 模塊超多,基本想到的都可以找到
Nginx 代理
- 說到代理,首先我們要明確一個概念,所謂代理就是一個代表、一個渠道此時就涉及到兩個角色,一個是被代理角色 (A_),一個是目標角色 (B_),A_ 通過這個代理訪問 B_ 完成一些任務的程序稱為代理 (C_) 操作程序;比如客人去買雙鞋,這個店鋪就是 (C_),(A_) 就是廠家,(B_) 就是用戶,代理呢又分為正向代理和反向代理
正向代理:
- 首先我們先舉個例子:比如說我們在 YouTob 上查找學習資料,大家會發現很慢;這個時候就會需要到正向代理,最明顯的例子(1FQ),FQ的方式主要是找到一個可以訪問國外網站的代理服務器,我們將請求發送給代理服務器,代理服務器去訪問國外的網站,然后將訪問到的資料傳遞給我們
- 這就是正向代理,正向代理最大的特點是客戶端非常明確要訪問的服務器地址;服務器只清楚請求來自哪個代理服務器,而不清楚來自哪個具體的客戶端;正向代理模式屏蔽或者隱藏了真實客戶端資訊,
- 總結來說:正向代理,“它代理的是客戶端,代客戶端發出請求”,是一個位于客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理發送一個請求并指定目標(原始服務器),然后代理向原始服務器轉交請求并將獲得的內容回傳給客戶端,客戶端必須要進行一些特別的設定才能使用正向代理,
正向代理的用途:
- 訪問原來無法訪問的資源,如Google
- 可以做快取,加速訪問資源
- 對客戶端訪問授權,上網進行認證
- 代理可以記錄用戶訪問記錄(上網行為管理),對外隱藏用戶資訊
正向代理配置:
- 現在的網站基本上都是https,要解決既能訪問http80埠也能訪問https443埠的網站,需要配置兩個SERVER節點,一個處理HTTP轉發,另一個處理HTTPS轉發,而客戶端都通過HTTP來訪問代理,通過訪問代理不同的埠,來區分HTTP和HTTPS請求,
環境介紹:
- 代理服務器系統環境為:centos
- nginx代理服務器為:192.168.10.10
- 測驗客戶端為局域網內任意windows電腦或Linux電腦
[root@localhost ~] vim /usr/local/nginx-1.12.1/conf/nginx.conf server { resolver 114.114.114.114; #指定DNS服務器IP地址 listen 80; location / { proxy_pass http://$host$request_uri; #設定代理服務器的協議和地址 proxy_set_header HOST $host; proxy_buffers 256 4k; proxy_max_temp_file_size 0k; proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60; proxy_next_upstream error timeout invalid_header http_502; } } server { resolver 114.114.114.114; #指定DNS服務器IP地址 listen 443; location / { proxy_pass https://$host$request_uri; #設定代理服務器的協議和地址 proxy_buffers 256 4k; proxy_max_temp_file_size 0k; proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60; proxy_next_upstream error timeout invalid_header http_502; } } [root@localhost ~] /usr/local/nginx-1.12.1/sbin/nginx -s reload
Linux客戶端訪問測驗:
[root@localhost ~] curl -I --proxy 192.168.10.10:80 www.baidu.com HTTP/1.1 200 OK Server: nginx/1.12.1 Date: Mon, 11 Jun 2018 15:37:47 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Thu, 31 May 2018 09:28:16 GMT Connection: keep-alive ETag: "5b0fc030-264" Accept-Ranges: bytes https的訪問測驗 [root@localhost ~] curl -I --proxy 192.168.10.10:443 www.baidu.com HTTP/1.1 200 OK Server: nginx/1.12.1 Date: Mon, 11 Jun 2018 15:38:07 GMT Content-Type: text/html Content-Length: 277 Connection: keep-alive Accept-Ranges: bytes Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform Etag: "575e1f5c-115" Last-Modified: Mon, 13 Jun 2016 02:50:04 GMT Pragma: no-cache
設定Linux客戶端全域代理:
[root@localhost ~] vim /etc/profile export http_proxy='192.168.10.10:80' export http_proxy='192.168.10.10:443' export ftp_proxy='192.168.10.10:80' [root@localhost ~] source /etc/profile [root@localhost ~] curl -I www.baidu.com:80 HTTP/1.1 200 OK Server: nginx/1.12.1 Date: Mon, 11 Jun 2018 16:10:18 GMT Content-Type: text/html Content-Length: 277 Connection: keep-alive Accept-Ranges: bytes Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform Etag: "575e1f5c-115" Last-Modified: Mon, 13 Jun 2016 02:50:04 GMT Pragma: no-cache [root@localhost ~]# curl -I www.baidu.com:443 HTTP/1.1 200 OK Server: nginx/1.12.1 Date: Mon, 11 Jun 2018 16:10:27 GMT Content-Type: text/html Content-Length: 277 Connection: keep-alive Accept-Ranges: bytes Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform Etag: "575e1f59-115" Last-Modified: Mon, 13 Jun 2016 02:50:01 GMT Pragma: no-cache
上面結果就說明我們的服務端nginx正向代理和客戶端使用nginx做為全域代理設定成功,
反向代理:
- 舉例:我國的某寶網站,每天同時連接到網站的訪問人數已經爆表,單個服務器遠遠不能滿足用戶訪問量了,此時就出現了分布式部署;也就是通過部署多臺服務器來解決訪問人數限制的問題;某寶網站中大部分功能也是直接使用Nginx進行反向代理實作的,并且通過封裝Nginx和其他的組件之后起了個高大上的名字:Tengine,有興趣的童鞋可以訪問Tengine的官網查看具體的資訊http://tengine.taobao.org/,
- 多個客戶端給服務器發送的請求,Nginx服務器接收到之后,按照一定的規則分發給了后端的業務處理服務器進行處理了, 此時~請求的來源也就是客戶端是明確的,但是請求具體由哪臺服務器處理的并不明確了,Nginx扮演的就是一個反向代理角色,
- 客戶端是無感知代理的存在的,反向代理對外都是透明的,訪問者并不知道自己訪問的是一個代理, 因為客戶端不需要任何配置就可以訪問,
- 反向代理,“它代理的是服務端,代服務端接收請求”,主要用于服務器集群分布式部署的情況下,反向代理隱藏了服務器的資訊,
反向代理的作用:
- 保證內網的安全,通常將反向代理作為公網訪問地址,Web服務器是內網
- 負載均衡,通過反向代理服務器來優化網站的負載
反向代理配置:
- 本文主要配置Nginx的反向代理,及公司有多臺服務器都需要公司一臺主Nginx代理配置,使用Nginx+Tomcat實作此專案的反向代理,至于Nginx,tomcat如何搭建百度一大把,此案例是在一臺服務器上面實作,一臺虛擬機安裝了兩個tomcat,
虛擬機環境介紹:
- 服務器ip:192.168.161.189
- Nginx埠:80
- Tomcat1埠:8070
- Tomcat2埠:8080
- 一臺服務器安裝了兩個Tomcat,使用不同埠實作,
測驗搭建的nginx,tomcat是否正常訪問:
先測驗一下訪問搭建好的nginx有沒有問題,

Nginx訪問正常,
測驗一下搭建的tomcat,(自己編輯了一個用于測驗的簡單頁面,埠是8070)

配置反向代理:
[root@localhost conf] vim Nginx.conf
在server段里面的location加上proxy_pass http://ip:埠
server{ listen 80; server_name 192.168.161.189; # charset koi8-r; # access_log logs/host.access.log main; location / { proxy_pass http://192.168.161.189:8070; `注意這里` root html; idnex index.html index.htm; } }
Nginx配置完成后重啟一下nginx:
# 命令大全 1、查找nginx路徑:whereis nginx 2、啟動 service nginx start 3、查看Nginx的版本號:nginx -V 4、停止 nginx -s stop 5、退出 nginx -s quit 6、重啟加載配置 nginx -s reload /etc/init.d/nginx -s reload 也可以
重啟沒報錯說明組態檔沒問題:
使用瀏覽器進行訪問

簡單的反向代理已經完成
配置代理多個網站及服務:
[root@localhost conf] vim Nginx.conf
配置多個反向代理實作方式,是通過不同的埠代理訪問,這里復制一個server段,將兩個server段nginx的埠更改,使用nginx的不同埠訪問,
第一個server段配置tomcat1(192.168.161.189:8070)

第二個server段配置(192.168.161.189:8080)

配置完成后,重啟nginx代理,
[root@localhost conf] /etc/init.d/nginx -s reload
先訪問nginx代理的第一個tomcat1,(通過nginx的8081代理的tomcat1,)

訪問nginx代理的第二個tomcat2,(通過nginx的8082代理的tomcat2,)

總結:
- 以上配置就是通過nginx的不同埠代理多個地址,若還要代理更多通過nginx的不同埠,增加server段即可,訪問量大的網站不建議代理太多,
- 正向代理是代理客戶端,為客戶端收發請求,使真實客戶端對服務器不可見;而反向代理是代理服務器端,為服務器收發請求,使真實服務器對客戶端不可見,
基于上文的一些簡單配置,大概能知道Nginx的一個流程,我們繼續往下看:
- 在B/S應用中,頁面快取技術是提升服務能力的重要手段,頁面快取又分為瀏覽器快取和服務端快取兩類,本文僅討論Nginx服務器的頁面快取,Nginx服務快取的基本原理是對客戶請求過的資源建立本地副本,在一段合理時期內任何用戶再次請求該資源時,Nginx服務器無需要再次向后端服務器發出請求,而是直接應答快取的副本,因此,快取技術可以明顯降低后端服務器的負載,減輕網路傳輸負擔,極大地提升回應速度,
tornado的吞吐能力
我們用一個最簡單的例子,測驗一下tornado的吞吐能力:
# -*- coding: utf-8 -*- import os import sys import tornado.web import tornado.ioloop import tornado.httpserver from tornado.options import parse_command_line class Handler(tornado.web.RequestHandler): def get(self): self.write('我是tornado,我夠快!') class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", Handler) ] settings = dict( title='壓力測驗', debug=True, ) tornado.web.Application.__init__(self, handlers, **settings) parse_command_line() http_server = tornado.httpserver.HTTPServer(Application(), xheaders=True, max_buffer_size=504857600) http_server.listen(80) print('Web server is started') tornado.ioloop.IOLoop.instance().start()
啟動該腳本后,使用瀏覽器訪問127.0.0.1,頁面顯示“我是tornado,我夠快!”,這個例子沒有使用檔案讀寫、資料庫讀寫等耗時的操作,更能反應出tornado本身的吞吐能力,
壓力測驗通常使用Apache自帶的ab.exe,ab的使用方法為:
ab -n 請求數 -c 并發數 URL
下面是并發10個請求共計100個請求的壓力測驗:
ab -n 100 -c 10 http://127.0.0.1/ This is ApacheBench, Version 2.3 <$Revision: 1843412 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: TornadoServer/6.0.3 Server Hostname: 127.0.0.1 Server Port: 9001 Document Path: / Document Length: 22 bytes Concurrency Level: 10 Time taken for tests: 0.107 seconds Complete requests: 100 Failed requests: 0 Total transferred: 21700 bytes HTML transferred: 2200 bytes Requests per second: 937.09 [#/sec] (mean) Time per request: 10.671 [ms] (mean) Time per request: 1.067 [ms] (mean, across all concurrent requests) Transfer rate: 198.58 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 0.6 0 2 Processing: 4 9 3.0 9 18 Waiting: 2 9 3.2 8 18 Total: 4 10 3.1 9 19 WARNING: The median and mean for the initial connection time are not within a normal deviation These results are probably not that reliable. Percentage of the requests served within a certain time (ms) 50% 9 66% 10 75% 13 80% 14 90% 15 95% 15 98% 18 99% 19 100% 19 (longest request)
它的輸出中有以下關鍵資訊:
- Concurrency Level: 并發數,使用-c引數指定的數量
- Time taken for tests: 測驗用共用時長
- Complete requests: 完成的請求數
- Failed requests: 失敗的請求數
- Total transferred: 共傳輸的資料量
- HTML transferred: 頁面傳輸的資料量
- Requests per second: 平均每秒回應的請求數(吞吐量)
- Time per request: 用戶平均請求等待時間 [ms]
- Time per request: 服務器平均處理時間 [ms]
- Transfer rate: 輸入速率
我們發送10000次請求,用不同的并發數,多次進行測驗,得到的結果如下表所示:

從資料中可以看出,隨著并發數量的增加,服務器平均處理時間和用戶平均請求等待時間都在增加;并發小于100時,服務器還沒有飽和,吞吐量還在增加;并發大于100后,服務器的處理能力開始受到影響,吞吐量開始下降,
我使用windows平臺,在我的測驗條件下,tornado每秒最多回應1305次請求,Linux平臺上,tornado的表現要比windows平臺好得多,
Nginx 反向代理
- 代理服務器是架設在客戶端和服務器之間的中間服務器,我們一般所說的代理是正向代理,正向代理是客戶端的出口,客戶端將請求發送給正向代理服務器,告訴正向代理服務器我要訪問哪個服務器,然后正向代理服務器向目標服務器發送請求,并將回應回傳給客戶端,從服務器的角度看,它并不知道真正的請求是哪個客戶端發出來的,有幾個客戶端,只從代理服務器接受請求,
- 與正向代理相反,反向代理是服務器的入口,客戶端并不知道真正的服務器是哪個,有幾個服務器,只知道反向代理服務器是哪個,它向反向代理服務器發送請求,反向代理服務器會有選擇的把請求發送到其中的一臺服務器,并將服務器的回應回傳給客戶端,
- 反向代理使服務器由一個變為多個,并為多個服務器提供統一的入口,可根據每個服務器的負載向負載最輕的服務器轉發請求,這就是負載均衡,
- nginx是一款優秀的反向代理服務器,可以從官網下載壓縮包,解壓后直接使用,
首先,我們修改一下服務器的代碼,使之可以同時啟動多個行程:
# -*- coding: utf-8 -*- import os import sys import multiprocessing import tornado.web import tornado.ioloop import tornado.httpserver from tornado.options import parse_command_line # 頁面句柄 class Handler(tornado.web.RequestHandler): def get(self): self.write('我是tornado,我夠快!') class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", Handler), ] settings = dict( title='壓力測驗', debug=True, ) tornado.web.Application.__init__(self, handlers, **settings) # 啟動服務器 def start_web_server(port): parse_command_line() http_server = tornado.httpserver.HTTPServer(Application(), xheaders=True, max_buffer_size=504857600) http_server.listen(port) print('Web server is started on port %d.' % port) tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__": if len(sys.argv) == 1: start_web_server(80) else: try: ports = [int(port) for port in sys.argv[1].split(',')] except: try: a, b = sys.argv[1].split('-') ports = range(int(a), int(b) + 1) except: ports = list() print ('Parameter error.') multiprocessing.freeze_support() for port in ports: p = multiprocessing.Process(target=start_web_server, args=(port,)) p.start()
在命令列中輸入如下命令,啟動兩個服務器行程,每個行程使用不同的埠:
python server.py 9001-9002
接下來,配置ngnix,nginx的配置并不復雜,可以復制解壓目錄下的conf/ngnix.conf,進行修改即可,
在http部分中添加upstream,語法為:
http {
upstream 名稱 {
負載均衡策略
server IP地址:埠 其它引數;
}
}
其中可選的負載均衡策略有:
- ip_hash: 這種策略會把某一ip映射到一個固定的服務器,其優點是容易保持session的一致性,缺點是當該服務器負載過重后,也不能分流到其他服務器
- least_conn: 這種策略根據服務器連接的數量,選擇連接數量最小的服務器,同一客戶端不同的請求有可能會進入不同的服務器
- least_time: 這種策略計算每個服務器的回應時間,選擇回應時間小短的服務器,同一客戶端不同的請求有可能會進入不同的服務器
我選擇least_time,配置如下:
upstream serv { least_conn; server 127.0.0.1:9001; server 127.0.0.1:9002; }
將原來的location /的內容修改為如下內容:
proxy_pass http://serv$request_uri; #以下三行,目的是將代理服務器收到的用戶的資訊傳到真實服務器上 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://serv$request_uri中,serv為剛才配置的upstream的名稱,
修改并洗掉了原來組態檔中的注釋會,組態檔如下:
worker_processes 1; events { worker_connections 1024; } http { sendfile on; keepalive_timeout 65; upstream serv { least_conn; server 127.0.0.1:9001; server 127.0.0.1:9002; } server { listen 80; server_name localhost; location / { proxy_pass http://serv$request_uri; #以下三行,目的是將代理服務器收到的用戶的資訊傳到真實服務器上 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
啟動tornado,并進入組態檔的目錄,使用如下命令啟動nginx:
nginx -c nginx.conf
OK,反向代理配置完成,再次用ab進行壓力測驗, 結果并不像我們期望的那樣,吞吐量成倍增長,這是因為tornado的IO幾乎已經做到了極致,幾乎比肩nginx,wondows平臺上單臺PC的吞吐量大致也就如此了,當tornado需要進行檔案讀寫、資料庫讀寫等耗時的操作時,多行程的反向代理才能體現出優勢,
使用快取技術
除了反向代理,nginx還可以啟用快取技術,進一步提高服務能力,當客戶端第一次請求某url時,nginx將請求轉發給服務器,服務器回傳后,nginx在本地創建快取,在快取未失效前,nginx不再轉發請求,而是直接將快取的內容回傳給客戶端,服務器的負載被轉嫁到nginx上,而nginx的性能是非常出色的,
在nginx組態檔中設定快取,語法為:
http { proxy_cache_path 快取路徑 keys_zone=快取名稱:快取大小 levels=一級快取名長度:二級快取名長度 inactive=失活時間 max_size=最大大小; server { location url { proxy_cache 快取名稱; proxy_cache_min_uses 訪問次數(url被訪問多少次后進行快取); proxy_cache_valid any 有效期; } } }
修改后nginx的組態檔為:
worker_processes 1; events { worker_connections 1024; } http { sendfile on; keepalive_timeout 65; upstream serv { least_conn; server 127.0.0.1:9001; server 127.0.0.1:9002; server 127.0.0.1:9003; server 127.0.0.1:9004; } # 設定快取路徑 proxy_cache_path cache keys_zone=CACHE:10m levels=1:4 inactive=1m max_size=1g; server { listen 80; server_name localhost; location / { proxy_pass http://serv$request_uri; #以下三行,目的是將代理服務器收到的用戶的資訊傳到真實服務器上 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_cache CACHE; proxy_cache_min_uses 1; proxy_cache_valid any 1m; } } }
重啟nginx,此時使用瀏覽器訪問127.0.0.1,第一次nginx沒有快取,服務器端列印出了訪問日志,再以后的訪問,服務器不再列印日志,說明nginx快取起到了作用,
我們在tornado服務器的代碼中加入100毫秒的sleep,來模擬訪問資料庫的操作,對不啟用快取和啟用快取進行壓力測驗:

可以看出,快取技術對吞吐量的提升非常有效!
快取的副作用及解決方案
快取,意味著不是最新的,如果某頁面的內容的變化很快,使用快取技術將導致客戶端接收到錯誤的結果,如我增加一個url,輸出服務器當前的時間:
# -*- coding: utf-8 -*- import os import sys import time import datetime import multiprocessing import tornado.web import tornado.ioloop import tornado.httpserver from tornado.options import parse_command_line # 頁面句柄 class StaticHandler(tornado.web.RequestHandler): def get(self): time.sleep(0.1) self.write('我是tornado,我夠快!') class VariableHandler(tornado.web.RequestHandler): def get(self): now = datetime.datetime.now() self.write(now.strftime("%Y-%m-%d %H:%M:%S")) class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", StaticHandler), # 可以快取的頁面 (r"/variable", VariableHandler), # 禁止快取的頁面 ] settings = dict( title='壓力測驗', debug=True, ) tornado.web.Application.__init__(self, handlers, **settings) # 啟動服務器 def start_web_server(port): parse_command_line() http_server = tornado.httpserver.HTTPServer(Application(), xheaders=True, max_buffer_size=504857600) http_server.listen(port) print('Web server is started on port %d.' % port) tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__": if len(sys.argv) == 1: start_web_server(80) else: try: ports = [int(port) for port in sys.argv[1].split(',')] except: try: a, b = sys.argv[1].split('-') ports = range(int(a), int(b) + 1) except: ports = list() print ('Parameter error.') multiprocessing.freeze_support() for port in ports: p = multiprocessing.Process(target=start_web_server, args=(port,)) p.start()
此時瀏覽器訪問127.0.0.1/variable,第一次出現了正確的時間,以后的1分鐘以內,時間不再變化,等1分鐘以后快取過期,再訪問出能得到新的時間,為了解決這個問題,可以在nginx配置中添加多個location,分別指定是否啟用快取即可:
worker_processes 1; events { worker_connections 1024; } http { sendfile on; keepalive_timeout 65; upstream serv { least_conn; server 127.0.0.1:9001; server 127.0.0.1:9002; server 127.0.0.1:9003; server 127.0.0.1:9004; } proxy_cache_path cache keys_zone=CACHE:1m levels=1:2 inactive=1m max_size=1g; server { listen 80; server_name localhost; location / { proxy_pass http://serv$request_uri; #以下三行,目的是將代理服務器收到的用戶的資訊傳到真實服務器上 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_cache CACHE; proxy_cache_min_uses 1; proxy_cache_valid any 1m; } # 只轉發請求,不進行快取 location /variable { proxy_pass http://serv$request_uri; #以下三行,目的是將代理服務器收到的用戶的資訊傳到真實服務器上 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } }
重啟nginx后,再訪問127.0.0.1/variable,每次都可以得到最新的時間,
負載均衡
- 負載均衡也是Nginx常用的一個功能,負載均衡其意思就是分攤到多個操作單元上進行執行,例如Web服務器、FTP服務器、企業關鍵應用服務器和其它關鍵任務服務器等,從而共同完成作業任務,
- 簡單而言就是當有2臺或以上服務器時,根據規則隨機的將請求分發到指定的服務器上處理,負載均衡配置一般都需要同時配置反向代理,通過反向代理跳轉到負載均衡,而Nginx目前支持自帶3種負載均衡策略,還有2種常用的第三方策略,
RR(默認)
每個請求按時間順序逐一分配到不同的后端服務器,如果后端服務器down掉,能自動剔除,
簡單配置:
upstream test { server localhost:8080; server localhost:8081; } server { listen 81; server_name localhost; client_max_body_size 1024M; location / { proxy_pass http://test; proxy_set_header Host $host:$server_port; } }
負載均衡的核心代碼為:
upstream test { server localhost:8080; server localhost:8081; }
這里我配置了2臺服務器,當然實際上是一臺,只是埠不一樣而已,而8081的服務器是不存在的,也就是說訪問不到,但是我們訪問http://localhost 的時候,也不會有問題,會默認跳轉到http://localhost:8080
具體是因為Nginx會自動判斷服務器的狀態,如果服務器處于不能訪問(服務器掛了),就不會跳轉到這臺服務器,所以也避免了一臺服務器掛了影響使用的情況,由于Nginx默認是RR策略,所以我們不需要其他更多的設定,
權重
指定輪詢幾率,weight和訪問比率成正比,用于后端服務器性能不均的情況,例如
upstream test { server localhost:8080 weight=9; server localhost:8081 weight=1; }
那么10次一般只會有1次會訪問到8081,而有9次會訪問到8080
ip_hash
上面的2種方式都有一個問題,那就是下一個請求來的時候請求可能分發到另外一個服務器,當我們的程式不是無狀態的時候(采用了session保存資料),這時候就有一個很大的很問題了,比如把登錄資訊保存到了session中,那么跳轉到另外一臺服務器的時候就需要重新登錄了,所以很多時候我們需要一個客戶只訪問一個服務器,那么就需要用iphash了,iphash的每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決session的問題,
upstream test { ip_hash; server localhost:8080; server localhost:8081; }
fair(第三方)
按后端服務器的回應時間來分配請求,回應時間短的優先分配,
upstream backend { fair; server localhost:8080; server localhost:8081; }
url_hash(第三方)
按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,后端服務器為快取時比較有效,在upstream中加入hash陳述句,server陳述句中不能寫入weight等其他的引數,hash_method是使用的hash演算法
upstream backend { hash $request_uri; hash_method crc32; server localhost:8080; server localhost:8081; }
以上5種負載均衡各自適用不同情況下使用,所以可以根據實際情況選擇使用哪種策略模式,不過fair和url_hash需要安裝第三方模塊才能使用,由于本文主要介紹Nginx能做的事情,所以Nginx安裝第三方模塊不會再本文介紹
HTTP服務器
Nginx本身也是一個靜態資源的服務器,當只有靜態資源的時候,就可以使用Nginx來做服務器,同時現在也很流行動靜分離,就可以通過Nginx來實作,首先看看Nginx做靜態資源服務器
server { listen 80; server_name localhost; client_max_body_size 1024M; location / { root e:\wwwroot; index index.html; } }
這樣如果訪問http://localhost 就會默認訪問到E盤wwwroot目錄下面的index.html,如果一個網站只是靜態頁面的話,那么就可以通過這種方式來實作部署,
動靜分離
動靜分離是讓動態網站里的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以后,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路
upstream test{ server localhost:8080; server localhost:8081; } server { listen 80; server_name localhost; location / { root e:\wwwroot; index index.html; } # 所有靜態請求都由nginx處理,存放目錄為html location ~ \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ { root e:\wwwroot; } # 所有動態請求都轉發給tomcat處理 location ~ \.(jsp|do)$ { proxy_pass http://test; } error_page 500 502 503 504 /50x.html; location = /50x.html { root e:\wwwroot; } }
這樣我們就可以吧HTML以及圖片和css以及js放到wwwroot目錄下,而tomcat只負責處理jsp和請求,例如當我們后綴為gif的時候,Nginx默認會從wwwroot獲取到當前請求的動態圖檔案回傳,當然這里的靜態檔案跟Nginx是同一臺服務器,我們也可以在另外一臺服務器,然后通過反向代理和負載均衡配置過去就好了,只要搞清楚了最基本的流程,很多配置就很簡單了,另外localtion后面其實是一個正則運算式,所以非常靈活
總結
Nginx是支持熱啟動的,也就是說當我們修改組態檔后,不用關閉Nginx,就可以實作讓配置生效,當然我并不知道多少人知道這個,反正我一開始并不知道,導致經常殺死了Nginx執行緒再來啟動…..Nginx重新讀取配置的命令是
nginx -s reload
windows下面就是:
nginx.exe -s reload
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/185246.html
標籤:Python
下一篇:Python - AI自動摳圖
