常规配置模板
#user www www; | |
worker_processes auto; | |
error_log /home/wwwlogs/nginx_error.log crit; | |
#pid /usr/local/nginx/nginx.pid; | |
#Specifies the value for maximum file descriptors that can be opened by this process. | |
worker_rlimit_nofile 655350; | |
events | |
{ | |
use epoll; | |
worker_connections 655350; | |
} | |
http | |
{ | |
include mime.types; | |
default_type application/octet-stream; | |
server_names_hash_bucket_size 128; | |
client_header_buffer_size 32k; | |
large_client_header_buffers 4 32k; | |
client_max_body_size 50m; | |
server_tokens off; | |
sendfile on; | |
tcp_nopush on; | |
tcp_nodelay on; | |
keepalive_timeout 60; | |
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 256k; | |
proxy_connect_timeout 600; | |
proxy_read_timeout 600; | |
proxy_send_timeout 600; | |
proxy_buffer_size 64k; | |
proxy_buffers 4 32k; | |
proxy_busy_buffers_size 64k; | |
proxy_temp_file_write_size 64k; | |
gzip on; | |
gzip_min_length 1k; | |
gzip_buffers 4 16k; | |
gzip_http_version 1.0; | |
gzip_comp_level 2; | |
gzip_types text/plain application/x-javascript text/css application/xml text/xml application/json; | |
gzip_vary on; | |
log_format access '$remote_addr - $remote_user [$time_local] $host ' | |
'"$request" $status $body_bytes_sent $request_time ' | |
'"$http_referer" "$http_user_agent" "$http_x_forwarded_for"' | |
'$upstream_addr $upstream_status $upstream_response_time' ; | |
#设置Web缓存区名称为cache_one,内存缓存空间大小为256MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。 | |
proxy_temp_path /home/proxy_temp_dir; | |
proxy_cache_path /home/proxy_cache_path levels=1:2 keys_zone=cache_one:256m inactive=1d max_size=30g; | |
server { | |
listen 80; | |
server_name _; | |
return 403; | |
} | |
include vhost/*.conf; | |
} |
以“exmaple.org”为例,如下为基于 upstream 负载均衡模式的配置:
upstream example_backend { | |
server 127.0.0.1:9080; | |
server 192.168.1.198:9080; | |
server 172.16.0.4:80 weight=5 max_fails=3 fail_timeout=10s; # 权重、健康监测 | |
server 172.16.0.5:8080 backup; # 备份节点, | |
ip_hash; #调度算法 | |
} | |
server { | |
listen 80; | |
server_name www.example.org example.com .example.org; | |
location / { | |
# 如果后端服务器出现502 或504错误代码的话nginx就不会请求某台服务器了,当后端服务器又工作正常了,nginx继续请求,这样一来达到了后端服务器健康状况检测的功能, | |
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; | |
proxy_pass http://example_backend; | |
proxy_http_version 1.1; | |
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_connect_timeout 600; | |
proxy_read_timeout 600; | |
proxy_send_timeout 600; | |
proxy_buffer_size 8k; | |
proxy_temp_file_write_size 64k; | |
# nginx本地cache开启 | |
proxy_cache cache_one; | |
proxy_cache_valid 200 304 30d; | |
proxy_cache_valid 301 302 404 1m; | |
proxy_cache_valid any 1m; | |
proxy_cache_key $host$request_uri; | |
# 客户端缓存,在header中增加“Expires” | |
expires 30d; | |
add_header Cache-Control public; | |
add_header X-Proxy-Cache $upstream_cache_status; | |
proxy_set_header If-Modified-Since $http_if_modified_since; | |
if_modified_since before; | |
} | |
location ~ .*\.(gif|jpg|jpeg|png|bmp|ico|swf|xml|css|js)$ { | |
proxy_pass http://example_backend; | |
proxy_set_header Host $host; | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
expires 15d; | |
} | |
location ~ .*\.(jhtml)$ { | |
proxy_pass http://example_backend; | |
proxy_set_header Host $host; | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
expires -1; | |
} | |
access_log logs/www.example.org.log; | |
} |
其他的 proxy 配置:
1.proxy_set_header :在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息。 2.proxy_connect_timeout:配置Nginx与后端代理服务器尝试建立连接的超时时间。 3.proxy_read_timeout : 配置Nginx向后端服务器组发出read请求后,等待相应的超时时间。 4.proxy_send_timeout:配置Nginx向后端服务器组发出write请求后,等待相应的超时时间。 5.proxy_redirect :用于修改后端服务器返回的响应头中的Location和Refresh。
用户认证
# htpasswd -bc /usr/local/nginx/auth/passwd admin 123456 | |
vim /usr/local/nginx/conf/vhost/www.conf | |
server { | |
listen 80; | |
server_name www.com; | |
index index.html index.htm; | |
root /www; | |
location / { | |
auth_basic "test"; | |
auth_basic_user_file /usr/local/nginx/auth/passwd; | |
} | |
#service nginx restart |
解决跨域
# 提示: add_header 也可以添加到 server 中,这样当前 server 下都允许跨域 | |
server | |
{ | |
listen 3002; | |
server_name localhost; | |
location /ok { | |
proxy_pass http://localhost:3000; | |
# 指定允许跨域的方法,*代表所有 | |
add_header Access-Control-Allow-Methods *; | |
# 预检命令的缓存,如果不缓存每次会发送两次请求 | |
add_header Access-Control-Max-Age 3600; | |
# 带cookie请求需要加上这个字段,并设置为true | |
add_header Access-Control-Allow-Credentials true; | |
# 表示允许这个域跨域调用(客户端发送请求的域名和端口) | |
# $http_origin动态获取请求客户端请求的域 不用*的原因是带cookie的请求不支持*号 | |
add_header Access-Control-Allow-Origin $http_origin; | |
# 表示请求头的字段 动态获取 | |
add_header Access-Control-Allow-Headers $http_access_control_request_headers; | |
# OPTIONS预检命令,预检命令通过时才发送请求 | |
# 检查请求的类型是不是预检命令 | |
if ($request_method = OPTIONS){ | |
return 200; | |
} | |
} | |
} |
URL 重写 比如说访问某站点的路径为/forum/ , 此时想使用/bbs 来访问此站点需要做 url 重写如下
location / { | |
rewrite ^/forum/?$ /bbs/ permanent; | |
} | |
比如说某站点有个图片服务器(10.0.0.1/p_w_picpaths/ ) 此时访问某站点上/p_w_picpaths/的资源时希望访问到图片服务器上的资源 | |
location / { | |
rewrite ^/p_w_picpaths/(.*\.jpg)$ /p_w_picpaths2/$1 break; | |
} |
域名跳转
server { | |
listen 80; | |
server_name www.com; | |
rewrite ^/ http://www.www.com/; | |
# return 301 http://www.andy.com/; | |
} |
域名镜像
server { | |
listen 80; | |
server_name www.com; | |
rewrite ^/(.*)$ http://www.www.com/$1 last; | |
} |
判断表达式
-f 和 !-f 用来判断是否存在文件
-d 和 !-d 用来判断是否存在目录
-e 和 !-e 用来判断是否存在文件或目录
-x 和 !-x 用来判断文件是否可执行
防盗链
location ~* \.(gif|jpg|png|swf|flv)$ { | |
valid_referers none blocked www.com; | |
if ($invalid_referer) { | |
rewrite ^/ http://www.com/403.html; | |
} |
会话保持
# ip_hash使用源地址哈希算法,将同一客户端的请求只发往同一个后端服务器(除非该服务器不可用)。 | |
# 问题: 当后端服务器宕机后,session会话丢失;同一客户端会被转发到同一个后端服务器,可能导致负载失衡; | |
upstream backend { | |
ip_hash; | |
server backend1.example.com; | |
server backend2.example.com; | |
server backend3.example.com down; | |
} | |
sticky_cookie_insert | |
# 使用sticky_cookie_insert 启用会话亲缘关系,会导致来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。因此可以避免上述ip_hash中来自同一客户端导致负载失衡的情况(需要引入第三方模块才能实现)。 | |
upstream backend { | |
server backend1.example.com; | |
server backend2.example.com; | |
sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/; | |
} | |
server { | |
listen 80; | |
server_name 3evip.cn; | |
location / { | |
proxy_pass http://backend; | |
} | |
} |
expires:设置浏览器中保持 cookie 的时间 domain:定义 cookie 的域 path:为 cookie 定义路径
日志切割 示列一
# 适合单个网站日志文件 | |
LOGS_PATH=/home/wwwroot/yunwei/logs | |
yesterday=`date +"%F" -d "-1 days"` | |
mv ${LOGS_PATH}/yunwei.log ${LOGS_PATH}/yunwei-${yesterday}.log | |
kill -USR1 $(cat /var/logs/nginx.pid) |
示列二
#nginx日志切割 | |
# Nginx pid | |
NGINX_PID=$(cat /var/logs/nginx.pid) | |
# 多个日志文件 | |
LOGS=(xxx.access.log xxx.access.log) | |
# Nginx日志路径目录 | |
BASH_PATH="/www/wwwlogs" | |
# xxxx年xx月 | |
lOG_PATH=$(date -d yesterday +"%Y%m") | |
# 昨天日期 | |
DAY=$(date -d yesterday +"%d") | |
# 循环移动 | |
for log in ${LOGS[@]} | |
do | |
# 先判断日志目录是否存在 | |
[[ ! -d "${BASH_PATH}/${lOG_PATH}" ]] && mkdir -p ${BASH_PATH}/${lOG_PATH} | |
# 进入日志目录 | |
cd ${BASH_PATH} | |
mv ${log} ${lOG_PATH}/${DAY}-${log} | |
#kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'` | |
kill -USR1 ${NGINX_PID} | |
# 删除30天的备份,最好是移动到其他位置,不建议 rm -fr | |
#find ${BASH_PATH}/${lOG_PATH} -mtime +30 -name "." -exec rm -fr {} \; | |
done |
示列三
#set the path to nginx log files | |
log_files_path="/usr/local/nginx/logs/" | |
log_files_dir=${log_files_path}$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m") | |
#set nginx log files you want to cut | |
log_files_name=(gw20 gw20-json) | |
#set the path to nginx. | |
nginx_sbin="/usr/bin/nginx" | |
#Set how long you want to save | |
save_days=10 | |
############################################ | |
#Please do not modify the following script # | |
############################################ | |
mkdir -p $log_files_dir | |
log_files_num=${#log_files_name[@]} | |
#cut nginx log files | |
for((i=0;i<$log_files_num;i++));do | |
mv ${log_files_path}${log_files_name[i]}.log ${log_files_dir}/${log_files_name[i]}_$(date -d "yesterday" +"%Y%m%d").log | |
done | |
#delete 30 days ago nginx log files | |
find $log_files_path -mtime +$save_days -exec rm -rf {} \; | |
$nginx_sbin -s reload |
示列四
server{ | |
if ($time_iso8601 ~ '(\d{4}-\d{2}-\d{2})') { | |
set $day $1; | |
} | |
access_log /www/wwwlogs/xxx.com-$day.log main; | |
error_log /www/wwwlogs/xxx.com.error.log; | |
} |
动静分离
为加快网站解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 在动静分离的 tomcat 的时候比较明显,因为 tomcat 解析静态很慢,简单来说,是使用正则表达式匹配过滤,交给不同的服务器。 1、准备环境
192.168.62.159 代理服务器 | |
192.168.62.157 动态资源 | |
192.168.62.155 静态资源 |
2、配置 nginx 反向代理 upstream
[root@nginx-server conf.d]# cat upstream.conf | |
upstream static { | |
server 192.168.62.155:80 weight=1 max_fails=1 fail_timeout=60s; | |
} | |
upstream phpserver { | |
server 192.168.62.157:80 weight=1 max_fails=1 fail_timeout=60s; | |
} | |
server { | |
listen 80; | |
server_name localhost; | |
#动态资源加载 | |
location ~ \.(php|jsp)$ { | |
proxy_pass http://phpserver; | |
proxy_set_header Host $host:$server_port; | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
} | |
#静态资源加载 | |
location ~ .*\.(html|gif|jpg|png|bmp|swf|css|js)$ { | |
proxy_pass http://static; | |
proxy_set_header Host $host:$server_port; | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
} | |
} |
3、192.168.62.155 静态资源
#静态资源配置 | |
server { | |
listen 80; | |
server_name localhost; | |
location ~ \.(html|jpg|png|js|css|gif|bmp|jpeg) { | |
root /home/www/nginx; | |
index index.html index.htm; | |
} | |
} |
4、192.168.62.157 动态资源
server { | |
listen 80; | |
server_name localhost; | |
location ~ \.php$ { | |
root /home/nginx/html; #指定网站目录 | |
fastcgi_pass 127.0.0.1:9000; #指定访问地址 | |
fastcgi_index index.php; #指定默认文件 | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #站点根目录,取决于root配置项 | |
include fastcgi_params; #包含nginx常量定义 | |
} | |
} |
location 优先级
当有多条 location 规则时,nginx 有一套比较复杂的规则,优先级如下: | |
`精确匹配= | |
`前缀匹配^~(立刻停止后续的正则搜索) | |
`按文件中顺序的正则匹配~或~* | |
`匹配不带任何修饰的前缀匹配。 | |
这个规则大体的思路是 | |
`先精确匹配,没有则查找带有^~的前缀匹配,没有则进行正则匹配,最后才返回前缀匹配的结果(如果有的话) | |
HTTPS 使用自颁发证书实现
建立存放https证书的目录
mkdir -pv /usr/local/nginx/conf/.sslkey
生成网站私钥文件
cd /usr/local/nginx/conf/.sslkey | |
openssl genrsa -out https.key 1024 |
生存网站证书文件,需要注意的是在生成的过程中需要输入一些信息根据自己的需要输入,但Common Name 项输入的必须是访问网站的FQDN
openssl req -new -x509 -key https.key -out https.crt
为了安全起见,将存放证书的目录权限设置为400
chmod -R 400 /usr/local/nginx/conf/.sslkey | |
vim /usr/local/nginx/conf/vhost/www.conf | |
server { | |
listen 443; | |
server_name www.com; | |
index index.html index.htm; | |
root /www; | |
ssl on; | |
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; | |
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5; | |
ssl_certificate /usr/local/nginx/conf/.sslkey/https.crt; | |
ssl_certificate_key /usr/local/nginx/conf/.sslkey/https.key; | |
ssl_session_cache shared:SSL:10m; | |
ssl_session_timeout 10m; | |
} | |
#重新启动nginx服务 | |
service nginx restar | |
基于 HTTPS 配置核心配置 | |
upstream example_backend { | |
server 127.0.0.1:9080; | |
server 192.168.1.198:9080; | |
} | |
server { | |
listen 80; | |
server_name www.example.org example.org; | |
rewrite ^/(.*)$ https://$host/$1 last; | |
} | |
server { | |
listen 443; | |
server_name www.example.org example.org; | |
ssl on; | |
ssl_certificate /usr/local/nginx/conf/ssl/example.crt; | |
ssl_certificate_key /usr/local/nginx/conf/ssl/example.key; | |
ssl_session_timeout 5m; | |
ssl_protocols SSLv3 TLSv1 TLSv1.2 TLSv1.1; | |
ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP; | |
ssl_prefer_server_ciphers on; | |
location / { | |
... | |
} | |
} |
根据页面不存在则自定义跳转
if (!-f $request_filename) { | |
rewrite ^(/.*)$ http://www.com permanent; | |
} |
根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ { | |
if (-f $request_filename) { | |
expires 1h; | |
break; | |
} | |
} |