1
votes

here is the goal: a PHP application connecting to an ActiveMQ failover cluster (Master/Slave) using Stomp.

Here are the versions:

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

Here is the setup:

  • 2 servers with ActiveMQ;
  • keepalived installed on both servers, sharing a VIP
  • the PHP script is the following
< ? 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");
}

?>

With a consequent number of messages, we get these kinds of error in the ActiveMQ debug log

2014-10-03 13:19:13,941 | DEBUG | Transport Connection to: tcp://127.0.0.1:37125 failed: java.io.EOFException | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: 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) at org.apache.activemq.transport.stomp.StompWireFormat.readLine(StompWireFormat.java:148) at org.apache.activemq.transport.stomp.StompWireFormat.parseAction(StompWireFormat.java:170) at org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:98) at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:229) at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:221) at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:204) at java.lang.Thread.run(Thread.java:745)

This causes the STOMP connection to drop, and leads us to other issues.

It seems that the ActiveMQ errors might be linked to the keepalived setup, and that the better configuration would be to use failover scheme in the client.

We tried these connection strings in the Stomp object creation:

> 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)

But they all lead to Invalid broker URI error.

Can't find much doc/issues on the web about such thing..

Any recommandation or advise on implementing failover client side?

1
Failover is not part of stomp spec. It's an ActiveMQ feature that some ActiveMQ client libs implement. You probably have to reconnect manually in a generic stomp lib.Petter Nordlander
I had the same problem, while I ended up by adding a while loop to connect to an active mq broker. You can always connect to a vip address, and let the vip server redirect the request to an active broker. And I dont think stomp-php extension supports failover right now.蒋艾伦

1 Answers

1
votes

PHP Stomp does not support failover by default, you have to implement it yourself to support it, like shown in the following example:

$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;
    }
}