1. 程式人生 > >大資料學習-Nginx章

大資料學習-Nginx章

大資料學習-Nginx章


(一) 產生背景

我們在日常生活中會遇見的一些問題:
如:大學選課、12306網站、京東、淘寶,大量使用者進行訪問操作時,出現的故障。

主要2大原因:

  • 巨大流量—海量的併發訪問
  • 單臺伺服器資源和能力有限

在海量併發的環境下,使用者每一次請求伺服器,都需要大量的建立執行緒,每一次的執行緒都必須分配資源(CPU、記憶體、頻寬、磁碟IO等),當資源不足的時候就會使得伺服器宕機而無法提供服務。
那麼如何保證網站在流量峰值時能夠順利運作???

(二) 負載均衡(Load Balance)

2-1、高併發

見名知意,高(大量的),併發就是可以使用多個執行緒或者多個程序,同時處理(就是併發)不同的操作。
簡而言之就是每秒內有多少個請求同時訪問。

2-2、負載均衡

將請求/資料【均勻】分攤到多個操作單元上執行,負載均衡的關鍵在於【均勻】,也是分散式系統架構設計中必須考慮的因素之一。

2-3、tomcat併發圖

在這裡插入圖片描述
有tomcat的併發測試圖可以發現,當每秒300個請求同時訪問tomcat時,tomcat已經開始承受不住,出現波動。
那麼大型網站是如何處理高併發的呢?
以下是高併發場景下,實現負載均衡的一個簡化圖。
在這裡插入圖片描述
只需要實現“將請求/資料 均勻分攤到多個操作單元上執行”,就能實現負載均衡。

(三) Nginx初探

3-1、什麼是Nginx?

Nginx是一款輕量級的Web 伺服器、反向代理伺服器及電子郵件(IMAP/POP3)代理伺服器。
由俄羅斯的程式設計師Igor Sysoev所開發,其特點是佔有記憶體少

併發能力強,nginx的併發能力確實在同類型的網頁伺服器中表現非常好。

  • 官方測試nginx能夠支撐5萬併發連結,並且CPU、記憶體等資源消耗卻非常低,執行非常穩定。

(四) Nginx 和 apache 的優缺點

4-1.nginx相對於apache的優點:

  • 輕量級
  • 同樣起web 服務,比apache 佔用更少的記憶體及資源高併發
  • nginx 處理請求是非同步非阻塞(如前端ajax)的,而apache 則是阻塞型的
  • 在高併發下nginx能保持低資源低消耗高效能高度模組化的設計
  • 編寫模組相對簡單
  • 還有,它社群活躍,各種高效能模組出品迅速(十幾年時間發展)
  • Nginx 配置簡潔, Apache 複雜

4-2.apache 相對於nginx 的優點:

  • Rewrite重寫 ,比nginx 的rewrite 強大模組超多
  • 基本想到的都可以找到少bug ,nginx 的bug 相對較多。(出身好起步高)

(五) Nginx安裝

5-1、安裝依賴

依賴 gcc openssl-devel pcre-devel zlib-devel
執行命令:

yum -y install gcc openssl-devel pcre-devel zlib-devel

在這裡插入圖片描述

5-2、解壓檔案

下載檔案(如nginx-1.8.1.tar.gz 或 tengine-2.1.0.tar.gz),通過Xftp,上傳到伺服器,將檔案解壓
解壓指令 :

tar -zxvf tengine-2.1.0.tar.gz

在這裡插入圖片描述

5-3、configure配置

進入解壓後的原始碼目錄,然後執行configure命令進行配置
在這裡插入圖片描述
./configure --prefix=/usr/soft/nginx
這裡我是直接 執行 ./configure
預設路徑生成
在這裡插入圖片描述

5-4、編譯並安裝

進入解壓後的原始碼目錄,然後執行 make && make install 命令進行配置

make && make install

在這裡插入圖片描述
安裝好後,會在預設路徑下生成nginx目錄(也可在configure時指定路徑),這個目錄就是nginx的軟體了。
在這裡插入圖片描述

5-5、nginx命令

配置Nginx為系統服務,以方便管理

  1. 在/etc/rc.d/init.d/目錄中建立文字檔案nginx

    cd /etc/rc.d/init.d/
    vim nginx
    

    在這裡插入圖片描述

  2. 在檔案中貼上下面的內容:

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ “KaTeX parse error: Expected 'EOF', got '&' at position 22: …KING" = "no" ] &̲& exit 0 nginx=…(basename KaTeX parse error: Expected 'EOF', got '&' at position 87: …config/nginx ] &̲& . /etc/syscon…nginx -V 2>&1 | grep ‘configure arguments:’`
for opt in $options; do
if [ `echo $opt | grep ‘.*-temp-path’` ]; then
value=`echo KaTeX parse error: Can't use function '\`' in math mode at position 22: …cut -d "=" -f 2\̲`̲ if …value” ]; then
# echo “creating” $value
mkdir -p $value && chown -R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c N G I N X C O N F F I L E r e t v a l = NGINX_CONF_FILE retval= ?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc p r o g Q U I T r e t v a l = prog -QUIT retval= ?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc n g i n x H U P R E T V A L = nginx -HUP RETVAL= ?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case “$1” in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $“Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}”
exit 2
esac

  1. 修改nginx檔案的執行許可權

    chmod +x nginx
    
  2. 新增該檔案到系統服務中去

    chkconfig --add nginx
    

    檢視是否新增成功

    chkconfig --list nginx
    
  3. 啟動,停止,重新裝載

    service nginx start|stop
    

