• Haproxy常见用法


    简介

    HAProxy 提供高可用性、负载均衡以及基于 TCP 和 HTTP 应用的代理,支持虚拟主机,

    它是免费、快速并且可靠的一种解决方案。

    HAProxy 特别适用于那些负载特大的 web 站点, 这些站点通常又需要会话保持或七层处理。HAProxy 运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中.

    同时可以保护你的 web 服务器不被暴露到网络上.

    事件驱动、单一进程模型。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

    实验环境

    rhel6.5 selinux and iptables disabled

    实验主机:haproxy    172.25.12.1(server1.example.com)

    haback 172.25.12.4(server4.example.com)

    web1 172.25.12.2(server2.example.com)

    web2 172.25.12.3(server3.example.com)

    软件下载:http://haproxy.1wt.eu/

    安装

    @源码方式:

    tar zxf haproxy-1.4.23.tar.gz

    cd haproxy-1.4.23

    make TARGET=linux26(*内核版本号) ARCH=x86_64 USE_PCRE=1 PREFIX=/usr/local/haproxy install

    @yum源安装

    yum install haproxy –y         [enable yum repo `HighAvailability LoadBalancer packages` ]

     

    配置:

    vim/etc/haproxy/haproxy.cfg

    global段:设定全局参数,属于进程级的配置,通常和操作系统的配置相关

    maxconn 设定每个haproxy进程可接受的最大并发连接数。此选项等同于ulimt –n.一般设定大写 maxconn 65535

        daemon 后台运行

        user/uid,group/gid指定运行的属主

        nbproc <number>:启动进程个数,推荐使用默认的1个进程。如果设定多进程,也不要超过CPU的个数;

     

    defaults段:设定默认参数。

        mode:

    tcp:服务器和客户端建立一个全双工的连接,Haproxy充当路由。不会对七层报文做任何的检测

    http:客户端与haproxy建立一次连接,haproxy和服务端建立一次连接。

    health:直接不用

        retries:设定连接后端服务器失败重试次数

        timeout connect:haproxy连接RS最长时间

        timeout client:客户端发送数据时最长等待时间

        timeout server: 服务器回应给客户端数据最长等待时间

     

    frontend段:设定监听端口,配置ACL,使用的后端RS pool。

        option httplog: 详细的记录http的请求信息,如果记录访问数据到文件的话。默认记录很简单,源目IP

        option httpclose 表示在客户端和服务端完成第一次数据请求后,Haproxy将主动关闭此选项。另外Haproxy在http mode下支持五种连接相应模式。默认是keep alive(option http-keep-alive),连接保持开放但是在相应结束之前和下一个新的请求来之间是空闲的。另外的tunnel ("option http-tunnel")1.0-1.5-dev21的默认模式,只有第一个请求和响应才会出来,其他的只转发不做处理。不能用在http请求,问题很多。还有另外的两种:server close ("option http-server-close")forced close ("option forceclose")

     

    backend段:设定RS,一般的调度算法也在这里配置。还有RS健康检查

        算法:常见的

    1. roundrobin:基于权重的轮询,适用于RS处理能力相近的情况。不过后端服务器是有限定的
    2. static-rr: 和rr差不多的,静态的,后端服务器没有限定
    3. source:根据source IP进行hash,然后与服务器的总权数相除,选出后端的服务器。常用于session的保持。顺带提下参数hash-type [map-based,consistent]。map-based设定中,hash表包含所有在线服务器的静态数组。consitent是树状的结构。相当于MC的一致性hash,因此hash均衡性更好,适用于后端服务器经常调整。
    4. leastconn:选出连接数最少的,一般用于长连接的处理,如mysql,ldap等。不适用http这种短连接。
    5. uri基于uri生成hash表的算法,主要用于后端是缓存服务器。

      len 基于多少个字符的uri

      depth 基于多少个目录层次的uri

      例子: http://test.com/a/b/c/d/e/a.jpg

    len 3 hash的uri是/a/

    depth 3 hash的uri是/a/b/c/

         两个都指定的话,只要一个匹配到就停止

    1. url_params据url的参数来调度,用于将同一个用户的信息,都发送到同一个后端server
    2. hdr(name):基于http的首部hash,不满足条件时,使用rr

    cookie:表示允许向cookie插入serverid

    option httpchk <method> <uri> <version>:启动http的检测功能

            method:GET、POST、HEAD(常用、只返回状态码,200为正常,不返回数据)

            version:http的版本号

        server:check [port num]启用监控、inter 2000间隔2秒、rise 1检测成功1次再次添加至正常RS pool中、fall 2检测两次失败就剔除、cookie设定cookie用于回话保持、weight <0-255>权重、backup备机

     

    listen段:frontend和backend的结合体,一般配置haproxy的监控页面

     

    @测试实验效果:

    修改haproxy的配置文件(注释,添加规则)

    #frontend main *:5000

    # acl url_static path_beg -i /static /images /javascript /stylesheets

    # acl url_static path_end -i .jpg .gif .png .css .js

    #

    # use_backend static if url_static

    # default_backend app

    #

    #---------------------------------------------------------------------

    # static backend for serving up images, stylesheets and such

    #---------------------------------------------------------------------

    #backend static

    # balance roundrobin

    # server static 127.0.0.1:4331 check

    #

    #---------------------------------------------------------------------

    # round robin balancing between the various backends

    #---------------------------------------------------------------------

    # round robin balancing between the various backends

    #---------------------------------------------------------------------

    #backend app

    # balance roundrobin

    # server app1 127.0.0.1:5001 check

    # server app2 127.0.0.1:5002 check

    # server app3 127.0.0.1:5003 check

    # server app4 127.0.0.1:5004 check

     

    listen www.haproxy.com *:80

    balance roundrobin

    server web1 172.25.12.2 check

    server web2 172.25.12.3 check

    实验结果为在web1.web2之间轮询

     

    @看状态:

    defaults

    mode http

    log global

    option httplog

    option dontlognull

    option http-server-close

    option forwardfor except 127.0.0.0/8

    option redispatch

    retries 3

    timeout http-request 10s

    timeout queue 1m

    timeout connect 10s

    timeout client 1m

    timeout server 1m

    timeout http-keep-alive 10s

    timeout check 10s

    maxconn 3000

    stats     uri     /status    /添加此行

     

    @设置权重

    listen www.haproxy.com *:80

            balance roundrobin

            server web1 172.25.12.2 check weight 2

            server web2 172.25.12.3 check weight 1

     

    @建立备机

    listen www.haproxy.com *:80

            balance roundrobin

            server web1 172.25.12.2 check weight 2

            server web2 172.25.12.3 check weight 1

    server backup 172.25.12.1:8080 backup

    如果web1web2都down了那haproxy就顶上。但是如果只有还有一个存活,backup就不会启动。

    当有多个备机时,haproxy默认当所有主机都挂了只会选择其中一个来作为备机,如果认为一个不够,可以使用option allbackups

     

    当然,需要把haproxy的http    监听的端口改成8080.因为haproxy已经把redhat1的80端口占了.用途可以是    服务器故障,在haproxy发布此信息

    [root@server1 haproxy]# cat /var/www/html/index.html

    sorry! the server is broken, please try again later.

     

    @配置前端后端

    frontend www.haproxy.com *:80

        default_backend webbalance

     

    backend webbalance

        balance roundrobin

        server web1 172.25.12.2:80 check weight 2

        server web2 172.25.12.3:80 check weight 1

        server backup 172.25.12.1:8080 backup

     

    @监控界面添加用户名密码(注意删除上面的测试stats uri /status)

    listen stats_auth *:1889

        stats enable

        stats uri /status

        stats auth wxl:redhat            #管理帐号和密码,可以建立多个,换行重写

        stats auth qiandan:love*you        

        stats refresh 5s                    #刷新频率

    stats realm     Haproxy Staticstic    #输入密码时显示的提示

     

    @HAproxy访问控制

    语法:acl acl名称    acl方法    -i [匹配路径、主机等]

    acl方法:常见的

    hdr_reg(host),根据主机的正则匹配。

        acl store hdr_reg(host) –i ^(www.wxl.com|www.qiandan.com)

    hdr_dom (host), 主机名

            acl bbs hdr_dom(host) –i bbs.wxl.com

        hdr_beg(host),主机名以什么开始

        url_sub,    url中包含的子串

        path_beg,path_end.路径的以什么开始或结尾

    应用 use_backend backend_name if|unless acl1 acl2 or acl3

        block if acl4

    注意:if acl1 || acl2 acl3 表示。acl1和acl2 或者 acl2和acl3为一组

     

    控制特定IP的访问

    拒绝:

    frontend www.haproxy.com *:80

        acl wxl src 172.25.12.250 172.25.12.4

        tcp-request content reject if wxl

        default_backend webbalance

    只允许

    frontend www.haproxy.com *:80

        acl wxl src 172.25.12.250 172.25.12.4

        tcp-request content if wxl

    tcp-request content reject

        default_backend webbalance

    @重定向:

    redirect location <loc> [code <code>] <option> [{if | unless} <condition>]

    redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>]

    redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]

     

    frontend www.haproxy.com *:80

        acl wxl src 172.25.12.250

        redirect location http://server2.example.com/ if wxl

    #结果是一直在server2.exmaple.com上,当然地址栏中显示是server2的信息地址

        default_backend webbalance

     

    一些例子:

    #定向login的URL到https

    acl clear dst_port 80

    acl secure dst_port 8080

    acl login_page url_beg /login

    acl logout url_beg /logout

    acl uid_given url_reg /login?userid=[^&]+

    acl cookie_set hdr_sub(cookie) SEEN=1

     

    redirect prefix https://mysite.com set-cookie SEEN=1 if !cookie_set

    redirect prefix https://mysite.com if login_page !secure

    redirect prefix http://mysite.com drop-query if login_page !uid_given

    redirect location http://mysite.com/ if !login_page secure

    redirect location / clear-cookie USERID= if logout

     

    对于URL结尾没有"/"定向到有"/"

    acl missing_slash path_reg ^/article/[^/]*$

    redirect code 301 prefix / drop-query append-slash if missing_slash

     

    在定向http到https

    redirect scheme https if !{ ssl_fc }

     

    在主机前添加www.

    http-request redirect code 301 location www.%[hdr(host)]%[req.uri]

    unless { hdr_beg(host) -i www }

     

    重定向到错误页:代码支持400, 403, 408, 500, 502, 503, and 504.不支持404

    frontend www.haproxy.com *:80

        acl wxl src 172.25.12.250

        block if wxl

        errorloc 403 http://172.25.12.1:8080 if wxl

        default_backend webbalance

     

    还有文件的形式,但是受限也比较多的,文件大小在8-16k,否则太大被截断。

    errorfile 400 /etc/haproxy/errorfiles/400badreq.http

    errorfile 408 /dev/null # workaround Chrome pre-connect bug

    errorfile 403 /etc/haproxy/errorfiles/403forbid.http

    errorfile 503 /etc/haproxy/errorfiles/503sorry.http

     

     

    动静分离(注意用户访问的网页在web1上一定是存在的。如

        http://www.haproxy.com/test.php.那么web1上就有test.php)

    frontend www.haproxy.com *:80

        acl php    path_end -i .php

        use_backend phpapp if php

        default_backend webbalance

     

    backend webbalance

        balance roundrobin

        server web1 172.25.12.2:80 check weight 2

        server web2 172.25.12.3:80 check weight 1

        server backup 172.25.12.1:8080 backup

     

    backend phpapp

        server web1 172.25.12.2:80 check

     

        

     

    @定义haproxy日志

    log 127.0.0.1 local0 err            

    日志级别err、warning、info、debug。一般选择err,性能才不会影响

     

    # vi /etc/rsyslog.conf #接受 haproxy 日志

    $ModLoad imudp             #imudp模块名,支持UDP协议

    $UDPServerRun 514

    local0.*             /var/log/haproxy.log

    还需修改/etc/sysconfig/rsyslog

    SYSLOGD_OPTIONS="-c 2 -r -m 0"

    /etc/init.d/rsyslog restart

     

     

    后端获取客户端IP

    haproxy设定:option forwardfor [expect <network>] [header <name>] [if-none]

    一般定义在listen段

     

    # Public HTTP address also used by stunnel on the same machine

    frontend www

    mode http

    option forwardfor except 127.0.0.1 # stunnel already adds the header

     

    # Those servers want the IP Address in X-Client

    backend www

    mode http

    option forwardfor header X-Client

     

    Nginx日志中获取访客真实IP

    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 /var/log/nginx/localhost.access.log  main;

    Apache:    

    LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined

    将其修改为:

    LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i" "%{X-Forwarded-For}i" " combined

    Tomcat

    1、修改tomcat的server.xml,如:vi /usr/local/tomcat7/conf/server.xml。

    2、修改pattern为pattern='%{X-Forwarded-For}i %h %l %u %t "%r" %s %b',则会记录headers头中的X-Forwarded-For信息。

     

    生产环境haproxy的Iptables

    一般情况下,由于Haproxy的所接受的流量都比较大,所以基本上要把本机的iptables关闭,而是使用专门的硬件防火墙

    高可用Haproxy

    与keepalived结合(高可用+负载均衡)

    在haproxy haback 上安装keepalived

    yum install -y keepalived.x86_64 --nogpgcheck(提示key有问题)

    编写keepalives调用haproxy的脚本

    [root@server1 keepalived]# cat check_haproxy.sh

    #!/bin/bash

    service haproxy status &> /dev/null || service haproxy restart &> /dev/null

     

    if [ $? -ne 0 ];then

    service keepalived stop &> /dev/null

    fi

    测试脚本。并给以执行权限 +x 否则 keepalived对haproxy的检测不成功

    MAster端haproxy的keepalived配置文件

    [root@server1 keepalived]# cat keepalived.conf

    ! Configuration File for keepalived

     

    vrrp_script check_haproxy {

        script "/etc/keepalived/check_haproxy.sh"

     

    #检测的另一种方式

    #script "killall -0 haprxy"        #设置探测Haproxy访问运行状态

        

    interval 2

        weight 2

    }

        

    global_defs {

    notification_email {

    root@localhost

    }

    notification_email_from keepalived@server1.example.com

    smtp_server 127.0.0.1

    smtp_connect_timeout 30

    router_id LVS_DEVEL

    }

     

    vrrp_instance VI_1 {

    state MASTER            #BACKUP

    interface eth0

    virtual_router_id 51

    priority 100                 #BACKUP端小于此值

    advert_int 1

        nopreempt                #设定主机恢复后,不回切

    authentication {

    auth_type PASS

    auth_pass 1111

    }

     

        #配置报警

        notify_master "/path/to/alert_scripts.py master"

    notify_backup "/path/to/alert_scripts.py backup"

    notify_falut "/path/to/alert_scripts.py fault"

     

     

    virtual_ipaddress {

    172.25.12.100

    }

    track_script {

    check_haproxy

    }

    }

    如果有多个VIP的话,可以考虑做双主,keepalived启多个vrrp_instance

  • 相关阅读:
    iOS设计模式:观察者
    Java面向接口编程小例子
    《The DeadLine》(《最后期限》) 读后感
    Codeforces Round #395 Div1的A题Timofey and a tree
    重写和强制转换再调用能编译但不能运行
    Java继承和静态-加载顺序
    C++之pair
    用Java面向对象思想实现一个微博的功能(未完)
    Java对象在内存图示
    Java中OOP对象和引用
  • 原文地址:https://www.cnblogs.com/wxl-dede/p/5193892.html
Copyright © 2020-2023  润新知