• Linux系统中使用Nignx配置反向代理负载均衡


    使用nginx实现动静分离的负载均衡集群

    Nginx官网源码包下载链接:http://nginx.org/en/download.html
    官方文档:http://nginx.org/en/docs/

    Nginx简介;

    • 概述:Nginx是一款由俄罗斯开发的开源的高性能HTTP服务器和反向代理服务器,同时支持IMAP/POP3/SMTP代理服务,其性能优势着为显著,官网上称:单台nginx服务器可以处理50000并发;

    • 特点:高性能、稳定、消耗硬件资源小、能够处理大并发,主要用于静态的解析,动静页面的分离;

    • 优势:

      1.作为Web服务器,nginx处理静态文件、索引文件以及自动索引效率非常高。

      2.作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站运行速度。

      3.作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持HTTP代理服务器,对外进行服务。同时支持简单的容错和利用算法进行负载均衡。

    • 在性能方面,Nginx在实现上非常注重效率。它采用内核Poll模型,可以支持更多的并发连接,最大可以支持对50 000个并发连接数的响应,而且占用很低的内存资源。

    • 在稳定性方面,Nginx采取了分阶段资源分配技术,使得对CPU与内存的占用率非常低。Nginx官方表示Nginx保持10 000个没有活动的连接,这些连接只占2.5M内存,因此,类似DOS这样的攻击对Nginx来说基本上是没有任何作用的。

    • 在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到7*24小时的不间断运行。

    Nginx实现原理;

    Nginx核心组件:

    核心模块:HTTP模块、EVENT事件模块、MAIL模块。

    基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块、HTTP Rewrite模块

    第三方模块:HTTP Upstream Request Hash模块、Notice模块、HTTP Access Key模块。

    Nginx模块分类(基于功能):

    • Handlers:处理器模块,此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。

    • Filters:过滤器模块,此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。

    • Proxies:代理类模块,此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

    Nginx的进程模型:

    单工作进程模式:除主进程外,还有一个工作进程,工作进程是单线程的,默认为此模式;

    多工作进程模式:每个工作进程包含多个线程;

    Nginx master进程:

    1.接收外界传递给Nginx的信号,进而管理服务的状态等;

    2.管理worker进程,向各worker进程发送信号,监控worker进程的运行状态,当worker进程异常情况下退出后,会自动重新启动新的worker进程;

    3.master进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。

    worker进程:

    1.处理基本的网络事件,多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核♥数一致;

    Nginx支持高并发的原因;

    I/O模型之select:

    1.每个连接对应一个描述。select模型受限于 FD_SETSIZE(即进程最大打开的描述符数),linux2.6.35为1024,实际上linux每个进程所能打开描数字的个数仅受限于内存大小,然而在设计select的系统调用时,却是参考FD_SETSIZE的值。可通过重新编译内核更改此值,但不能根治此问题,对于百万级的用户连接请求即便增加相应进程数,仍显得杯水车薪;
    2、select每次请求都会扫描一个文件描述符的集合,这个集合的大小是作为select第一个参数传入的值。但是每个进程所能打开文件描述符若是增加了,扫描的效率也将减小;
    3、内核到用户空间,采用内存复制方式传递信息,这样就增加了不必要的复制延迟;
    I/O模型之epoll模型:

    1.请求无文件描述字大小限制,仅与内存大小相关;

    2.epoll返回时已经明确的知道哪个socket fd发生了什么事件,不用像select那样再一个个比对;

    3.内核到用户空间,采用共享内存方式传递消息,使用mmap加速内核与用户空间的消息传递;

    apache:Apache 2.2.9之前只支持select模型,2.2.9之后支持epoll模型;

    Nginx:支持epoll模型;

    LB负载均衡集群分两类: LVS (四层)和 nginx或haproxy (七层)

    客户端通过访问分发器的VIP来访问网站

           |
    

    现在应用更复杂,比如现在网站页面有: .php .html .png .jpeg .jsp 等, 有动态页面有静态页面。静态页面一般是不变的,想访问更快些,前面学习过SQUID。

           |
    

    但是前面的LVS是四层的。基于IP的。现在需要在应用层基于不同的应用进行分发。

           |
    

    七层LB , Nginx / Haproxy都可以支持7层LB

    理想的效果是这样:

    静态文件处理:可以使用nginx 或apache

    动文件处理: apache ,tomcat

    图片文件处理: squid

    使用nginx实现动静分离的负载均衡集群

    Nginx 负载均衡基础知识

    Nginx 的 upstream 负载的5种方式,目前最常用 前3 种方式

    • 1)、轮询(默认)

      每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

    • 2)、weight

    指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。

    • 3)、ip_hash

      每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。

    • 4)、fair(第三方)

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

    • 5)、url_hash(第三方) url哈西

    按访问url的hash结果来分配请求,使同样的url定向到同一个后端服务器,后端服务器为缓存时比较有效

    正向代理和反向代理

    反向代理,外部机器通过网关访问网关后面服务器上的内容,网关起到了反向代理的功能,我们平时通过浏览器访问远程的web服务器大都是这样实现的。

    正向代理,就是上面的过程反过来,我们平时说的代理上网,局域网中的用户通过网关做代理访问外部的网络。

    使用nginx实现负载均衡和动静分离

    • 源码编译安装nginx

    一、安装nginx时必须先安装相应的编译工具和相关依赖

    [root@harry63 ~]# yum -y install gcc gcc-c++ autoconf automake
    [root@harry63 ~]# yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
    

    zlib:nginx提供gzip模块,需要zlib库支持
    openssl:nginx提供ssl功能
    pcre:支持地址重写rewrite功能

    • 安装nginx:
    [root@harry63 ~]# ll nginx-1.8.0.tar.gz  -h  #整个nginx文件不到只813K,很小
    -rw-r--r-- 1 root root 813K Jul 14 20:17 nginx-1.8.0.tar.gz
    [root@harry63 ~]# tar -zxvf nginx-1.8.0.tar.gz  -C /usr/local/src/
    [root@harry63 ~]# cd /usr/local/src/nginx-1.8.0/
    [root@harry63 ~]# ./configure --prefix=/usr/local/nginx  --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module
    
    ##查看参数:
    [root@harry63 nginx-1.8.0]# ./configure  --help | grep mp4
    
    
    • 参数说明:

    --with-http_dav_module 启用ngx_http_dav_module支持(增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法)默认情况下为关闭,需编译开启

    --with-http_stub_status_module启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态)

    --with-http_addition_module 启用ngx_http_addition_module支持(作为一个输出过滤器,支持不完全缓冲,分部分响应请求)

    --with-http_sub_module 启用ngx_http_sub_module支持(允许用一些其他文本替换nginx响应中的一些文本)

    --with-http_flv_module 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件)

    --with-http_mp4_module 启用对mp4文件支持(提供寻求内存使用基于时间的偏移量文件)

    • 编译和安装: (查看CPU逻辑数cat /proc/cpuinfo | grep processor | wc -l)
    [root@harry63 ~]#make -j 4
    [root@harry63 ~]#make  install
    
    • 生成运行nginx的用户:
    [root@harry63 nginx-1.8.0]# useradd -u 8000 -s /sbin/nologin  nginx
    
    [root@harry63 nginx-1.8.0]# id !$
    id nginx
    uid=8000(nginx) gid=8000(nginx) groups=8000(nginx)
    
    
    • nginx主要目录结构说明:

    [root@harry63 /]# ls /server/nginx-1.8.0/

    conf html logs sbin

    conf #配置文件

    conf #配置文件

    html #网站根目录

    logs #日志

    sbin #nginx启动脚本

    • 主配置文件:
    [root@harry63 /]# ls /server/nginx-1.8.0/conf/nginx.conf
    
    • 启动nginx:
    [root@harry63 /]# /server/nginx-1.8.0/sbin/nginx   
    [root@harry63 /]# netstat -antup | grep :80
    tcp        0     0 0.0.0.0:80                 0.0.0.0:*                   LISTEN      5281/httpd       
    
    [root@harry63 /]# netstat -antup | grep :80
    
    
    • 开机启动:

    [root@harry63 nginx-1.8.0]# echo '/server/nginx-1.8.0/sbin/nginx & ' >> /etc/rc.local

    测试在浏览器访问:

    http://192.168.1.63/

    nginx服务日常操作:

    • 测试配置文件语法:
    [root@harry63 nginx-1.8.0]# /server/nginx-1.8.0/sbin/nginx -t
    nginx: the configuration file /server/nginx-1.8.0/conf/nginx.confsyntax is ok
    nginx: configuration file /server/nginx-1.8.0/conf/nginx.conf test is successful
    
    • 重新加载配置文件
    [root@harry63 nginx-1.8.0]# /server/nginx-1.8.0/sbin/nginx -s reload
    
    • 关闭nginx
    [root@harry63 /]# /server/nginx-1.8.0/sbin/nginx -s stop
    [root@harry63 /]# /server/nginx-1.8.0/sbin/nginx -s start #没有start参数
    nginx: invalid option: "-s start"
    

    配置nginx成为分发器,实现动静分离

    [root@harry63 conf]# cd  /server/nginx-1.8.0/conf    #配置文件目录
    [root@harry63 conf]# cp nginx.conf nginx.conf.back   #备份一下配置文件
    [root@harry63 conf]# vim nginx.conf    
    [root@harry63 nginx-1.8.0]# vim /server/nginx-1.8.0/conf/nginx.conf  #指定启动nginx用户
    改:# user nobody;
    为:user nginx nginx;  
    
    

    改:

    location / {
    
     root   html;
    
    index  index.html index.htm;          #在location / { 。。。} 中添加以下内容 #定义分发策略
    
    location / {
    
    root   html;
            index index.html index.htm;
    if ($request_uri ~* .html$){
    
                   proxy_pass http://htmlservers;
    
          }   
    
       if ($request_uri ~* .php$){
    
                   proxy_pass http://phpservers;
    
          }  
    
                  proxy_pass http://picservers;
          }
    

    把以下内容注释掉,否则php文件直接在nginx服务器上解析了,不再解析给后端服务器:

    location ~ .php$ {
     73 #           root          html;
     74 #           fastcgi_pass   127.0.0.1:9000;
     75 #           fastcgi_index  index.php;
     76 #           fastcgi_param  SCRIPT_FILENAME  /server/nginx-1.8.0/html$fastcgi_script_name;
     77 #           include        fastcgi_params;
     78 #       }
    
    • 定义负载均衡设备的 Ip

    在配置文件nginx.conf的最后一行}前,添加以下内容:

        upstream  htmlservers {   #定义负载均衡服务器组名称
       server 192.168.1.62:80;  
       server 192.168.1.64:80;
         }
         
          upstream phpservers{
        server 192.168.1.62:80;
        server 192.168.1.64:80;
        }
        upstream picservers {
        server 192.168.1.62:80;
        server 192.168.1.64:80;
        }
    

    后期可根据需要,配置成具体业务的IP地址

    wq保存退出。

    • 重新加载nginx服务器配置文件:
    [root@harry63 conf]# /server/nginx-1.8.0/sbin/nginx -t
    nginx: the configuration file /server/nginx-1.8.0/conf/nginx.conf syntax is ok
    nginx: configuration file /server/nginx-1.8.0/conf/nginx.conf test is successful
    
    [root@harry63 conf]# /server/nginx-1.8.0/sbin/nginx -s reload
    
    • 配置web服务器:
    [root@harry62 html]# yum install httpd  php -y
    
    • 生成静态测试文件:
    [root@harry62 html]#echo 192.168.1.62 > /var/www/html/index.html
    
    • 生成动态测试文件:
    [root@harry62 html]#vim  /var/www/html/test.php   #写如以下内容:
    192.168.1.62-php
    <?php
    phpinfo();
    ?>
    
    • 生成图片文件:

    上传如下图片,到“Rich七哥62网站/var/www/html/目录下:

    • 启动apache服务器:

    [root@harry62 html]# service httpd restart

    • 配置后端服务器: Rich七哥64

    IP: 192.168.1.64

    • 配置web服务器:

    [root@harry64 html]# yum install httpd php -y

    • 生成静态测试文件:

    echo 192.168.1.64 > /var/www/html/index.html

    • 生成动态测试文件:
    vim  /var/www/html/test.php   #写如以下内容:
    192.168.1.64-php
    <?php
    phpinfo();
    ?>
    

    生成图片文件:

    上传图片,到“Rich七哥64网站/var/www/html/目录下:

    [root@harry64 html]# service httpd restart

    到此nginx实现负载均衡结束。

    测试负载均衡

    测试转发静态页面:

    http://192.168.1.63/

    http://192.168.1.63/

    测试转发动态页面:

    http://192.168.1.63/test.php

    http://192.168.1.63/test.php

    测试转发图片:

    http://192.168.1.63/pic.jpg

    http://192.168.1.63/pic.jpg

    测试自动剔除坏的节点:

    [root@harry64 html]# service httpd stop

    Stopping httpd: [ OK ]

    访问:

    http://192.168.1.63/pic.jpg

    http://192.168.1.63/pic.jpg

    都访问到:

    测试性能:

    扩展: 文件打开数过多

    [root@harry64 html]# ab -n 1000 -c 1000 http://192.168.1.62/index.html #运行正常

    [root@harry64 html]# ab -n 2000 -c 2000 http://192.168.1.62/index.html #报错

    This is ApacheBench, Version 2.3 <$Revision: 655654 $>

    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

    Licensed to The Apache Software Foundation, http://www.apache.org/

    Benchmarking 192.168.1.62 (be patient)

    socket: Too many open files (24) # 测试时,一次打开的socket文件太多。

    ulimit -a #查看

    ulimit -n

    1024

    系统默认一个进程最多同时允许打开1024的文件

    解决:

    ulimit -n 10240 #报错的解决方法

    Nginx负载的5种策略设置方法(在nginx配置文件里添加):

    1、轮询(默认)

    每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

    upstream backserver {
    server 192.168.1.62;
    server 192.168.1.64;
    }
    
    

    2、指定权重

    指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

    upstream backserver {
    server 192.168.1.62 weight=1;
    server 192.168.1.64 weight=2;
    }
    

    3、IP绑定 ip_hash

    每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

    upstream backserver {
    ip_hash;
    server 192.168.1.62:80;
    server 192.168.1.64:80;
    }
    

    4、fair(第三方)

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

    upstream backserver {
    server server1;
    server server2;
    fair;
    }
    

    5、url_hash(第三方)

    按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

    upstream backserver {
    server squid1:3128;
    server squid2:3128;
    hash $request_uri;
    hash_method crc32;
    }
    
    

    总结,扩展:

    如有tomcat ,apache,squid 配置为如下:

    [root@harry63 conf]# vim nginx.conf  #  在最后添加以下内容。   定义Rich七哥服务器组
    
    upstream tomcat_servers {
            server 192.168.1.2:8080;
           server  192.168.1.1:8080;
           server  192.168.1.11:8080;
    }
    
    upstream apache_servers {
           server  192.168.1.5:80;
           server  192.168.1.177:80;
           server  192.168.1.15:80;
    }
    
    upstream squid_servers {
           server  192.168.1.26:3128;
           server  192.168.1.55:3128;
           server  192.168.1.18:3128;
    
    }
    
  • 相关阅读:
    office365离线安装
    c#使用emit方法DB,实体相互转换
    c#采用emit将DataTable转List
    c#将List转换成DataTable
    c#将List转换成DataTable(采用Emit)
    聊聊编程开发的数据库批量插入(sql)
    c#随便聊聊数据库操作
    c#聊聊文件数据库kv
    WPF几个样式
    c#(IronPython)调用Python方法
  • 原文地址:https://www.cnblogs.com/fusheng11711/p/11803860.html
Copyright © 2020-2023  润新知