跳至主要內容

nginx配置

zheng大约 12 分钟CICDnginx

一、负载均衡策略

负载均衡用于从“upstream”模块定义的后端服务器列表中选取一台服务器接受用户的请求。一个最基本的upstream模块是这样的,模块内的server是服务器列表:

#动态服务器组
upstream dynamic_zuoyu {
    server localhost:8080;  #tomcat1
    server localhost:8081;  #tomcat2
    server localhost:8082;  #tomcat3
    server localhost:8083;  #tomcat4
}

在upstream模块配置完成后,要让指定的访问反向代理到服务器列表:

#其他页面反向代理到tomcat容器
location ~ .*$ {
    index index.jsp index.html;
    proxy_pass http://dynamic_zuoyu;
}

这就是最基本的负载均衡实例,但这不足以满足实际需求;目前Nginx服务器的upstream模块支持6种方式的分配:
负载均衡策略
img_1.png
在这里,只详细说明Nginx自带的负载均衡策略,第三方不多描述。

1、轮询

最基本的配置方法,上面的例子就是轮询的方式,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。
 有如下参数:
img.png
注意:

  • 在轮询中,如果服务器down掉了,会自动剔除该服务器。
  • 缺省配置就是轮询策略。
  • 此策略适合服务器配置相当,无状态且短平快的服务使用。

2、weight

权重方式,在轮询策略的基础上指定轮询的几率。例子如下:

 upstream dynamic_zuoyu {
        server localhost:8080   weight=2;  #tomcat 1
        server localhost:8081;  #tomcat 2
        server localhost:8082   backup;  #tomcat 3
        server localhost:8083   max_fails=3 fail_timeout=20s;  #tomcat 4
    }

在该例子中,weight参数用于指定轮询几率,weight的默认值为1,;weight的数值与访问比率成正比,比如Tomcat 7.0被访问的几率为其他服务器的两倍。
注意:

  • 权重越高分配到需要处理的请求越多。
  • 此策略可以与least_conn和ip_hash结合使用。
  • 此策略比较适合服务器的硬件配置差别比较大的情况。

3、ip_hash

指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。

#动态服务器组
    upstream dynamic_zuoyu {
        ip_hash;    #保证每个访客固定访问一个后端服务器
        server localhost:8080   weight=2;  #tomcat 1
        server localhost:8081;  #tomcat 2
        server localhost:8082;  #tomcat 3
        server localhost:8083   max_fails=3 fail_timeout=20s;  #tomcat 4
    }

注意:

  • 在nginx版本1.3.1之前,不能在ip_hash中使用权重(weight)。
  • ip_hash不能与backup同时使用。
  • 此策略适合有状态服务,比如session。
  • 当有服务器需要剔除,必须手动down掉。

4、least_conn

把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。

#动态服务器组
upstream dynamic_zuoyu {
    least_conn;    #把请求转发给连接数较少的后端服务器
    server localhost:8080   weight=2;  #tomcat 1
    server localhost:8081;  #tomcat 2
    server localhost:8082 backup;  #tomcat 3
    server localhost:8083   max_fails=3 fail_timeout=20s;  #tomcat 4
}

5、第三方策略

(1)fair

按照服务器端的响应时间来分配请求,响应时间短的优先分配。

# 动态服务器组
upstream dynamic_zuoyu {
        server localhost:8080;  #tomcat 1
        server localhost:8081;  #tomcat 2
        server localhost:8082;  #tomcat 3
        server localhost:8083;  #tomcat 4
        fair;    #实现响应时间短的优先分配
}

(2)url_hash

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。
同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。
而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。

#动态服务器组
upstream dynamic_zuoyu {
    hash $request_uri;    #实现每个url定向到同一个后端服务器
    server localhost:8080;  #tomcat 1
    server localhost:8081;  #tomcat 2
    server localhost:8082;  #tomcat 3
    server localhost:8083;  #tomcat 4
}

二、nginx匹配规则

nginx.conf主要由三部分组成:全局块, events块, http块,详细如下:

  • 1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
  • 2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
  • 3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
  • 4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
  • 5、location块:配置请求的路由,以及各种页面的处理情况。

(1)语法

location [=|~|~*|^~] /uri/ {}
location = /uri    = 表示精确匹配,只有完全匹配上才能生效
location ^~ /uri    ^~ 开头对URL路径进行前缀匹配,并且在正则之前。
location ~ pattern    开头表示区分大小写的正则匹配
location ~* pattern    开头表示不区分大小写的正则匹配
location /uri    不带任何修饰符,也表示前缀匹配,但是在正则匹配之后
location /    通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default

