pingcap / tiproxy

Apache License 2.0
56 stars 27 forks source link

TiProxy keeps reporting errors for HAProxy health check #478

Open djshow832 opened 8 months ago

djshow832 commented 8 months ago

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

  1. Start HAProxy and set the health check port to 6000 of TiProxy
  2. Start TiProxy

2. What did you expect to see? (Required)

No errors in TiProxy

3. What did you see instead (Required)

TiProxy keeps reporting:

[2024/02/28 15:43:14.752 +08:00] [WARN] [main.proxy] [proxy/proxy.go:206] [failed to set tcp keep alive option] [connID=15] [client_addr=127.0.0.1:62842] [addr=0.0.0.0:6000] [error="failed to set keepalive and timeout: set tcp [::7f00:1]:6000->127.0.0.1:62842: setsockopt: invalid argument"]
[2024/02/28 15:43:15.157 +08:00] [WARN] [main.proxy] [proxy/proxy.go:206] [failed to set tcp keep alive option] [connID=16] [client_addr=127.0.0.1:62845] [addr=0.0.0.0:6000] [error="failed to set keepalive and timeout: set tcp 127.0.0.1:6000->127.0.0.1:62845: setsockopt: invalid argument"]
[2024/02/28 15:43:20.757 +08:00] [WARN] [main.proxy] [proxy/proxy.go:206] [failed to set tcp keep alive option] [connID=17] [client_addr=127.0.0.1:62855] [addr=0.0.0.0:6000] [error="failed to set keepalive and timeout: set tcp 127.0.0.1:6000->127.0.0.1:62855: setsockopt: invalid argument"]
[2024/02/28 15:43:23.164 +08:00] [WARN] [main.proxy] [proxy/proxy.go:206] [failed to set tcp keep alive option] [connID=18] [client_addr=127.0.0.1:62862] [addr=0.0.0.0:6000] [error="failed to set keepalive and timeout: set tcp [::7f00:1]:6000->127.0.0.1:62862: setsockopt: invalid argument"]

4. What is your version? (Required)

master

yorkhellen commented 6 months ago

I have also reproduced the issue. it's because the haproxy already reset the connection when tiproxy set tcp keepalive and i write a simple server as haproxy backend server for test, the code as below


package main

import (
    "bufio"
    "fmt"
    "log"
    "net"
    "time"
)

func main() {
    listener, err := net.Listen("tcp", fmt.Sprintf("%s:%s", "127.0.0.1", "6000"))
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Printf("Error accepting connection: %v\n", err)
        }
        fmt.Printf("Message incoming: %s\n", conn.RemoteAddr())
        go func(conn net.Conn) {
            defer conn.Close()
            tcpcn, ok := conn.(*net.TCPConn)
            if !ok {
                fmt.Printf("not tcp connection\n")
                return
            }

            if err := tcpcn.SetKeepAlive(true); err != nil {
                fmt.Printf("failed to set keep alive: %v\n", err)
            }

            deadline := time.Now().Add(1 * time.Second)
            conn.SetReadDeadline(deadline)
            reader := bufio.NewReader(conn)

            for {
                message, err := reader.ReadString('\n')

                if err != nil {
                    conn.Close()
                    fmt.Printf("Error reading message: %s\n", err)
                    return
                }
                fmt.Printf("Message incoming: %s", string(message))
                conn.Write([]byte("Message received.\n"))
            }
        }(conn)
    }
}

the server std print looks like

failed to set keep alive: set tcp 127.0.0.1:6000->127.0.0.1:62435: setsockopt: invalid argument
Error reading message: read tcp 127.0.0.1:6000->127.0.0.1:62435: read: connection reset by peer
Message incoming: 127.0.0.1:62438
failed to set keep alive: set tcp 127.0.0.1:6000->127.0.0.1:62438: setsockopt: invalid argument
Error reading message: read tcp 127.0.0.1:6000->127.0.0.1:62438: read: connection reset by peer
Message incoming: 127.0.0.1:62439
failed to set keep alive: set tcp 127.0.0.1:6000->127.0.0.1:62439: setsockopt: invalid argument
Error reading message: read tcp 127.0.0.1:6000->127.0.0.1:62439: read: connection reset by peer

We have to read or write to the TCP connection if we want to figure out the TCP connection status.