`
jimmee
  • 浏览: 537979 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

haproxy安装配置及丢包问题分析

阅读更多

1. 下载haproxy与安装

例如,我这里下载的是haproxy-1.3.15.10.tar.gz

 

解压后编译安装

tar xvf haproxy-1.3.15.10.tar.gz

 

cd haproxy-1.3.15.10

 

make TARGET=linux32 PREFIX=/usr/local/haproxy

 

make install PREFIX=/usr/local/haproxy

 

2. 编辑haproxy的配置文件,例如/usr/local/haproxy/etc/haproxy.cfg

 

 

###########全局配置#########
global
       log 127.0.0.1 local0 debug
        daemon
        nbproc 1
        pidfile /var/run/haproxy.pid
       

########默认配置############
defaults
        mode tcp                #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
        retries 2               #两次连接失败就认为是服务器不可用,也可以通过后面设置
        option redispatch       #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
        option abortonclose     #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
        maxconn 4096            #默认的最大连接数
        timeout connect 5000ms  #连接超时
        timeout client 30000ms  #客户端超时
        timeout server 10000ms  #服务器超时
        timeout check 2000ms    #=心跳检测超时
        log global

########test1配置#################
listen test1
       log global
        balance roundrobin
        bind 0.0.0.0:90
        mode tcp
        option tcplog
        maxconn 4086
        server s1 192.168.1.101:8081

 

 

 

3. haproxy的日志打印配置

(1)需要安装rsyslog

jme@jme:~$ sudo apt-get install rsyslog

(2)/etc/default/rsyslog里的配置调整为:

RSYSLOGD_OPTIONS="-c5 -r -x"

(3)/etc/rsyslog.conf中如小的配置项去掉注释生效

$ModLoad imudp

$UDPServerRun 514

 

/etc/rsyslog.conf的最后添加haproxy的日志配置(其中local0与haproxy的日志输出对应):

local0.* /var/log/haproxy.log

 

4. 启动haproxy

sudo /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.cfg

 

5. haproxy配置的超时配置的影响:

 

创建一个server:

 

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8081);
while (true) {
Socket socket = server.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
int read = 0;
while ((read = in.read()) != -1) {
System.out.println("server: " + read);
out.write(read);
out.flush();
}
}
}
}

 

 

 

创建一个client:

 

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 90);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
while (true) {
out.write('a');
out.flush();
int read = in.read();
System.out.println("client: " + read);
Thread.sleep(15000);
}
}
}

 

 

情况1:haproxy在服务器超时后的表现,client端在haproxy的server端超时后继续发送数据:

server端的日志打印:

server: 97

server: 97

server: 97

server: 97

 

client的日志打印:

client: 97

client: -1

client: -1

client: -1

 

看haproxy的日志:

Jun 29 11:28:29 127.0.0.1 haproxy[18636]: 127.0.0.1:37775 [29/Jun/2014:11:26:50.563] test1 test1/s1 0/0/98858 1 sD 0/0/0/0/0 0/0

 

sD的含义:

The server did not send nor acknowledge any data for as long as the

"timeout server" setting during the data phase. This is often caused

by too short timeouts on L4 equipements before the server (firewalls,

load-balancers, ...), as well as keep-alive sessions maintained

between the client and the server expiring first on haproxy.

 

可以看到haproxy检测到server端超时后,client->haproxy->server的链接并没有全部断掉(可以理解为半关闭),只是server过期了,client端能发送数据到server,但是不能从server端接收数据。

 

情况2:haproxy在客户端超时后的表现,为方便测试,可以先调整haproxy的超时配置:

  timeout client 10000ms  #客户端超时

  timeout server 0ms  #服务器超时

server端日志:

server: 97

 

client端日志:

client: 97

 

之后就停住了,主要是haproxy已经关闭client这端,因此client数据发不出去了

对应的抓包数据:

sudo tcpdump -ntX 'port 90 or port 8081' -i lo

 

从client->haproxy的第一个‘a’字符

IP 127.0.0.1.38733 > 127.0.0.1.90: Flags [P.], seq 1:2, ack 1, win 342, options [nop,nop,TS val 3608278 ecr 3608278], length 1

0x0000:  4500 0035 32ab 4000 4006 0a16 7f00 0001  E..52.@.@.......

0x0010:  7f00 0001 974d 005a d797 3c80 b25a 50cc  .....M.Z..<..ZP.

0x0020:  8018 0156 fe29 0000 0101 080a 0037 0ed6  ...V.).......7..

0x0030:  0037 0ed6 61                             .7..a

从haproxy->server的第一个‘a’字符

IP 192.168.1.101.52738 > 192.168.1.101.8081: Flags [P.], seq 1:2, ack 1, win 342, options [nop,nop,TS val 3608278 ecr 3608278], length 1

0x0000:  4500 0035 85b0 4000 4006 30f8 c0a8 0165  E..5..@.@.0....e

0x0010:  c0a8 0165 ce02 1f91 4bb4 8b79 ca7c 27a5  ...e....K..y.|'.

0x0020:  8018 0156 8442 0000 0101 080a 0037 0ed6  ...V.B.......7..

0x0030:  0037 0ed6 61                             .7..a

 

server->haproxy的回写的‘a’字符:

IP 192.168.1.101.8081 > 192.168.1.101.52738: Flags [P.], seq 1:2, ack 2, win 342, options [nop,nop,TS val 3608278 ecr 3608278], length 1

0x0000:  4500 0035 2974 4000 4006 8d34 c0a8 0165  E..5)t@.@..4...e

0x0010:  c0a8 0165 1f91 ce02 ca7c 27a5 4bb4 8b7a  ...e.....|'.K..z

0x0020:  8018 0156 8442 0000 0101 080a 0037 0ed6  ...V.B.......7..

0x0030:  0037 0ed6 61                             .7..a

 

haproxy->client的回写的‘a’字符:

IP 127.0.0.1.90 > 127.0.0.1.38733: Flags [P.], seq 1:2, ack 2, win 342, options [nop,nop,TS val 3608278 ecr 3608278], length 1

0x0000:  4500 0035 5e1b 4000 4006 dea5 7f00 0001  E..5^.@.@.......

0x0010:  7f00 0001 005a 974d b25a 50cc d797 3c81  .....Z.M.ZP...<.

0x0020:  8018 0156 fe29 0000 0101 080a 0037 0ed6  ...V.).......7..

0x0030:  0037 0ed6 61                             .7..a

 

之后hapropxy检测到client超时,关闭后,client继续发送数据:

client->haproxy是成功的:

IP 127.0.0.1.38733 > 127.0.0.1.90: Flags [P.], seq 2:3, ack 2, win 342, options [nop,nop,TS val 3612028 ecr 3608278], length 1

0x0000:  4500 0035 32ad 4000 4006 0a14 7f00 0001  E..52.@.@.......

0x0010:  7f00 0001 974d 005a d797 3c81 b25a 50cd  .....M.Z..<..ZP.

0x0020:  8018 0156 fe29 0000 0101 080a 0037 1d7c  ...V.).......7.|

0x0030:  0037 0ed6 61                             .7..a

 

但是由于haproxy不再向server发送数据。因此这种情况就丢包了。

 

haproxy的日志:

Jun 29 11:51:14 127.0.0.1 haproxy[20154]: 192.168.1.101:53597 [29/Jun/2014:11:49:03.266] test1 test1/s1 0/0/131359 1 cD 0/0/0/0/0 0/0

cD的含义:

The client did not send nor acknowledge any data for as long as the

"timeout client" delay. This is often caused by network failures on

the client side, or the client simply leaving the net uncleanly.

 

小结: 可见,用haproxy做tcp代理,client和server端的超时设置一定要正确,否则就可能出现读取数据错误,或者丢包的情况。

 

 

 

 

 

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics