Nginx日常笔记
Docker Nginx
1.启动一个测试容器
docker run --rm --name nginx-test -p 8080:80 -d nginx
2.创建本地目录
mkdir -p /app/nginx/www /app/nginx/logs /app/nginx/conf
3.将测试容器的nginx.conf配置文件拷出
docker cp nginx-test:/etc/nginx/nginx.conf /app/nginx/conf/
4.启动新的容器,并挂载本地目录
docker run --rm -d -p 8081:80 --name nginx-test-web \
-v /app/nginx/www:/usr/share/nginx/html \
-v /app/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /app/nginx/logs:/var/log/nginx \
nginx
高并发测试使用的配置文件 nginx.conf
user nginx;
worker_processes 12;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 65535;
}
http {
include /etc/nginx/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 /var/log/nginx/access.log main;
access_log off;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
快速安装
apt-get install nginx
配置文件 /etc/nginx/nginx.conf
Nginx的配置文件是/etc/nginx/nginx.conf,其中设置了一些必要的参数,我们发现其中这样的语句:
include /etc/nginx/sites-enabled/*
可以看出/etc/nginx/sites-enabled/default文件也是一个核心的配置文件,其中包含了主要的配置信息,
如服务器跟目录、服务器名称、location信息和server信息。
开启反向代理
开启代理池:
upstream malu.me {
server 192.168.1.210:80; #Apache
}
location配置:
location / {
proxy_pass http://malu.me;
#Proxy Settings
proxy_redirect off;
#For relay ip
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
client_max_body_size 20M;
}
开启缓存
缓存目录配置:http
#proxy cache
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20m max_size=1g;
然后新建缓存目录:
mkdir -pv /data/nginx/cache/webserver
添加配置规则:http server
#proxy cache
#add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
proxy_pass http://malu.me;
#host header
proxy_set_header Host $host;
#proxy cache
proxy_cache webserver;
proxy_cache_valid 200 302 1m;
proxy_cache_valid 404 1m;
proxy_cache_valid 1m;
proxy_cache_valid any 1m;
}
关闭Web服务器头信息(Header)里的Server值
默认会看到nginx返回的头信息里有版本号,比如:Server:nginx/1.4.6 (Ubuntu)
将这个信息去除
http{}里面加:
server_tokens off;
上传文件大小配置
默认情况下使用nginx反向代理上传超过2MB的文件,会报错413 Request Entity Too Large
解决这个方法很简单,修改配置client_max_body_size值即可 http server location:
client_max_body_size 10M;
添加HTTPS支持:
在http server里添加
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/malu.me.crt;
ssl_certificate_key /etc/nginx/ssl/malu.me.key;
完整配置如下:
upstream malu.me {
server 192.168.1.210:80; #Apache
}
#proxy cache
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20m max_size=1g;
server {
listen 80 default_server;
#IPv6配置
#listen [::]:80 default_server ipv6only=on;
listen 443 ssl;
#ssi支持(Server Side Includes)
ssi on;
ssi_silent_errors on;
ssi_types text/shtml;
#同时开启80和443是这边ssl on要注释掉!
#ssl on;
ssl_certificate /etc/nginx/ssl/malu.me.crt;
ssl_certificate_key /etc/nginx/ssl/malu.me.key;
#有CA证书情况下开启
#ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_session_timeout 5m;
ssl_verify_client on; #打开客户端证书验证,有CA证书情况下关闭off
#加密配置
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
server_name malu.me;
#proxy cache
#add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
location / {
proxy_pass http://malu.me;
#Proxy Settings
proxy_redirect off;
#For relay ip
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#防止客户端伪造IP
proxy_set_header X-Forwarded-For $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#给后端传递https或http状态信息
proxy_set_header X-Forwarded-Proto $scheme;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
client_max_body_size 20M;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css|ico)$ {
proxy_pass http://malu.me;
#host header 虚拟主机用得到,否则会出现404错误
proxy_set_header Host $host;
#proxy cache
proxy_cache_valid 404 10s;
proxy_cache webserver;
proxy_cache_valid 200 302 1m;
proxy_cache_valid 1m;
proxy_cache_valid any 1m;
#proxy_cache_key $host$uri$is_args$args; #清理缓存需要ngx_cache_purge模块
}
}
生成HTTPS证书
nginx要实现ssl,在编译时要添加–with-http_ssl_module,如: ./configure –with-http_ssl_module
# cd /etc/nginx/
# mkdir ssl
# cd ssl
生成一个私有key
# openssl genrsa -des3 -out malu.me.key 1024
提示输入密码 生成CSR(Certificate Signing Request)文件:
# openssl req -new -key malu.me.key -out malu.me.csr
填写证书内容,组织机构、域名等,Common Name填写域名
# cp malu.me.key malu.me.key.bak
# openssl rsa -in malu.me.key.bak -out malu.me.key
# openssl x509 -req -days 365 -in malu.me.csr -signkey malu.me.key -out malu.me.crt
完整配置参数说明
#定义Nginx运行的用户和用户组
user www www;
#nginx进程数,建议设置为等于CPU总核心数。
worker_processes 8;
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;
#进程文件
pid /var/run/nginx.pid;
#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;
#工作模式与连接数上限
events {
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
use epoll;
#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 768;
}
#设定http服务器
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型
#charset utf-8; #默认编码
server_names_hash_bucket_size 128; #服务器名字的hash表大小
client_header_buffer_size 32k; #上传文件大小限制
large_client_header_buffers 4 64k; #设定请求缓
client_max_body_size 8m; #设定请求缓
sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on; #防止网络阻塞
tcp_nodelay on; #防止网络阻塞
keepalive_timeout 120; #长连接超时时间,单位是秒
#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用
#nginx版本信息关闭
server_tokens off;
upstream malu.me {
#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
server 192.168.0.222:80 weight=3;
server 192.168.0.221:80 weight=2;
server 192.168.0.220:80 weight=3;
}
#虚拟主机的配置
server {
#监听端口
listen 80;
#域名可以有多个,用空格隔开
server_name blog.malu.me malu.me;
index index.html index.htm index.php;
root /data/www/html;
location ~ .*.(php|php5)?$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
#图片缓存时间设置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*.(js|css)?$ {
expires 1h;
}
#日志格式设定 $scheme访问协议 $request_time请求时间
log_format access '$remote_addr - $remote_user [$time_local] "$scheme $request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for "$request_time"';
#定义本虚拟主机的访问日志
access_log /var/log/nginx/access.log access;
#对 "/" 启用反向代理
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host; #向后台主机传递host头
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
}
#设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
}
#本地动静分离反向代理配置
#所有jsp的页面均交由tomcat或resin处理
location ~ .(jsp|jspx|do)?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
#所有静态文件由nginx直接读取不经过tomcat或resin
location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ {
expires 15d;
}
location ~ .*.(js|css)?$ {
expires 1h;
}
}
}
log_format日志格式说明
$remote_addr, $http_x_forwarded_for 记录客户端IP地址
$remote_user 记录客户端用户名称
$request 记录请求的URL和HTTP协议
$status 记录请求状态
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。
$bytes_sent 发送给客户端的总字节数。
$connection 连接的序列号。
$connection_requests 当前通过一个连接获得的请求数量。
$msec 日志写入时间。单位为秒,精度是毫秒。
$pipe 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
$http_referer 记录从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器相关信息
$request_length 请求的长度(包括请求行,请求头和请求正文)。
$request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601 ISO8601标准格式下的本地时间。
$time_local 通用日志格式下的本地时间。
log写入redis
让nginx登录到syslog服务器,从syslog-ng到redis这里是我在nginx http指令中的配置
apt install syslog-ng
systemctl start syslog-ng
systemctl enable syslog-ng
log_format xxx_log_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
在nginx server指令中
access_log syslog:server=127.0.0.1:601 xxx_log_format;
在syslog-ng config中
source s_syslog {
udp(
port(601)
);
};
destination d_redis {
redis(
host("REDIS-IP")
port(6379)
command("LPUSH", "access_logs", "${MESSAGE}")
);
};
log {
source(s_syslog);
destination(d_redis);
};
ip访问频率限制
使用limit_req_zone和limit_req指令配合使用来达到限制。一旦并发连接超过指定数量,就会返回503错误。
http{
...
#定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
#以$binary_remote_addr 为key,限制平均每秒的请求为20个,
#1M能存储16000个状态,rete的值必须为整数,
#如果限制两秒钟一个请求,可以设置成30r/m
limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
...
server{
...
location {
...
#限制每ip每秒不超过20个请求,漏桶数burst为5
#brust的意思就是,如果第1秒、2,3,4秒请求为19个,
#第5秒的请求为25个是被允许的。
#但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。
#nodelay,如果不设置该选项,严格使用平均速率限制请求数,
#第1秒25个请求时,5个请求放到第2秒执行,
#设置nodelay,25个请求将在第1秒执行。
limit_req zone=allips burst=5 nodelay;
...
}
...
}
...
}
Nginx + php-fpm
Nginx相比Apache高并发优势明显,下面介绍php7.1的部署过程:
1.安装
apt-get install php7.1-fpm
2.修改配置文件
php-fpm
vim /etc/php/7.1/fpm/pool.d/www.conf
;listen = /run/php/php7.1-fpm.sock
listen = 127.0.0.1:9000 #推荐用TCP socket方式
nginx
vim /etc/nginx/sites-enabled/default
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
#fastcgi_pass unix:/run/php/php7.1-fpm.sock; #Unix socket方式
fastcgi_index index.php;
include fastcgi_params;
}
3.重启2个进程
service nginx restart
service php7.1-fpm restart
socket.io (websocket)反向代理
server {
listen 80;
listen 443 ssl;
server_name example.domain;
root "/project/path";
index index.html index.htm index.php;
// ssl密钥设定
ssl on;
ssl_certificate /ssl/malu.pem;
ssl_certificate_key /ssl/malu.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
ssl_prefer_server_ciphers on;
// 配置负载的后端
upstream socket_nodes {
ip_hash;
server server1.app:5000 weight=5;
server server2.app:5000;
server server3.app:5000;
server server4.app:5000;
}
location /socket.io/ {
proxy_pass http://socket_nodes;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
// 其他配置项
// ...
}
WebSocket proxying 官方文档:http://nginx.org/en/docs/http/websocket.html
nginx服务器安装及配置文件详解: http://seanlook.com/2015/05/17/nginx-install-and-config/