Nginx web服務優化 (一)

一、Nginx基本安全優化

a、更改配置文件參數隱藏版本javascript

編輯nginx.conf配置文件增長參數,實現隱藏Nginx版本號的方式以下。在nginx配置文件nginx.conf中的http標籤段內加入 「server_tokens off;」參數,以下:php

http{
……
server_tokens off;
……
}

此參數放置在http標籤內,做用是控制http response header內的web服務版本信息的顯示,以及錯誤信息中web服務版本信息的顯示。css

server_tokens參數的官方說明以下:html

syntax:      server_tokens on | off ;     #此行爲參數語法,on爲開啓狀態,off爲關閉狀態 default:      server_tokens on;           #此行意思是不配置該參數,軟件默認狀況的結果
context:      http,server, location      #此行爲server_tokens參數能夠放置的位置

參數做用:激活或禁止nginx的版本信息顯示在報錯信息和servser的響應首部位置中
Enables or disables emitting of nginx version in error messages and in the "server" response header field

官方資料地址:http://nginx.org/en/docs/http/ngx_http_core_moudule.html前端

b、更改源碼隱藏nginx軟件名及版本號java

第一里程碑:依次修改3個nginx源碼文件node

修改第一個文件爲nginx-1.10.2/src/core/nginx.h,以下:linux

[root@web nginx-1.10.2]# sed -n '13,27p'  src/core/nginx.h
#define NGINX_VERSION "1.10.2"    #修改成想要顯示的版本號,如1.6.2
#define NGINX_VER "nginx/" NGINX_VERSION    #將nginx修改成想要修改的軟件名稱,如Apachenginx

 
 

#ifdef NGX_BUILD
#define NGINX_VER_BUILD NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD NGINX_VER
#endifweb

 
 

#define NGINX_VAR "NGINX"       #將nginx修改成想要修改的軟件名稱,如Apache           
#define NGX_OLDPID_EXT ".oldbin"


#endif /* _NGINX_H_INCLUDED_ */

 

修改第二個文件是nginx-1.10.2/src/http/ngx_http_header_filter_module.c 的49行,須要修改的字符串以下:

[root@web nginx-1.10.2]# grep -n 'Server: nginx' src/http/ngx_http_header_filter_module.c
49:static char ngx_http_server_string[] = "Server: nginx" CRLF;              #把「Server: nginx」替換爲「Server: Apache」

提示:sed替換命令
sed  "49 s#Server: nginx#Server: Apache#" src/http/ngx_http_header_filter_module.c
sed -i "49 s#nginx#Apache#"
src/http/ngx_http_header_filter_module.c

修改第三個文件是 nginx-1.10.2/src/http/ngx_http_special_response.c,對外頁面報錯時,它會控制是否展現敏感信息。

[root@web nginx-1.10.2]# sed -n '21,30p' src/http/ngx_http_special_response.c 
static u_char ngx_http_error_full_tail[] =
"<hr><center>" NGINX_VER "</center>" CRLF       #此行須要修改,修改"<hr><center>" NGINX_VER "(http://www.xxx.com)</center>" CRLF
"</body>" CRLF "</html>" CRLF ; 
static u_char ngx_http_error_tail[] = "<hr><center>nginx</center>" CRLF #此行須要修改,將對外展現的nginx改成Apache
"</body>" CRLF

注:修改後編譯安裝軟件,啓動服務使其生效。

C、更改nginx服務的默認用戶

爲了讓web服務更安全,要儘量地改掉軟件默認的全部配置,包括端口、用戶等,通用其餘軟件服務。

nginx服務啓動後,默認用戶是nobody(編譯安裝時能夠指定建立用戶),查看默認配置文件,以下:

[root@web nginx-1.10.2]# grep "#user" conf/nginx.conf.default 
#user  nobody;

爲了防止黑客使用默認用戶進行攻擊,用戶須要更改爲特殊的用戶,例如www或nginx等等,但用戶必須存在,下面以www用戶爲例進行說明。

第一里程碑:建立用戶

useradd  -s /sbin/nologin -m  www        #無需有登陸權限,只需在系統內容執行任務

id www #檢查建立的用戶

第二里程碑:配置nginx服務,讓其使用建立的用戶www用戶(編譯安裝時已指定用戶,無需作此操做)

將默認的#user nobody;改成如下內容:
user www www
注:若是註釋或不設置上述參數,默認用戶爲nobody用戶,不推薦使用nobody用戶名。
編譯安裝nginx軟件時指定編譯的用戶和組,編譯命令如:
./configure --prefix=/usr/local/nginx-1.10.2 --user=www --group=www --with-http_stub_status_module  --with-http_ssl_module