(六) Nginx配置

6-1、nginx預設配置詳解

在這裡插入圖片描述

#程序數,建議設定和CPU個數一樣或2倍
worker_processes 2;
#日誌級別
error_log logs/error.log warning;(預設error級別)
# nginx 啟動後的pid 存放位置
#pid logs/nginx.pid;
events {
#配置每個程序的連線數,總的連線數= worker_processes * worker_connections
#預設1024
worker_connections 10240;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#連線超時時間,單位秒
keepalive_timeout 65;
server {
listen 80;
server_name localhost
#預設請求
location / {
root html; #定義伺服器的預設網站根目錄位置
index index.php index.html index.htm; #定義首頁索引檔案的名稱
}
#定義錯誤提示頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

在這裡插入圖片描述

6-2、負載均衡配置:

nginx支援以下負載均衡機制(或​​方法):

  1. 輪詢負載均衡 - 對應用程式伺服器的請求以迴圈方式分發
  2. 加權負載均衡
  3. 最少連線數 - 將下一個請求分配給活動連線數最少的伺服器
  4. ip-hash - 雜湊函式用於確定下一個請求(基於客戶端的IP地址)應該選擇哪個伺服器。

6-2-1、預設負載平衡配置

使用nginx進行負載平衡的最簡單配置可能如下所示:

http { 
	    upstream qiaoke{
	        server node02;
	        server node03;
        }

        server {
	        listen 80;
	        server_name  localhost;
	        location / {
	            proxy_pass http://qiaoke;
	        }
        }
}

執行相同應用程式的3個例項。如果沒有專門配置負載均衡方法,則預設為迴圈法。所有請求都被 代理到伺服器組qiaoke,並且nginx應用HTTP負載平衡來分發請求。

6-2-2、加權負載平衡

通過使用伺服器權重,還可以進一步影響nginx負載均衡演算法,誰的權重越大,分發到的請求就越多。
權重範圍:1-10 ,預設權重為1

upstream qiaoke {
    server node02 weight=3;
	server node03;
}

6-2-3、最少連線負載平衡

在連線負載最少的情況下,nginx會盡量避免將過多的請求分發給繁忙的應用程式伺服器,而是將新請求分發給不太繁忙的伺服器,避免伺服器過載。

upstream qiake {
    least_conn;
    server node02;
	server node03;
}

6-2-4、會話永續性

上述的迴圈或最少連線數的負載平衡方法,每個後續客戶端的請求都可能被分發到不同的伺服器。不能保證相同的客戶端總是定向到相同的伺服器。
如果需要將客戶端繫結到特定的應用程式伺服器 - 換句話說,就是始終選擇相同的伺服器而言,就要使客戶端的會話“粘滯”或“持久” 。
ip-hash負載平衡機制就是有這種特性。使用ip-hash,客戶端的IP地址將用作雜湊鍵,以確定應該為客戶端的請求選擇伺服器組中的哪臺伺服器。此方法可確保來自同一客戶端的請求將始終定向到同一臺伺服器,除非此伺服器不可用

upstream shsxt{
    ip_hash;
    server node02;
	server node03;
}

6-3、Nginx的訪問控制

Nginx還可以對IP的訪問進行控制,allow代表允許,deny代表禁止。

location / {
	deny 192.168.4.242;
	allow 192.168.78.0/24;
	deny all;
	proxy_pass http://qiaoke;
}

從上到下的順序,匹配到了便跳出。如上的例子先禁止了1個,接下來允許了1個網段,最後未匹配的IP全部禁止訪問。

(七)、虛擬主機

7-1、何為虛擬主機

虛擬主機是指在網路伺服器上分出一定的磁碟空間,使用者可以租用此部分空間,以供使用者放置站點及應用元件,提供必要的資料存放和傳輸功能。

說白了虛擬主機就是把一臺物理伺服器劃分成多個“虛擬”的伺服器,各個虛擬主機之間完全獨立,在外界看來,每一臺虛擬主機和一臺單獨的主機的表現完全相同。所以這種被虛擬化的邏輯主機被形象地稱為“虛擬主機”。

優點:

由於多臺虛擬主機共享一臺真實主機的資源,每個虛擬主機使用者承受的硬體費用、網路維護費用、通訊線路的費用均大幅度降低。許多企業建立網站都採用這種方法,這樣不僅大大節省了購買機器和租用專線的費用,網站伺服器伺服器管理簡單,諸如軟體配置、防病毒、防攻擊等安全措施都由專業服務商提供,大大簡化了伺服器管理的複雜性;同時也不必為使用和維護伺服器的技術問題擔心,更不必聘用專門的管理人員。

類別:
  1. 基於域名的虛擬主機,通過域名來區分虛擬主機
  2. 基於埠的虛擬主機,通過埠來區分虛擬主機
  3. 基於ip的虛擬主機,很少用

7-2、基於域名的虛擬主機

http { 
    upstream qiaoke01{ 
        server node02; 
	} 
	upstream qoake02{ 
        server node03; 
     } 
 	server { 
        listen 80; 
		#訪問 qiaoke01.com 的時候,會把請求導到 qiaoke01 的伺服器組裡
		server_name  qiaoke01.com;
	        location / {
	            proxy_pass http://qiaoke01;
	    }
	} 
    server { 
        listen 80; 
		#訪問 qiake02.com 的時候,會把請求導到 qoake02 的伺服器組裡
		server_name  qoake02.com; 
	        location / {
	            proxy_pass http://qoake02;
	     }
	} 
}

注意:基於域名的虛擬機器主機 在模擬應用場景時,需要在windows系統的hosts檔案裡配置域名對映。(C:\Windows\System32\drivers\etc\hosts)
在這裡插入圖片描述

啟動nginx後,分別訪問qiake01.com ,qiaoke02.com
可看出,訪問不同域名,訪問的是對應的tomcat服務。

7-3、基於埠的虛擬主機

http { 
    upstream qiaoke01{ 
        server node02; 
	} 
	upstream qoake02{ 
        server node03; 
     } 
 	server { 
 	    #當訪問nginx的80埠時,將請求導給qiaoke01組
        listen 80; 
		server_name  localhost;
	        location / {
	            proxy_pass http://qiaoke01;
	    }
	} 
    server { 
       #當訪問nginx的81埠時,將請求導給qoake02組
        listen 81; 
		server_name  localhost; 
	        location / {
	            proxy_pass http://qoake02;
	     }
	} 
}

通過不同埠訪問,訪問的是對應tomcat服務

(九)Nginx的session的一致性問題

http協議是無狀態的,即你連續訪問某個網頁100次和訪問1次對伺服器來說是沒有區別對待的,因為它記不住你。

那麼,在一些場合,確實需要伺服器記住當前使用者怎麼辦?比如使用者登入郵箱後,接下來要收郵件、寫郵件,總不能每次操作都讓使用者輸入使用者名稱和密碼吧,為了解決這個問題,session的方案就被提了出來,事實上它並不是什麼新技術,而且也不能脫離http協議以及任何現有的web技術。

session的常見實現形式是會話cookie(session cookie),即未設定過期時間的cookie,這個cookie的預設生命週期為瀏覽器會話期間,只要關閉瀏覽器視窗,cookie就消失了。

9-1、Session共享

首先我們應該明白,為什麼要實現共享,如果你的網站是存放在一個機器上,那麼是不存在這個問題的,因為會話資料就在這臺機器,但是如果你使用了負載均衡把請求分發到不同的機器呢?這個時候會話id在客戶端是沒有問題的,但是如果使用者的兩次請求到了兩臺不同的機器,而它的session資料可能存在其中一臺機器,這個時候就會出現取不到session資料的情況,於是session的共享就成了一個問題。

9-2、Session一致性解決方案

  1. session複製

tomcat 本身帶有複製session的功能。

  1. 共享session

需要專門管理session的軟體,
memcached 快取服務,可以和tomcat整合,幫助tomcat共享管理session。

9-3、安裝memcached

  1. 安裝memcached記憶體資料庫

    yum install memcached –y
    

在這裡插入圖片描述
啟動指令:

 memcached -d -m 128m -p 11211 -l "memcached伺服器IP" -u root -P /tmp/

在這裡插入圖片描述

  1. web伺服器連線memcached的jar包拷貝到tomcat的lib
    在這裡插入圖片描述

  2. 配置tomcat的conf目錄下的context.xml

<Manager className=“de.javakaffee.web.msm.MemcachedBackupSessionManager”
memcachedNodes=“n1:192.168.17.9:11211”
sticky=“true”
lockingMode=“auto”
sessionBackupAsync=“false”
requestUriIgnorePattern=".*.(ico|png|gif|jpg|css|js)$"
sessionBackupTimeout=“1000” transcoderFactoryClass=“de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory” />

配置memcachedNodes屬性,配置memcached資料庫的ip和埠,預設11211,多個的話用逗號隔開。
目的是為了讓tomcat伺服器從memcached快取裡面拿session或者是放session
在這裡插入圖片描述

  1. 修改index.jsp,取sessionid看一看

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述