企業級Nginx Web服務優化

nginx基本安全優化

隱藏版本號

  • 修改nginx.conf的http標籤
http {
.......
server_tokens off ;
.......
}
  • 重啓nginx
nginx -s reload
  • 檢查
[root@nginx1 conf]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx    #版本號已消失
Date: Mon, 24 Jun 2019 06:09:30 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 06 May 2019 07:58:22 GMT
Connection: keep-alive
ETag: "5ccfe91e-264"
Accept-Ranges: bytes

修改軟件名

在這裏插入圖片描述
這裏需要修改nginx的3個源碼文件

  • 修改nginx-1.6.3/src/core/nginx.h
    在這裏插入圖片描述
#define NGINX_VER          "nginx/" NGINX_VERSION 將這裏的nginx修改爲想要的軟件名字

#define NGINX_VAR          "NGINX"       #將這裏的NGINX修改爲想要 的軟件名字
#define NGX_OLDPID_EXT     ".oldbin"
  • 修改結果如下
#define NGINX_VER          "test/" NGINX_VERSION   已修改爲自己想要的結果

#define NGINX_VAR          "test"  已修改爲自己想要的結果
#define NGX_OLDPID_EXT     ".oldbin"
  • 修改nginx-1.6.3/src/http/ngx_http_header_filter_module.c 的49行
    在這裏插入圖片描述
static char ngx_http_server_string[] = "Server: nginx" CRLF;#將nginx修改爲想要的名字
  • 修改後的結果
static char ngx_http_server_string[] = "Server: test" CRLF;#已修改爲自己想要的結果
  • 修改nginx-1.6.3/src/http/ngx_http_special_response.c
    在這裏插入圖片描述
static u_char ngx_http_error_tail[] =
"<hr><center>nginx</center>" CRLF 
"</body>" CRLF
 "</html>" CRLF
  • 修改後的結果
static u_char ngx_http_error_tail[] =
"<hr><center>test</center>" CRLF
"</body>" CRLF
"</html>" CRLF
  • 重新編譯nginx
./configure  --prefix=/application/nginx --user=nginx --group=nginx
make&&make install

在這裏插入圖片描述
在這裏插入圖片描述

更改nginx默認用戶

在編譯的時候可以利用–user和–group來指定用戶

 ./configure --user=nginx --group=nginx --prefix=/application/nginx
  • 已經編譯後修改默認用戶
useradd nginx_test -s /sbin/nologin -M 
  • 編輯nginx.conf
    在這裏插入圖片描述
  • 重啓nginx服務
    在這裏插入圖片描述發現默認用戶已經改變
    在這裏插入圖片描述

優化nginx服務性能

優化nginx服務的worker進程數

在高併發、高訪問量的web服務場景中,需要啓動好更多的nginx進程,以保證快速響應處理大量併發用戶的請求。
好比飯店開業需要招聘服務員,如果招聘的人數很少,但是客流量很大,就會出現接待顧客不及時的情況,導致顧客喫飯體驗差。如果招聘人數過多,客流量缺很少,就會出現服務員很閒,沒事幹的情況,這樣也會導致飯店的成本升高。因此在開業前期需要對客流量進行預估,然後根據估值調整到最佳的人數。
nginx的worker進程也是如此,在上線前期做出合理的預測可以使用戶有一個好的體驗。

  • 優化nginx進程設置
worker_processes 1  #<< 指定了nginx要開啓的進程數,結尾的數字就是要開啓進程的個數

nginx的worker_processes優化與cpu的核數相關

  • 查看cpu的核數
grep -c /proc/cpuinfo | wc -l

在這裏插入圖片描述
表示爲1顆cpu一核

  • 查看cpu總顆數
grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l

在這裏插入圖片描述
對physical id去重,表示一顆cpu
將worker_processes數修改爲與cpu的核數一致

  • 重啓查看
    在這裏插入圖片描述

worker_processes爲定義worker進程的數量,建議設置爲cpu的核數或核數*2的進程數,具體情況要根據實際的業務來選擇,因爲這個參數,除了要和cpu核數匹配外,和硬盤存儲的數據以及系統的負載也會有關,設置爲cpu的個數或是核數是一個好的起始配置

優化綁定不同的nginx進程到不同的cpu上