第三里程碑:檢查更改用戶的效果

從新加載配置後,檢查nginx服務進行的對應用戶,以下:

[root@web nginx-1.10.2]# ps -ef | grep nginx | grep -v grep

二、根據nginx.conf配置文件參數優化nginx服務性能

在高併發、高訪問量的web服務場景,須要事先啓動好更多的nginx進程,以保證快速響應並處理大量併發用戶的請求。

a、優化nginx服務的worker進程個數

0一、優化nginx進程對應nginx服務的配置參數以下:

#配置文件信息
[root@web nginx-1.10.2]# cat conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
……
}

#須要修改的參數:
worker_processes 1;    #指定了nginx要開啓的進程數,結尾的數字就是進程的個數

注:worker_processes參數調整的是nginx服務的worker進程數,nginx有master進程和worker進程之分,Master爲管理員進程,真正接待「顧客」的是worker進程。

0二、優化nginx進程個數的策略

work_processes參數大小的設置最好和網站的用戶數量相關聯。

搭建服務器時,worker進程數最開始的設置能夠等於CPU的核數,且worker進程數要多一些,這樣起始提供服務時就不會出現由於訪問量快速增長而臨時啓動新進程提供服務的問題,縮短了系統的瞬時開銷和提供服務的時間,提高了服務用戶的速度。高流量高併發場合也能夠考慮將進程數提升至CPU核數*2,具體狀況要根據實際的業務來選擇,由於這個參數除了要和CPU核數匹配外,也和硬盤存儲的數據及系統的負載有關,設置爲CPU的核數是一個好的起始配置。

0三、查看web服務器CPU硬件資源信息

下面介紹查看linux服務器CPU總核數的方法。

經過/proc/cpuinfo可查看CPU個數及總核數。查看CPU總核數的示例以下:

[root@web ~]# grep processor /proc/cpuinfo |wc -l
8            #表示爲1顆CPU八核
[root@web ~]# grep processor /proc/cpuinfo

查看CPU總顆數的示例以下:

[root@web ~]# grep 'physical id' /proc/cpuinfo |sort|uniq |wc -l
1       #對physical id去重計數,表示1顆CPU

經過執行top命令,而後按數字1,便可顯示全部CPU核數,以下:

[root@web ~]# top  #按1顯示多核CPU
top - 09:20:02 up 7:04, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 82 total, 1 running, 81 sleeping, 0 stopped, 0 zombie Cpu0 : 0.3%us, 1.0%sy, 0.0%ni, 98.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu1 : 0.1%us, 1.0%sy, 0.0%ni, 98.2%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu2 : 0.3%us, 1.0%sy, 0.0%ni, 98.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu3 : 0.2%us, 1.0%sy, 0.0%ni, 98.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu4 : 0.1%us, 1.0%sy, 0.0%ni, 98.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu5 : 0.1%us, 1.0%sy, 0.0%ni, 98.2%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu6 : 0.3%us, 1.0%sy, 0.0%ni, 98.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu7 : 0.2%us, 1.0%sy, 0.0%ni, 98.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 2493928k total, 485836k used, 2008092k free, 79828k buffers Swap: 1048572k total, 0k used, 1048572k free, 187784k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7 root 20 0 0 0 0 S 0.3 0.0 0:26.20 events/0 1 root 20 0 19356 1528 1228 S 0.0 0.3 0:02.06 init
注:這是單CPU 八核的信息
例如:CPU核數爲8,就配置worker_processes 8

 0四、實操==》修改nginx配置

第一里程碑:檢查nginx.conf配置文件裏的worker_processes數來了解,命令以下:

[root@web conf]# grep worker_processes nginx.conf
worker_processes  1;

第二里程碑:修改配置文件中參數

[root@web conf]# sed -i 's#worker_processes  1#worker_processes  8#g' nginx.conf
[root@web conf]# grep worker_processes nginx.conf worker_processes
8;

第三里程碑:平滑啓動nginx,使修改生效,以下:

[root@web conf]# /usr/local/nginx/sbin/nginx -t         #檢查配置文件是否有錯,養成修改配置文件後檢查的好習慣(修改配置文件須要先備份)
nginx: the configuration file /usr/local/nginx-1.10.2//conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx-1.10.2//conf/nginx.conf test is successful

[root@web02 conf]# /application/nginx/sbin/nginx -s reload    #平滑重啓

第四里程碑:檢查修改後worker進程數量,命令以下:

[root@web conf]# ps -ef | grep nginx | grep -v grep

參考連接:http://nginx.org/en/docs/ngx_core_module.html

