一 什么是nginx
Nginx是一款輕量級的Web 服務器,反向代理服務器及電子郵件(IMAP/POP3)代理服務器
其特點是占有內存少,並發能力強,能夠支持高達 50,000 個並發連接數的響應。
事實上nginx的並發能力確實在同類型的網頁服務器中表現較好,使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等
nginx工作原理
Nginx 服務器,正常運行過程中:
- 多進程:一個 Master 進程、多個 Worker 進程
- Master 進程:管理 Worker 進程,監控 worker 進程的運行狀態,worker 進程異常終止后,自動重啟 worker 進程
- Worker 進程:所有 Worker 進程都是平等的 實際處理:網絡請求,由 Worker 進程處理;
- Worker 進程數量:在 nginx.conf 中配置,一般設置為核心數,充分利用 CPU 資源,同時,避免進程數量過多,避免進程競爭 CPU 資源,增加上下文切換的損耗。
二 環境准備
1 准備一台干凈的centos7服務器,或者虛擬機或者購買的VPS。Nginx是C開發的,建議在 Linux上運行,當然,也可以安裝Windows 版本。
2 安裝依賴,安裝需要gcc環境,所以需要安裝gcc;zlib是用來對http包的內容進行gzip壓縮的;openssl則是支持https的SSL協議;pcre庫是用來匹配正則的,rewrite規則需要它
yum install gcc-c++
pcre pcre-devel
zlib zlib-devel
3.下載最新穩定版的nginx,目前穩定版是1.14.2。官網下載地址:http://nginx.org/en/download.html,下載后將安裝包上傳到CentOS中。
可以使用wget命令直接下載到CentOS系統中:
wget http://nginx.org/download/nginx-1.14.2.tar.gz
groupadd www
useradd -s /sbin/nologin -g www www
4 編譯安裝
進入下載的安裝包目錄,解壓nginx,進入nginx解壓后的目錄,配置安裝參數:
tar -zxvf nginx -1.14.2.tar.gz
cd nginx -1.14.2
更改源碼修改軟件名稱和版本號
[root@localhost core]# pwd
/usr/local/src/nginx-1.8.1/src/core
[root@localhost core]# vim nginx.h
#define nginx_version 8008001 #define NGINX_VERSION "8.12.0" #define NGINX_VER "wg007/" NGINX_VERSION #ifdef NGX_BUILD #define NGINX_VER_BUILD NGINX_VER " (" NGX_BUILD ")" #else #define NGINX_VER_BUILD NGINX_VER #endif #define NGINX_VAR "WG007" #define NGX_OLDPID_EXT ".oldbin"
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-http_sub_module
http_stub_status_module 作用:監控nginx運行狀態
http_sub_module 作用:用於替換字符串
http_ssl_module 作用:支持https訪問
http_gzip_static_module 作用:實現靜態壓縮功能,節約帶寬
進行編譯安裝
make && make install
5 管理nginx
編輯nginx 啟動腳本
# chkconfig: 2345 99 20
2345表示系統運行級別是2,3,4或者5時都啟動此服務,
99,是啟動的優先級,
20, 是關閉的優先級 #description: nginx-server nginx=/usr/local/nginx/sbin/nginx case $1 in start) netstat -anptu | grep nginx if [ $? -eq 0 ] then echo "nginx-server is already running" else echo "nginx-server begin start" $nginx fi ;; stop) $nginx -s stop if [ $? -eq 0 ] then echo "nginx-server is stoped" else echo "nginx-server stop fail,try again" fi ;; status) netstat -anlpt | grep nginx if [ $? -eq 0 ] then echo "nginx-server is running" else echo "nginx-server is stoped" fi ;; restart) $nginx -s reload if [ $? -eq 0 ] then echo "nginx-server is begin restart" else echo "nginx-server restart fail" fi ;; *) echo "please enter {start restart status stop}" ;;
esac
vi /etc/init.d/nginx
chkconfig --add nginx 將nginx 添加為系統服務
chkconfig --list|grep nginx
chmod +x /etc/init.d/nginx
.停止和重新載入nginx配置。
/usr/local/nginx/sbin/nginx –s stop # 停止
/usr/local/nginx/sbin/nginx -s reload # 重載nginx使配置生效
測試配置文件是否正常。
/usr/local/nginx/sbin/nginx –t
關於優化
1 關於系統連接數的優化
linux 默認值 open files 和 max user processes 為 1024
說明 server 只允許同時打開 1024 個文件,處理 1024 個用戶進程
#ulimit -n
1024
使用ulimit -a 可以查看當前系統的所有限制值,使用ulimit -n 可以查看當前的最大打開文件數。
新裝的linux 默認只有1024 ,當作負載較大的服務器時,很容易遇到error: too many open files 。因此,需要將其改大。
解決方法:
-S 指soft ,-H 指hard
臨時修改方法:
ulimit -SHn 65535
永久修改方法:
在/etc/security/limits.conf 最后增加:
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
備注:ulimit 命令本身就有分軟硬設置,加-H 就是硬,加-S 就是軟默認顯示的是軟限制
soft 限制不能設置的比 hard 限制更高。 只有 root 用戶才能夠增加 hard 限制值。
2 nginx全局配置優化 nginx.conf:
1 修改nginx運行的用戶
user www
2 nginx初始進程數量
worker_processes auto; #cpu核數
3 單進程處理最大請求連接數
worker_connections 65535;
4 IO模型
events {
worker_connections 65535; #每個工作進程允許的最大連接數
use epoll; #使用高性能的 epoll 事件驅動,處理效率高
IO多路復用是指多個描述符的I/O操作都能在一個線程內並發交替地順序完成,
這里的“復用”指的是復用同一個線程;
Linux 中一切皆文件,比如 C++ 源文件、視頻文件、Shell腳本、可執行文件等,就連鍵盤、顯示器、鼠標等硬件設備也都是文件。
一個 Linux 進程可以打開成百上千個文件,為了表示和區分已經打開的文件,Linux 會給每個文件分配一個編號(一個 ID),這個編號就是一個整數,被稱為文件描述符(File Descriptor)。
#什么是epoll 名詞解釋 http://www.mamicode.com/info-detail-2283798.html
}
5 長連接超時時長 :keepalive_timeout 65;
6 壓縮: gzip on;
靜態數據緩存過期時長
7 隱藏版本號
在http模塊中添加
server_tokens off;
驗證:curl -I http://127.0.0.1
8 拒絕訪問敏感目錄
拒絕訪問 admin和config目錄
location ~ ^/(admin|config)/ {
deny all;
}
9 允許客戶端緩存所有圖片數據360天
location ~ \.(jpg|gif|png|jpeg)$ {
expires 360d;
}
四 loction 匹配模式及順序
location = /uri =開頭表示精確匹配,只有完全匹配上才能生效。
location ^~ /uri ^~ 開頭對URL路徑進行前綴匹配,並且在正則之前。
location ~ pattern ~開頭表示區分大小寫的正則匹配。
location ~* pattern ~*開頭表示不區分大小寫的正則匹配。
location /uri 不帶任何修飾符,也表示前綴匹配,但是在正則匹配之后。
location / 通用匹配,任何未匹配到其它location的請求都會匹配到,相當於switch中的default。
location ^~ /admin { deny all; } location = /50x.html { #root html; return 600; } location ~ /helloword { return 601; } location ~* /Helloword { return 602; }
匹配的順序是先匹配普通字符串,然后再匹配正則表達式。
五: nginx 防DDos配置防御
DDOS是一個系統工程,攻擊花樣多,防御的成本高瓶頸多,防御起來即被動又無奈。
DDOS的特點是分布式,針對帶寬和服務攻擊,也就是四層流量攻擊和七層應用攻擊,相應的防御瓶頸四層在帶寬,七層的多在架構的吞吐量。
對於七層的應用攻擊,我們還是可以做一些配置來防御的,例如前端是Nginx,主要使用nginx的http_limit_conn和http_limit_req模塊來防御。
ngx_http_limit_conn_module 可以限制單個IP的連接數
ngx_http_limit_req_module 可以限制單個IP每秒請求數,通過限制連接數和請求數能相對有效的防御CC攻擊。
下面是配置方法:
http { limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; //觸發條件,所有訪問ip 限制每秒10個請求 … server { location / { root html; index index.html index.htm; limit_req zone=one burst=5 nodelay;//執行的動作,通過zone名字對應 } }
nodelay 超過的請求不被延遲處理
驗證: ab -n2000 -c 1000 http://127.0.0.1/a.html
[root@localhost html]# pwd /usr/local/nginx/html [root@localhost html]# ll total 12 -rw-r--r--. 1 root root 537 Nov 5 22:24 50x.html -rw-r--r--. 1 root root 4 Nov 6 01:57 a.html -rw-r--r--. 1 root root 612 Nov 5 22:24 index.html
[root@localhost ~]# tailf /usr/local/nginx/logs/access.log
127.0.0.1 - - [06/Nov/2019:02:26:17 -0800] "GET /a.html HTTP/1.0" 503 537 "-" "ApacheBench/2.3" "-"
127.0.0.1 - - [06/Nov/2019:02:26:17 -0800] "GET /a.html HTTP/1.0" 503 537 "-" "ApacheBench/2.3" "-"
127.0.0.1 - - [06/Nov/2019:02:26:17 -0800] "GET /a.html HTTP/1.0" 503 537 "-" "ApacheBench/2.3" "-"
[root@localhost ~]# tailf /usr/local/nginx/logs/error.log 2019/11/06 02:26:17 [error] 27170#0: *4021 limiting requests, excess: 5.910 by zone "one", client: 127.0.0.1, server: localhost, request: "GET /a.html HTTP/1.0", host: "127.0.0.1" 2019/11/06 02:26:17 [error] 27170#0: *4022 limiting requests, excess: 5.910 by zone "one", client: 127.0.0.1, server: localhost, request: "GET /a.html HTTP/1.0", host: "127.0.0.1" 2019/11/06 02:26:17 [error] 27170#0: *4023 limiting requests, excess: 5.910 by zone "one", client: 127.0.0.1, server: localhost, request: "GET /a.html HTTP/1.0", host: "127.0.0.1" 2019/11/06 02:26:17 [error] 27170#0: *4024 limiting requests, excess: 5.910 by zone "one", client: 127.0.0.1, server: localhost, request: "GET /a.html HTTP/1.0", host: "127.0.0.1" 2019/11/06 02:26:17 [error] 27170#0: *4025 limiting requests, excess: 5.910 by zone "one", client: 127.0.0.1, server: localhost, request: "GET /a.html HTTP/1.0", host: "127.0.0.1"
二.限制IP連接數
http { limit_conn_zone $binary_remote_addr zone=addr:10m; //觸發條件 … server { … location /download/ { limit_conn addr 1; // 限制同一時間內1個連接,超出的連接返回503 } } }
使用ab命令進行測試
yum -y install httpd-tools
測試:ab -n 請求數 -c 並發數 http://172.18.47.92:8080/admin
並發數不能大於請求數