2010-06-02 51 views
12

我试图从Ruby中的UNIX套接字进行连接,读取和写入。它是haproxy使用的统计套接字。从Ruby中的Unix套接字读取/写入

我的代码如下:

require 'socket' 
socket = UNIXSocket.new("/tmp/haproxy.stats.socket") 

# First attempt: works 

socket.puts("show stat") 

while(line = socket.gets) do 
    puts line 
end 

# Second attemp: fails 

socket.puts("show stat") 

while(line = socket.gets) do 
    puts line 
end 

它成功的第一次,但在第二次尝试失败。我不知道为什么。

# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt, 
stats,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,, 
stats,BACKEND,0,0,0,0,2000,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,22,0,,1,1,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0, 
legacy_socket,FRONTEND,,,0,0,1000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,, 
all,FRONTEND,,,0,0,10000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,3,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,1,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,2,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,3,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,4,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,5,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,6,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,22,22,,1,4,7,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,21,21,,1,4,8,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,21,21,,1,4,9,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,socket,0,0,0,0,200,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,21,21,,1,4,10,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
socket_backend,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,DOWN,0,0,0,,1,21,21,,1,4,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0, 
api_backend,api,0,0,0,0,200,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,22,0,,1,5,1,,0,,2,0,,0,L4OK,,0,0,0,0,0,0,0,0,,,,0,0, 
api_backend,api,0,0,0,0,1,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,22,0,,1,5,2,,0,,2,0,,0,L4OK,,0,0,0,0,0,0,0,0,,,,0,0, 
api_backend,api,0,0,0,0,1,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,1,21,21,,1,5,3,,0,,2,0,,0,L4CON,,0,0,0,0,0,0,0,0,,,,0,0, 
api_backend,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,2,2,0,,0,22,0,,1,5,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0, 
www_backend,ruby-www,0,0,0,0,10000,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,22,0,,1,6,1,,0,,2,0,,0,L4OK,,0,0,0,0,0,0,0,0,,,,0,0, 
www_backend,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,1,1,0,,0,22,0,,1,6,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0, 

/Users/Olly/Desktop/haproxy_stats.rb:14:in `write': Broken pipe (Errno::EPIPE) 
    from /Users/Olly/Desktop/haproxy_stats.rb:14:in `puts' 
    from /Users/Olly/Desktop/haproxy_stats.rb:14 

什么问题?有没有一个很好的参考使用UNIX套接字和Ruby?

回答

5

看起来像第一次请求后连接已关闭。我认为你没有做错什么。 HAProxy统计套接字可能被设计为响应单个命令,然后关闭连接。

我认为你需要重新连接每个请求。

如果你看一下this blog post这是关于使用HAProxy的统计插座与socat那么这是有道理的,因为你管的show stat命令到socat和socat从套接字中,直到它关闭。

+0

谢谢。看起来我需要了解UNIX套接字如何工作。我期待它像TCPSocket一样工作,保持开放。 – Olly 2010-06-03 08:36:52

+0

我没有得到的东西之一是当我使用socat,然后我总是得到从套接字返回的结果,但是当我通过上面的ruby代码执行此操作时,每隔一段时间我都不会收到任何返回的数据从HAproxy ...所以我必须运行几次...我猜,在Ruby的套接字实现中有一些狡猾的东西。 – gyre 2013-01-20 15:30:53

0

您可以使用man插座。您可以像使用C函数那样使用套接字类。

我发现手册页非常有用。

13

奥利,

HAProxy的封闭第一请求后连接,除非您使用“提示”命令(见http://haproxy.1wt.eu/download/1.4/doc/configuration.txt 9.2节):

#!/usr/bin/env ruby                               

require 'socket'                                

socket = UNIXSocket.new("/tmp/haproxy.stats.socket")                        

# Goes interactive mode 
socket.puts("prompt")                              

# Ask statistics every second                                
while true                                 
    socket.puts("show stat")                             
    socket.each_char do |c| 
    # We had the prompt, break out                         
    break if c == '>'                              
    print c                                 
    end                                  

    sleep 1                                 
end    
2

我也遇到了同样的问题,当使用socket.puts,你可以使用socket.write而不是socket.puts来修复它。

#!/usr/bin/evn ruby 
# -*- coding: UTF-8 -*- 

require 'rubygems' 
require 'uri' 
require 'socket' 
require 'yaml' 

SOCKET = URI.parse("/var/run/haproxy/haproxy.sock") 

def get_info 
    UNIXSocket.open(SOCKET.path) do |socket| 
    socket.write("show info;") 
    info = YAML::load socket 
    #info.each {|key, value| puts "#{key} ➤ #{value}"} 
    end 
end 

puts get_info["Uptime_sec"] 

看看这个gem了解更多信息,源代码是here