b、優化綁定不一樣的nginx進程到不一樣的CPU上

優化不一樣的nginx進程對應不一樣的CPU配置時,八核CPU服務器的參數配置參考以下:

 

[root@web02 conf]# cat nginx.conf
worker_processes  8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000   #此行爲cpu親和力參數,cpumask爲cpu掩碼 events { worker_connections  1024;
}
……

 

worker_cpu_affinity的做用是綁定不一樣的worker進程數到一組CPU上。經過設置bitmask控制進行容許使用的CPU,默認worker進程不會綁定到任何CPU。

示例配置:

worker_processes  4;
worker_cpu_affinity 0001 0010 0100 1000 #綁定每一個工做進程到一個單獨的CPU,而
worker_processes
2; worker_cpu_affinity 0101 1010#綁定第一個工做進程到CPU0/CPU2,第二個工做進程綁定到CPU1/CPU3。第二個例子適用於超線程。 #特殊值auto容許將工做進程自動綁定到可用的CPU: # worker_processes auto; # worker_cpu_affinity auto; 參考連接http://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity

C、nginx事件處理模型優化

nginx的聯機處理機制在不一樣的操做系統會採用不一樣的I/O模型,在linux下,nginx使用epoll的I/O多路複用模型,在freebsd中使用kequeue的I/O多路複用模型,在Solaris中使用/dev/poll方式的I/O多路複用模型,在windows中使用的是icop等等。

要根據系統類型選擇不一樣的時間處理模型,可供使用的選擇有「use[kqueue|rtsig|epoll|/dev/poll|select|poll];」,其中select和poll都是標準的工做模式,kqueue和epoll是高效的工做模式,不一樣的是epoll用在linux平臺上,而kqueue用在BSD系統中。對於linux系統linux 2.6.x的內核,推薦選擇epoll工做模式,這是高性能高併發的設置。

本環境使用centos 6.9,所以將nginx的事件模型調整爲epoll模型。

具體配置參數以下:

events            #events指令是設定nginx的工做模式及鏈接數上限
{
    use epoll;
#use是一個事件模塊指令,用來指定nginx的工做模式。  
}

d、調整nginx單個進程容許的客戶端最大鏈接數

控制鏈接數的參數爲worker_connections,此值要根據具體服務器性能和程序的內存使用量來指定,配置以下:

events  #events指令是設定nginx的工做模式及鏈接數上限
{
worker_connections 2048;
#最大客戶端鏈接數由worker_processes和worker_connections決定,即Max_client=worker_processes*worker_connections。進程的最大鏈接數受linux系統進程的最大打開文件數限制,在執行操做系統命令 「ulimit -Hsh 65535」或配置相應文件後,worker_connections的設置才能生效
}

參考連接:http://nginx.org/en/docs/ngx_core_module.html

e、配置nginx worker進程最大打開文件數

參數配置以下:

worker_rlimit_nofile  65535;
#最大打開文件數限制,執行操做系統命令 「ulimit -HSh 」的結果

f、優化服務器域名的散列表大小

 

在HTTP配置塊中調整server_names_hash_max_size和server_names_hash_bucket_size的值。
server_names_hash_bucket_size的默認值多是32或64,也多是其餘值,這取決於CPU的緩存行的長度。

g、開啓高效文件傳輸模式

 

1、設置參數:sendfile  on;
2、設置參數:tcp_nopush on;

參考連接:http://nginx.org/en/docs/http/ngx_core_module.html#sendfile
        http://nginx.org/en/docs/http/ngx_core_module.html

 

h、優化nginx鏈接參數,調整鏈接超時時間

 

nginx鏈接超時的參數設置:
1、設置參數:keepalive_timeout 60;
2、設置參數tcp_nodelay on;
3、設置參數:client_header_timeout 15;
#用於設置讀取客戶端請求頭數據的超時時間。此處的數值爲15,其單位是秒,爲經驗參考值。 4、設置參數:client_body_timeout 15
#用於設置讀取客戶端請求主題的超時時間,默認值時60.
5、設置參數:send_timeout 25#用於指定響應客戶端的超時時間。這個超時僅限於兩個鏈接活動之間的時間,若是超過這個時間,客戶端沒有任何活動,nginx將會關閉鏈接。

 

i、上傳文件大小的限制(動態應用)

在主配置文件里加入以下參數:

client_max_body_size 8m;     #具體大小根據業務作調整

j、FastCGI相關參數調優(配合PHP引擎動態服務)

FastCGI Cache資料連接:http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache

 

