nginx Fundamentals: High Performance Servers
nginx 是什么就不必廢話了均澳,高性能web服務(wù)器楚午。下面還是一步步介紹:
安裝
查看當(dāng)前系統(tǒng)的信息:cat /etc/lsb-release
可以使用 apt-get install nginx 就可以按照默認(rèn)的設(shè)定安裝nginx
對(duì)于centos系統(tǒng)止后,可能不可以使用yum install nginx安裝徐鹤,會(huì)報(bào)沒(méi)有nginx的源听绳,這時(shí)候颂碘,就需要運(yùn)行:yum install epel-release 安裝所需要的源。然后再使用yum install nginx安裝椅挣。
查看nginx所在的目錄:/etc/nginx
查看nginx的服務(wù)運(yùn)行狀態(tài):service nginx status/start/stop/restart/reload
使用源代碼編譯安裝:
- 可能系統(tǒng)需要先update头岔,然后安裝build-essential。
- 安裝可能需要的依賴: libpcre3 libpcre3-dev libpcrecpp0v5 libssl-dev zlib1g-dev
其中的pcre包是regex相關(guān)的鼠证,用于nginx的配置峡竣;ssl相關(guān)用于ssl或者h(yuǎn)ttps,zlib相關(guān)用于壓縮靜態(tài)資源量九。 - 在“build nginx from source”的網(wǎng)頁(yè)上(wiki.nginx.org)打開compile-time option頁(yè)面适掰,就可以看到相關(guān)的命令行參數(shù)信息,我們使用如下所示的配置方式:
./configure
--sbin-path=/usr/bin/nginx
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--with-debug
--with-pcre
--with-http_ssl_module
或者使用沒(méi)有空行的版本:
./configure --sbin-path=/usr/bin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-debug --with-pcre --with-http_ssl_module
點(diǎn)擊 modules荠列,查看上面命令行最后一個(gè)參數(shù)的信息类浪。
- configure完成后,運(yùn)行make肌似,再make install费就。
配置服務(wù)
如果我們直接輸入service nginx start,可能系統(tǒng)不能識(shí)別
將上面的github中的代碼下載到/etc/init.d/目錄下川队,命名為nginx力细,然后使用chmod給該文件加上可執(zhí)行權(quán)限,最后固额,使用命令:
update-rc.d -f nginx defaults 就可以使用service查看nginx的狀態(tài)了
但是眠蚂,此時(shí)我們輸入 service nginx status, 會(huì)報(bào)錯(cuò): you don't have the permission to execute nginx. 這是因?yàn)槲覀儧](méi)有按照默認(rèn)的配置安裝nginx,解決的辦法就是查看上面的github頁(yè)面斗躏,里面有寫:nginx是使用/etc/default/nginx里面的配置來(lái)作為 覆蓋 所有配置的默認(rèn)選項(xiàng)逝慧。
echo "NGINX_CONF_FILE=/etc/nginx/nginx.conf" > /etc/default/nginx
echo "DAEMON=/usr/bin/nginx" >> /etc/default/nginx
這樣,我們就可以使用service nginx status查看狀態(tài)了。
配置nginx
先看配置文件馋艺;一共有倆術(shù)語(yǔ): contexts 和 directives栅干。
context:類似與創(chuàng)建一個(gè)scope,server/http之類的context
directives:鍵值對(duì)
創(chuàng)建一個(gè)虛擬主機(jī)(virtual host)
首先捐祠,創(chuàng)建一個(gè)靜態(tài)網(wǎng)站放在/sites/bootstrap 目錄下,然后修改/etc/nginx/nginx.conf桑李,得到一下內(nèi)容:
events {}
http {
server {
listen 80:
server_name 106.187.89.216;
root /sites/bootstrap;
}
}
此時(shí)發(fā)現(xiàn)nginx 可能沒(méi)有發(fā)送一個(gè) mind type(踱蛀?)想要驗(yàn)證我們的想法,可以使用一下命令:
curl -I http://<IPaddress>/css/bootstrap.css
可以看到content-type是text/plain
如果查看一下圖片贵白,使用一下命令:
curl -I http://<ipaddress>/tile.png
得到的content-type同樣是text/plain率拒,這就需要修改配置文件:
events {}
http {
include mime.types
server {
listen 80:
server_name 106.187.89.216;
root /sites/bootstrap;
}
}
如果使用命令 head /etc/nginx/mime.types,可以看到mime.types所支持的類型禁荒。
location blocks
如果訪問(wèn)了不存在的url猬膨,nginx可以按照如下所示的方式定義
events {}
http {
include mime.types
server {
listen 80:
server_name 106.187.89.216;
root /sites/bootstrap;
## matches any prefix
# - /greet*
# - /greeting
# - /greet/something
location /greet {
return 200 'hello from nginx locations';
}
# exact match
location = /greet {
return 200 * "hello from nginx exact match location block!"
}
# regex match - case sensitive
location ~ /greet[0-9] {
return 200 * "hello from nginx case sensitive regex match location block!"
}
# regex match - case insensitive
location *~ /greet[0-9] {
return 200 * "hello from nginx case insensitive regex match location block!"
}
# prefix preferential match
# same as location /greet, but more important than regex match
location ^~ /greet[0-9] {
return 200 * "hello from nginx match with preference over regex match.. location block!"
}
}
}
注意匹配順序:
1. = exact match
2. ^~ preferential prefix
3. ~ & *~ regex match
4. no modifier prefix match no modifier
還有一個(gè)特性是動(dòng)態(tài)加載文件:假設(shè)我們?cè)?sites目錄下面創(chuàng)建一個(gè)/download目錄,里面放一些圖片和文本文件呛伴〔眨可以用以下配置文件:
events {}
http {
include mime.types
server {
listen 80:
server_name 106.187.89.216;
root /sites/bootstrap;
location /downloads {
root /sites;
try_files $uri = 404
}
}
}
非常好,現(xiàn)在我們也看到了nginx配置文件中的第一個(gè)變量热康。
logging
已經(jīng)在配置的一開始就設(shè)置了將日志信息輸出的位置沛申,當(dāng)然,也可以制定某些特定錯(cuò)誤的位置:
events {}
http {
include mime.types
server {
listen 80:
server_name 106.187.89.216;
root /sites/bootstrap;
location /downloads {
error_log /var/log/nginx/download.error.log debug;
root /sites;
try_files $uri = 404
}
}
}
或者姐军,可以關(guān)閉access log或者 error log:
events {}
http {
include mime.types
server {
listen 80:
server_name 106.187.89.216;
root /sites/bootstrap;
location /downloads {
error_log off;
access_log off;
root /sites;
try_files $uri = 404
}
}
}
配置文件的定義:
# array type directive
access_log logs/access.log;
access_log logs/access_notice.log notice;
http {
include mime.types;
#stardard directive
gzip on;
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /home {
rewrite ^ /index.html;
}
location /downloads {
# standard directive
gzip off;
$ array type directive
access_log logs/access_downloads.log main;
$ try files directive
try_files $uri =404;
}
}
}
關(guān)于這個(gè)uri的詳細(xì)內(nèi)容铁材,可以參考http://nginx.org/en/docs/varindex.html
上述的所有內(nèi)容,基本上就是隨便哪個(gè)編程語(yǔ)言中的scope的套路奕锌。
配置動(dòng)態(tài)語(yǔ)言的后端
user www-data www-data;
events {}
http {
include /etc/nginx/mime.types
server {
listen 80;
server_name localhost;
root /sites/wordpress
index index.php index.html
location / {
try_files $uri $uri/ /index.php?$args;
}
# pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php${
include fastcgi_params;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
}
對(duì)于wordpress著觉,進(jìn)入/etc/php5/fpm/pool.d/www.conf, 修改33行的listen ,將其值指向 127.0.0.1:9000,然后重啟nginx惊暴,php5-fpm饼丘,,就可以在網(wǎng)頁(yè)上看到想要的結(jié)果缴守,按照網(wǎng)頁(yè)的要求葬毫,一步步配置數(shù)據(jù)庫(kù)。
配置nginx的workers和其他directives
user www-data www-data;
# how many worker threads to run;
# auto set it to the number of cpu cores available in the system and offers the best
# performance, don't set it higher than the number of cpu cores if changing this parameter
worker_processes auto;
# maximum file descriptors that can be opened per process this should be just > worker connections
worker_rlimit_nofile 1035;
pid /var/run/nginx.pid;
events {
worker_connections 1024; #最大打開時(shí)數(shù)量的文件描述符
multi_accept on; # 總是異步接受新的連接屡穗,或者off將設(shè)定為接受
use epoll;
}
http {
# basic settings
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
types_hash_max_size 2048;
# enable open file cache
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# configure buffer size
client_body_buffer_size 16k;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
#configure timeout
client_body_timeout 12;
client_header_timeout 12;
# sue a higher keepalive timeout to reduce the need for repeated handshakes
keepalive_timeout 300;
send_timeout 10;
# hide nginx version information.
server_token off;
# mime types
include /etc/nginx/mime.types
# add extra mime types
types {
application/x-httpd-php .html;
}
default type application/octet-stream;
access_log off;
# access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# gzip settings
gzip on;
gzip_ disable "msie6"
gzip_vary on;
gzip_proxied any;
gzip_comp_level 2;
gzip_min_length 256;
gzip_buffers 4 16k;
gzip_http_version 1.1;
# turn on gzip for all content types that should benefit from it.
gzip_types application/ecmascript;
gzip_types application/javascript;
gzip_types application/json;
gzip_types application/pdf;
gzip_types application/postscript;
gzip_types application/x-javascript;
gzip_types image/svg+xml;
gzip_types text/css;
gzip_types text/csv;
gzip_types text/javascript;
gzip_types text/plain;
gzip_types text/xml;
# enable fastcgi caching
fastcgi_cache_path /tmp/nginx-cache levels=1:2 keys_zone=WORDPRESS:50m inactive=3d;
fastcgi_cache_key "$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set_Cookie;
#######################################################################################
# upstream to abstract backend connections for php.
#######################################################################################
upstream php {
server unix:/var/run/php-fpm.sock;
}
#
# rewrite requests for http://youdomain.ext to http://yourdomain.ext
#
server {
listen 80;
server_name {{host_domain}};
return 301 https://{{host_domain}}$request_uri
}
# https server
server {
listen 443 ssl spdy;
server_name {{ host_domain }};
index index.php index.html index.htm;
ssl_certificate {{ directory }}{{ sslcertificatechainfile }};
ssl_certificate_key {{ directory }}{{ sslcertificatekeyfile }};
ssl_prefer_server_ciphers On;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# optimize SSL by caching session parameters for 10 minutes. this cuts down on the number of expensive SSL handshakes. the handshake is the most CPU-intensive operation, and by default it is re-negotiated on every new/parallel connections by enabling a cache (of type "shared between all Nginx workers") we tell the client to re-use the already negotiated further optimization can be archieve by raising keepalive_timeout, but that shouldn't be done unless you serve primary.
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 24h;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384;ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256
# SSL buffer size was added in 1.5.9
ssl_buffer_size 1400;
# enable OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=60s;
resolver_timeout 5s;
# prevent mobile providers modding site
add_header "cache-Control" "no-transform";
# the X-Frame-Options header indicates whether a browser should be allowed
# to render a page within a frame or iframe.
add_header X-Frame-Options SAMEORIGIN;
# enable HSTS
add_header Strict-Transport-Security "max-age=3153600;";
# inform brwowser of SPDY availability
add_header Alternative-Protocol 443:npn-spdy/3;
# adjust connection keepalive for spdy clients:
spdy_keepalive_timeout 300; # up from 180 secs default
# enable spdy header compressing
spdy_headers_comp 6;
}
}
在linux環(huán)境下贴捡,可以使用 nproc 查看當(dāng)前的cpu 核心的數(shù)量, 使用 lscpu 將展示更多關(guān)于當(dāng)前系統(tǒng)cpu的信息村砂。
注意烂斋,worker_processes 和 worker_connections 的乘法作為當(dāng)前系統(tǒng)所能支持的最大數(shù)量的連接,但是考慮到每個(gè)瀏覽器可能同時(shí)簡(jiǎn)歷多個(gè)連接,所以所能支持的數(shù)量是這個(gè)數(shù)值的一半甚至四分之一.
可以使用ulimit -n 這個(gè)命令查看 Linux系統(tǒng)里打開文件描述符的最大值
dynamic modules
在nginx的安裝目錄汛骂,運(yùn)行 ./configure --help | grep dynamic 查看那些可以使用dynamic module配置的選項(xiàng)罕模,現(xiàn)在我們選中:
./configure --with-http_image_filter_module=dynamic
直接運(yùn)行,會(huì)報(bào)錯(cuò)帘瞭,說(shuō)是系統(tǒng)沒(méi)有安裝GD包淑掌,下面我們使用如下所示的命令安裝:apt install libgd2-xpm-dev,然后沒(méi)有任何錯(cuò)誤的運(yùn)行:./configure --with-http_image_filter_module=dynamic & make & make install蝶念。
然后切換到nginx 的配置文件所在的位置:/usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location = /img/logo.png {
image_filter resize 300 300;
}
}
}
以上為默認(rèn)的nginx 的配置文件抛腕,但是加上了圖片顯示的配置信息,重新加載 nginx媒殉,會(huì)報(bào)錯(cuò):unknown directive 'image_filter' 這是因?yàn)樵撃K沒(méi)有被正確的加載担敌。
此時(shí),如果查看/usr/local/nginx/modules, 會(huì)發(fā)現(xiàn)里面有 ngx_http_image_filter_module.so 文件廷蓉,因此全封,就需要對(duì)于配置文件作出一下的修改:
load_module "modules/ngx_http_image_filter_module.so"
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location = /img/logo.png {
image_filter resize 300 300;
}
}
}
重啟nginx,這次沒(méi)有報(bào)錯(cuò)桃犬,然后重新加載圖片刹悴,可以看到圖片的尺寸已經(jīng)被修改為300*300.
nginx的 location字段的匹配優(yōu)先級(jí):
- exact
- preferential prefix
- regex
- prefix
一下是網(wǎng)上找到的一段文字,慚愧疫萤,學(xué)的時(shí)候沒(méi)有關(guān)注到這個(gè)點(diǎn):
location表達(dá)式類型
~ 表示執(zhí)行一個(gè)正則匹配颂跨,區(qū)分大小寫
~* 表示執(zhí)行一個(gè)正則匹配,不區(qū)分大小寫
^~ 表示普通字符匹配扯饶。使用前綴匹配恒削。如果匹配成功,則不再匹配其他location尾序。
= 進(jìn)行普通字符精確匹配钓丰。也就是完全匹配。
@ 它定義一個(gè)命名的 location每币,使用在內(nèi)部定向時(shí)携丁,例如 error_page, try_files
location優(yōu)先級(jí)說(shuō)明
在nginx的location和配置中l(wèi)ocation的順序沒(méi)有太大關(guān)系。正location表達(dá)式的類型有關(guān)兰怠。相同類型的表達(dá)式梦鉴,字符串長(zhǎng)的會(huì)優(yōu)先匹配。
以下是按優(yōu)先級(jí)排列說(shuō)明:
等號(hào)類型(=)的優(yōu)先級(jí)最高揭保。一旦匹配成功肥橙,則不再查找其他匹配項(xiàng)。
^~類型表達(dá)式秸侣。一旦匹配成功存筏,則不再查找其他匹配項(xiàng)宠互。
正則表達(dá)式類型(~ ~*)的優(yōu)先級(jí)次之。如果有多個(gè)location的正則能匹配的話椭坚,則使用正則表達(dá)式最長(zhǎng)的那個(gè)予跌。
常規(guī)字符串匹配類型。按前綴匹配善茎。
location優(yōu)先級(jí)示例
配置項(xiàng)如下:
location = / {
# 僅僅匹配請(qǐng)求 /
[ configuration A ]
}
location / {
# 匹配所有以 / 開頭的請(qǐng)求券册。
# 但是如果有更長(zhǎng)的同類型的表達(dá)式,則選擇更長(zhǎng)的表達(dá)式垂涯。
# 如果有正則表達(dá)式可以匹配汁掠,則優(yōu)先匹配正則表達(dá)式。
[ configuration B ]
}
location /documents/ {
# 匹配所有以 /documents/ 開頭的請(qǐng)求集币。
# 但是如果有更長(zhǎng)的同類型的表達(dá)式,則選擇更長(zhǎng)的表達(dá)式翠忠。
# 如果有正則表達(dá)式可以匹配鞠苟,則優(yōu)先匹配正則表達(dá)式。
[ configuration C ]
}
location ^~ /images/ {
# 匹配所有以 /images/ 開頭的表達(dá)式秽之,如果匹配成功当娱,則停止匹配查找。
# 所以考榨,即便有符合的正則表達(dá)式location跨细,也不會(huì)被使用
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif jpg jpeg結(jié)尾的請(qǐng)求。
# 但是 以 /images/開頭的請(qǐng)求河质,將使用 Configuration D
[ configuration E ]
}
請(qǐng)求匹配示例
/ -> configuration A
/index.html -> configuration B
/documents/document.html -> configuration C
/images/1.gif -> configuration D
/documents/1.jpg -> configuration E
注意冀惭,以上的匹配和在配置文件中定義的順序無(wú)關(guān)。
提問(wèn):那種類型的directive 可以在同一個(gè)上下文中使用多次掀鹅?
Array directive like the logging directive can be applied multiple times within the same context to specify multiple values. For example you could specify 3 different access logs by using the access_log directive with 3 different values.
nginx可以和后端交互使用哪兩種方法散休?TCP port和unix socket
Expires header
將那些不長(zhǎng)變更的數(shù)據(jù)加上緩存:
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {# <- 主要查看這一段
assess_log off;
expires 1M; # 或者 30d;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
}
重啟之后乐尊,可以查看到相關(guān)擴(kuò)展名的文件戚丸,其已經(jīng)被cached,而且也可以看到expired date的設(shè)定扔嵌。
Gzip
我們想要查看某個(gè)文件是否支持GZip的方式限府,可以使用如下所示的命令查看:
curl -I -H 'Accept-Encoding: gzip, deflate' http://<ipaddress>/wp-content/theme/twentyfifteen/style.css
似乎,沒(méi)有關(guān)于gzip的任何信息痢缎。下面重新編輯configure 文件
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
# Gzip configuration
gzip on;
gzip_min_length 100;
gzip_comp_level 3;
gzip_types text/plain
gzip_types text/css
gzip_types text/javascript
gzip_disable "msie6";
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {# <- 主要查看這一段
assess_log off;
expires 1M; # 或者 30d胁勺;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
}
然后查看配置文件是否編寫正確,可以使用如下所示的命令:nginx -t
重啟nginx牺弄,然后再次使用上面的curl命令姻几,可以看到返回值里面有: Content-Encoding: gzip
fastcgi cache
運(yùn)行bench test:ab -n 100 -c 10 http://46.101.19.11/
-n: 表示連接個(gè)數(shù)宜狐;100
-c: 表示10個(gè)并發(fā)連接
可以看到結(jié)果是需要等待五秒左右, requests per second 大概也就是幾十左右;
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# FastCgi Cache <<<-----主要看這一段
fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=microcache:10m max_size=500m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header microcache-status $upstream_cache_status
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
# Gzip configuration
gzip on;
gzip_min_length 100;
gzip_comp_level 3;
gzip_types text/plain
gzip_types text/css
gzip_types text/javascript
gzip_disable "msie6";
# Default cache for everything << -- 還有這一段
set $no_cache 0;
# Bypass cache for POST requests
if ($request_method = POST) { set $no_cache 1; }
# Bypass cache for URL with query string
if ($request_uri != "") { set $no_cache 1; }
# Don't cache the following URLs
if ($request_uri ~* "/wp-admin") { set $no_cache 1; }
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {
assess_log off;
expires 1M; # 或者 30d蛇捌;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_cache microcache; <<<- 加上這一段
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_pass 127.0.0.1:9000;
}
}
}
現(xiàn)在加上了fastcgi的部分痪寻,再次運(yùn)行ab命令填物,得到的requess per second大約是2800左右。提升效果顯著啊。
現(xiàn)在再加上add_header那一段配置葛家,然后再次重新啟動(dòng)nginx,可以用一下方式配置測(cè)試:
curl -I http://46.101.19.11/
可以看到microcache-status: HIT
如果將配置中的/tmp/nginx_cache 刪除待秃,再次運(yùn)行以上的curl命令嘹吨,得到的結(jié)果就是:microcache-status:MISS
然后設(shè)置$no_cache變量,使用的時(shí)候萍恕,可以看到microcache-status的bypass逸嘀。
limiting
- concurrency 2. frequecy
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# FastCgi Cache <<<-----主要看這一段
fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=microcache:10m max_size=500m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header microcache-status $upstream_cache_status
# limit concurrency
# limit_conn_zone $server_name zone=per_vhost:5m;
# limit_conn_zone $binary_remote_addr zone=per_ip:5m;
limit_req_zone $binary_remote_addr zone=one_per_sec:5m rate=1r/s;
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
# Gzip configuration
gzip on;
gzip_min_length 100;
gzip_comp_level 3;
gzip_types text/plain
gzip_types text/css
gzip_types text/javascript
gzip_disable "msie6";
# Default cache for everything
set $no_cache 0;
# Bypass cache for POST requests
if ($request_method = POST) { set $no_cache 1; }
# Bypass cache for URL with query string
if ($request_uri != "") { set $no_cache 1; }
# Don't cache the following URLs
if ($request_uri ~* "/wp-admin") { set $no_cache 1; }
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {
assess_log off;
expires 1M; # 或者 30d;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
# limit_conn per_ip 1;<---非常有用允粤,限定每次只能有1個(gè)IP訪問(wèn)
limit_req zone=one_per_sec burst=5;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_cache microcache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_pass 127.0.0.1:9000;
}
}
}
video streaming
需要加上--with_http_mp4_module崭倘,查看文檔,可以看到一些相關(guān)的信息:
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# FastCgi Cache
fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=microcache:10m max_size=500m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header microcache-status $upstream_cache_status
# limit concurrency
# limit_conn_zone $server_name zone=per_vhost:5m;
# limit_conn_zone $binary_remote_addr zone=per_ip:5m;
limit_req_zone $binary_remote_addr zone=one_per_sec:5m rate=1r/s;
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
# Gzip configuration
gzip on;
gzip_min_length 100;
gzip_comp_level 3;
gzip_types text/plain
gzip_types text/css
gzip_types text/javascript
gzip_disable "msie6";
# Default cache for everything
set $no_cache 0;
# Bypass cache for POST requests
if ($request_method = POST) { set $no_cache 1; }
# Bypass cache for URL with query string
if ($request_uri != "") { set $no_cache 1; }
# Don't cache the following URLs
if ($request_uri ~* "/wp-admin") { set $no_cache 1; }
location ~ \.mp4$ { <<<---主要看這段
root /sites/downloads/;
mp4;
mp4_buffer_size 4M;
mp4_max_buffer_size 10M;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {
assess_log off;
expires 1M; # 或者 30d类垫;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
# limit_conn per_ip 1;
limit_req zone=one_per_sec burst=5;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_cache microcache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_pass 127.0.0.1:9000;
}
}
}
GeoIP
使用 --with-http_geoip_module
直接使用 ./configure --with-http_geoip_module 可能會(huì)有報(bào)錯(cuò)司光,提示缺少安裝包,可以使用以下命令安裝:apt install libgeoip-dev
然后再 make & make install 最后悉患,運(yùn)行命令nginx -V 查看安裝和配置情況残家。
建立相關(guān)的目錄:mkdir /etc/nginx/geoip
進(jìn)入dev.maxmind.com 下載GeoLite2 free downloadable database,進(jìn)入頁(yè)面售躁,下載GeoLite Country 和 GeoLite City坞淮,將這兩個(gè)文件在在到上面建立的geoip目錄下,然后使用gunzip命令解壓縮迂求。
下面修改配置文件
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# FastCgi Cache
fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=microcache:10m max_size=500m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header microcache-status $upstream_cache_status
# limit concurrency
# limit_conn_zone $server_name zone=per_vhost:5m;
# limit_conn_zone $binary_remote_addr zone=per_ip:5m;
# limit_req_zone $binary_remote_addr zone=one_per_sec:5m rate=1r/s;
# GeoIP <<<<--- 主要看這段
geoip_country /etc/nginx/geoip/GeoIP.dat
geoip_city /etc/nginx/geoip/GeoLiteCity.dat
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
# Gzip configuration
gzip on;
gzip_min_length 100;
gzip_comp_level 3;
gzip_types text/plain
gzip_types text/css
gzip_types text/javascript
gzip_disable "msie6";
# Default cache for everything
set $no_cache 0;
# Bypass cache for POST requests
if ($request_method = POST) { set $no_cache 1; }
# Bypass cache for URL with query string
if ($request_uri != "") { set $no_cache 1; }
# Don't cache the following URLs
if ($request_uri ~* "/wp-admin") { set $no_cache 1; }
location /geo_country { <<<--主要看這段
return 200 "visiting from $geoip_country_name"
}
location /geo_city { <<<--主要看這段
return 200 "visiting from $geoip_city_name"
}
location ~ \.mp4$ {
root /sites/downloads/;
mp4;
mp4_buffer_size 4M;
mp4_max_buffer_size 10M;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {
assess_log off;
expires 1M; # 或者 30d碾盐;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
# limit_conn per_ip 1;
limit_req zone=one_per_sec burst=5;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_cache microcache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_pass 127.0.0.1:9000;
}
}
}
HTTP2
- binary protocol
- header compression
- persistent connections
- multiplex streams
- server push
簡(jiǎn)單的說(shuō):http2是基于Binary的協(xié)議(http1是基于文本的協(xié)議)header壓縮,長(zhǎng)連接揩局。比如毫玖,在http1下,如果客戶端請(qǐng)求一個(gè)index.html文件凌盯,后續(xù)會(huì)請(qǐng)求jquery.js和style.css三個(gè)文件付枫,需要建立三個(gè)連接。
但是在HTTP2環(huán)境下驰怎,只需要建立一次請(qǐng)求阐滩,index.html,服務(wù)器端就會(huì)一次性返回三個(gè)文件县忌。
開啟HTTP2:使用 ./configure --with-http2_v2_module --with-http_ssl_module, 需要打開兩個(gè)模塊掂榔,是因?yàn)镠TTP2默認(rèn)需要使用加密继效。然后make&make install。
測(cè)試HTTP2是否配置成功装获,需要使用以下方法:
- Online keycdn(ip not supported)<-沒(méi)法用瑞信,僅僅支持域名
- Chrome Extention
- Latest version of curl
- safari developer tools
查看 /usr/local/nginx/ssl/ 可以看到兩個(gè)文件:nginx.crt, nginx.key
修改配置文件:/usr/local/nginx/conf/nginx.conf
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 60;
# HTTPS server
server {
listen 443 ssl http2; <---主要看這里
server_name localhost;
ssl_certificate /usr/local/nginx/ssl/nginx.crt; <---主要看這里
ssl_certificate_key /usr/local/nginx/ssl/nginx.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm
}
}
}
}
其實(shí),就是安裝好相應(yīng)的模塊穴豫,然后配置好配置文件就可以了凡简。
問(wèn)題:嘗試的時(shí)候,總是看到瀏覽器中https上有一個(gè)橫線精肃,似乎https并沒(méi)啟用秤涩,略奇怪。司抱。還需要繼續(xù)挖掘筐眷。
SSL
創(chuàng)建目錄:mkdir /etc/nginx/ssl
運(yùn)行命令: sudo openssl req -x509 -nodes -days 365 -newky rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
這個(gè)命令將生成key 文件和certificate 文件。更詳細(xì)內(nèi)容习柠,可以搜索:how to create an ssl certificate on nginx for ubuntu 14.04浊竟。
然后配置:
ssl_certificate /usr/local/nginx/ssl/nginx.crt; <---主要看這里
ssl_certificate_key /usr/local/nginx/ssl/nginx.key;
參考:
http://nginx.org/en/docs/http/ngx_http_ssl_module.html
https://www.digitalocean.com/community/tutorials/how-to-create-an-ssl-certificate-on-nginx-for-ubuntu-14-04
basic auth
首先安裝相應(yīng)的包:apt install apache2-utils
創(chuàng)建密碼:sudo htpasswd -c /etc/nginx/.htpassw <username>,然后輸入密碼
user www-data www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# FastCgi Cache
fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=microcache:10m max_size=500m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header microcache-status $upstream_cache_status
# limit concurrency
# limit_conn_zone $server_name zone=per_vhost:5m;
# limit_conn_zone $binary_remote_addr zone=per_ip:5m;
limit_req_zone $binary_remote_addr zone=one_per_sec:5m rate=1r/s;
server {
listen 80;
server_name localhost;
root /sites/wordpress;
index index.php index.html;
# Gzip configuration
gzip on;
gzip_min_length 100;
gzip_comp_level 3;
gzip_types text/plain
gzip_types text/css
gzip_types text/javascript
gzip_disable "msie6";
# Default cache for everything
set $no_cache 0;
# Bypass cache for POST requests
if ($request_method = POST) { set $no_cache 1; }
# Bypass cache for URL with query string
if ($request_uri != "") { set $no_cache 1; }
# Don't cache the following URLs
if ($request_uri ~* "/wp-admin") { set $no_cache 1; }
location ~ \.mp4$ {
root /sites/downloads/;
auto_basic "Restricted Content"; #<<<---主要看這段
auto_basic_user_file /etc/nginx/.htpassw;
mp4;
mp4_buffer_size 4M;
mp4_max_buffer_size 10M;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|jpg\png\gif)$ {
assess_log off;
expires 1M; # 或者 30d津畸;兩者等價(jià)
add_header Pragma public;
add_header Cache-Control public;
add_header Vary Accept-Encoding;
# limit_conn per_ip 1;
limit_req zone=one_per_sec burst=5;
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_cache microcache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_pass 127.0.0.1:9000;
}
}
}
看mp4的部分,重啟nginx必怜,就可以看到如果想要訪問(wèn)mp4的資源肉拓,必須輸入賬號(hào)密碼。
Hardening nginx
首先梳庆,移除不用的nginx模塊暖途,查看以下那些可以刪除:
./configure --help | grep without
可以看到一個(gè)模塊叫做 --without-http_autoindex_module
關(guān)閉顯示 nginx的版本信息
在配置文件的http 中加上 server_tokens off
set buffer size
還是在配置文件的http中加上:
configure buffer sizes
client_body_buffer_size 16k;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
關(guān)于更詳細(xì)信息,還是查看相關(guān)的文檔膏执。
block user agents
這樣可以禁止某些agent的訪問(wèn)驻售,達(dá)到部分的反爬蟲的效果:
if ($http_user_agent ~* badbot) {
return 403;
}
重啟nginx,然后再使用curl -I -A "BadBot" <ipaddress>更米∑劾酰可以得到的403的返回值
if ($http_referer ~* badbot) {
return 403;
}
configure X-Frame-Options
# the X-Frame-Options header indicates whether a browser should be allowed to
# rnder a page within a frame or iframe
add_header X-Frame-Options SAMEORIGIN;
更多信息,參考 http://modsecurity.org
如果想要?jiǎng)h除默認(rèn)安裝的庫(kù)征峦,可以這么實(shí)現(xiàn):
In order to compile and install Nginx without certain default modules, we have to pass the --without flag for those modules during the configure step. This can only be done when installing Nginx from source.
nginx的反向代理
可以用nginx啟動(dòng)一個(gè)web:localhost:8888迟几,然后再用Flask啟動(dòng)一個(gè)webapp:localhost:8000,但是栏笆,我們?cè)趺赐ㄟ^(guò)nginx訪問(wèn)使用flask建立的webapp呢类腮?可以通過(guò)修改nginx配置文件的方式:
events {}
http {
server {
listen 8888;
location / {
return 200 "hello from nginx\n";
}
location /flask {
proxy_pass 'http://localhost:8000/flask';
}
}
}
reload nginx server 通過(guò):nginx -s reload
https://www.nginx.com/resources/admin-guide/reverse-proxy/
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
load balance 負(fù)載均衡
簡(jiǎn)單的說(shuō),就是將nginx作為一個(gè)路由蛉加,后端有N個(gè)相同的消費(fèi)者蚜枢,nginx一次將需要處理的任務(wù)交付給這些消費(fèi)者缸逃,如果某一個(gè)消費(fèi)者宕機(jī),剩余的消費(fèi)者會(huì)自動(dòng)接管任務(wù)的消費(fèi)厂抽,如果宕機(jī)的消費(fèi)者恢復(fù)需频,還可以繼續(xù)從nginx那邊接受任務(wù)。
此時(shí)修肠,需要?jiǎng)?chuàng)建一個(gè)文件名為:load-balance.conf:
events {}
http {
upstream flask_server {
server localhost:8001;
server localhost:8002;
server localhost:8003;
}
server {
listen 8888;
location / {
proxy_pass http://flask_server;
}
}
}
測(cè)試的時(shí)候贺辰,需要開啟三個(gè)終端,開啟三個(gè)flask 實(shí)例嵌施,然后再打開一個(gè)終端饲化,重啟nginx,然后運(yùn)行命令:while sleep 1; do curl http://localhost:8000; done
然后隨機(jī)關(guān)閉三個(gè)終端里面的flask實(shí)例吗伤,再打開吃靠。
結(jié)果:三個(gè)終端的端口依次消費(fèi),如果終止某一個(gè)終端足淆,則消費(fèi)端就不顯示已經(jīng)終止的終端巢块。如果再將這個(gè)終端開啟,則繼續(xù)恢復(fù)顯示這個(gè)終端巧号。
以下族奢,將查看sticky session(IP hashing)
events {}
http {
upstream flask_server {
ip_hash; #<---關(guān)注這一行
server localhost:8001;
server localhost:8002;
server localhost:8003;
}
server {
listen 8888;
location / {
proxy_pass http://flask_server;
}
}
}
測(cè)試的時(shí)候,和上面例子一樣丹鸿,開啟三個(gè)終端越走,還是需要執(zhí)行這個(gè)腳本:while sleep 1; do curl http://localhost:8000; done
可以看到和上面的例子結(jié)果不一樣,每次都是通過(guò)第一個(gè)終端消費(fèi)靠欢,如終端1廊敌,如果終止這個(gè)終端1,則繼續(xù)用終端2 消費(fèi)门怪,如果終端1 恢復(fù)骡澈,則恢復(fù)使用終端1 消費(fèi)。
events {}
http {
upstream flask_server {
least_conn; #<---關(guān)注這一行
server localhost:8001;
server localhost:8002;
server localhost:8003;
}
server {
listen 8888;
location / {
proxy_pass http://flask_server;
}
}
}
假設(shè)某一個(gè)請(qǐng)求特別耗時(shí)掷空,這就需要依照服務(wù)器的負(fù)載分布任務(wù)而不是按照順序分布任務(wù)肋殴。
參考文檔:
http://nginx.org/en/docs/http/load_balancing.html
https://www.nginx.com/resources/admin-guide/load-balancer/
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
有用的在線資源
http://nginx.org/en/docs/
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
http://codex.wordpress.org/Nginx
https://github.com/facmbus/nginx-resources
1