如何解决多并发时的TIME_WAIT状态问题?

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

How to solve TIME_WAIT state issue when in multiple concurrency?

问题

如果我在Windows上运行下面的示例,我会很快达到TCP连接限制(我将其设置为64k),并收到错误消息:dial tcp 127.0.0.1:3306: connectex: Only one usage of each socket address (protocol/network address/port) is normally permitted.

我通过使用netstat -ano|findstr 3306命令看到了所有这些处于TIME_WAIT状态的连接。

为什么连接不会立即关闭?

代码如下:

package main

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	"log"
	"sync"
)

var (
	db_instance *sqlx.DB
	wg          sync.WaitGroup
)

func main() {
	db, err := sqlx.Connect("mysql", "user:pass@/table")
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()
	db_instance = db

	for {
		for l := 0; l < 50; l++ {
			wg.Add(1)
			go DB_TEST()
		}
		wg.Wait()
	}
}

func DB_TEST() {
	defer wg.Done()

	var s string
	err := db_instance.QueryRow("SELECT NOW()").Scan(&s)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println(s)
}
英文:

If I run below example on Windows I will quickly hit TCP connection limit (which I set to 64k) and get error: dial tcp 127.0.0.1:3306: connectex: Only one usage of each socket address (protocol/network address/port) is normally permitted.

I see all this TIME_WAIT states waiting for there lifetime to end with: netstat -ano|findstr 3306

Why aren't connections closed immediately?

The code:

package main

import (
	_ &quot;github.com/go-sql-driver/mysql&quot;
	&quot;github.com/jmoiron/sqlx&quot;
	&quot;log&quot;
	&quot;sync&quot;
)

var (
	db_instance *sqlx.DB
	wg          sync.WaitGroup
)

func main() {
	db, err := sqlx.Connect(&quot;mysql&quot;, &quot;user:pass@/table&quot;)
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()
	db_instance = db

	for {
		for l := 0; l &lt; 50; l++ {
			wg.Add(1)
			go DB_TEST()
		}
		wg.Wait()
	}
}

func DB_TEST() {
	defer wg.Done()

	var s string
	err := db_instance.QueryRow(&quot;SELECT NOW()&quot;).Scan(&amp;s)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println(s)
}

答案1

得分: 1

利用SetMaxOpenConnsSetMaxIdleConns设置来控制TIME_WAIT状态和连接。如果需要,也可以使用SetConnMaxLifetime,但通常不需要。

英文:

Drafting answer from my comments discussion with @Glavić.

Utilize the SetMaxOpenConns and SetMaxIdleConns settings to keep TIME_WAIT status and connections under control. If needed use SetConnMaxLifetime too, generally it's not needed.

huangapple
  • 本文由 发表于 2017年6月15日 14:41:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/44560390.html
匿名

发表评论

匿名网友

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

确定