Nginx 是一個高性能的 Web 服務器,從 2001 年發展至今,因爲 Nginx 對硬件和操做系統內核特性的深度挖掘,使得在保持高併發的同時還可以保持高吞吐量。Nginx 還採用了模塊設計,有大量的第三方模塊能夠擴展 Nginx 的功能,所以 Nginx 的場景很是豐富,同時 Nginx 採用的是 BSD 許可證,賦予了 Nginx 最大的靈活性。簡單來講,Nginx 具備如下幾個優勢:javascript
BSD開源協議是一個給予使用者者很大自由的協議。基本上使用者能夠「隨心所欲」,能夠自由的使用,修改源代碼,也能夠將修改後的代碼做爲開源或者專有軟件再發布。php
截止 2019 年 9 月份,Nginx 的市場份額已經達到了 33%,且還在持續增加,穩居市場頭把交椅。css
Nginx 出現的背景是因爲互聯網的快速普及致使數據量的快速增加,同時催生出了海量的鏈接。傳統的 Apache 等服務器採用的是單進程模型,這意味着,每處理一個請求就會建立一個進程,這不但存在進程建立的開銷,並且進程之間相互切換產生的上下文開銷也很是耗費 CPU 資源,致使這種傳統的服務器在面對成千上萬的併發鏈接時,性能很是低下,而這是快速發展的互聯網所不可以忍受的。html
在這種背景下,Nginx 採用的是進程池和 epoll 處理模型,這兩者加起來使得 Nginx 的性能很是優異,一臺 32 核的機器上能夠支撐數千萬的併發鏈接。java
Nginx 有一個 master 進程和若干個 worker 進程,master 進程是用來管理 worker 進程的,worker 進程負責處理具體的請求,worker 進程是 master 進程的子進程。nginx
介紹完 Nginx 的背景,咱們就該說說 Nginx 的版本了。目前 Nginx 有三個主要的產品:正則表達式
針對咱們平常學習來講,選擇官方開源版的 Nginx 以及 OpenResty 就能夠了。shell
在 Linux 上,固然可使用 yum、apt-get 等軟件包管理工具來下載 Nginx,可是 Nginx 的不少模塊並非默認開啓的,第三方模塊不少也並不包含,因此,若是想要開啓內置的模塊或編譯第三方模塊,仍是須要編譯 Nginx。vim
在 nginx.org/en/download… 裏面能夠直接下載 Nginx 源代碼。包含如下目錄:bash
nginx-1.17.8
├── CHANGES # 每一個版本提供的特性和 bugfix
├── CHANGES.ru # 俄羅斯版本的 CHANGES 文件
├── LICENSE
├── Makefile
├── README
├── auto # 自動檢測系統環境以及編譯相關的腳本,輔助 config 腳本執行的時候去斷定 nginx 支持哪些模塊,當前操做系統有什麼樣的特性能夠供給 nginx 使用
├── conf # 示例文件,方便運維配置,會把 conf 示例文件拷貝到安裝目錄
├── configure # 命令腳本,用來生成中間文件,執行編譯前的一個必備動做
├── contrib # 提供了兩個 pl 腳本和 vim 工具
├── html # 一個 500 錯誤的默認頁面,另外一個是默認的 index 頁面
├── man # nginx 對 Linux 的幫助文件,man ./nginx.8
└── src # nginx 源代碼
複製代碼
配置 Vim
若是 Vim 沒有開啓語法高亮的話,最好開啓一下
cp -r contrib/vim/* ~/.vim
# mac 下須要在家目錄下新建 .vimrc 文件並配置
syntax on
複製代碼
./configure --help # --help 命令能夠查看配置腳本支持哪些參數
複製代碼
--prefix=PATH set installation prefix # 指定這個路徑就能夠了,其餘文件會在 prefix 目錄下創建相應的文件夾
--sbin-path=PATH set nginx binary pathname
--modules-path=PATH set modules path
--conf-path=PATH set nginx.conf pathname
--error-log-path=PATH set error log pathname
--pid-path=PATH set nginx.pid pathname
--lock-path=PATH set nginx.lock pathname
複製代碼
能夠配置使用或不使用哪些模塊,前綴一般是 with 和 with out,須要加 with 參數的一般是不會被 Nginx 默認編譯的,without 則是會移出編譯。
--with-http_ssl_module enable ngx_http_ssl_module
--with-http_v2_module enable ngx_http_v2_module
--with-http_realip_module enable ngx_http_realip_module
...
--without-http_charset_module disable ngx_http_charset_module
--without-http_gzip_module disable ngx_http_gzip_module
--without-http_ssi_module disable ngx_http_ssi_module
...
複製代碼
# 1. 使用默認參數,指定編譯安裝目錄
./configure --prefix=/Users/mtdp/myproject/nginx/nginx
# 編譯完成後生成 objs 文件夾中間文件
➜ objs ll
total 176
-rw-r--r-- 1 mtdp staff 40K 3 3 07:23 Makefile
-rw-r--r-- 1 mtdp staff 25K 3 3 07:23 autoconf.err
-rw-r--r-- 1 mtdp staff 5.4K 3 3 07:23 ngx_auto_config.h
-rw-r--r-- 1 mtdp staff 531B 3 3 07:23 ngx_auto_headers.h
-rw-r--r-- 1 mtdp staff 5.7K 3 3 07:23 ngx_modules.c # ngx_modules.c 決定了接下來的編譯會生成哪些模塊
drwxr-xr-x 9 mtdp staff 288B 3 3 07:23 src
2. # 編譯
make # 生成了大量的中間文件。若是是版本升級,就不能直接 makeinstall,須要將 obj 拷貝到安裝目錄。若是生成了動態模塊,編譯後也會放在 objs 目錄下
3. # 安裝
make install
➜ nginx ll # 安裝完成後生成如下文件夾
total 0
drwxr-xr-x 17 mtdp staff 544B 3 3 07:29 conf # 從 Nginx 源碼目錄拷貝的
drwxr-xr-x@ 4 mtdp staff 128B 3 3 07:29 html # 從 Nginx 源碼目錄拷貝的
drwxr-xr-x 2 mtdp staff 64B 3 3 07:29 logs # 日誌文件目錄,包括 access log 和 error log
drwxr-xr-x 3 mtdp staff 96B 3 3 07:29 sbin # Nginx 二進制文件目錄
複製代碼
OpenResty 的編譯安裝步驟與 Nginx 基本一致
在 openresty.org/en/download… 中下載 OpenResty 的源代碼,而後按照 Nginx 的編譯步驟執行便可。
events {
worker_connections 1024;
}
http {
#incloud 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/geek.access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
gzip_min_length 1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png multipart/form-data;
server {
listen 8080;
server_name 127.0.0.1;
#charset koi8-r;
access_log logs/geek.access.log main;
location /lua {
default_type text/html;
content_by_lua ' ngx.say("User-Agent: ", ngx.req.get_headers()["User-Agent"]) ';
}
}
#error_page 404 /404.html;
}
複製代碼
如上所示,是一個非典型的 Nginx 配置文件,Nginx 的配置文件語法遵循如下規則:
events { # 指令塊
worker_connections 1024; # 指令
}
複製代碼
這些指令塊在接下來都會遇到。
在剛剛編譯完成的 Nginx 目錄下,有一個 sbin 目錄,就是用來存放 Nginx 的二進制文件的
➜ sbin ll
total 1712
-rwxr-xr-x 1 mtdp staff 854K 3 3 07:29 nginx
複製代碼
Nginx 啓動時,有一系列的命令行參數能夠指定,下面分別介紹一下。
./nginx
-h/-? # 打開幫助
-c # 使用指定的配置文件,而不是默認的 conf 文件夾下的配置文件
-g # 指定配置命令,覆蓋掉配置文件中的指令
-p # 指定運行目錄
-s # 發送信號 stop 馬上中止服務;quit 優雅的中止服務;reload 重載配置文件;reopen 從新開始記錄日誌文件
-t/-T # 測試配置文件是否有語法錯誤
-v/-V # 打印 nginx 的版本信息、編譯信息等
複製代碼
當配置文件發生變動時,須要重載配置文件:
nginx -s reload
複製代碼
但想要更換 nginx 版本時,就須要採用熱部署的方式:
# master 進程 pid 爲 83308
kill -USR2 61333
複製代碼
查看 Nginx 進程。能夠發現,新的 master 進程也是基於老的 master 進程 fork 出來的
# 優雅的關閉老的 master 全部的 worker 進程,執行後,老的 master 並不會退出可是 worker 已經沒了,防止新進程有問題,還能夠經過 reload 來回滾
kill -WINCH 61333
複製代碼
# 優雅的退出 master
kill -quit 61333
複製代碼
一條命令便可實現日誌切割:
nginx -s reopen # 會從新生成日誌文件
複製代碼
關注公衆號回覆 Nginx 領取知識圖譜