nginx反向代理和负载均衡策略实战案例

欢迎关注:glmapper_2018php

引言

先来看下nginx在web服务器排名上的趋势: html

存在即合理,那为何要使用nginx呢?这得看看nginx能帮咱们作些什么。nginx

首先,nginx能作反向代理【关于反向代理和正向代理此处不作说明了,感兴趣的小伙伴自行谷歌】;比方说,我想在本地使用 www.glmapper1.com 的域名去访问www.taobao.com。那么这个时候咱们就能够经过nginx去实现。web

再者,nginx能实现负载均衡,什么是负载均衡呢?就是说应用部署在不一样的服务器上,可是经过统一的域名进入,nginx则对请求进行分发,将请求分发到不一样的服务器上去处理,这样就能够有效的减轻了单台服务器的压力。算法

在上面这两种状况下,nginx服务器的做用都只是做为分发服务器,真正的内容,咱们能够放在其余的服务器上,这样来,还能起到一层安全隔壁的做用,nginx做为隔离层。spring

解决跨域问题后端

同源:URL由协议、域名、端口和路径组成,若是两个URL的协议、域名和端口相同,则表示他们同源。跨域

浏览器的同源策略:浏览器的同源策略,限制了来自不一样源的"document"或脚本,对当前"document"读取或设置某些属性。从一个域上加载的脚本不容许访问另一个域的文档属性。浏览器

由于nginx和tomcat不能共用同一端口,url同样,端口不一样,这样就会有跨域问题。缓存

PS:点到为止,这里本次测试没有涉及,就不妄自菲薄了!!!

配置文件解析

配置文件主要由四部分组成:

  • main(全区设置)
  • server(主机配置)
  • http(控制着nginx http处理的全部核心特性)
    • location(URL匹配特定位置设置)。
  • upstream(负载均衡服务器设置)

下面以默认的配置文件来讲明下具体的配置文件属性含义:

#Nginx的worker进程运行用户以及用户组
#user nobody;

#Nginx开启的进程数
worker_processes  1;

#定义全局错误日志定义类型,[debug|info|notice|warn|crit]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#指定进程ID存储文件位置
#pid logs/nginx.pid;


#事件配置
events {
    
    
    #use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
    #epoll模型是Linux内核中的高性能网络I/O模型,若是在mac上面,就用kqueue模型。
    use kqueue;
    
    #每一个进程能够处理的最大链接数,理论上每台nginx服务器的最大链接数为worker_processes*worker_connections。理论值:worker_rlimit_nofile/worker_processes
    worker_connections  1024;
}