优先级:(location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (/)
前缀匹配时,Nginx 不对 url 做编码,因此请求为 /static/20%/aa,可以被规则 ^~ /static/ /aa 匹配到(注意是空格)

(2)规则

一个请求过来后,Nginx匹配这个请求的流程如下:

  • 1> 先查找是否有=开头的精确匹配,
如:location = /test/abc/user.do {}
  • 2> 再查找普通匹配,以 最大前缀 为原则,如有以下两个location,则会匹配后一项
  location /test/ {}
  location /test/abc {}
  • 3> 匹配到一个普通格式后,搜索并未结束,而是暂存当前匹配的结果,并继续搜索正则匹配模式
  • 4> 所有正则匹配模式location中找到第一个匹配项后,就以此项为最终匹配结果
    所以正则匹配项匹配规则,受定义的前后顺序影响,但普通匹配模式不会
  • 5> 如果未找到正则匹配项,则以3中缓存的结果为最终匹配结果
  • 6> 如果一个匹配都没搜索到,则返回404
    注:精确匹配与模糊匹配差别:
  location =/ {} 与 location / {} 的差别:
  • 前一个是精确匹配,只响应/请求,所有/xxx或/xxx/xxxx类的请求都不会以前缀的形式匹配到它
  • 后一个是只要以 / 为前缀的请求都会被匹配到。如:/abc , /test/abc, /test/abc/aaaa
    示例1
server {
	listen 80;
	server_name x.x.x.x;
	......
	location /subdir {
		proxy_pass http://y.y.y.y;   ###注意这里没有以/结尾
	}
}
# 那么用户请求http://x.x.x.x/subdir/other时,匹配到该区块,nginx反代会保留虚拟路径
# nginx实际转发后端的请求URL为http://http://y.y.y.y/subdir/other

示例2

server {
	listen 80;
	server_name x.x.x.x;
	......
	location /subdir {
		proxy_pass http://y.y.y.y/;   ##注意这里以/结尾
	}
}
# 那么用户请求http://x.x.x.x/subdir/other时,匹配到该区块,nginx反代不会保留虚拟路径,
# nginx实际转发后端的请求URL为http://http://y.y.y.y//other

二、rewrite重写

rewrite使用场景:

  • 地址跳转,用户访问www.nginx01.com这个URL时,将其定向至一个新的域名www.nginx02.comopen in new window
  • 协议跳转,将用户通过http的请求协议重新跳转至https协议(实现https主要手段)。
  • URL静态化,将动态URL地址显示为静态URL的一种技术,能提高搜索引擎抓取 并且能减少动态URL对外暴露过多的参数。PS:Rewrite会轻微增加服务器负担。

四种方案

  • last 停止处理后续rewrite指令集,跳出location作用域,并开始搜索与更改后的URI相匹配的location,URL地址不变
  • break 停止处理后续rewrite指令集,不会跳出location作用域,不再进行重新查找,终止匹配,URL地址不变
  • redirect 返回302临时重定向,浏览器地址栏会显示跳转后的URL地址,爬虫不会更新自己的URL数据库
  • permanent 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址,爬虫会更新自己的URL数据库
    注:使用last和break时浏览器中的地址不会改变,使用redirect和permanent则会改变

三、return

返回状态码

location /test {    
    set $name 'user123';
    return 404  $name;
}

返回字符串

location /test {
    return 200 'hello';
}

地址跳转

location /test {    
    return http://www.baidu.com;
}

返回自定义变量

set $name 'user123';
return 200 $name;

返回内置变量

return $uri;

返回日志信息实例

return  200 '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';

四 、常用的全局变量

例:http://www.abc.com:99/aa/bb/test.jsp
$host        www.abc.com
$server_port     8080
$request_uri     /aa/bb/test.jsp
$document_root   /pm_code
$request_filename  /pm_code/aa/bb/test.jsp

五、root和alias指令

root

location /i/ {  
    root /data/w3;
}
# 请求 http://test.net/i/picture.jpg 这个地址时,那么在服务器里面对应的真正的资源
# 注意:真实的路径是root指定的值加上location指定的值 。

alias

location /i/ {  
    alias /data/w3/;
}
# 同样请求 http://test.net/i/picture.jpg 时,在服务器查找的资源路径是: /data/w3/picture.jpg

区别:

  • alias 只能作用在location中,而root可以存在server、http和location中。
  • alias 后面必须要用 “/” 结束,否则会找不到文件,而 root 则对 ”/” 可有可无。

六、Gzip

将响应报⽂发送⾄客户端之前可以启⽤压缩功能,这能够有效地节约带宽,并提⾼响应⾄客户端的速度。Gzip压缩可以配置http,server和location模块下。
配置如下:

gzip on;                 #决定是否开启gzip模块,on表示开启,off表示关闭;
gzip_min_length 1k;      #设置允许压缩的页面最小字节(从header头的Content-Length中获取) ,当返回内容大于此值时才会使用gzip进行压缩,K为单位,当值为0时,所有页面都进行压缩。建议大于1k
gzip_buffers 4 16k;      #设置gzip申请内存的大小,其作用是按块大小的倍数申请内存空间,param2:int(k) 后面单位是k。这里设置以16k为单位,按照原始数据大小以16k为单位的4倍申请内存
gzip_http_version 1.1;   #识别http协议的版本,早起浏览器可能不支持gzip自解压,用户会看到乱码
gzip_comp_level 2;       #设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大;等级1-9,最小的压缩最快 但是消耗cpu
gzip_types text/plain application/x-javascript text/css application/xml;    #设置需要压缩的MIME类型,非设置值不进行压缩,即匹配压缩类型
gzip_vary on;            #启用应答头"Vary: Accept-Encoding"
gzip_proxied off;
nginx做为反向代理时启用,off(关闭所有代理结果的数据的压缩),expired(启用压缩,如果header头中包括"Expires"头信息),no-cache(启用压缩,header头中包含"Cache-Control:no-cache"),
no-store(启用压缩,header头中包含"Cache-Control:no-store"),private(启用压缩,header头中包含"Cache-Control:private"),no_last_modefied(启用压缩,header头中不包含
"Last-Modified"),no_etag(启用压缩,如果header头中不包含"Etag"头信息),auth(启用压缩,如果header头中包含"Authorization"头信息)
gzip_disable msie6;
(IE5.5IE6 SP1使用msie6参数来禁止gzip压缩 )指定哪些不需要gzip压缩的浏览器(将和User-Agents进行匹配),依赖于PCRE

推荐配置如下:

gzip on;						#开启gzip压缩功能
gzip_min_length 10k;			#设置允许压缩的页面最小字节数; 这里表示如果文件小于10个字节,就不用压缩,因为没有意义,本来就很小.
gzip_buffers 4 16k;			#设置压缩缓冲区大小,此处设置为416K内存作为压缩结果流缓存
gzip_http_version 1.1;			#压缩版本
gzip_comp_level 6;			#设置压缩比率,最小为1,处理速度快,传输速度慢;9为最大压缩比,处理速度慢,传输速度快; 这里表示压缩级别,可以是09中的任一个,级别越高,压缩就越小,节省了带宽资源,但同时也消耗CPU资源,所以一般折中为6
gzip types text/css text/xml application/javascript;		#制定压缩的类型,线上配置时尽可能配置多的压缩类型!
gzip_disable "MSIE [1-6]\.";		#配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip vary on;					#选择支持vary header;改选项可以让前端的缓存服务器缓存经过gzip压缩的页面; 这个可以不写,表示在传送数据时,给客户端说明我使用了gzip压缩

七、配置https示例

http {
        include mime.types;
	    #include luawaf.conf;
	    #include proxy.conf;
        default_type  application/octet-stream;
        server_names_hash_bucket_size 512;
        client_header_buffer_size 32k;
        large_client_header_buffers 4 32k;
        client_max_body_size 50m;
        sendfile   on;
        tcp_nopush on;
        keepalive_timeout 60;
        tcp_nodelay on;
        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;
		fastcgi_intercept_errors on;

        gzip on;
        gzip_min_length  1k;
        gzip_buffers     4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
        gzip_vary on;
        gzip_proxied   expired no-cache no-store private auth;
        gzip_disable   "MSIE [1-6]\.";

        limit_conn_zone $binary_remote_addr zone=perip:10m;
		limit_conn_zone $server_name zone=perserver:10m;

        server_tokens off;
        access_log off;
	upstream webservers{
            server  127.0.0.1:8082;
        }
        server {
            #SSL 默认访问端口号为 443
            listen 443 ssl;
            #请填写绑定证书的域名
            server_name www.tianqi.icu; 
            #请填写证书文件的相对路径或绝对路径
            ssl_certificate  /etc/nginx/tianqi.icu_bundle.crt; 
            #请填写私钥文件的相对路径或绝对路径
            ssl_certificate_key /etc/nginx/tianqi.icu.key; 
            ssl_session_timeout 5m;
            #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
            ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
            #请按照以下协议配置
            ssl_protocols TLSv1.2 TLSv1.3;
            ssl_prefer_server_ciphers on;
            location / {
                #if ( $host = '152.136.121.33' ) {
		#    return 301 https://zhengtianqi.asia$request_uri;
		#}
                proxy_pass http://webservers;
                proxy_next_upstream http_500 http_504 http_502 error timeout invalid_header;
                # 启用keep alive
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                # 获取 xforward和真实IP
                proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_set_header  X-Real-IP  $remote_addr;
                proxy_set_header  Host $host;
            }
        }
        server {
                listen 80;
                server_name www.tianqi.icu;
                proxy_next_upstream http_500 http_504 http_502 error timeout invalid_header;
                # 启用keep alive
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                # 获取 xforward和真实IP
                proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_set_header  X-Real-IP  $remote_addr;
                proxy_set_header  Host $host;
                #把http的域名请求转成https
                #return 301 https://zhengtianqi.asia$request_uri; 
		return 301 https://www.tianqi.icu$request_uri;
        }
        #include /www/server/panel/vhost/nginx/*.conf;
}
上次编辑于:
贡献者: 郑天祺