在Ruby中从Unix套接字读/写

在Ruby中从Unix套接字读/写,ruby,unix-socket,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 soc

我正在尝试从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的好参考?

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

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


如果你看看哪个是关于使用HAProxy stats socket的,那么这是有意义的,因为你将
show stat
命令导入socat,socat从socket读取,直到它关闭。

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

我发现手册页非常有用。

奥利

HAproxy在第一次请求后关闭连接,除非您使用“提示”命令(见第9.2节):


我在使用
socket.put
时也遇到了同样的问题,您可以使用
socket.write
而不是
socket.put
来修复它

#/usr/bin/evnruby
#-*-编码:UTF-8-*-
需要“rubygems”
需要“uri”
需要“插座”
需要“yaml”
SOCKET=URI.parse(“/var/run/haproxy/haproxy.sock”)
def获取_信息
UNIXSocket.open(SOCKET.path)do | SOCKET|
socket.write(“显示信息;”)
info=YAML::加载套接字
#info.each{key,value}放置“{key}”➤ #{value}“}
结束
结束
放置获取信息[“正常运行时间/秒”]

有关详细信息,请参阅此文档,源代码为。

谢谢。看起来我需要详细了解UNIX套接字的工作原理。我希望它像一个开放的TCPSocket一样工作。我没有得到的一件事是,当我使用socat时,我总是从套接字返回结果,但是当我通过上面的ruby代码执行此操作时,有时候我没有从HAproxy返回任何数据…所以我必须运行几次…我猜Ruby的socket实现中有些不可靠的东西。
#!/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