java - 如何从其他应用程序中读取神经节信息?

标签 java python ganglia

我已经设法在我的集群上安装和配置 Ganglia。我不想只在 ganglia Web 界面上查看所有性能数据,而是想从其他应用程序中读取集群信息(应用程序可能是基于 Java 或 Python 的)。我无法找到它是否可能。

是否有任何 API 可以读取 Ganglia 数据?

为了测试 Ganglia,我使用了 telnet master 8649 Ganglia 在我的控制台上向我展示了漂亮的 XML 文本。但是我如何使用 Java 或 Python 做同样的事情呢?我绝对可以使用套接字连接到 8649,但是在那之后我需要向 Ganglia 守护进程发送一些东西吗?

最佳答案

我可以帮助您对此有所了解。但在此之前我必须告诉你,我不是 Java 程序员,而是 C/C++ 程序员。所以,这意味着我可以让你知道 ganglia 是如何工作的,你可以在 Java/Python 中找到等效的方法来重写你想要的代码。

请注意,ganglia 中没有 API 可以实现您想要的。

首先考虑以下神经节的设置以正确理解:

ganglia minimal setup

GS1 和 GS2 正在收集系统指标并将其推送给 GM。
因此,根据您的问题,如果您想通过您自己的基于 Java/Python 的应用程序收集所有此类指标,那么您可能必须在主服务器上安装该应用程序(即用您自己的应用程序替换 GS)。

GS1 和 GS2 通过 UDP 单播 channel 或 UDP 多播 channel 发送所有收集的指标。建议在每个 gmond.conf 中启用 UDP 单播,以便于扩展。

我不会对 GS1 和 GS2 进行太多讨论,因为您的问题更多是关于用您自己的工具替换 GM。

GM 大量使用两个重要的库来建立 UDP 连接并将数据转换为自己的可读格式。它们是 APR (Apache Portable Runtime),用于建立 UDP 连接并执行相关 Activity ,以及 XDR (External Data Representation),用于跨网络发送数据并执行 RPC。

您需要首先在 Java 和 Python 中找到 APR 和 XDR 等效库。 XDR 已经在 J​​ava 中可用,并且 APR 可以替换为您自己的基本实现以执行网络间操作(即创建 UDP 套接字等)。

打开 ganglia 的 gmond.c 源文件,转到第 1436 行。你会发现一个 C 函数:
static void process_udp_recv_channel(const apr_pollfd_t *desc, apr_time_t now)

该函数主要执行“UDP 连接建立”和“数据转换为可读格式” Activity 。

上述函数的调用流程如下图所示:
Call flow

现在,让我们扩展第 1436 行的函数以了解更多信息。

该函数的第一个参数携带IP、Port等网络参数,下面展开结构。您也可以在 Java 中找到类似的对象。

struct apr_pollfd_t {
    apr_pool_t *p;              /**< associated pool */
    apr_datatype_e desc_type;   /**< descriptor type */
    apr_int16_t reqevents;      /**< requested events */
    apr_int16_t rtnevents;      /**< returned events */
    apr_descriptor desc;        /**< @see apr_descriptor */
    void *client_data;          /**< allows app to associate context */
};

如果 SFLOW 被禁用,则第二个参数无关。

因此,从创建 APR 池、UDP 连接等开始。
  socket         = desc->desc.s;
  channel       = desc->client_data;

  apr_pool_create(&p, global_context);
  status = apr_socket_addr_get(&remotesa, APR_LOCAL, socket);

  status = apr_sockaddr_info_get(&remotesa, NULL, remotesa->family, remotesa->port, 0, p);

  /* Grab the data */
  status = apr_socket_recvfrom(remotesa, socket, 0, buf, &len);
  if(status != APR_SUCCESS)
    {
      apr_pool_destroy(p);
      return;
    }  

  apr_sockaddr_ip_buffer_get(remoteip, 256, remotesa);

  /* Check the ACL */
  if(Ganglia_acl_action( channel->acl, remotesa) != GANGLIA_ACCESS_ALLOW)
    {
      apr_pool_destroy(p);
      return;
    }

变量的所有声明都可以在展开的函数的开头找到(第 1439 到 1456 行)。

然后,创建 XDR 流:
xdrmem_create(&x, buf, max_udp_message_len, XDR_DECODE);

刷新保存元数据和指标值的结构的数据:
memset( &fmsg, 0, sizeof(Ganglia_metadata_msg));
memset( &vmsg, 0, sizeof(Ganglia_value_msg));

fmsg (Ganglia_metadata_msg) 和 vmsg (Ganglia_value_msg) 结构定义可以在 gm_protocol.h 头文件中找到。用 Java 重新编写它们。

然后,确定收到的消息是“元数据”还是“指标值”。
xdr_Ganglia_msg_formats(&x, &id); // this function is located in the source file gm_protocol_xdr.c and this file is generated by rpcgen.

注意:rpcgen 是一个 rpc 编译器,它的解释可以在这个 question 中找到。

注意:这是 gm_protocol_xdr.c 的链接。

这里,id 是一个 enum,它的声明如下所示:
enum Ganglia_msg_formats {
    gmetadata_full = 128,
    gmetric_ushort = 128 + 1,
    gmetric_short = 128 + 2,
    gmetric_int = 128 + 3,
    gmetric_uint = 128 + 4,
    gmetric_string = 128 + 5,
    gmetric_float = 128 + 6,
    gmetric_double = 128 + 7,
    gmetadata_request = 128 + 8,
};
typedef enum Ganglia_msg_formats Ganglia_msg_formats;

根据 id 的值,您可以确定数据包具有什么样的值。
为此,此函数调用另一个函数(实际上由 rpcgen 生成)来确定数据包具有的值类型,如果找到,它也将其转换为人类可读的格式。

功能是:
xdr_Ganglia_value_msg(&x, &vmsg);

您可以在第 275 行的 gm_protocol_xdr.c 中找到此函数的完整扩展。

之后,您可以对这些数据包做任何您想做的事情。

最后,您必须释放所有已分配的 XDR 变量和 APR 池。

我希望这能给你一个公平的想法来开始你自己的应用程序。

关于java - 如何从其他应用程序中读取神经节信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24675209/

相关文章:

java - Java 中的多线程管道

python - 通过 Twitter API 提取趋势标签

python - 如果找到则替换行或追加 - python

hadoop - Ambari 仪表板未检索任何统计信息

charts - 如何更改 RRDTool 图表?

java - 如何使用斯坦福大学的 CoreNlp 获得词嵌入?

java - 如何在java中将两个不同的excel文件连接为同一服务器上的数据库?

java - 创建简单递归函数的递归方程

python - 从多级字典创建平面数据框的最好(也是最快)方法是什么

graphite - 将数据从神经节发送到 Graphite