Nginx(engine x)是一個高性能的HTTP服務器,也是一款輕量級的Web服務器,反向代理服務器及電子郵件IMAP/POP3/SMTP代理服務器。Nginx是由伊戈爾·賽索耶夫爲站點Rambler.ru開發的。第一個公開版本發佈於2004年10月4日。其將源代碼以類BSD許可證的形式發佈,因它的穩定性、豐富的功能集、示列配置文件和低系統資源的消耗而聞名。其特色是佔用內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現比較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。html
Nginx是一種輕量級,高性能,多進程的Web服務器,很是適合做爲靜態資源服務器使用,而動態的訪問操做能夠是用穩定的Apache,Tomcat及IIS等來實現。這裏就以Nginx做爲代理服務器的同時,也使用其做爲靜態資源服務器。
靜態資源服務器經過絕對路徑去訪問,放在nginx服務器當中。
動態資源經過url拼接字符串的方式去訪問例如tomcat服務器node
1).輪詢(默認)
每一個請求按實際順序逐一分配到不一樣的後端服務器,若是後端服務器dump掉,能自動剔除。
2) weight(權重)
爲後臺服務器指定輪詢概率,weight和訪問量成正比,讓性能高的服務器承擔更多的訪問量。
3).ip_hash
每一個請求按訪問ip的hash結構分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。
4).fair(第三方)
按後端服務器的響應時間來分配請求,響應時間快短的優先分配。
5).url_hash(第三方)
按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。nginx
當咱們肯定一系列負載的服務器後,若是你先訪問到A服務器,下一次請求忽然轉到B服務器。這時候與A服務器創建的Session,傳到B服務器確定是沒法響應的。下面咱們來看一下解決方案:
1).Session或憑據緩存到獨立的服務器上
將seesion保存到獨立的服務器,緩存效率會比較高,但若是同時訪問的服務器過多的話,可能致使session服務器沒法負荷而宕機。
2).Session或憑據保存數據庫中
保存到數據中,除了要控制Session的有效期,同時也加劇了數據庫的負擔,因此最終轉變爲SQL Server負載均衡,涉及讀,寫,過時同步,處理起來會很複雜。
3).nginx ip_hash保持同一IP的請求都是指定到固定的一臺服務器
經過nginx ip_hash負載保持對同一服務器的會話,這種方式最方便,最輕量。git
若是實現了均衡負載,除了Session問題,咱們還會碰到文件的上傳下載問題。文件不可能上傳不一樣的服務器上,這樣會致使下載不到對應文件的問題。下面來看一下解決方案:
1).獨立文件服務器
2).文件壓縮數據庫
兩種方案都是經常使用的,咱們來講一下文件壓縮數據庫,之前的方式都是將文件二進制壓縮相當系型數據庫,而如今NOSQL的流行,加上MongoDB處理文件又比較方便,因此文件壓庫又多了一種選擇。畢竟文件服務器的效率和管理以及安全都不及數據庫。github
反向代理(Reverse Proxy)方式是指以代理服務器來接受Internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器;並將從服務器上獲得的結果返回給Internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個服務器。
反向代理服務器:
一般的代理服務器,只用於代理內部網絡對Internet的鏈接請求,客戶機必須指定代理服務器,並將原本要直接發送到Web服務器上的http請求發送到代理服務器中。當一個代理服務器可以代理外部網絡上的主機,訪問內部網絡時,這種代理服務的方式稱爲反向代理服務器。web
某臺節點服務器掛了,可是Nginx仍然會可能選中這個出故障的機器,而後就一直鏈接着是由於超時時間很長,具體多長不清楚,因此爲了不一直鏈接着,咱們須要設置超時時間。
用Keepalived搭建雙Nginx server集羣,防止單點故障正則表達式
worker_processes auto; worker_rlimit_nofile 100000; worker_cpu_affinity 0001 0010 0100 1000 0001 0010 0100 1000;
worker_processes:
定義了nginx對外提供web服務時的worker進程數。最優值取決於許多因素,包括(但不限於)CPU核的數量、存儲數據的硬盤數量及負載模式。不能肯定的時候,將其設置爲可用的CPU內核數將是一個好的開始(設置爲「auto」將嘗試自動檢測它)。shell
worker_rlimit_nofile:
更改worker進程的最大打開文件數限制。若是沒設置的話,這個值爲操做系統的限制。設置後你的操做系統和Nginx能夠處理比「ulimit -a」更多的文件,因此把這個值設高,這樣nginx就不會有「too many open files」問題了。數據庫
worker_cpu_affinity:
CPU親和力配置,讓不一樣的進程綁定不一樣的CPU,能夠減小因爲線程切換時CPU切換帶來的緩存拷貝致使下降效率。後端
events模塊中包含Nginx中全部處理鏈接的設置。
events { worker_connections 2048; multi_accept on; use epoll; }
worker_connections:
設置可由一個worker進程同時打開的最大鏈接數。若是設置了上面提到的worker_rlimit_nofile,咱們能夠將這個值設得很高。可是不能超過系統的可用socket鏈接數限制(~ 64K)。
multi_accept:
告訴nginx收到一個新鏈接通知後接受盡量多的鏈接。
use 設置用於複用客戶端線程的輪詢方法。若是你使用Linux 2.6+,你應該使用epoll。若是你使用FreeBSD,你應該使用kqueue。
(值得注意的是若是你不知道Nginx該使用哪一種輪詢方法的話,它會選擇一個最適合你操做系統的)
HTTP模塊控制着Nginx http處理的全部核心特性。
http { server_tokens off; sendfile on; tcp_nopush on; tcp_nodelay on; ... }
server_tokens:
並不會讓nginx執行的速度更快,但它能夠關閉在錯誤頁面中的nginx版本數字,這樣對於安全性是有好處的。
sendfile:
可讓sendfile()發揮做用。sendfile()能夠在磁盤和TCP socket之間互相拷貝數據(或任意兩個文件描述符)。Pre-sendfile是傳送數據以前在用戶空間申請數據緩衝區。
以後用read()將數據從文件拷貝到這個緩衝區,write()將緩衝區數據寫入網絡。sendfile()是當即將數據從磁盤讀到OS緩存。
由於這種拷貝是在內核完成的,sendfile()要比組合read()和write()以及打開關閉丟棄緩衝更加有效(更多有關於sendfile)。
tcp_nopush:
告訴nginx在一個數據包裏發送全部頭文件,而不一個接一個的發送。
tcp_nodelay:
告訴nginx不要緩存數據,而是一段一段的發送--當須要及時發送數據時,就應該給應用設置這個屬性,這樣發送一小塊數據信息時就不能當即獲得返回值。
access_log off; error_log /var/log/nginx/error.log crit;
access_log:
設置nginx是否將存儲訪問日誌。關閉這個選項可讓讀取磁盤IO操做更快(aka,YOLO)
error_log:
告訴nginx只能記錄嚴重的錯誤:
nginx依賴於pcre, openssl, zlib, nginx-rtmp-module。故在編譯nginx以前必須下載先編譯這些庫。
pcre是一個Perl庫,包括perl兼容的正則表達式庫。
zlib提供數據壓縮用的函式庫。
nginx-rtmp-module是nginx的rtmp流媒體服務拓展庫,實現了rtmp,hls,dash的流媒體服務功能。下面是本人編寫的nginx一鍵下載編譯腳本,運行該腳步便可下載編譯nginx:
#!/bin/bash #indicate that this script execute by /bin/bash # 本腳本用於自動下載nginx已經依賴庫pcre, openssl, zlib, nginx-rtmp-module,並編譯安裝,安裝時須要輸入管理員帳號權限 #zipexts=(".tar.gz" ".tar.bz2" ".tar.Z" ".tgz" ".tar" ".gz" ".bz2" ".Z" ".rar" ".zip") #zipexts=(".tar.gz" ".tar.bz2" ".tar.Z" ".tgz" ".tar" ".gz" ".bz2" ".Z" ".rar" ".zip") # 因爲shell腳本的函數不能返回字符串,故設置全局變量以便記錄dezip產生的返回值以及下downloazanddezip函數下載解壓後的文件夾名稱 extname="" outputname="" # 解壓壓縮包,並返回解壓後的文件夾或文件名稱 # param1:壓縮包名稱,必填項 # param2:解壓到指定文件夾,可爲空 # 返回值:無, 注,shell返回值只能爲整形,不能爲字符串 dezip(){ outputname=$2 extname="" exename="tar" unzipflag="" echo "param1:"$1 # 檢測壓縮包類型,並使用對應的解壓方式 if expr match $1 ".*.tar.gz" != 0; then extname=".tar.gz" exename="tar" unzipflag="-zxvf" #echo $extname elif expr match $1 ".*.tar.bz2" != 0; then extname=".tar.bz2" exename="tar" unzipflag="-xjf" #echo $extname elif expr match $1 ".*.tar" != 0; then extname=".tar" exename="tar" unzipflag="-xvf" elif expr match $1 ".*.tgz" != 0; then extname=".tgz" exename="tar" unzipflag="-xvf" elif expr match $1 ".*.gz" != 0; then extname=".gz" exename="gzip" # 或gunzip unzipflag="-d" elif expr match $1 ".*.bz2" != 0; then extname=".bz2" exename="bzip2" # 或bunzip2 unzipflag="-d" elif expr match $1 ".*.tar.Z" != 0; then extname=".tar.Z" exename="tar" unzipflag="-xZf" elif expr match $1 "*.Z" != 0; then extname=".Z" exename="uncompress" unzipflag="" elif expr match $1 ".*.rar" != 0; then extname=".rar" exename="unrar" unzipflag="e" elif expr match $1 ".*.zip" != 0; then extname=".zip" exename="unzip" unzipflag="-o" fi if [ ! -d $outputname ]; then outputname=${1%$extname} echo "outputname" $outputname fi #if [ ! -d $outputname ]; then #mkdir $outputname #echo $outputname #fi echo "$exename $unzipflag $1" # 解壓文件 $exename $unzipflag $1 #return $extname } # 下載壓縮包並解壓 # param1:url # param2:zip # return: dezip filename downloazanddezip() { if [ -d $1 ]; then echo "Invalid url, please input url while you run downloazanddezip" fi downloadurl=$1 # 截取?前面的字符串 downloadurl=${downloadurl%\?*} echo $downloadurl # 截取最後一個/後面的字符串,即壓縮包名稱 zipname=${downloadurl##*/} echo $zipname if [ ! -f $zipname ]; then curl -o $zipname $1 echo 'curl -o $zipname $1' fi echo "dezip:"$zipname dezip $zipname #extname=$? echo $extname'=dezip' $zipname if expr match $zipname $extname == 0; then zipname=${zipname%$extname} echo "zipname:"$zipname fi outputname=$zipname } # 下載nginx源碼,若是連接有誤,直接替換連接便可 curdir=$PWD downloazanddezip http://117.128.6.28/cache/nginx.org/download/nginx-1.14.2.tar.gz?ich_args2=468-23103716018527_5b6f2632bf91b3cdae35405cfb43338b_10001002_9c89612cdfcbf8d59538518939a83798_ff478ef610d500dd7f20fe13dd251d7b # 記錄nginx庫源碼文件夾目錄名稱 nginxname=$outputname cd $outputname if [ ! -d "./thirdpart/" ];then mkdir thirdpart fi cd ./thirdpart # 下載pcre庫 downloazanddezip https://ftp.pcre.org/pub/pcre/pcre-8.42.zip # 記錄pcre庫源碼文件夾目錄名稱 pcrename=$outputname # 下載openssl downloazanddezip https://www.openssl.org/source/openssl-1.0.2q.tar.gz # 記錄openssl庫源碼文件夾目錄名稱 opensslname=$outputname # 下載zlib庫 downloazanddezip http://117.128.6.17/cache/www.zlib.net/zlib-1.2.11.tar.gz?ich_args2=531-22232503018317_67f53fed3443a8995b0d31f74b74bce1_10001002_9c89612cdfc7f8d09639518939a83798_9b3b5eb8fa2f98e0b42e37f3838be97f # 記錄zlib庫源碼文件夾目錄名稱 zlibname=$outputname # 從github下載nginx-rtmp-module源碼 if [ ! -d "./nginx-rtmp-module/" ];then git clone https://github.com/arut/nginx-rtmp-module.git fi cd ../ make clean ./configure --prefix=$curdir/$nginxname/build --with-openssl=$curdir/$nginxname/thirdpart/$opensslname --with-pcre=$curdir/$nginxname/thirdpart/$pcrename --with-zlib=$curdir/$nginxname/thirdpart/$zlibname --add-module=$curdir/$nginxname/thirdpart/nginx-rtmp-module --with-http_ssl_module make make install
打開build目錄下conf文件夾下的nginx.conf文件:
http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; # add stat page location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root $nginxpath/thirdpart/nginx-rtmp-module; } # add stat page end location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # 支持flv、mp4文件點播 location ~* \.flv$ {#flv 支持 root $flvpath;#flv點播文件目錄 } location ~* \.mp4$ {#MP4 支持 root $mp4path;#mp4點播文件目錄 } }
運行nginx:
$sudo ./nginx -c $buildpath/conf/nginx.conf
而後打開瀏覽器訪問:
http://127.0.0.1/test.mp4 若是可以正常播放,說明點播服務配置成功。
http { include 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 logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root $nginxpath/third/nginx-rtmp-module; } location / { root html; index index.html index.htm; } location /live { #這裏也是須要添加的字段。 types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /opt/video/hls; expires -1; add_header Cache-Control no-cache; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # 支持flv、mp4文件點播 location ~* \.flv$ {#flv 支持 root $flvpath;#flv點播文件目錄 } location ~* \.mp4$ {#MP4 支持 root $mp4path;#mp4點播文件目錄 } } } # 增長rtmp服務 rtmp { server { listen 1935; chunk_size 4096; # rtmp點播 application vod { play $rtmpvodpath;#rtmp點播文件存放路徑 } # rtmp直播 application live { live on; hls on; #這個參數把直播服務器改形成實時回放服務器。 wait_key on; #對視頻切片進行保護,這樣就不會產生馬賽克了。 hls_path $hls_save_path; #切片視頻文件存放位置。 hls_fragment 10s; #每一個視頻切片的時長。 hls_playlist_length 60s; #總共能夠回看的事件,這裏設置的是1分鐘。 hls_continuous on; #連續模式。 hls_cleanup on; #對多餘的切片進行刪除。 hls_nested on; #嵌套模式。 } } }
安裝ffmpeg,並使用ffmpeg進行rtmp推流
$ sudo apt-get install ffmpeg $ ffmpeg -re -I $mp4path/test.mp4 -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/live $ ffplay -I rtmp://localhost:1935/live
若能正常播放rtmp流,則rtmp直播服務發佈成功。