【发布时间】:2017-09-22 18:42:27
【问题描述】:
我正在使用 HAProxy acl 设置简单的 tcp 连接路由。这个想法是根据具有两种风格的请求内容路由连接:读取和写入请求。
为了测试,我使用 perl 做了一个简单的 tcp 客户端/服务器设置。奇怪的是,大约 10-40% 的 ACL 失败并被发送到默认后端。
ACL 应该找到子字符串 'read' 或 'write' 并相应地路由,但并非总是如此。
使用nc(netcat)发送读/写请求也有同样的效果。
我使用 mode=http 测试了这个配置,一切正常。
我还用 reg、sub 和 bin 进行了测试,但无济于事。
示例服务器设置如下:
HAProxy 实例,监听 8000 端口
客户端(创建到代理的 tcp 连接,并通过端口 8000 将用户输入(读/写字符串)发送到服务器,然后关闭连接)
Server1(写服务器),监听8001端口
Server2(读取服务器),监听 8002 端口
Server3(默认服务器),监听 8003 端口
我的 HAProxy 配置文件看起来是:
global
log /dev/log local0 debug
#daemon
maxconn 32
defaults
log global
balance roundrobin
mode tcp
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend tcp-in
bind *:8000
tcp-request inspect-delay 3s
acl read req.payload(0,4) -m sub read
acl write req.payload(0,5) -m sub write
use_backend read_servers if read
use_backend write_server if write
default_backend testFault
backend write_server
server server1 127.0.0.1:8001 maxconn 32
backend read_servers
server server2 127.0.0.1:8002 maxconn 32
backend testFault
server server3 127.0.0.1:8003 maxconn 32
客户端代码(perl):
use IO::Socket::INET;
# auto-flush on socket
#$| = 1;
print "connecting to the server\n";
while(<STDIN>){
# create a connecting socket
my $socket = new IO::Socket::INET (
PeerHost => 'localhost',
PeerPort => '8000',
Proto => 'tcp',
);
die "cannot connect to the server $!\n" unless $socket;
# data to send to a server
$req = $_;
chomp $req;
$size = $socket->send($req);
print "sent data of length $size\n";
# notify server that request has been sent
shutdown($socket, 1);
# receive a response of up to 1024 characters from server
$response = "";
$socket->recv($response, 1024);
print "received response: $response\n";
$socket->close();
}
服务器(perl 代码):
use IO::Socket::INET;
if(!$ARGV[0]){
die("Usage; specify a port..");
}
# auto-flush on socket
$| = 1;
# creating a listening socket
my $socket = new IO::Socket::INET (
LocalHost => '0.0.0.0',
LocalPort => $ARGV[0],
Proto => 'tcp',
Listen => 5,
Reuse => 0
);
die "cannot create socket $!\n" unless $socket;
print "server waiting for client connection on port $ARGV[0]\n";
while(1){
# waiting for a new client connection
my $client_socket = $socket->accept();
# get information about a newly connected client
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
print "connection from $client_address:$client_port\n";
# read up to 1024 characters from the connected client
my $data = "";
$client_socket->recv($data, 1024);
print "received data: $data\n";
# write response data to the connected client
$data = "ok";
$client_socket->send($data);
# notify client that response has been sent
shutdown($client_socket, 1);
$client_socket->close();
print "Connection closed..\n\n";
}
$socket->close();
【问题讨论】:
标签: tcp routing acl backend haproxy