worker_processes  4;
pid        conf/nginx.pid;
events {
    worker_connections  1024;
}
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  65;
    client_header_timeout 15;
    client_body_timeout 15;
    send_timeout 15;
    gzip  on;
    server_tokens off;
  fastcgi_connect_timeout 240; fastcgi_send_timeout 240; fastcgi_read_timeout 240; fastcgi_buffer_size 64k; fastcgi_buffer 4 64k; fastcgi_temp_file_write_size 128k; fastcgi_temp_path /data/ngx_fcgi_tmp; fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 
  keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g;

    server {
        listen       80;
        server_name  localhost;
        access_log  logs/host.access.log  main;
        location / {
            root   html;
            index index.php index.html index.htm;
        }
        }


        location ~ \.php$ {
            root           html;
            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_min_uses 1; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_cache_key http://$host$request_uri;
        }

……

 

k、配置nginx gzip壓縮實現性能優化

目的:節省帶寬、提升訪問速度。

參數介紹及配置:

gzip on   #開啓壓縮功能
gzip_min_length 1k;       #設置容許壓縮的頁面最小字節數,頁面字節數從header頭的Content-Length中獲取。默認值是0,表示無論頁面多大都進行壓縮,建議設置成大於1k.
gzip_buggers   4 16k;      #壓縮緩衝區大小。表示申請4個單位爲16k的內存做爲壓縮結果流緩存,默認值是申請與原始數據大小相同的內存空間來存儲gzip壓縮結果。
gzip_http_version 1.1#壓縮版本(默認1.1,前端爲squid2.5時使用1.0),用於設置識別HTTP協議版本,使用默認便可。
gzip_comp_level 2;   #壓縮比率。用來指定gzip壓縮比,1壓縮比最小,處理速度最快;9壓縮比最大,傳輸速度快,單處理最慢,也比較消耗CPU資源。
gzip_types  text/plain application/x-javascript text/css application/xml;       #用來指定壓縮的類型,「text/html」類型老是會被壓縮,這個就是HTTP原理部分將的媒體類型。
gzip_vary on;    #vary header支持。該選項可讓前端的緩存服務器緩存通過gzip壓縮的頁面。例如用squid緩存通過nginx壓縮的數據。
 #完整配置以下:
gzip  on;
gzip_min_length 1k;
gzip_buffers  4 32k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text/css text/xml  /app/javascripts;
gzip-vary on;

注:不一樣版本的nginx,gzip_types的配置可能會有不一樣。

L、配置nginx expires 緩存實現性能優化

 

 

目的:下降網站的帶寬、節約成本、加快訪問速度、減輕服務器壓力。

a、根據擴展名進行判斷

nginx expires配置詳解(配置在nginx.conf中的server模塊中):
……
server{
……

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
      expires  365d;   當用戶訪問網站URL結尾的文件擴展名爲上述指定類型的圖片時,設置緩存365天。
}

location ~ .*\.(js | css)?$
{
      expires   30d;      #當用戶訪問網站URL結尾的文件擴展名爲js、css類型的元素時,設置緩存30天。
}
……

b、根據URI中的路徑(目錄)進行判斷,添加expires功能範例

 

location ~ ^/ (images|javascript|js|css|flash|media|static)/ {
      expires  360d;  
}

 

c、單個文件添加expires功能範例

 

location ~(robots.txt){
                expires 7d;    #給robots.txt機器人文件設置過去時間,在設置的期間內不記錄404錯誤日誌。
break; }

 

Nginx expires功能缺點及解決方法

當網站被緩存的界面或數據更新了,此時用戶端看到仍是舊的已經緩存的內容,這樣就會影響到用戶體驗,解決方法以下:

  • 對於常常須要變更的圖片等文件,能夠縮短對象緩存時間。例:谷歌的首頁圖片常常根據不一樣的日期換成一些節日圖,因此能夠將這個圖片設置爲緩存期1天。
  • 當網站改版或更新時,能夠在服務器將緩存的對象更名(網站代碼程序)
  1.  對於網站的圖片、附件,通常不會被用戶直接修改,用戶層面上的修改圖片,實際上個是從新傳到服務器,雖然內容同樣,可是會產生一個新的圖片名稱。
  2. 網站改版升級會修改js、css等樣式文件,若改版時對這些樣式文件中的元素改了名,會使得前端的CDN及用戶端須要從新緩存內容。

 

企業網站緩存日期曾經的案例參考:

若企業的業務和網站訪問量不一樣,那麼網站的緩存時間設置也是不一樣,以下企業所用的緩存日期:

  • 51CTO:1周
  • 新浪:15天
  • 京東:25年
  • 淘寶:10年
相關文章
相關標籤/搜索