golang unix socket 错误。拨号:资源暂时不可用。

huangapple go评论85阅读模式
英文:

golang unix socket error. dial: resource temporarily unavailable

问题

所以我正在尝试使用Unix套接字与Fluentd进行日志记录任务,并发现随机地,偶尔会出现错误:

dial: {socket_name} 资源暂时不可用

有什么想法,为什么会发生这种情况?

我尝试添加“重试”逻辑,以减少错误,但有时仍会发生。

此外,对于Fluentd,我们正在使用Unix套接字通信的默认配置。

func connect() {
    var connection net.Conn
    var err error
    for i := 0; i < retry_count; i++ {
        connection, err = net.Dial("unix", path_to_socket)
        if err == nil {
            break
        }
        time.Sleep(time.Duration(math.Exp2(float64(retry_count))) * time.Millisecond)
    }
    if err != nil {
        fmt.Println(err)
    } else {
        connection.Write(data_to_send_socket)
    }
    defer connection.Close()
}
英文:

So I'm trying to use unix sockets with fluentd for a logging task and find that randomly, once in a while the error

> dial: {socket_name} resource temporarily unavailable

Any ideas as to why this might be occurring?

I tried adding "retry" logic, to reduce the error, but it still occurs at times.

Also, for fluntd we are using the default config for unix sockets communication

func connect() {

var connection net.Conn
var err error
for i := 0; i &lt; retry_count; i++ {
	connection, err = net.Dial(&quot;unix&quot;, path_to_socket)
	if err == nil {
		break

	}
	time.Sleep(time.Duration(math.Exp2(float64(retry_count))) * time.Millisecond)
}
if err != nil {
	fmt.Println(err)

} else {
		connection.Write(data_to_send_socket)
		
	}
     defer connection.Close()
}

答案1

得分: 2

Go在创建套接字时使用非阻塞模式,这意味着某些通常会阻塞的系统调用会以非阻塞的方式执行。在大多数情况下,它会通过等待套接字准备好读取/写入来透明地处理"EAGAIN"错误(即"资源暂时不可用"的消息)。然而,在"Dial"中的"connect"调用中,它似乎没有这种逻辑。

如果连接到UNIX域套接字时其监听队列已满,"connect"可能会返回"EAGAIN"。如果客户端连接速度快于服务器接受连接的速度,就会发生这种情况。在这种情况下,Go应该等待套接字变为可连接状态,并像对"Read"/"Write"一样重试,但它似乎没有这种逻辑。

因此,你最好通过等待和重试"Dial"调用来处理这个错误。或者,找出为什么你的服务器不能及时接受连接。

英文:

Go creates its sockets in non-blocking mode, which means that certain system calls that would usually block instead. In most cases it transparently handles the EAGAIN error (what is indicated by the "resource temporarily unavailable" message) by waiting until the socket is ready to read/write. It doesn't seem to have this logic for the connect call in Dial though.

It is possible for connect to return EAGAIN when connecting to a UNIX domain socket if its listen queue has filled up. This will happen if clients are connecting to it faster than it is accepting them. Go should probably wait on the socket until it becomes connectable in this case and retry similar to what it does for Read/Write, but it doesn't seem to have that logic.

So your best bet would be to handle the error by waiting and retrying the Dial call. That, or work out why your server isn't accepting connections in a timely manner.

答案2

得分: 0

对于指数退避,您可以使用这个库:github.com/cenkalti/backoff。我认为您现在的方式总是以相同的时间间隔进行休眠。

对于网络错误,您需要检查它是否是临时错误。如果是,则重试:

type TemporaryError interface {
    Temporary() bool
}

func dial() (conn net.Conn, err error) {
    backoff.Retry(func() error {
        conn, err = net.Dial("unix", "/tmp/ex.socket")
        if err != nil {
            // 如果这是一个临时错误,则重试
            if terr, ok := err.(TemporaryError); ok && terr.Temporary() {
                return err
            }
        }
        // 如果我们成功了,或者有一个非临时错误,失败
        return nil
    }, backoff.NewExponentialBackOff())
    return
}
英文:

For the exponential backoff you can use this library: github.com/cenkalti/backoff. I think the way you have it now it always sleeps for the same amount of time.

For the network error you need to check if it's a temporary error or not. If it is then retry:

type TemporaryError interface {
	Temporary() bool
}

func dial() (conn net.Conn, err error) {
	backoff.Retry(func() error {
		conn, err = net.Dial(&quot;unix&quot;, &quot;/tmp/ex.socket&quot;)
		if err != nil {
			// if this is a temporary error, then retry
			if terr, ok := err.(TemporaryError); ok &amp;&amp; terr.Temporary() {
				return err
			}
		}
		// if we were successful, or there was a non-temporary error, fail
		return nil
	}, backoff.NewExponentialBackOff())
	return
}

huangapple
  • 本文由 发表于 2015年5月14日 10:53:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/30228482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定