MySQL의에서 golang은 연결 시간 초과 제한 시간 테스트를 확립

본 논문은 연결 시간 제한 mysql을 테스트합니다.

여기에 "연결"연결을 설정하기위한 것입니다.

MySQL의 연결 시간 초과는 시간 초과 매개 변수에 의해 설정된다.

1. 연결 제한 시간 테스트를 수립

다음 예에서, 접속 시간 5S 제공.
MySQL 서버의 IP는 192.168.0.101, 3306 포트입니다.

3S는 SQL에 한 번 수행.

// simple.go

package main

import (
        "database/sql"
        "log"
        "time"

        _ "github.com/go-sql-driver/mysql"
)

var DB *sql.DB
var dataBase = "root:Aa123456@tcp(192.168.0.101:3306)/?timeout=5s&readTimeout=6s"

func mysqlInit() {
        var err error
        DB, err = sql.Open("mysql", dataBase)
        if err != nil {
                log.Fatalln("open db fail:", err)
        }

        DB.SetMaxOpenConns(3)
        DB.SetMaxIdleConns(3)
}

func main() {
        mysqlInit()

        for {
                log.Println("start")
                execSql()
                time.Sleep(3*time.Second)
        }
}

func execSql() {
        var value int
        err := DB.QueryRow("select 1").Scan(&value)
        if err != nil {
                log.Println("query failed:", err)
                return
        }

        log.Println("value:", value)
}

프로그램을 시작합니다 :

go run simple.go

모든 패킷을 전송의 iptables를 사용하면 MySQL의 서비스에 내려 :

sudo iptables -A OUTPUT -p tcp --dport 3306 -d 192.168.0.101 -j DROP

이것은 재시도 메커니즘, 마지막 아웃 트리거합니다.

산출:

2019/10/27 18:34:52 start
2019/10/27 18:34:52 value: 1
2019/10/27 18:34:55 start
2019/10/27 18:34:55 value: 1
2019/10/27 18:34:58 start
2019/10/27 18:34:58 value: 1
2019/10/27 18:35:01 start
[mysql] 2019/10/27 18:35:07 packets.go:36: read tcp 192.168.0.104:54462->192.168.0.101:3306: i/o timeout
2019/10/27 18:35:07 query failed: invalid connection
2019/10/27 18:35:10 start
[mysql] 2019/10/27 18:35:15 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:35:20 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
2019/10/27 18:35:20 query failed: driver: bad connection
2019/10/27 18:35:23 start
[mysql] 2019/10/27 18:35:28 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:35:33 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:35:38 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
2019/10/27 18:35:38 query failed: driver: bad connection
2019/10/27 18:35:41 start
[mysql] 2019/10/27 18:35:46 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:35:51 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:35:56 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
2019/10/27 18:35:56 query failed: driver: bad connection
2019/10/27 18:35:59 start
[mysql] 2019/10/27 18:36:04 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:36:09 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
[mysql] 2019/10/27 18:36:14 driver.go:81: net.Error from Dial()': dial tcp 192.168.0.101:3306: i/o timeout
2019/10/27 18:36:14 query failed: driver: bad connection

당신은 출력에서 ​​볼 SQL의 각 실행 수, 연결 오류 로그 (3) 연결을 나타냅니다있다, 그것은 세 번 (설정 시간 초과) 제한 시간 5 초를 시도 할 것이다.

여기 모든 시간 SQL 실행이 세 번 연결을 시도 실시됩니다 왜 질문을 구걸?

확인하려면 QueryRow기본이되는 구현 코드를 :

func (db *DB) QueryRow(query string, args ...interface{}) *Row {
    return db.QueryRowContext(context.Background(), query, args...)
}

func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
    rows, err := db.QueryContext(ctx, query, args...)
    return &Row{rows: rows, err: err}
}

// QueryContext executes a query that returns rows, typically a SELECT.
// The args are for any placeholder parameters in the query.
func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
    var rows *Rows
    var err error
    for i := 0; i < maxBadConnRetries; i++ {
        rows, err = db.query(ctx, query, args, cachedOrNewConn)
        if err != driver.ErrBadConn {
            break
        }
    }
    if err == driver.ErrBadConn {
        return db.query(ctx, query, args, alwaysNewConn)
    }
    return rows, err
}

상기 식에서, maxBadConnRetries 2은 다음과 같이 정의된다

// maxBadConnRetries is the number of maximum retries if the driver returns
// driver.ErrBadConn to signal a broken connection before forcing a new
// connection to be opened.
const maxBadConnRetries = 2

ERR이 때 driver.ErrBadConn때 연결을 세 번 시도 할 것이다. 단지 세 번 연결 오류 로그인 이유입니다.

2.reject 테스트

당신의 iptables를 사용하는 경우 또한, 모든 MySQL 서버 패킷에 전송됩니다 밖으로 거부 :

sudo iptables -A OUTPUT -p tcp --dport 3306 -d 192.168.0.101 -j REJECT

RESET 조작을 직접 연결 재설정을 거부 반환됩니다, 우리는 연결 설정 시간 초과를 유발하지 않습니다.

출력 로그 :

2019/10/27 21:39:55 start
2019/10/27 21:39:55 value: 1
2019/10/27 21:39:58 start
2019/10/27 21:39:58 value: 1
2019/10/27 21:40:01 start
2019/10/27 21:40:01 value: 1
2019/10/27 21:40:04 start
2019/10/27 21:40:04 value: 1
2019/10/27 21:40:07 start
[mysql] 2019/10/27 21:40:13 packets.go:36: read tcp 192.168.0.104:54536->192.168.0.101:3306: i/o timeout
2019/10/27 21:40:13 query failed: invalid connection
2019/10/27 21:40:16 start
2019/10/27 21:40:17 query failed: dial tcp 192.168.0.101:3306: connect: connection refused
2019/10/27 21:40:20 start
2019/10/27 21:40:21 query failed: dial tcp 192.168.0.101:3306: connect: connection refused
2019/10/27 21:40:24 start
2019/10/27 21:40:25 query failed: dial tcp 192.168.0.101:3306: connect: connection refused
2019/10/27 21:40:28 start
2019/10/27 21:40:29 query failed: dial tcp 192.168.0.101:3306: connect: connection refused
2019/10/27 21:40:32 start
2019/10/27 21:40:33 query failed: dial tcp 192.168.0.101:3306: connect: connection refused

3. 참조

golang 데이터베이스의 SQL DSN (데이터 원본 이름) 中 的 타임 아웃, readTimeout

추천

출처www.cnblogs.com/lanyangsh/p/11749270.html