默認情況下nginx的多個進程有可能跑在某一個或某一刻cpu上,導致nginx進程使用硬件的資源不均,優化的目的是儘可能地分配不同的nginx進程給不同的cpu處理,達到充分利用硬件的多cpu多核資源的目的。
這裏以四核cpu爲例,參數配置如下:

  • 四核cpu開啓四個進程
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;  #<< worker_cpu_affinity就是配置nginx進程cpu親和力的參數,即把不同的進程分給cpu不同的內核處理。這裏的0001 0010 0100 1000是掩碼,分別代表1、2、3、4核,由於worker_processes進程數爲4,因此,上述配置會把每個進程分配給cpu的某一核處理,默認情況下不會綁定任何cpu。
  • 四核cpu開啓兩個進程
worker_processes 4;
worker_cpu_affinity 0101 1010;
  • 八核cpu開啓8個進程
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

worker_processes最多開啓8個,8個以上性能提升不會再提升了,而且穩定性變得更低,所以8個進程夠用了。配置完畢後,重啓nginx .

nginx事件處理模型優化

nginx的連接處理機制在於不同的操作系統會採用不同的I/O模型,在linux下,nginx使用epoll的I/O多路複用模型,在freebed中使用kqueue的I/O多路複用模型,在Solaris中使用/dev/poll方式的I/O多路複用模型,在Windows使用的是icop,等等。
要根據系統類型選擇不同的事件處理模型,可供使用的選擇有"use [kqueue|rtsig|epoll|/dev/poll|select|poll]"。

  • 以epoll爲例
events 
{
use epoll;
 #<< use是事件模塊指令,用來指定nginx的工作模式。nginx支持的工作模式有select、epoll、poll、
 kqueue、rtsig和/dev/poll。其中select和poll是標準的工作模式,kqueue和epoll是高效的工作模式,
 不同的是epoll用在linux平臺上,而kqueue用在BSD系統中。對於Linux系統Linux2.6+的內核,推薦
 選擇使用epoll工作模式,這是高性能高併發的設置。
}

調整nginx單個進程客戶端最大連接數

worker_connections的值要根據具體服務器的性能和程序的內存使用量來指定(一個程序啓動時使用的內存)

events {
worker_connections 20480;
#<< worker_connections,用於定義nginx每個進程的最大連接數,默認是1024。最大客戶端連接數
是由worker_connections和worker_process共同決定的,即max_client=worker_processes*worker_c
onnections。進程的最大連接數受Linux系統進程的最大打開文件數限制,在執行操作系統命令
"ulimit -HSn 65535"或配置相應文件後worker_conncetios才能生效
}

開啓高效文件傳輸模式

sendfile參數用於開啓文件的高效傳輸模式。同時將tcp_nopush和tcp_nodelay兩個指令設置問on,可防止網絡及磁盤I/O阻塞,提升nginx工作效率。

http {
sendfile on;
}
  • 設置tcp_nopush
http{
tcp_nopush on;
}

tcp_nopush需要sendfile開啓才能使用,tcp_nodelay也是

優化nginx連接超時時間

  • 連接超時的作用
  1. 設置將無用的連接儘快超時,可以保護服務器的系統資源
  2. 當連接很多時,及時斷掉那些已經建立好的但又長時間不做事的連接,以減少佔用服務器資源,因爲服務器維護連接也是消耗資源的
  3. 有時黑客或惡意用戶攻擊網站,就會不斷地和服務器建立多個連接,消耗連接數,但是什麼也不幹,只是持續建立連接,這樣就會大量消耗服務器的資源,此時就應該及時斷掉這些惡意佔用資源的連接。
  4. lnmp環境中,如果用戶請求了動態服務,則nginx就會建立連接請求fastcgi服務以及MySQL服務,此時nginx連接就要設置超時時間,在用戶容忍的時間內返回數據,或者再多等一會後端服務返回數據,具體時間要根據具體業務分析
  • 超時連接設置
http {
keepalive_timeout 60;
}

keepalive可以是客戶端到服務器端已經建立的連接一直工作不退出,當服務器有持續請求時,keepalive會使用正在建立的連接提供服務,從而避免服務器重新建立新連接處理請求

  • 設置客戶端連接超時(client_header_timeout)

用於設置讀取客戶端請求頭數據的超時時間,此處的數值15s。

http {
client_header_timeout 15;
}

設置讀取客戶端請求頭數據的超時時間。如果超過這個時間,客戶端還沒有發送完整的header數據,服務器將返回"Request time out (408)"錯誤。

  • 設置讀取客戶端請求主體超時時間(client_body_timeout)

