使用PHP / Stomp客户端进行故障转移的ActiveMQ

时间:2014-10-03 13:41:57

标签: php activemq failover stomp

目标是:使用Stomp连接到ActiveMQ故障转移群集(主/从)的PHP应用程序。

以下是版本:

  • ActiveMQ 5.7
  • PHP stomp 1.0.5 stable
  • PHP 5.4.4-14 + deb7u14(cli)

以下是设置:

  • 使用ActiveMQ的2台服务器;
  • keepalived安装在两台服务器上,共享VIP
  • PHP脚本如下
< ? php

$queue  = '/queue/test';

try {
    $stomp = new Stomp("tcp://VIP:61613");
} catch(StompException $e) {
    die('Connection failed: ' . $e->getMessage());
}

$stomp->subscribe($queue);

while ($stomp->hasFrame())
{
$frame = $stomp->readFrame();
var_dump($frame);
print_r($frame->headers["message-id"]."\n");

if ($stomp->ack($frame))
 print_r("Frame ACK!\n");
 else
   die("ACK Error");
}

?>

随着消息数量的增加,我们在ActiveMQ调试日志中出现了这类错误

  

2014-10-03 13:19:13,941 |调试|运输连接到:   tcp://127.0.0.1:37125失败:java.io.EOFException |   org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ的   传输:tcp:///127.0.0.1:37125 @ 61613 java.io.EOFException           at java.io.DataInputStream.readByte(DataInputStream.java:267)           at org.apache.activemq.transport.stomp.StompWireFormat.readHeaderLine(StompWireFormat.java:155)           在org.apache.activemq.transport.stomp.StompWireFormat.readLine(StompWireFormat.java:148)           at org.apache.activemq.transport.stomp.StompWireFormat.parseAction(StompWireFormat.java:170)           在org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:98)           在org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:229)           在org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:221)           at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:204)           在java.lang.Thread.run(Thread.java:745)

这会导致STOMP连接中断,并导致我们遇到其他问题。

似乎ActiveMQ错误可能与keepalived设置相关联,并且更好的配置是在客户端中使用故障转移方案。

我们在Stomp对象创建中尝试了这些连接字符串:

> failover://tcp://IP1:61613,tcp://IP2:61613
> failover:tcp://IP1:61613,tcp://IP2:61613
> failover://(tcp://IP1:61613,tcp://IP2:61613)
> failover:(tcp://IP1:61613,tcp://IP2:61613)

但他们都导致Invalid broker URI错误。

在网上找不到关于此类事情的文档/问题。

有关实施故障转移客户端的任何建议或建议吗?

1 个答案:

答案 0 :(得分:1)

默认情况下,PHP Stomp不支持故障转移,您必须自己实现它才能支持它,如下例所示:

$urls = array('ip1:61613','ip2:61613');
$conn = null;
foreach ($urls as $url) {
    $url = "tcp://".$url;
    try {
        $conn = new \Stomp($url,$user,$passwd);
    } catch(\Exception $e) {
    }
    if ($this->conn) {
        break;
    }
}