Ассистент Apache: проблемы с таймаутом клиента
У меня есть приложение для тестирования Apache Thrift (v.0.6.1) с perl-сервером и php-клиентом.
Поведение, которое я не могу объяснить: если мы вызываем server-method с недопустимым аргументом, мы видим ошибку в сервере-выходе, но php-клиент остается без ответа.
Вот источники сервера:
sub new {
my $classname = shift;
my $self = {};
return bless($self,$classname);
}
sub DateToTimestamp
{
my ($self, $date) = @_;
my $result = CommonAPI::DateToTimestamp($date);
return $result;
}
eval {
my $handler = new RPCHandler;
my $processor = new RPCPerformanceTest::RPCPerformanceTestProcessor($handler);
my $serversocket = new Thrift::ServerSocket(9091);
my $forkingserver = new Thrift::ForkingServer($processor, $serversocket);
print "Starting the server...\n";
$forkingserver->serve();
print "done.\n";
}; if ([email protected]) {
if ([email protected] =~ m/TException/ and exists [email protected]>{message}) {
my $message = [email protected]>{message};
my $code = [email protected]>{code};
my $out = $code . ':' . $message;
die $out;
} else {
die [email protected];
}
}
и клиент:
try {
$socket = new TSocket($server_host, $server_port);
$transport = new TBufferedTransport($socket, 1024, 1024);
$protocol = new TBinaryProtocol($transport);
$client = new RPCPerformanceTestClient($protocol);
$transport->open();
$start = microtime(true);
$result = $client->DateToTimestamp('071/26/2011 01:23:45');
var_dump($result);
} catch (Exception $e) {
echo 'Exception: <b>' . $e->getMessage() . '</b>';
}
Почему это происходит? Это моя вина? Ожидается ли это?
Ответы
Ответ 1
Это часто случается с протоколами, которые не предоставляют длину сообщения: клиент отправляет больше данных, а сервер ожидает и ожидает, что сервер получит данные. Сервер получает некоторые данные, пытается разобрать его и терпеть неудачу. Теперь серверная сторона протокола находится в ошибочном состоянии. Если он продолжает читать данные, он может блокироваться. Скорее всего, серверная сторона отправила вам некоторый ответ об ошибке и в то же время ожидает, что клиент получит ответ, но это никогда не произойдет.
Это мое предположение. Лучшая стратегия IMHO - установить тайм-аут как для клиентских, так и для серверных сокетов.
Ответ 2
Библиотека Thrift PHP немного сломана. Вам нужно вручную установить таймауты
Например.
$socket = new TSocket('host', 9095);
$socket->setSendTimeout(60000);
$socket->setRecvTimeout(60000)