从Ruby中的Unix Socket读取/写入

时间:2010-06-02 16:54:45

标签: ruby unix-socket

我正在尝试从Ruby中的UNIX套接字进行连接,读取和写入。它是haproxy使用的统计信息套接字。

我的代码如下:

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?

4 个答案:

答案 0 :(得分:13)

奥利,

HAproxy在第一个请求后关闭连接,除非您使用“prompt”命令(参见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            

答案 1 :(得分:5)

看起来第一次请求后连接已关闭。我不认为你做错了什么。 HAProxy stats套接字可能是为了响应单个命令然后关闭连接而设计的。

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

如果你看this blog post关于使用带有socat的HAProxy stats套接字,那么这是有意义的,因为你将show stat命令传递给socat并且socat从套接字读取直到它关闭

答案 2 :(得分: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

答案 3 :(得分:0)

你可以使用man socket。您可以像使用C函数一样使用套接字类。

我发现man-pages非常有用。