记录下工作中NGINX配置和使用,方便后续查阅
nginx主要功能:http服务器、反向代理、负载均衡;此外还有一些高级功能,限流等。
nginx配置文件是一个纯文本的文件,一般都是位于nginx的安装目录下,默认的安装路径的配置文件在/usr/local/nginx/conf/nginx.conf。它的配置文件都是以block的形式组织的,每个block一般都是以括号“{}”来表示的。主要包括全局,event,http,server等设置,event主要定义nginx的工作模式,http提供web功能,server用来设置虚拟主机,server可以存在多个,结构如下图
通常工作中需要配置的是http模块
http #设定http服务器
{
server {#虚拟主机的配置
listen 80;#监听端口
server_name 域名1,域名2; #域名可以有多个,用空格隔开
location / {# location指令的作用是根据用户请求的URI来执行不同的应用,也就是根据用户请求的网站URL进行匹配,匹配成功即进行相关的操作
#内容
}
#多个location
}
}
先来看一个具体例子
#定义Nginx运行的用户和用户组
user admin admin;
#Nginx进程数,建议设置为等于CPU总核心数。
worker_processes auto;
#全局错误日志定义类型,多个等级可并存,[ debug | info | notice | warn | error | crit ],从左到右错误信息越来越少;此指令可以在全局、http、server、location块中配置)
error_log /var/log/nginx/error.log notice;
error_log /var/log/nginx/error.log info;
#Nginx进程文件
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;
#单个进程最大连接数(最大连接数=连接数*进程数)参照getconf PAGESIZE
worker_connections 4096;
}
#设定http服务器
http
{
include mime.types; #文件扩展名与文件类型映射表
default_type application/json; #默认文件类型
#charset utf-8; #默认编码
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; #开启目录列表访问,合适下载服务器,默认关闭。
#server_tokens off; #关闭服务器版本号显示。
tcp_nopush on; #防止网络阻塞
tcp_nodelay on; #防止网络阻塞
keepalive_timeout 65; #长连接超时时间,单位是秒
#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连接数的时候需要使用
upstream test.com {
#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
server 192.168.80.121:80 weight=3;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}
#虚拟主机的配置
server
{
#监听端口
listen 80;
#域名可以有多个,用空格隔开
server_name localhost;
index index.html index.htm index.php;
root /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;
}
#日志格式设定
log_format access ‘$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/ha97access.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;
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;
}
#nginx禁止访问所有.开头的隐藏文件设置
location ~* /.* {
deny all;
}
#定义错误提示页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
我以我常用的一个配置来说明下ng的运行流程
http {
include mime.types;
default_type application/octet-stream;
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;
#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 0;
keepalive_timeout 65;
proxy_read_timeout 600;
proxy_send_timeout 600;
#gzip on;
server {
listen 80;
server_name ares.yhd.com;
client_max_body_size 50m;
location / {
root html/evolve;#前端代码放在html/evolve目录,运行用户是root
index index.html index.htm;
proxy_redirect off;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
}
location /api {
add_header Access-Control-Allow-Origin ‘ares.yhd.com‘;
add_header Access-Control-Allow-Credentials ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://localhost:10080/api;
proxy_set_header Cookie $http_cookie;
}
location /login {
add_header Access-Control-Allow-Origin ‘ares.yhd.com‘;
add_header Access-Control-Allow-Credentials ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://localhost:10080/login;
proxy_set_header Cookie $http_cookie;
}
location /logout {
add_header Access-Control-Allow-Origin ‘ares.yhd.com‘;
add_header Access-Control-Allow-Credentials ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://localhost:10080/logout;
proxy_set_header Cookie $http_cookie;
}
location /k8s {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://192.168.1.100:32001/;
}
}
}
监听80端口,访问ares.yhd.com的时候(本地hosts配置了ares.yhd.com 127.0.0.1)即访问本地的80端口服务(http服务),访问/资源的时候是直接访问html/evolve目录下的静态资源(js css等),访问/api时候,直接通过反向代理转发到本地的http://localhost:10080/api请求后台服务。
服务部署结构图如下,正常情况,流量是在pro上;在发版时候,先修改front pro机器上的NGINX配置,通过反向代理,把流量都反向代理到front pre环境,这样在pro发版期间,流量都在pre环境,等发版完成,再修改回来。
#front pro上NGINX配置
upstream order-backend {#负载均衡配置
# order-bacekend pro
server 192.168.1.110:8080 max_fails=1 fail_timeout=3s weight=3;
server 192.168.1.111:8080 max_fails=1 fail_timeout=3s weight=3;
}
server {#虚拟主机的配置
listen 80;
client_max_body_size 50m;
keepalive_timeout 90;
client_header_timeout 90;
client_body_timeout 90;
server_name order.yhd.com;
access_log /dev/stdout main;
error_log /dev/stderr warn;
location / {
root /home/baseuser/projects/order-front-pro;
index index.html index.htm;
try_files $uri $uri/ /index.html;
add_header Cache-Control no-cache; #nginx配置文件通过使用add_header指令来设置response header
add_header Cache-Control private;
expires -1s;
}
location /api {
#add_header指令来设置response header,通过浏览器F12查看到每个请求的response header都有下面四个属性
add_header Access-Control-Allow-Origin "order.yhd.com"; #该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
add_header Access-Control-Allow-Credentials "true"; #表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; #该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; #该字段可选。跨域允许的方法
#proxy_pass反向代理,对于访问/api开头的请求,均转发到负载均衡order-backend
proxy_pass http://order-backend;
#proxy_redirect
proxy_redirect off;
#proxy_set_header用来重定义发往后端服务器的请求头
proxy_set_header Host $host; #转发后台服务时候,请求header加上Host字段,$host是NGINX内置全局变量,表示前端请求上送的host
proxy_set_header Cookie $http_cookie; #转发后台服务时候,请求header加上Cookie字段,$http_cookie是NGINX内置全局变量,表示前端请求上送的cookie
#x-real-ip表示直连地址
proxy_set_header x-real-ip $remote_addr; #转发后台服务时候,请求header加上x-real-ip字段,$remote_addr是NGINX内置全局变量,表示浏览器实际地址
#https://www.cnblogs.com/diaosir/p/6890825.html
#在使用nginx做反向代理时,我们为了记录整个的代理过程,我们往往会在配置文件中做如下配置:proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;,内容通常X-Forwarded-For:192.168.247.1, 192.168.247.131, 192.168.247.132
#x-forwarded-for获取结果是一组ip,如果每个代理都设置了proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;,那么分别是ip1,,ip2,ip3地址,第一个地址就是实际地址
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for; #转发后台服务时候,请求header加上x-forwarded-for字段,$http_cookie是NGINX内置全局变量,表示前端请求上送的cookie。详细见https://www.cnblogs.com/diaosir/p/6890825.html
#proxy_cookie_path 解决反向代理session丢失。proxy_cookie_path 的作用是用来改变cookie的路径 nginx在每次传递请求时,如果没有传递cookie,没有添加proxy_cookie_path,服务器将视为两次请求,因此会重新生成一个新的session,致使session数据丢失。
proxy_cookie_path /api/ /;
#proxy_next_upstream 当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率,多可运用于前台程序负载
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
}
location /operation {
add_header ‘Access-Control-Allow-Origin‘ ‘order.yhd.com‘;
add_header ‘Access-Control-Allow-Credentials‘ ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://order-backend;
proxy_redirect off;
proxy_cookie_path /operation/ /;
proxy_set_header Cookie $http_cookie;
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 http_404;
}
location /login {
proxy_pass http://order-backend/login;
proxy_set_header Host $host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}
location /logout {
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://order-backend/logout;
}
}
#front pre上NGINX配置
upstream order-backend {#负载均衡配置
# order-bacekend pre
server 192.168.1.112:8080 max_fails=1 fail_timeout=3s weight=3;
}
server {#虚拟主机的配置
listen 80;
client_max_body_size 50m;
keepalive_timeout 90;
client_header_timeout 90;
client_body_timeout 90;
server_name order.yhd.com;
access_log /dev/stdout main;
error_log /dev/stderr warn;
location / {
root /home/baseuser/projects/order-front-pre;
index index.html index.htm;
try_files $uri $uri/ /index.html;
add_header Cache-Control no-cache; #nginx配置文件通过使用add_header指令来设置response header
add_header Cache-Control private;
expires -1s;
}
location /api {
#add_header指令来设置response header,通过浏览器F12查看到每个请求的response header都有下面四个属性
add_header Access-Control-Allow-Origin "order.yhd.com";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://order-backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header Cookie $http_cookie;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_cookie_path /api/ /;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
}
location /operation {
add_header ‘Access-Control-Allow-Origin‘ ‘order.yhd.com‘;
add_header ‘Access-Control-Allow-Credentials‘ ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://order-backend;
proxy_redirect off;
proxy_cookie_path /operation/ /;
proxy_set_header Cookie $http_cookie;
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 http_404;
}
location /login {
proxy_pass http://order-backend/login;
proxy_set_header Host $host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}
location /logout {
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://order-backend/logout;
}
}
发现front的NGINX上pro和pre配置相同,只是负载均衡的后台机器不同而已。那么如何实现发版无感知呢?首先域名是映射到192.168.1.100和192.168.1.101两台机器的,我们只需要在发版前,把front pro两台机器的ng配置修改,让流量反向代理到pre即可,具体分为前端流量代理到front pre,后端流量代理到后端pre。那么修改front pro两台机器的NGINX配置如下:
upstream order-backend {
# order-bacekend pre
server 192.168.1.112:8080 max_fails=1 fail_timeout=3s weight=3;
}
server {
listen 80;
client_max_body_size 50m;
keepalive_timeout 90;
client_header_timeout 90;
client_body_timeout 90;
server_name order.yhd.com;
access_log /dev/stdout main;
error_log /dev/stderr warn;
location / {
proxy_pass http://192.168.1.102; #把192.168.1.100/101两台机器的前端流量都反向代理到front pre上
add_header Cache-Control no-cache;
add_header Cache-Control private;
expires -1s;
}
location /api {
add_header Access-Control-Allow-Origin ‘order.yhd.com‘;
add_header Access-Control-Allow-Credentials ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://order-backend; #把192.168.1.100/101两台机器发往后端的流量,都反向代理到pre后台环境
proxy_redirect off;
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_cookie_path /api/ /;
proxy_set_header Cookie $http_cookie;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
}
location /operation {
add_header Access-Control-Allow-Origin ‘order.yhd.com‘;
add_header Access-Control-Allow-Credentials ‘true‘;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
proxy_pass http://order-backend;
proxy_redirect off;
proxy_cookie_path /operation/ /;
proxy_set_header Cookie $http_cookie;
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 http_404;
}
location /login {
proxy_pass http://order-backend/login;
proxy_set_header Host $host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}
location /logout {
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://order-backend/logout;
}
}
关键点看注释,通过修改front pro两台机器的NGINX配置,把前端流量都反向代理到front pre,把后端流量都从192.168.100/101直接去请求192.168.1.112这个pre环境。
使用反向代理,修改NGINX配置后nginx -s reload生效(nginx会等待旧请求都执行完毕,类似线程池优雅关闭那样),我们可以做到发版期间无感知。
上述切换流量是手工的,有没自动的呢? 可以使用lua,在蓝绿发布web自动切流量我们就使用到了,这个后续再写。
原文:https://www.cnblogs.com/zhangyjblogs/p/14433762.html