nginx簡介
Nginx (engine x) 是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務。
- 其主要功能爲:
處理靜態文件,索引文件以及自動索引;打開文件描述符緩衝。(html)
缺點:nginx支持高併發,但nginx沒有處理動態語言的能力(php、jsp等),所以它會交給後端的apache處理。
無緩存的反向代理加速,簡單的負載均衡和容錯,可以實現高速緩存和負載均衡。Nginx作爲負載均衡服務,在內部直接支持 Rails 和 PHP 程序對外進行服務,也可以支持作爲 HTTP代理服務對外進行服務。Nginx採用C進行編寫,不論是系統資源開銷還是CPU使用效率都比 Perlbal 要好很多。
FastCGI,簡單的負載均衡和容錯。
API,nginx可以做爲應用程序的接口,使用 openresty(本質上也是nginx) ,它集成了nginx的一些模塊和第三方插件。
- nginx的出現原因(優點):
user在增長,根據摩爾定律,最初在我們想提升apache性能的時候,回去提升apache 的配置,但隨着硬件配置不斷的提升,apache的併發量增長的甚至越來越低,這個時候我們的nginx出現了,它的特點是高併發,高性能,可拓展性非常好,因爲他的外圍文檔非常全面,可以二次開發,添加別的插件,並且它內存消耗特別少。3W的併發量,10個nginx進程只消耗150M內存。
nginx的配置文件非常簡單
成本非常低,相比於F5等硬件負載均衡非常換算
支持重寫規則,根據域名url 把我們的http請求分發到不同的http服務器組。
比如我們訪問 baidu.com
會自動的定向到:
這就是重寫的功能。
他還具有自帶健康檢查功能。
節省帶寬,支持gzip壓縮
模塊化
nginx的安裝
nginx.org 開源網站
nginx.com 提供更高級的功能
安裝穩定版
nginx目錄介紹:
auto裏面是一些輔助編譯的工具,一些操作系統,函數庫之類的輔助信息
changeds文件裏面記錄了歷史的一些改動和bug修復信息
changes.ru 作者是俄羅斯人,這裏面是俄羅斯版本的chenges
conf 配置文件,主要爲了方便運維護人員進行配置,裏面都是配置文件
configure 是編譯用的二進制文件
contrib 提供的nginx語法檢測的一些字體,通常用於檢測字體。
比如我們此時的配置文件是由黑色和藍色字體組成:
我們在加目錄下創建.vim 目錄
mkdir ~/.vim
cp -r ./vim/* ~/.vim 複製當前的vim目錄到家目錄下的.vim目錄
此時我們在看剛纔打開的文件就有顏色了,這樣方便我們編寫配置文件:
html 默認發佈目錄。裏面有默認發佈頁和報錯發佈頁
license 是一些證書
man 是一些文檔手冊
readme 是是說明
src 是源碼目錄。
編譯:
安裝依賴的開發包
yum install pcre-devel -y
yum install gcc -y
yum install openssl-devel -y
./configure --prefix=/usr/local/nginx --with-http_ssl_module 支持https
此時會出現一個objs的目錄
裏面的Makefile是用來指定c語言之間的一些文件的調用關係。指定編譯邏輯
然後
make
編譯完成後 objs 目錄下又多了一些文件
nginx 就是nginx的主程序
ngx_module_c 用來存放模塊
最後
make install
可見nginx已經安裝到了指定目錄,其下有四個目錄
conf 配置文件目錄
html 默認發佈目錄
logs 日誌目錄
sbin 二進制程序目錄
運行nginx
進入到nginx目錄下的sbin目錄下,直接執行
./nginx
80端口已經打開:
我們訪問一下:
說明我們的服務已經配置好了。
修改默認發佈頁面:
vim /usr/local/nginx/html/index.html
訪問:
改變成功
nginx 的一些功能
查看nginx版本
cd nginx/sbin
./nginx -V
版本熱更新和回滾
更新
我們先從官網下載一個1.17版本的包用於更新,(其實這裏應該先下載1.17版本,更新至1.18版本更合適,但這樣同樣也屬於更新。)
我們先 備份 ,以防操作失誤。
我們還是對1.17版本進行相同的解壓和編譯。
./configure --prefix=/usr/local/nginx --with-http_ssl_module
make
注意這時就不能在執行make install 了,make install 只在第一次編譯安裝nginx的時候執行,我們回滾不需要
這裏在1.17的目錄下也會出現objs的目錄,下面也會產生一個 nginx 的二進制文件:
我們只需要把這個二進制文件複製到原來的1.18的nginx 的目錄下的nginx二進制文件進行替換就行了
可見此時我們的版本已經是1.17版本了
這是nginx的兩個進程。
但是此時我們程序中用戶請求是還訪問的是1.18版本的,我們應該讓用戶請求的時候訪問1.17版本的:
kill -USR2 17476 USR2 是告訴17476進程不要在接受用戶請求了併產生一個新的master進程來接收請求
可見生成了新的nginx master
這裏說一下master 和worker 的作用;
如果沒有修改配置文件的話,默認值與一個worker進程,master進程的作用是fork 和監控worker進程的,如果worker進程有異常,它就會重新fork一個worker進程進行接收請求,master進程本身不處理請求,worker進程纔是真實處理請求的進程。
此時舊的master進程可能還正在處理請求:
kill -WINCH 17476 等它處理完請求後將它關閉
可以看出它還留了一個master 進程,它的作用其實還是備份,如果更新不成功,舊的進程還在,就可以恢復到原來的狀態。
這樣,我們就更新到1.17版本了。
回滾
我們現在將後來更新1.17版本回滾到第一次安裝的1.18版本。
這時原來的nginx.old備份就其作用了
cd /usr/local/nginx/sbin/
cp -f nginx.old nginx 強制覆蓋
./nginx -V 查看版本
此時又回到了1.18版本。
我們此時就要告訴原來的17476 master 進程重新拉起 worker進程進行接收請求。
此時又多了一個worker進程,它的父進程是17476進程,
同時告訴新的master 不要接收請求了,並讓他執行完當前請求後就關閉它從屬的worker進程:
kill -USR2 20316
kill -WINCH 20316
之後我們在直接關閉到新的master
kill -9 20316
這樣就只剩一個master了。此時的版本爲1.18版本。
日誌切割
由於訪問的請求巨大,如果我們不進行切割的話,一個日誌文件就會大至幾個G,如果大小大於了內存,這個文件就打不開了。通常我們查日誌文件的時候也會一天一天的查,混在一起很不方便
日誌放在 logs 目錄裏邊,分爲普通正常日誌和錯誤日誌:
p
ab -c 1 -n 100000 http://172.25.254.1/index.html
一個併發,十萬此請求 ,我們以此來增加日誌的大小
du -sh
p
現在已經有16M了,然後我們進行切割。
我們先備份它的日誌:
備份成當日的日誌:
mv access.log `date +%F -d -1day`_access.log
我們可以在當天十二點自動執行這個命令,這樣每天就會把當天的日誌文件生成一個日期了
p
我們重新打開nginx就會產生新的日誌文件
[root@server1 logs]\# ../sbin/nginx -s reopen
p
error.log 也同理可以備份。
我們可以把這些操作寫進腳本里放在chrotable中每天定時執行。
gzip壓縮
我們先把默認訪問頁面的大小擴充至:
我們訪問,然後fn+f12查看詳細信息:
文件有5M的大小,我們實際也轉換了5M
我們可以使用gzip壓縮,我們去配置文件裏面進行更改:
打開gzip開關,設置最小爲1k的時候不壓縮,並設置壓縮等級爲2,以神魔類型壓縮。
進行一個語法檢測:
sbin/nginx -t
重新加在nginx
./sbin/nginx -s reload
再次訪問:
文件轉換過來就只有62.21kb了。
這就是gzip的作用,這樣用戶再加載這個頁面時就會非常快。就好比傳送圖片時候的查看原圖,就是經過壓縮過的。
systemd管理nginx
官方把服務的管理一般都放在 /usr/lib/systemd/system :
但是我們自己搭的服務官方建議我們放在 /etc/systemd/system中進行管理.
nginx其實也是一個http服務器,我們可以安裝一個httpd ,把它的配置文件給nginx使用,兩個是共通的
cp /usr/lib/systemd/system/httpd.service /etc/systemd/system/nginx.service
我們修改配置文件:
改成這樣子,我們就可以通過systemctl start/stop 來控制 nginx.service 了
systemctl start nginx.service
端口打開,且訪問成功
nginx 配置文件
user nginx nginx; 指定用戶和組打開nginx
worker_processes 1; worker 的進程數,通常設置爲cpu 的核心數
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 65535; 最大併發連接數,作爲反向代理時支持的是這個數字的一半
}
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;
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;
server {
listen 80; 端口
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
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 {
root html; 報錯界面
}
。。。。。。。。
}
可見是nginx用戶打開的
nginx的一些常用用法
大致由這些用法。
我們在這裏實操幾個用法:
限制併發連接數
更改配置文件:
limit_conn_zone $binary_remote_addr zone=addr:10m;
location /download/ {
limit_conn addr 1;
} 訪問/download/目錄時就會使用addr這個共享內存併發數爲1
定義了一個共享區域 addr 大小爲10M 超過就會報錯。
放到圖中的位置。
測試:
創建目錄:
mkdir /usr/local/nginx/html/download 建立目錄
../sbin/nginx -s reload 重新加載
在裏面放入一個圖片。
嘗試訪問:
訪問成功。
我們用ab的方式測試2個併發:
ab -c 1 -n 10 http://172.25.254.1/download/vim.jpg -c一個併發 -n 訪問10次
ab -c 2 -n 10 http://172.25.254.1/download/vim.jpg
一個併發時全部成功訪問。
兩個併發時就會有另外5個報錯/
限制請求速率
更改配置文件
速率爲一秒一個,超過的速率會在one區域進行等待,等待的隊列只能有5個請求。
每秒請求1.11。
限制帶寬
最大速度爲50k。
ab -c 1 -n 2 http://172.25.254.1/download/vim.jpg
圖片大小爲350k,所以應該時間爲14s
日誌
nginx的日誌都默認爲這種格式:
我們可以在配置文件中打開 log_format 參數和 access_log 參數
這裏邊的內容對應上面圖片中的每個部分。
表示訪問下面的目錄時的日誌會保存到這個目錄下。
重新加載nginx,測試:
curl 172.25.254.1 訪問一次
可見日誌出現在了這個目錄下面。
獲取nginx源地址 X-Forwarded_For
我們訪問百度的時候,實際訪問的時220.181.38.148這個地址,但是我們的ip地址明顯不再一個網段,爲什麼我們能上網是因爲中間有路由器,我們獲得路由器分配的ip地址,就可以和路由器通信了,路由器連接的時電信公司,一級一級的我們就可以去上網了。
我們上網的時候,我們的ip時172.25.254.1,上網的流程是:
比如我們訪問淘寶:
client(172.25.254.1) —》 ADSL(192.168.0.34) ----》cdn(10.0.0.1) -----》slb(阿里雲的負載11.0.0.1) --》 nginx(12.0.0.1)
這裏nginx獲取的ip都來源於,11.0.0.1,而我們想要收集 172.25.254.1 這個ip地址時,就可以用nginx獲取源地址。
而我們使用的參數就是 X-Forwarded_For
在通信時每個ip地址都會加一個herader 到X-Forwarded_For上
可以去 nginx.org 查找realip模塊
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 192.168.2.1;
set_real_ip_from 2001:0db8::/32; 設置可信ip,三種類型都可,一般爲上級ip地址
real_ip_header X-Forwarded-For; 從哪個header檢測我們要的ip
real_ip_recursive on; 第歸排除上面的realip
這樣我們檢測到客戶端的ip不再realip中時,就獲取到了客戶ip。
先編譯realip模塊到nginx中
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module
make && make install
realip模塊已經添加上了。
我們編輯nginx的配置文件:
添加一個虛擬主機:
做好解析:
嘗試訪問:
指定兩個header,可見排除了 172.25.254.1 這個realip,只剩了真實的物理ip地址
反向代理 + 負載均衡
http {
upstream backend {
server backend1.example.com weight=5; weight是權重,訪問五次這個服務器,在訪問下面的服務器
server backend2.example.com;
server 192.0.0.1 backup; 後端服務器全掛時訪問的ip
}
}
server {
location / {
proxy_pass http://backend; 將請求傳遞給後端服務器
}
}
壓縮照片
比如淘寶這類的網站,裏面的圖片非常之多,爲了壓縮圖片大小,提升用戶體驗,需要添加圖片過濾模塊。
重新編譯加入模塊:–with-http_image_filter_module=dynamic 動態模塊,編譯後可以加入參數使用
先在pkgs 網站下載需要的 GD開發包,然後安裝,不然會報錯
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module=dynamic
make && make install
我們需要將objs中的ngx_http_image_filter_module.so手動的集成到 ngx_modules.c 中去,因爲我們所有的模塊都集成在這個文件中。不然不可以使用。
[root@server1 objs]# cp nginx /usr/local/nginx/sbin/
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y
[root@server1 objs]# mkdir /usr/local/nginx/modules
[root@server1 objs]# cp ngx_http_image_filter_module.so /usr/local/nginx/modules/
然後再nginx的安裝目錄中編輯配置文件,最開頭加上:
表示在運行的時候加載這個模塊。否則模塊不生效,加的配置參數系統不識別。
在加上參數:
我們先註釋掉看下原來的樣子。
可見傳過來的大小和源圖大小基本一致爲350kb。
然歐我們打開這個參數
再次訪問:
就變的只有4 kb 了而且圖片也變成了設定的像素大小。這就是圖片的壓縮
https
配置文件中又專門支持https 的配置:
我們需要把https模塊編譯到nginx中。
在進行配置。打開剛纔註釋掉的配置,更改如下:
然後生成證書:
cd /etc/pki/tls/certs/ 證書生成目錄
make cert.pem 生成證書
cp cert.pem /usr/local/nginx/conf/ 拷貝到配置文件下
mkdir /web 創建資源目錄
vim /web/index.html 配置訪問頁面
重新加載在nginx ,配置本地解析,然後測試訪問
我們的證書不具備法律效益,我們自己獲取證書
點 confirm,
訪問成功。
這就是我們自己獲取的證書,上面的內容和我們生成時設定的內容相同。
重寫規則
但是我們在訪問時不加https時;
訪問的就是我門另外一個訪問頁面了,所以說這是不可控的,用戶在訪問的時候不會去主動加上https,所以我們應該配置nginx的重寫規則,讓用戶固定訪問加密的通道。
編輯配置文件:
表示不論以什麼開頭結尾訪問www.westos.org都定向到https://www.westos.org ,$1是用戶輸入的內容。
^表示開頭,(.*)表示結尾
建立 /bbs 目錄,創建訪問頁面。
重新加載nginx。
再次訪問www.westos.org ,就直接定向到了https://
可見它是臨時重定向,不緩存到本地。
- 永久重定向
只需要在i重寫規則後面加上permanent參數就行了。
此時就是永久重定向了。
表示不論以什麼,以bbs結尾就定向到 hhtp://bbswestos.org/
判斷規則 防盜鏈
生活中存在盜鏈行爲,就是盜取別人的資源爲自己所用,讓別人訪問自己時指定到別人的資源。
nginx中就有相應的設置,不是直接訪問自己的ip時就不提供資源。
我們模擬一下場景
重新開啓一臺nginx服務其server2,充當 盜鏈的人,server1當作真實服務器。
在nginx/html/下放一張圖片供我們訪問時使用。
更改server1的配置文件:
讓訪問www.westos.org 時訪問html目錄裏面的發佈頁面。
我們還需要更改server2的配置文件,
配置本地解析解析 daolian.westos.org
建立server2上的 /web 和 發佈頁面
啓動server2上的nginx,
配置本地解析:
測試訪問:
這時盜鏈這就可以盜用別人的資源了。
爲了避免這種情況,我們應該設置防盜鏈:
配置server1的配置文件:
即通過www.westos.org訪問時允許通過,通過其它網址訪問時拒絕。
重新加載nginx。
訪問:
就訪問不到了。
我們可以重定向:
即通過www.westos.org訪問時不阻擋,通過其它地址訪問時重寫到自己禁止盜鏈頁面
以圖形化的方式監控nginx
goexcess第三方軟件,官網地址
官網戳這裏
下載1.3版本。
編譯:
在pkgs中下載GeoIP 和GeoIP-devel 和groipupdate的安裝包。 版本需要相同。
yum install ncurses-devel -y 依賴性
./configure --prefix=/usr/local/goaccess --enable-utf8 --enable-geoip=legacy --with-openssl
make && make install
將 /usr/local/goaccess/bin/goaccess 軟連接到 /usr/local/bin
ln -s /usr/local/goaccess/bin/goaccess /usr/local/bin/
然後我們就可以使用命令的方式去監控日誌了:
這是一個聯合日誌,會生成一個html頁面
goaccess access.log -o ../html/report.html --real-time-html --time-format='%H:%M:%S' --date-format='%d/%b/%Y' --log-format=COMBINED
此時打開了一個7890的端口:
我們需要現在nginx中進行配置。
即當我們訪問/report.html 時訪問的是 /usr/local/nginx/html/report.html 這個頁面。
測試訪問:
是不是很炫酷?!