haproxy安装以及简单示例

haproxy是个高性能的tcp和http的反向代理。它就是个代理。不像nginx还做web服务器

haproxy安装

  1. 下载及安装haproxy(安装包下载需FQ)

    $ cd /opt/k8s/keepalive-haproxy
    $ wget https://www.haproxy.org/download/2.1/src/haproxy-2.1.3.tar.gz
    $ tar -xzvf haproxy-2.1.3.tar.gz
    $ cd haproxy-2.1.3/
    $ make TARGET=linux53 CPU=x86_64 USE_OPENSSL=1 USE_SYSTEMD=1
        $ mkdir -p /opt/k8s/haproxy
    $ make install PREFIX=/opt/k8s/haproxy/
    
    
    • USE_OPENSSL=1 开启https

    • USE_SYSTEMD=1 指定为systemd模式,否则不能通过systemd进行启动,报错信息

      master-worker mode with systemd support (-Ws) requested, but not compiled. Use master-worker mode (-W) if you are not using Type=notify in your unit file or
      

recompile with USE_SYSTEMD=1.

	```
* TARGET=linux53 CPU=x86_64参数,通过uname -a 查看机器对应的系统内核信息决定
	
	```
	$ uname -a
	Linux master 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
	
	```
* PREFIX 指定安装路径
  1. 使用随安装包提供的配置示例启动haproxy

    $ cd /opt/k8s/keepalive-haproxy/haproxy-2.1.3
    $ mkdir /opt/k8s/haproxy/conf
    # 复制示例配置文件
    $ cp examples/option-http_proxy.cfg /opt/k8s/haproxy/conf/
    # 启动
    $ /opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/option-http_proxy.cfg
    
    

配置 haproxy 日志

因为haproxy会使用rsyslog进行日志处理,所以需要配置rsyslog

  1. 查看rsyslog的配置,

    $ cat /etc/rsyslog.conf
    
    #
    # Include all config files in /etc/rsyslog.d/
    #
    $IncludeConfig /etc/rsyslog.d/*.conf
    
    
    • /etc/rsyslog.conf 这个是ubuntu系统下的路径,其他系统要查看相对应的配置
    • 意思rsyslog会读取/etc/rsyslog.d/下面的 *.conf来进行日志配置
  2. 在/etc/rsyslog.d/下追加haproxy.conf

    $ cat > haproxy.conf<< EOF
    $ModLoad imudp
    $UDPServerRun 514
    local0.*     /var/log/haproxy.log
    EOF
    
    
    • 将haproxy日志写入到/var/log/haproxy.log
  3. 重启rsyslog

    $ systemctl restart rsyslog
    
    
  4. 停掉演示例子

    $ ps -elf | grep -e PID -e haproxy
    $ kill -9 ${上一步骤查出的PID}
    
    

下面通过具体例子来说明如何利用haproxy对我们的业务进行负载均衡

  1. 部署图如下

    • 客户端调用haproxy:8089,haproxy利用指定负载均衡算法,将请求代理到具体的后端服务
    • haproxy在9188上启动监听,响应haproxy自身的状态信息
  2. 对应的haproxy配置文件

    $ cd /opt/k8s/haproxy/conf
    cat >haproxy.cfg << EOF
    global
        maxconn         20000
        log             127.0.0.1 local0 info
        uid             200
    
        gid             200
        chroot          /opt/k8s/haproxy
        nbproc          1
        daemon
    
    defaults
            mode http
            retries 3
            timeout connect 10s
            timeout client 20s
            timeout server 30s
    
    frontend web
            bind            *:8089
            mode            http
            log             global
            option          httplog
            option          dontlognull
            option          nolinger
            option          http_proxy
            maxconn         8000
            timeout client  30s
    
            default_backend web-srv
    
    
    backend web-srv
            mode            http
            option  redispatch
            option  abortonclose
            balance roundrobin
            cookie  SERVERID
            option          httpchk GET /health
            server web1 192.168.0.114:8086 check cookie server1 inter 2000 fall 3 weight 30
            server web2 192.168.0.107:8086 check cookie server1 inter 2000 fall 3 weight 30
    listen admin_stats
            bind 0.0.0.0:9188
            mode http
            stats uri /haproxy-status
            stats auth admin:admin123
    EOF
    
    
  3. 验证配置文件

    
    $ /opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/haproxy.cfg -c
    Configuration file is valid
    
    
    • 追加 -c 参数,只针对配置文件格式内容进行验证,并不真正启动服务
  4. 启动后端服务

    后端服务采用spring boot编写的一个web程序,里面提供了两个restful API,一个用来做health检查,另一个用来调用测试,在application.yml中将端口设置成8086。

    核心代码如下:

    @RequestMapping("/header/list")
    public String listHeader(HttpServletRequest request) {
    
    	Enumeration<String> headers = request.getHeaderNames();
    
    	while (headers.hasMoreElements()) {
    		String header = headers.nextElement();
    		log.info(header + "  is " + request.getHeader(header));
    	}
    
    	return "OK";
    }
    
    @RequestMapping("/health")
    public String health(HttpServletRequest request) {
    
    	return "OK";
    }
    
    

    将服务打成可执行jar后,在192.168.0.107、和192.168.0.114上启动

  5. 启动haproxy

    $ cd /opt/k8s/haproxy
    $ ./sbin/haproxy -f conf/haproxy.cfg
    
    
  6. 查看统计页面

    • 可以看到对应的后端web1、web2都正常运行
  7. 访问 http://192.168.0.107:8089/header/list,观察启动的两个后端服务的日志,可以看到每次haproxy会选一个后端服务响应我们的请求

  8. 查看haproxy日志

    $ tail -10 /var/log/haproxy.log
    Mar 13 10:24:14 localhost haproxy[19512]: 192.168.0.108:56975 [13/Mar/2020:10:24:14.523] web web-srv/web1 0/0/0/11/11 200 181 - - ---- 2/2/0/0/0 0/0 "GET /header/list HTTP/1.1"
    Mar 13 10:24:14 localhost haproxy[19512]: 192.168.0.108:56975 [13/Mar/2020:10:24:14.561] web web-srv/web2 1/0/0/4/5 200 1117 - - ---- 2/2/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"
    Mar 13 10:28:50 localhost haproxy[19512]: 192.168.0.108:57713 [13/Mar/2020:10:28:50.103] web web-srv/web1 0/0/4/12/16 200 181 - - ---- 2/1/0/0/0 0/0 "GET /header/list HTTP/1.1"
    
    

模拟故障、故障恢复

  1. 停掉107服务器上的spring boot工程

  2. 再次观察haproxy的统计页面

    • 其中107服务器上对应的后端服务web2被标记成了DOWN
    • 此时继续请求http://192.168.0.107:8089/header/list,会发现haproxy只把请求转发给正常的服务器114
  3. 恢复107服务器上的spring boot服务

  4. 再次观察haproxy的统计页面,会发现web2状态重新变成UP,107上的spring boot也能收到haproxy分发过来的请求。

这样利用haproxy的负载技术,不仅仅实现了流量的分发,也在一定程度上提升了系统容错性

将haproxy设置成系统服务

采用此模式,编译阶段必须指定USE_SYSTEMD=1

  1. 编写haproxy服务启动脚本

    $ cat > //etc/systemd/system/haproxy.service <<"EOF"
    [Unit]
    Description=HAProxy Load Balancer
    After=network.target
    
    [Service]
    ExecStartPre=/opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/haproxy.cfg   -c -q
    ExecStart=/opt/k8s/haproxy/sbin/haproxy -Ws -f /opt/k8s/haproxy/conf/haproxy.cfg
    ExecReload=/bin/kill -USR2 $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    
    EOF
    
    
    • 启动参数-W 以master-worker模式工作,在此模式下可通过发送SIGUSR2信号重新加载haproxy
  2. 启动haproxy

    $ systemctl daemon-reload
    $ systemctl start haproxy
    $ systemctl status haproxy
    ● haproxy.service - HAProxy Load Balancer
       Loaded: loaded (/etc/systemd/system/haproxy.service; disabled; vendor preset: enabled)
       Active: active (running) since Fri 2020-03-13 11:48:25 CST; 13s ago
      Process: 14757 ExecStartPre=/opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/haproxy.cfg -c -q (code=exited, status=0/SUCCESS)
     Main PID: 14758 (haproxy)
        Tasks: 2 (limit: 4915)
       CGroup: /system.slice/haproxy.service
               ├─14758 /opt/k8s/haproxy/sbin/haproxy -Ws -f /opt/k8s/haproxy/conf/haproxy.cfg
               └─14759 /opt/k8s/haproxy/sbin/haproxy -Ws -f /opt/k8s/haproxy/conf/haproxy.cfg
    
    
    • 状态为running表示正常,否则 通过 journalctl -u haproxy查看具体原因
  3. 设置成开机启动

    $ systemctl enable haproxy.service
    
    

遇到问题

  1. configure: error: no acceptable C compiler found in $PATH

    $ apt install gcc
    
    
  2. Can not include OpenSSL headers files

    $ apt-get install libssl-dev
    
    
  3. systemd/sd-daemon.h: 没有那个文件或目录

    $ apt install libsystemd-dev
    
    
  4. 400 bad request
    一开始不懂haproxy的配置语法,在backend中追加了

    option  http_proxy  
    
    

    去掉这个配置就可以了

posted @ 2020-03-13 12:19  高枫_henu  Views(1043)  Comments(0Edit  收藏  举报