1、Nginx
1.1 特點
- Nginx (“engine x”) 是一個高性能的 HTTP 和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 代理服務器
- 其將源代碼以類BSD許可證的形式發佈,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名
- 官方測試nginx能夠支撐5萬併發鏈接,並且cpu、內存等資源消耗卻非常低,運行非常穩定
- Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。由俄羅斯的程序設計師Igor Sysoev所開發
- 其特點是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:新浪、網易、騰訊等。
1.2 功能
- web服務器
- web reverse prox
- smtp reverse proxy
1.3 Nginx和apache的優缺點
一、nginx相對於apache的優點:
- 輕量級,同樣起web 服務,比apache 佔用更少的內存及資源
- 抗併發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高性能
- 高度模塊化的設計,編寫模塊相對簡單
- 社區活躍,各種高性能模塊出品迅速啊
** 二、 apache 相對於nginx 的優點: **
- rewrite ,比nginx 的rewrite 強大
- 模塊超多,基本想到的都可以找到
- 少bug ,nginx 的bug 相對較多
**三、Nginx 配置簡潔, Apache 複雜 **
四、
最核心的區別在於apache是同步多進程模型,一個連接對應一個進程;nginx是異步的,多個連接(萬級別)可以對應一個進程
apache 多進程 fork() o(1) i/o : 阻塞
切分服務:1,連接成功;2,3秒內返回
2、Tengine
- Tengine 是nginx的加強版,封裝版,淘寶開源
- **官網**http://tengine.taobao.org/
- 動態模塊加載(DSO)支持。加入一個模塊不再需要重新編譯整個Tengine;
- 支持SO_REUSEPORT選項,建連性能提升爲官方nginx的三倍;
- 支持SPDY v3協議,自動檢測同一端口的SPDY請求和HTTP請求;
- 流式上傳到HTTP後端服務器或FastCGI服務器,大量減少機器的I/O壓力;
- 更加強大的負載均衡能力,包括一致性hash模塊、會話保持模塊,還可以對後端的服務器進行主動健康檢查,根據服務器狀態自動上線下線,以及動態解析upstream中出現的域名;
- 輸入過濾器機制支持。通過使用這種機制Web應用防火牆的編寫更爲方便;
- 支持設置proxy、memcached、fastcgi、scgi、uwsgi在後端失敗時的重試次數
- 動態腳本語言Lua支持。擴展功能非常高效簡單;
- 支持管道(pipe)和syslog(本地和遠端)形式的日誌以及日誌抽樣;
- 支持按指定關鍵字(域名,url等)收集Tengine運行狀態;
- 組合多個CSS、JavaScript文件的訪問請求變成一個請求;
- 自動去除空白字符和註釋從而減小頁面的體積
- –…….
3、Nginx和Tengine安裝之前準備
•1、依賴 gcc openssl-devel pcre-devel zlib-devel
• 安裝:yum install gcc openssl-devel pcre-devel zlib-devel
•2、創建用戶和用戶組。爲了方便nginx運行而不影響linux安全
• 創建組:groupadd -r nginx
• 創建用戶:useradd -r -g nginx -M nginx
• -M 表示不創建用戶的家目錄。
•簡潔方式:
–./configure \
– --prefix=/usr/tengine
–make && make install
# 1.安裝
–./configure \
– --prefix=/opt/sxt/soft/tengine-2.1.0/ \
– --error-log-path=/var/log/nginx/error.log \
– --http-log-path=/var/log/nginx/access.log \
– --pid-path=/var/run/nginx/nginx.pid \
– --lock-path=/var/lock/nginx.lock \
– --with-http_ssl_module \
– --with-http_flv_module \
– --with-http_stub_status_module \
– --with-http_gzip_static_module \
– --http-client-body-temp-path=/var/tmp/nginx/client/ \
– --http-proxy-temp-path=/var/tmp/nginx/proxy/ \
– --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
– --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
– --http-scgi-temp-path=/var/tmp/nginx/scgi \
– --with-pcre
#2. 安裝
–make && make install
–啓動和配置路徑用默認的,用戶和用戶組限制,都去掉
–其中/var/tmp/nginx/client/目錄需要手動創建
3.添加安裝的tengine到註冊表,具體內容見附件nginx
•注意修改路徑,而且必須是在**/etc/init.d、下面touch或者vi來新建**
•不能用xftp傳進去,否則文件不被識別
•1、修改nginx文件的執行權限
• chmod +x nginx
•2、添加該文件到系統服務中去
• chkconfig --add nginx
• 查看是否添加成功
• chkconfig --list nginx
•
•啓動,停止,重新裝載
•service nginx start|stop|reload
4 Nginx****配置解析
4.1 event下的一些配置及其意義
-
#單個後臺worker process進程的最大併發鏈接數
-
worker_connections 1024;
-
併發總數是 worker_processes 和 worker_connections 的乘積
-
即 max_clients = worker_processes * worker_connections
-
在設置了反向代理的情況下,max_clients = worker_processes * worker_connections / 4 爲什麼
-
爲什麼上面反向代理要除以4,應該說是一個經驗值
-
根據以上條件,正常情況下的Nginx Server可以應付的最大連接數爲:4 * 8000 = 32000
-
worker_connections 值的設置跟物理內存大小有關
-
因爲併發受IO約束,max_clients的值須小於系統可以打開的最大文件數
-
而系統可以打開的最大文件數和內存大小成正比,一般1GB內存的機器上可以打開的文件數大約是10萬左右
-
我們來看看360M內存的VPS可以打開的文件句柄數是多少:
-
$ cat /proc/sys/fs/file-max
-
輸出 34336
-
32000 < 34336,即併發連接總數小於系統可以打開的文件句柄總數,這樣就在操作系統可以承受的範圍之內
-
所以,worker_connections 的值需根據 worker_processes 進程數目和系統可以打開的最大文件總數進行適當地進行設置
-
使得併發總數小於操作系統可以打開的最大文件數目
– # 其實質也就是根據主機的物理CPU和內存進行配置
– # 當然,理論上的併發總數可能會和實際有所偏差,因爲主機還有其他的工作進程需要消耗系統資源。
– # ulimit -SHn 65535
4.2 nginx.conf配置文件
-
定義Nginx運行的用戶和用戶組
-
user www www;
-
nginx進程數,建議設置爲等於CPU總核心數。
-
worker_processes 8;
-
全局錯誤日誌定義類型,[ debug | info | notice | warn | error | crit ]
-
error_log /var/log/nginx/error.log info;
-
進程文件
-
pid /var/run/nginx.pid;
-
一個nginx進程打開的最多文件描述符數目,理論值應該是最多打開文件數(系統的值ulimit -n)與nginx進程數相除,但是nginx分配請求並不均勻,所以建議與ulimit -n的值保持一致。
-
worker_rlimit_nofile 65535;
4.3 http下的一些配置及其意義
–#設定http服務器
–http
–{
–include mime.types; #文件擴展名與文件類型映射表
–default_type application/octet-stream; #默認文件類型
–#charset utf-8; #默認編碼
–server_names_hash_bucket_size 128; #服務器名字的hash表大小
–client_header_buffer_size 32k; #上傳文件大小限制
–large_client_header_buffers 4 64k; #設定請求緩
–client_max_body_size 8m; #設定請求緩
–sendfile on; #開啓高效文件傳輸模式,sendfile指令指定nginx是否調用sendfile函數來輸出文件,對於普通應用設爲 on,如果用來進行下載等應用磁盤IO重負載應用,可設置爲off,以平衡磁盤與網絡I/O處理速度,降低系統的負載。注意:如果圖片顯示不正常把這個改成off。
–autoindex on; #開啓目錄列表訪問,合適下載服務器,默認關閉。
–tcp_nopush on; #防止網絡阻塞
–tcp_nodelay on; #防止網絡阻塞
–keepalive_timeout 120; #長連接超時時間,單位是秒
4.4 gzip的一些配置及其意義
–#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;
\#壓縮類型,默認就已經包含text/html,所以下面就不用再寫了,寫上去也不會有問題,但是會有一個warn。
gzip_vary on;
\#limit_zone crawler $binary_remote_addr 10m; #開啓限制IP連接數的時候需要使用
4.4 虛擬主機一些配置及其意義
–#虛擬主機的配置
server
{
\#監聽端口
listen 80;
\#域名可以有多個,用空格隔開
server_name www.ha97.com ha97.com;
index index.html index.htm index.jsp;
root /data/www/ha97;
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.jsp;
include fastcgi.conf;
}
5 什麼是虛擬主機
虛擬主機是一種特殊的軟硬件技術,它可以將網絡上的每一臺計算機分成多個虛擬主機,每個虛擬主機可以獨立對外提供www服務,這樣就可以實現一臺主機對外提供多個web服務,每個虛擬主機之間是獨立的,互不影響的
5.1 通過nginx可以實現虛擬主機的配置,nginx支持三種類型的虛擬主機配置
–1、基於ip的虛擬主機, (一塊主機綁定多個ip地址)
–2、基於域名的虛擬主機(servername)
–3、基於端口的虛擬主機(listen如果不寫ip端口模式)
–示例基於虛擬機ip的配置,這裏需要配置多個ip
–server
–{
– listen 192.168.20.20:80;
– server_name www.linuxidc.com;
– root /data/www;
–}
–server
–{
– listen 192.168.20.21:80;
– server_name www.linuxidc.com;
– root /data/www;
–}
nginx.conf下的配置
–http{
–server{
– #表示一個虛擬主機
–}
–}
5.2 location 映射(ngx_http_core_module)
•location 映射(ngx_http_core_module)
– location [ = | ~ | ~* | ^~ ] uri { ... }
– location URI {}:
– 對當前路徑及子路徑下的所有對象都生效;
– location = URI {}: 注意URL最好爲具體路徑。
– 精確匹配指定的路徑,不包括子路徑,因此,只對當前資源生效;
– location ~ URI {}:
– location ~* URI {}:
– 模式匹配URI,此處的URI可使用正則表達式,~區分字符大小寫,~*不區分字符大小寫;
– location ^~ URI {}:
– 不使用正則表達式
– 優先級:= > ^~ > ~|~* > /|/dir/
–
–/loghaha.html
–/logheihei.html
–^/log.*html$
•location配置規則
•Directives with the = prefix that match the query exactly. If found, searching stops.
•All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.
•Regular expressions, in order of definition in the configuration file.
•If #3 yielded a match, that result is used. Else the match from #2 is used.
•=前綴的指令嚴格匹配這個查詢。如果找到,停止搜索。
•所有剩下的常規字符串,最長的匹配。如果這個匹配使用^〜前綴,搜索停止。
•正則表達式,在配置文件中定義的順序。
•如果第3條規則產生匹配的話,結果被使用。否則,如同從第2條規則被使用
•location配置規則
•location 的執行邏輯跟 location 的編輯順序無關。
矯正:這句話不全對,“普通 location ”的匹配規則是“最大前綴”,因此“普通 location ”的確與 location 編輯順序無關;
•
•但是“正則 location ”的匹配規則是“順序匹配,且只要匹配到第一個就停止後面的匹配”;
•“普通location ”與“正則 location ”之間的匹配順序是?先匹配普通 location ,再“考慮”匹配正則 location 。
•注意這裏的“考慮”是“可能”的意思,也就是說匹配完“普通 location ”後,有的時候需要繼續匹配“正則 location ”,有的時候則不需要繼續匹配“正則 location ”。兩種情況下,不需要繼續匹配正則 location :
–( 1 )當普通 location 前面指定了“ ^~ ”,特別告訴 Nginx 本條普通 location 一旦匹配上,則不需要繼續正則匹配;
–( 2 )當普通location 恰好嚴格匹配上,不是最大前綴匹配,則不再繼續匹配正則
–
–loghaha.html
–l: logha
–l: ^~ loghah
–l: loghaha.html
–l: =loghaha.html
–l: ^logh.*html$
–l: ^logha.*html$
5.4 用戶認證訪問
–模塊ngx_http_auth_basic_module 允許使用“HTTP基本認證”協議驗證用戶名和密碼來限制對資源的訪問。
– location / {
– auth_basic "closed site";
– auth_basic_user_file /var/users;
– }
–Apache發行包中的htpasswd命令來創建user_file 文件
–
–要通過yum –y install httpd
–htpasswd -c -m /var/users username
–**注:需要安裝****httpd****纔可以使用上面命令**
6 反向代理
什麼是反向代理?
- 通常的代理服務器,只用於代理內部網絡對Internet的連接請求,客戶機必須指定代理服務器,並將本來要直接發送到Web服務器上的http請求發送到代理服務器中由代理服務器向Internet上的web服務器發起請求,最終達到客戶機上網的目的。
- 反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然後將請求轉發給內部網絡上的服務器,並將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器
6.1 經典的反向代理
•反向代理:
•proxy_pass
location /baidu {
proxy_pass http://192.168.9.12【/】; //nginx收到客戶端的uri是否傳遞到上游,由是否在上游域名後有uri設定,沒有uri的情況下:傳遞
}
# 反向代理配置nginx.conf:
upstream 名字 {
server IP:PORT;
server IP:PORT;
}
server {
location / {
proxy_pass http://名字;
}
}
7. Nginx的session一致性問題
- http協議是無狀態的,即你連續訪問某個網頁100次和訪問1次對服務器來說是沒有區別對待的,因爲它記不住你。那麼,在一些場合,確實需要服務器記住當前用戶怎麼辦?比如用戶登錄郵箱後,接下來要收郵件、寫郵件,總不能每次操作都讓用戶輸入用戶名和密碼吧,爲了解決這個問題,session的方案就被提了出來,事實上它並不是什麼新技術,而且也不能脫離http協議以及任何現有的web技術
- session的常見實現形式是會話cookie(session cookie),即未設置過期時間的cookie,這個cookie的默認生命週期爲瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。實現機制是當用戶發起一個請求的時候,服務器會檢查該請求中是否包含sessionid,如果未包含,則系統會創造一個名爲JSESSIONID的輸出 cookie返回給瀏覽器(只放入內存,並不存在硬盤中),並將其以HashTable的形式寫到服務器的內存裏面;當已經包含sessionid是,服務端會檢查找到與該session相匹配的信息,如果存在則直接使用該sessionid,若不存在則重新生成新的 session。這裏需要注意的是session始終是有服務端創建的,並非瀏覽器自己生成的。 但是瀏覽器的cookie被禁止後session就需要用get方法的URL重寫的機制或使用POST方法提交隱藏表單的形式來實現
Session共享
- 首先我們應該明白,爲什麼要實現共享,如果你的網站是存放在一個機器上,那麼是不存在這個問題的,因爲會話數據就在這臺機器,但是如果你使用了負載均衡把請求分發到不同的機器呢?這個時候會話id在客戶端是沒有問題的,但是如果用戶的兩次請求到了兩臺不同的機器,而它的session數據可能存在其中一臺機器,這個時候就會出現取不到session數據的情況,於是session的共享就成了一個問題
Session一致性解決方案
1、session複製:
– tomcat 本身帶有複製session的功能。
2、共享session:
– 需要專門管理session的軟件,
– memcached 緩存服務,可以和tomcat整合,幫助tomcat共享管理session
•安裝memcached
–1、安裝libevent
–2、安裝memcached
–3、啓動memcached
– memcached -d -m 128m -p 11211 -l 192.168.9.11 -u root -P /tmp/
– -d:後臺啓動服務
– -m:緩存大小
– -p:端口
– -l:IP
– -P:服務器啓動後的系統進程ID,存儲的文件
– -u:服務器啓動是以哪個用戶名作爲管理用戶
如果源配置了也可以用
yum –y install memcached
•配置session共享如下:
–3、拷貝jar到tomcat的lib下,jar包見附件
–4、配置tomcat,每個tomcat裏面的context.xml中加入
•<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
• memcachedNodes="n1:192.168.9.11:11211"
• sticky="false"
• lockingMode="auto"
• sessionBackupAsync="false"
• requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
• sessionBackupTimeout="1000" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
•/>
•tengine新增會話保持功能:
– 在upstream 裏面增加一行配置:
– upstream laoxiao {
– session_sticky cookie=uid fallback=on mode=insert option=indi rect;
– server node2:8009 weight=5;
– server node3:8009 weight=5;
– }
–
– location ~ \.jsp$ {
– session_sticky_hide_cookie upstream=laoxiao;#對後端服務器隱藏增加的cookie
– proxy_pass ajp://laoxiao;
– }
8 Tengine 會話保持
**ngx_http_upstream_session_sticky_module**
- 該模塊是一個負載均衡模塊,通過cookie實現客戶端與後端服務器的會話保持, 在一定條件下可以保證同一個客戶端訪問的都是同一個後端服務器。
mode設置cookie的模式:
- insert: 在回覆中本模塊通過Set-Cookie頭直接插入相應名稱的cookie。
- prefix: 不會生成新的cookie,但會在響應的cookie值前面加上特定的前綴,當瀏覽器帶着這個有特定標識的cookie再次請求時,模塊在傳給後端服務前先刪除加入的前綴,後端服務拿到的還是原來的cookie值,這些動作對後端透明。如:“Cookie: NAME=SRV~VALUE”。
- rewrite: 使用服務端標識覆蓋後端設置的用於session sticky的cookie。如果後端服務在響應頭中沒有設置該cookie,則認爲該請求不需要進行session sticky,使用這種模式,後端服務可以控制哪些請求需要sesstion sticky,哪些請求不需要。
8.1 會話保持模塊配置
–#insert + indirect模式:
– upstream test {
–session_sticky cookie=uid domain=www.xxx.com fallback=on path=/ mode=insert option=indirect;
–server 127.0.0.1:8080;
– }
–Server
– {
– location / {
– #在insert + indirect模式或者prefix模式下需要配置session_sticky_hide_cookie
–#這種模式不會將保持會話使用的cookie傳給後端服務,讓保持會話的cookie對後端透明
–session_sticky_hide_cookie upstream=test;
– proxy_pass [http://test](http://test/);
– }
– }
8.2 Tengine 額外功能
•配置在tomcat日誌中獲取真實的客戶端ip
– 在nginx配置文件中加: proxy_set_header Y-Real-IP $remote_addr;
– 在tomcat的conf/server.xml配置文件中修改
– <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
– prefix="localhost_access_log." suffix=".txt"
– pattern="%{Y-Real-IP}i %l %u %t "%r" %s %b" />
–
•注意 上面的Y-Real-IP配置和server.xml裏面的配置要求一樣纔行