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

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

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状态的连接。

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

代码如下:

  1. package main
  2. import (
  3. _ "github.com/go-sql-driver/mysql"
  4. "github.com/jmoiron/sqlx"
  5. "log"
  6. "sync"
  7. )
  8. var (
  9. db_instance *sqlx.DB
  10. wg sync.WaitGroup
  11. )
  12. func main() {
  13. db, err := sqlx.Connect("mysql", "user:pass@/table")
  14. if err != nil {
  15. log.Fatalln(err)
  16. }
  17. defer db.Close()
  18. db_instance = db
  19. for {
  20. for l := 0; l < 50; l++ {
  21. wg.Add(1)
  22. go DB_TEST()
  23. }
  24. wg.Wait()
  25. }
  26. }
  27. func DB_TEST() {
  28. defer wg.Done()
  29. var s string
  30. err := db_instance.QueryRow("SELECT NOW()").Scan(&s)
  31. if err != nil {
  32. log.Println(err)
  33. return
  34. }
  35. log.Println(s)
  36. }
英文:

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:

  1. package main
  2. import (
  3. _ &quot;github.com/go-sql-driver/mysql&quot;
  4. &quot;github.com/jmoiron/sqlx&quot;
  5. &quot;log&quot;
  6. &quot;sync&quot;
  7. )
  8. var (
  9. db_instance *sqlx.DB
  10. wg sync.WaitGroup
  11. )
  12. func main() {
  13. db, err := sqlx.Connect(&quot;mysql&quot;, &quot;user:pass@/table&quot;)
  14. if err != nil {
  15. log.Fatalln(err)
  16. }
  17. defer db.Close()
  18. db_instance = db
  19. for {
  20. for l := 0; l &lt; 50; l++ {
  21. wg.Add(1)
  22. go DB_TEST()
  23. }
  24. wg.Wait()
  25. }
  26. }
  27. func DB_TEST() {
  28. defer wg.Done()
  29. var s string
  30. err := db_instance.QueryRow(&quot;SELECT NOW()&quot;).Scan(&amp;s)
  31. if err != nil {
  32. log.Println(err)
  33. return
  34. }
  35. log.Println(s)
  36. }

答案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:

确定