簡單瞭解Nginx
Nginx:engine X ,2002年,開源,商業版 Nginx是免費的、開源的、高性能的HTTP和反向代理服務器、郵件代理服務器、以及TCP/UDP代理服務器 解決C10K問題(10K Connections),http://www.ideawu.net/blog/archives/740.html Nginx官網:http://nginx.org nginx的其它的二次發行版: Tengine:由淘寶網發起的Web服務器項目。它在Nginx的基礎上,針對大訪問量網站的需求,添加了很多高級功能和特性。Tengine的性能和穩定性已經在大型的網站如淘寶網,天貓商城等得到了很好的檢驗。它的最終目標是打造一個高效、穩定、安全、易用的Web平臺。從2011年12月開始,Tengine成爲一個開源項目,官網 http://tengine.taobao.org/ OpenResty:基於Nginx 與 Lua 語言的高性能 Web 平臺, 章亦春團隊開發,官網:http://openresty.org/cn/
Nginx基礎特性
- 模塊化設計,較好的擴展性
- 高可靠性
- 支持熱部署:不停機更新配置文件,升級版本,更換日誌文件
- 低內存消耗:10000個keep-alive連接模式下的非活動連接,僅需2.5M內存
- event-driven,aio,mmap,sendfile
基本功能
- 靜態資源的web服務器
- http協議反向代理服務器
- pop3/imap4協議反向代理服務器
- FastCGI(LNMP),uWSGI(python)等協議
- 模塊化(非DSO),如zip,SSL模塊
和web服務相關的功能
- 虛擬主機(server)
- 支持 keep-alive 和管道連接(利用一個連接做多次請求)
- 訪問日誌(支持基於日誌緩衝提高其性能)
- url rewirte
- 路徑別名
- 基於IP及用戶的訪問控制
- 支持速率限制及併發數限制
- 重新配置和在線升級而無須中斷客戶的工作進程
Nginx請求處理機制
- 多進程方式:服務器每接收到一個客戶端請求就有服務器的主進程生成一個子進程響應客戶端,直到用戶關閉連接,這樣的優勢是處理速度快,子進程之間相互獨立,但是如果訪問過大會導致服務器資源耗盡而無法提供請求。
- 多線程方式:與多進程方式類似,但是每收到一個客戶端請求會有服務進程派生出一個線程來個客戶方進行交互,一個線程的開銷遠遠小於一個進程,因此多線程方式在很大程度減輕了web服務器對系統資源的要求,但是多線程也有自己的缺點,即當多個線程位於同一個進程內工作的時候,可以相互訪問同樣的內存地址空間,所以他們相互影響,一旦主進程掛掉則所有子線程都不能工作了,IIS服務器使用了多線程的方式,需要間隔一段時間就重啓一次才能穩定。
Nginx組織模型
Nginx是多進程組織模型,而且是一個由Master主進程和Worker工作進程組成。
主進程(master process)的功能
- 讀取Nginx 配置文件並驗證其有效性和正確性
- 建立、綁定和關閉socket連接
- 按照配置生成、管理和結束工作進程
- 接受外界指令,比如重啓、升級及退出服務器等指令
- 不中斷服務,實現平滑升級,重啓服務並應用新的配置
- 開啓日誌文件,獲取文件描述符
- 不中斷服務,實現平滑升級,升級失敗進行回滾處理
- 編譯和處理perl腳本
工作進程(woker process)的功能
- 接受處理客戶的請求
- 將請求以此送入各個功能模塊進行處理
- IO調用,獲取響應數據
- 與後端服務器通信,接收後端服務器的處理結果
- 緩存數據,訪問緩存索引,查詢和調用緩存數據
- 發送請求結果,響應客戶的請求
- 接收主程序指令,比如重啓、升級和退出等
進程間通信
- 工作進程之間的通信原理基本上和主進程與工作進程之間的通信是一樣的,只要工作進程之間能夠取得彼此的信息,建立管道即可通信,但是由於工作進程之間是完全隔離的,因此一個進程想要直到另外一個進程的狀態信息就只能通過主進程來設置了。
- 爲了實現工作進程之間的交互,主進程在生成工作進程之後,在工作進程表中進行遍歷,將該新進程的ID以及針對該進程建立的管道句柄傳遞給工作進程中的其他進程,爲工作進程之間的通信做準備,當工作進程1向工作進程2發送指令的時候,首先在主進程給它的其他工作進程工作信息中找到2的進程ID,然後將正確的指令寫入指向進程2的管道,工作進程2捕獲到管道中的事件後,解析指令並進行相關操作,這樣就完成了工作進程之間的通信。
Nginx模塊
核心模塊
是 Nginx 服務器正常運行 必不可少 的模塊,提供 錯誤日誌記錄 、 配置文件解析 、 事件驅動機制 、進程管理 等核心功能
標準HTTP模塊
標準HTTP模塊:提供 HTTP 協議解析相關的功能,比如: 端口配置 、 網頁編碼設置 、HTTP響應頭設置 等等
可選HTTP模塊
主要用於擴展標準的 HTTP 功能,讓 Nginx 能處理一些特殊的服務,比如: Flash 多媒體傳輸 、解析 GeoIP 請求、 網絡傳輸壓縮 、 安全協議 SSL 支持等
郵件服務模塊
主要用於支持Nginx 的郵件服務 ,包括對 POP3 協議、 IMAP 協議和 SMTP協議的支持
第三方模塊
是爲了擴展 Nginx 服務器應用,完成開發者自定義功能,比如: Json 支持、 Lua 支持等
安裝Nginx
Nginx的安裝版本分爲開發版、穩定版和過期版, Nginx安裝可以使用yum或源碼安裝,但是推薦使用源碼,一是yum的版本比較舊,二是編譯安裝可以更方便自定義相關路徑,三是使用源碼編譯可以自定義相關功能,更方便業務的上的使用,源碼安裝需要提前準備標準的編譯器,GCC的全稱是(GNU Compiler collection),其有GNU開發,並以GPL即LGPL許可,是自由的類UNIX即蘋果電腦Mac OS X操作系統的標準編譯器,因爲GCC原本只能處理C語言,所以原名爲GNU C語言編譯器,後來得到快速發展,可以處理C++,Fortran,pascal,objective-C,java以及Ada等其他語言,此外還需要Automake工具,以完成自動創建Makefile的工作,Nginx的一些模塊需要依賴第三方庫,比如pcre(支持rewrite),zlib(支持gzip模塊)和openssl(支持ssl模塊)等。
YUM安裝Nginx
安裝前需要提前配置好epel源
[root@CentOS7 ~]#yum install -y nginx
編譯安裝Nginx
準備編譯安裝的基礎環境
[root@CentOS7 ~]#yum install -y vim lrzsz tree screen psmisc lsof tcpdump wget ntpdate gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools iotop bc zip unzip zlib-devel bash-completion nfs-utils automake libxml2 libxml2-devel libxslt libxslt-devel perl perl-ExtUtils-Embed
gcc爲GNU Compiler Collection的縮寫,可以編譯C和C++源代碼等,它是GNU開發的C和C++以及其他很多種語言的編譯器(最早的時候只能編譯C,後來很快進化成一個編譯多種語言的集合,如Fortran、Pascal、Objective-C、Java、Ada、 Go等。)
gcc 在編譯C++源代碼的階段,只能編譯 C++ 源文件,而不能自動和 C++ 程序使用的庫鏈接(編譯過程分爲編譯、鏈接兩個階段,注意不要和可執行文件這個概念搞混,相對可執行文件來說有三個重要的概念:編譯(compile)、鏈接(link)、加載(load)。源程序文件被編譯成目標文件,多個目標文件連同庫被鏈接成一個最終的可執行文件,可執行文件被加載到內存中運行)。因此,通常使用 g++ 命令來完成 C++ 程序的編譯和連接,該程序會自動調用 gcc 實現編譯。
gcc-c++也能編譯C源代碼,只不過把會把它當成C++源代碼,後綴爲.c的,gcc把它當作是C程序,而g++當作是c++程序;後綴爲.cpp的,兩者都會認爲是c++程序,注意,雖然c++是c的超集,但是兩者對語法的要求是有區別的。
automake是一個從Makefile.am文件自動生成Makefile.in的工具。爲了生成Makefile.in,automake還需用到perl,由於automake創建的發佈完全遵循GNU標準,所以在創建中不需要perl。libtool是一款方便生成各種程序庫的工具。
pcre pcre-devel:在Nginx編譯需要 PCRE(Perl Compatible Regular Expression),因爲Nginx的Rewrite模塊和HTTP 核心模塊會使用到PCRE正則表達式語法。
zlip zlib-devel:nginx啓用壓縮功能的時候,需要此模塊的支持。
openssl openssl-devel:開啓SSL的時候需要此模塊的支持。
下載源碼包,解壓
[root@CentOS7 ~]# cd /usr/local/src/
[root@CentOS7 src]# wget https://nginx.org/download/nginx-1.14.2.tar.gz
[root@CentOS7 src]# tar xf nginx-1.14.2.tar.gz
[root@CentOS7 src]# cd nginx-1.14.2/
編譯安裝
[root@CentOS7 nginx-1.14.2]#./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
[root@CentOS7 nginx-1.14.2]# make # 編譯步驟,根據Makefile文件生成相應的模塊
[root@CentOS7 nginx-1.14.2]# make install # 創建目錄,並將生成的模塊和文件複製到相應的目錄
Nginx安裝完成之後會生成四個主要目錄:
1、conf:保存nginx所有的配置文件,其中nginx.conf是nginx服務器的最核心最主要的配置文件,其他的.conf則是用來配置nginx相關的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params兩個文件,配置文件一般都有個樣板配置文件,是文件名.default結尾,使用的使用將其複製爲並將default去掉即可。
2、html目錄中保存了nginx服務器的web文件,但是可以更改爲其他目錄保存web文件,另外還有一個50x的web文件是默認的錯誤頁面提示頁面。
3、logs:用來保存nginx服務器的訪問日誌錯誤日誌等日誌,logs目錄可以放在其他路徑,比如/var/logs/nginx裏面。
4、sbin:保存nginx二進制啓動腳本,可以接受不同的參數以實現不同的功能。
創建nginx用戶
[root@CentOS7 nginx-1.14.2]# useradd nginx -s /sbin/nologin -u 2000
對安裝目錄授權
[root@CentOS7 nginx-1.14.2]# chown nginx.nginx -R /apps/nginx/
驗證版本即編譯參數
[root@CentOS7 ~]#/apps/nginx/sbin/nginx -V
nginx version: nginx/1.14.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
啓動nginx
[root@CentOS ~]#/apps/nginx/sbin/nginx
[root@CentOS ~]#ss -ntl | grep 80
LISTEN 0 128 *:80 *:*
Nginx測試頁訪問
Nginx默認配置文件
[root@CentOS-Test ~]#cat /apps/nginx/conf/nginx.conf
user nginx nginx; #啓動Nginx工作進程的用戶和組
worker_processes 1; #啓動Nginx工作進程的數量
#錯誤日誌記錄配置
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid; #pid文件保存路徑
events { #events設置快,主要影響nginx服務器與用戶的網絡連接,比如是否允許同時接受多個網絡連接,使用哪種事件驅動模型處理請求,每個工作進程可以同時支持的最大連接數,是否開啓對多工作進程下的網絡連接進行序列化等。
worker_connections 1024; #設置單個nginx工作進程可以接受的最大併發,作爲web服務器的時候最大併發數爲worker_connections * worker_processes,作爲反向代理的時候爲(worker_connections * worker_processes)/2
}
http { #http塊是Nginx服務器配置中的重要部分,緩存、代理和日誌格式定義等絕大多數功能和第三方模塊都可以在這設置,http塊可以包含多個server塊,而一個server塊中又可以包含多個location塊,server塊可以配置文件引入、MIME-Type定義、日誌自定義、是否啓用sendfile、連接超時時間和單個鏈接的請求上限等。
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; # 作爲web服務器的時候打開sendfile加快靜態文件傳輸,指定是否使用sendfile系統調用來傳輸文件,sendfile系統調用在兩個文件描述符之間直接傳遞數據(完全在內核中操作),從而避免了數據在內核緩衝區和用戶緩衝區之間的拷貝,操作效率很高,被稱之爲零拷貝,硬盤 >> kernel buffer (快速拷貝到kernelsocket buffer) >>協議棧。
#tcp_nopush on; # 在開啓了sendfile的情況下,合併請求後統一發送給客戶端。
#keepalive_timeout 0;
keepalive_timeout 65; # 長連接超時時間(會話保持時長),單位是秒
#gzip on; # 開啓文件壓縮
server { # 設置一個虛擬機主機,可以包含自己的全局快,同時也可以包含多個location模塊。比如本虛擬機監聽的端口、本虛擬機的名稱和IP配置,多個server 可以使用一個端口,比如都使用80端口提供web服務
listen 80; # 配置server監聽的端口
server_name localhost; # 本server的名稱,當訪問此名稱的時候nginx會調用當前serevr內部的配置進程匹配。
#charset koi8-r; # nginx編碼格式,默認爲俄語,建議設置成utf-8格式
#access_log logs/host.access.log main;
location / { # location其實是server的一個指令,爲nginx服務器提供比較多而且靈活的指令,都是在location中提現的,主要是基於nginx接受到的請求字符串,對用戶請求的UIL進行匹配,並對特定的指令進行處理,包括地址重定向、數據緩存和應答控制等功能都是在這部分實現,另外很多第三方模塊的配置也是在location模塊中配置。
root html; # 相當於默認頁面的目錄名稱,默認是相對路徑,可以使用絕對路徑配置。
index index.html index.htm; # 默認的頁面文件名稱
}
#error_page 404 /404.html; # 錯誤頁面的文件名稱
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; # 錯誤頁面的文件名稱
location = /50x.html { # location處理對應的不同錯誤碼的頁面定義到/50x.html,這個跟對應其server中定義的目錄下
root html; # 定義默認頁面所在的目錄
}
# PHP頁面配置
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ { # 以http的方式轉發php請求到指定web服務器
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ { # 以fastcgi的方式轉發php請求到php處理
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht { # 拒絕web形式訪問指定文件,如很多的網站都是通過.htaccess文件來改變自己的重定向等功能。
# deny all; # 拒絕所有
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server { # 自定義虛擬server
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm; # 指定默認網頁文件,此指令由ngx_http_index_module模塊提供
# }
#}
# HTTPS server
#
#server { # https服務器配置
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
#導入其他路徑的配置文件
#include /apps/nginx/conf.d/*.conf
}