用於設置讀取客戶端請求主體的超時時間,默認是60s。

http {
client_body_timeout 15;
}

設置讀取客戶端請求主體的超時時間。這個超時僅僅爲兩次成功的讀取操作之間的一個超時,非請求整個主體數據的超時時間,如果在這個超時時間內,客戶端沒有發送任何數據,nginx將返回"Request time out(408)"錯誤。

  • 設置響應超時時間(send_timeout)

用於指定響應客戶端的超時時間。這個超時僅限於兩個連接活動之間的時間,如果超過這個時間,客戶端沒有任何活動,nginx將會關閉連接,默認60s。

http {
send_time 25;
}

設置服務器端傳送http響應信息到客戶端的超時時間,這個超時時間僅僅爲兩次握手後的一個超時,非請求整個響應數據的超時時間,如果在這個時間內,客戶端沒有接收任何數據,連接將被關閉。

限制用戶上傳文件大小

http {
client_max_body_size 8m ;
}

設置最大的允許客戶端請求主體大小,在請求頭域有"Content-Lenth",如果超過了此配置值,客戶端會收到413錯誤,意思是請求的條目過大,有可能瀏覽器不能正確的顯示這個錯誤,設置爲0表示禁止檢查客戶端請求主體大小。

fastcgi相關參數調優

nginx fastcgi相關參數 說明
fastcgi_connect_timeout 表示nginx服務器和後端fastcgi服務器連接的超時時間,默認爲60s,這個參數通常不要超過75s,因爲建立的連接越多消耗的資源就越多。
fastcgi_send_timeout 設置nginx允許fastcgi服務端返回數據的超時時間,即在規定時間之內後端服務器必須傳完所有的數據,否則nginx將斷開連接,默認值爲60s。
fastcgi_read_timeout 設置nginx從fastcgi服務端讀取響應信息的超時時間。表示連接建立成功後,nginx等待後端服務器響應的時間,是nginx已經進入後端的排隊之中等候處理的時間。
fastcgi_buffer_size 這是nginx fastcgi的緩衝區大小參數,設定用來讀取從fastcgi服務端收到的第一部分響應信息的緩衝區大小,這裏的第一部分通常會包含一個小的響應頭部,默認情況這個參數的大小是由fastcgi_buffer指定的一個緩衝區大小。
fastcgi_buffers 設定用來讀取從fastcgi服務端收到的響應信息的緩衝區大小以及緩衝區數量。默認值fastcgi_buffers 8 4k|8k;指定本地需要用多少和多大的緩衝區來緩衝fastcgi的應答請求。如果一個php腳本所產生的頁面大小爲256KB,那麼會爲其分配4個64KB的緩衝區來緩存;如果頁面大小大於256KB,那麼大於256KB的部分會緩存到fastcgi_temp指定的路徑中,但是這並不是好的辦法,因爲內存中的數據處理速度快於硬盤。一般這個值應該爲站點中PHP腳本所產生的頁面大小的中間值,如果站點大部分腳本所產生的頁面大小爲256KB,那麼可以把這個值設置爲"16 16KB"、“4 64KB”。
fastcgi_busy_buffers_size 用於設置系統很忙時可以使用的fastcgi_buffers大小,官方推薦的大小爲fastcgi_buffers *2。默認值fastcgi_busy_buffers_size 8K|16K;
fastcgi_temp_file_write_size fastcgi臨時文件的大小,可設置128-256K
fastcgi_cache cache-name 表示開啓fastcgi緩存併爲其命名。開啓緩存非常有用,可以有效降低CPU的負載,並防止502錯誤的發生,但是開啓也會引起其他問題,要根據具體情況選擇。
fastcgi_cache_min_uses 示例:fastcgi_cache_min_uses 1;設置請求幾次之後響應將被緩存。
fastcgi_cache_use_stale 示例:fastcgi_cache_use_stale error timeout invalid_header http_500,定義哪些情況下使用過期緩存
fastcgi_cache_valid 示例:fastcgi_cache_valid 200 301 1h;用來指定應答代碼的緩存時間,示例中的值表示將200和302應答緩存一個小時;示例:fastcgi_cache_valid 301 1d,表示將301應答緩存1天;示例:fastcgi_cahce_valid any 1m,表示將其他應答緩存1分鐘。
  • 配置示例
