PHP使用fsockopen和fwrite静默地无法通过UDP将数据发送到石墨

时间:2013-08-09 11:34:56

标签: php udp graphite

代码

我正在使用php和python通过UDP向graphite发送指标。

我的 python 客户端看起来像这样

#!/usr/bin/python
import time
from socket import socket

sock = socket()
try:
  sock.connect( ('127.0.0.1', 2003) )
except:
  print 'network error'
  sys.exit(12)

message = ("some.custom.metric.python 1 %d\n" % (int( time.time() )))
print message
sock.sendall(message)

输出:

  

some.custom.metric.python 1 1376045467

我的 php 客户端就像这样

<?php

try {
    $fp = fsockopen("udp://127.0.0.1", 2003, $errno, $errstr);

    if (!empty($errno)) echo $errno;
    if (!empty($errstr)) echo $errstr;

    $message = "some.custom.metric.php 1 ".time().PHP_EOL;
    $bytes = fwrite($fp, $message);
    echo $message;
} catch (Exception $e) {
    echo "\nNetwork error: ".$e->getMessage();
}

输出:

  

some.custom.metric.php 1 1376042961

测试

我启动 carbon 启用调试输出:

/opt/graphite/bin/carbon-cache.py --debug start

当我运行 python 客户端时,它运行正常,我可以在调试输出上看到它

09/08/2013 13:13:05 :: [listener] MetricLineReceiver connection with 127.0.0.1:58134 established
09/08/2013 13:13:05 :: [listener] MetricLineReceiver connection with 127.0.0.1:58134 closed cleanly

我使用 netcat

通过CLI执行相同的操作
echo "some.custom.metric.netcat 1 `date +%s`" | nc -w 1 127.0.0.1 2003

我可以在调试输出中看到连接

09/08/2013 13:17:46 :: [listener] MetricLineReceiver connection with 127.0.0.1:58136 established
09/08/2013 13:17:48 :: [listener] MetricLineReceiver connection with 127.0.0.1:58136 closed cleanly

问题

我的php客户端从不与碳通信。即使我使用不同的端口,没有应用程序监听我的PHP只是告诉我一切都很好。如果我在我的python客户端上执行相同操作,则会出现网络错误。

根据PHP文档,由于协议的性质,fsockopen 从不在使用UDP时失败,但在执行 fwrite 时我会收到错误。在我的情况下,无论打开套接字时我使用哪个主机/端口,fwrite总是返回$ message的len()。

如果我使用netcat或python客户端的错误端口,我会收到预期的网络错误。

PHP-cli有error_display = Onerror_reporting = E_ALL。我已经在Windows 7上的debian 7.1和PHP 5.5上使用PHP 5.4.4-14进行了测试。

有没有人碰到类似的东西?我几乎可以肯定我的石墨或网络配置没问题,所以我敢打赌它与PHP有关。

1 个答案:

答案 0 :(得分:2)

检查您是否有一个开放的UDP端口(默认情况下它是关闭的)。我用于测试的代码(简化版本)(使用TCP)

$line = "foo.bla 1 " . time() . "\n";

$fp = fsockopen('127.0.0.1', 2003, $err, $errc, 1);
fwrite($fp, $line);

fclose($fp);