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的優點:** 二、 apache 相對于nginx 的優點: **
- 輕量級,同樣起web 服務,比apache 占用更少的記憶體及資源
- 抗并發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的,在高并發下nginx 能保持低資源低消耗高性能
- 高度子產品化的設計,編寫子產品相對簡單
- 社群活躍,各種高性能子產品出品迅速啊
- rewrite ,比nginx 的rewrite 強大
- 子產品超多,基本想到的都可以找到
- 少bug ,nginx 的bug 相對較多
**三、Nginx 配置簡潔, Apache 複雜 **
四、
最核心的差別在于apache是同步多程序模型,一個連接配接對應一個程序;nginx是異步的,多個連接配接(萬級别)可以對應一個程序
apache 多程序 fork() o(1) i/o : 阻塞
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SO0YzM0gTZiR2MjlDMhdzYyYzX4IjMxETM4AzLcdDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
切分服務: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
•簡潔方式:
–./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
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 使用者認證通路
{
– auth_basic "closed site";
– auth_basic_user_file /var/users;
– }
–Apache發行包中的htpasswd指令來建立user_file 檔案
–
–要通過yum –y install
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一緻性解決方案
•安裝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
•配置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**
**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" />