http
{
 fastcgi_connect_timeout 240;
 fastcgi_send_timeout 240;
 fastcgi_read_timeout 240;
 fastcgi_buffer_size 64k;
 fastcgi_buffers 4 64k;
 fastcgi_busy_buffers_size 128k;
 fastcgi_temp_file_write_size 128k;
 #fastcgi_temp_path /tmp/ngx_fcgi_tmp;
 fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2;
 keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g;
}

location ~.*\.(php|php5)?$ 
{
 fastcgi_pass 127.0.0.1:9000;
 fastcgi_index index.php;
 include fastcgi.conf;
 fastcgi_cache ngx_fcgi_cache;
 fastcgi_cache_valid 200 302 1h;
 fastcgi_cache_valid 301 1d;
 fastcgi_cache_valid any 1m;
 fastcgi_cache_use_stale error timeout invalid_header http_500;
 fastcgi_cache_key http://$host$request uri;
}

nginx gzip壓縮優化

  • gzip壓縮功能簡介
    nginx gzip壓縮模塊提供了壓縮文件內容的功能,用戶請求的內容在發送出用戶客戶端之前,nginx服務器會根據一些具體的策略實施壓縮,以節約網站出口帶寬,同時加快了數據傳輸效率,提升了用戶訪問體驗。

  • 需要與不需要壓縮的對象

  1. 純文本內容壓縮比很高,因此,純文本的內容最好壓縮,例如:html、js、css、xml、shtml等格式的文件。
  2. 被壓縮的純文本文件必須大於1KB,由於壓縮算法的特殊原因,極小的文件壓縮後可能變大。
  3. 圖片、視頻(流媒體)等文件儘量不壓縮,因爲這些文件大多多時經過壓縮的,如果再壓縮很可能不會減小,或者有可能增大,而在壓縮的時候還會消耗大量的CPU、內存資源。
  • 參數介紹及配置說明

nginx 的gzip壓縮功能依賴於ngx_http_gzip_module模塊,默認已安裝。
對應的壓縮參數說明如下:

gzip on;
# 開啓壓縮功能
gzip_min_length 1k;
# 設置允許壓縮的頁面最小字節數,頁面字節數從header頭的content-Length中獲取。默認值是0,表示不管頁面多大都進行壓縮。
gzip buffers 4 16k;
# 壓縮緩衝區大小。表示申請4個單位爲16k的內存作爲壓縮結果流緩存,默認值是申請與原始數據大小相同的內存空間來存儲gzip壓縮結果。
gzip_http_version 1.1;
# 壓縮版本用於設置識別http協議版本,默認是1.1目前大部分瀏覽器已經支持gzip解壓,使用默認即可。
gzip_com_level 2;
# 壓縮比率。用來指定壓縮比,1壓縮比最小,處理速度最快;9壓縮比最大,傳輸速度最快,但是處理速度最慢,也比較消耗CPU資源。
 gzip_types text/css text/xml application/javascript;
# 用來指定壓縮類型
gzip_vary on;
# vary header支持。該選項可以讓前端的緩存服務器緩存經過gzip壓縮的頁面,例如用squid緩存經過nginx壓縮的數據。
  • 推薦配置如下
http {
 gzip on;
 gzip_min_length 1k;
 gzip_buffers 4 32k;
 gzip_http_version 1.1;
 gzip_types text/css text/xml application/javascript;
 gzip_vary on;
 }

不同的nginx版本中,gzip_types的配置可能會有不同,上述配置示例適合nginx-1.6.3。對應的文件類型需要查看安裝目錄下的mine.types文件

圖片防盜鏈

常見防盜鏈解決方案的基本原理

  • 根據http referer

在HTTP協議中,有一個表頭叫referer,使用URL格式來表示是哪裏的鏈接用了當前網頁的資源。通過referer可以檢測目標訪問的來源網頁,如果是資源文件,可以跟蹤到顯示他的網頁地址,一旦檢測出來源不是本站,馬上進行阻止或返回指定頁面。
HTTP Referer是header頭的一部分,當瀏覽器向web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器藉此可以獲得一些信息用於處理。Apache、NGINX、lightHTTP三者都支持根據http referer實現防盜鏈referer是目前網站圖片、附件、html等最常用的防盜鏈手段。

  • 修改配置文件
server {
  location ~*^.+\.(jpg|png|swf|rar)${
  valid_referers none blocked *.test.com test.com;
  if ($invalid_referer) {
  rewdrite ^/http://www.error.com/images/error.jgpg;
  }
  root html/www;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章