#http参数
http {
    #文件扩展名与文件类型映射表
    include       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 logs/access.log main;

    #开启高效传输模式
    sendfile        on;
    
    #防止网络阻塞
    #tcp_nopush on;

    #客户端链接超时时间,单位是秒
    #keepalive_timeout 0;
    keepalive_timeout  65;

    #开启gzip压缩输出
    #gzip on;

    #虚拟主机基本设置
    server {
        #监听的端口号
        listen       80;
        #访问域名
        server_name  localhost;
        
        #编码格式,若是网页格式与当前配置的不一样的话将会被自动转码
        #charset koi8-r;

        #虚拟主机访问日志定义
        #access_log logs/host.access.log main;
        
        #对URL进行匹配
        location / {
            #访问路径,可相对也可绝对路径
            root   html;
            #首页文件,匹配顺序按照配置顺序匹配
            index  index.html index.htm;
        }
        
        #错误信息返回页面
        #error_page 404 /404.html;
        
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        
        #访问URL以.php结尾则自动转交给127.0.0.1
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        # proxy_pass http://127.0.0.1;
        #}
        
        #php脚本请求所有转发给FastCGI处理
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        # root html;
        # fastcgi_pass 127.0.0.1:9000;
        # fastcgi_index index.php;
        # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
        # include fastcgi_params;
        #}

        #禁止访问.ht页面
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        # deny all;
        #}
    }

    #第二个虚拟主机配置
    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    # listen 8000;
    # listen somename:8080;
    # server_name somename alias another.alias;

    # location / {
    # root html;
    # index index.html index.htm;
    # }
    #}


    #HTTPS虚拟主机定义
    # HTTPS server
    #
    #server {
    # listen 443 ssl;
    # server_name localhost;

    # ssl_certificate cert.pem;
    # ssl_certificate_key cert.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;
    # }
    #}
    include servers/*;
}

复制代码

反向代理实例

假设我如今须要本地访问www.baidu.com;配置以下:

server {
    #监听80端口
    listen 80;
    server_name localhost;
     # individual nginx logs for this web vhost
    access_log /tmp/access.log;
    error_log  /tmp/error.log ;

    location / {
        proxy_pass http://www.baidu.com;
    }
复制代码

验证结果:

能够看到,我在浏览器中使用localhost打开了百度的首页...

负载均衡实例

下面主要验证最经常使用的三种负载策略。虚拟主机配置:

server {
    #监听80端口
    listen 80;
    server_name localhost;
    
    # individual nginx logs for this web vhost
    access_log /tmp/access.log;
    error_log  /tmp/error.log ;

    location / {
        #负载均衡
        #轮询 
        #proxy_pass http://polling_strategy;
        #weight权重
        #proxy_pass http://weight_strategy;
        #ip_hash
        # proxy_pass http://ip_hash_strategy;
        #fair
        # proxy_pass http://fair_strategy;
        #url_hash
        # proxy_pass http://url_hash_strategy;
        #重定向
        #rewrite ^ http://localhost:8080;
    }
复制代码

轮询策略

# 一、轮询(默认)
# 每一个请求按时间顺序逐一分配到不一样的后端服务器,若是后端服务器down掉,能自动剔除。 
upstream polling_strategy { 
    server glmapper.net:8080; # 应用服务器1
    server glmapper.net:8081; # 应用服务器2
} 
复制代码

测试结果(经过端口号来区分当前访问):

8081:hello
8080:hello
8081:hello
8080:hello
复制代码

权重策略

#二、指定权重
#指定轮询概率,weight和访问比率成正比,用于后端服务器性能不均的状况。 
upstream  weight_strategy { 
    server glmapper.net:8080 weight=1; # 应用服务器1
    server glmapper.net:8081 weight=9; # 应用服务器2
}
复制代码

测试结果:总访问次数15次,根据上面的权重配置,两台机器的访问比重:2:13;知足预期!

ip hash策略

#三、IP绑定 ip_hash
#每一个请求按访问ip的hash结果分配,这样每一个访客固定访问一个后端服务器,
#能够解决session的问题;在不考虑引入分布式session的状况下,
#原生HttpSession只对当前servlet容器的上下文环境有效
upstream ip_hash_strategy { 
    ip_hash; 
    server glmapper.net:8080; # 应用服务器1
    server glmapper.net:8081; # 应用服务器2
} 
复制代码

iphash 算法:ip是基本的点分十进制,将ip的前三个端做为参数加入hash函数。这样作的目的是保证ip地址前三位相同的用户通过hash计算将分配到相同的后端server。做者的这个考虑是极为可取的,所以ip地址前三位相同一般意味着来着同一个局域网或者相邻区域,使用相同的后端服务让nginx在必定程度上更具备一致性。

为何说要解释下iphash,由于采坑了;和猪弟在进行这个策略测试时使用了5台机器来测试的,5台机器均在同一个局域网内【192.168.3.X】;测试时发现5台机器每次都路由到了同一个服务器上,一开始觉得是配置问题,可是排查以后也排除了这个可能性。最后考虑到多是对于同网段的ip作了特殊处理,验证以后确认了猜想。

其余负载均衡策略

这里由于须要安装三方插件,时间有限就不验证了,知悉便可!

#四、fair(第三方)
#按后端服务器的响应时间来分配请求,响应时间短的优先分配。 
upstream fair_strategy { 
    server glmapper.net:8080; # 应用服务器1
    server glmapper.net:8081; # 应用服务器2
    fair; 
} 

#五、url_hash(第三方)
#按访问url的hash结果来分配请求,使每一个url定向到同一个后端服务器,
#后端服务器为缓存时比较有效。 
upstream url_hash_strategy { 
    server glmapper.net:8080; # 应用服务器1
    server glmapper.net:8081; # 应用服务器2 
    hash $request_uri; 
    hash_method crc32; 
} 
复制代码

重定向rewrite

location / {
    #重定向
    #rewrite ^ http://localhost:8080;
}
复制代码

验证思路:本地使用localhost:80端口进行访问,根据nginx的配置,若是重定向没有生效,则最后会停留在当前localhost:80这个路径,浏览器中的地址栏地址不会发生改变;若是生效了则地址栏地址变为localhost:8080;

经过验证,知足预期!

总结

本文先对nginx的做用和基本的配置作了简单说明;而后经过负载均衡的实例测试了不一样负载均衡算法的具体应用反馈结果。帮助本身更加深入的理解nginx服务器中的一些配置细节。感谢刘秘提供的helloworld程序【基于springboot的脚手架,有须要的能够联系他获取;还有就是刘秘是个男的...😜】

参考

  • http://nginx.org/
  • https://www.nginx.com/
  • http://www.sohu.com/a/161411719_324809
相关文章
相关标签/搜索