内容简介:一 出现大量 close wait二 出现大量 time wait三 模拟 TIME_WAIT
一 出现大量 close wait
- 我方被动关闭连接导致的, 我方代码有问题, 可能没有关闭连接, 导致服务方因为超时等原因强制关闭了连接
- 解决的方法如果是单连接, 确保连接关闭; 如果是连接池, 确保连接回收到池子中
二 出现大量 time wait
- 我方主动关闭连接导致的, 我方代码有问题, 可能频繁的创建连接, 所以频繁关闭连接, 而 time wait 需要 2 MSL 时间才会消失, 所以形成堆积.
- 解决的方法是要么使用连接池,要么在同一个连接做尽可能多的事情,避免频繁开关.
三 模拟 TIME_WAIT
运行附件一 time_wait.go 的代码, 可以模拟 TIME_WAIT 形成的情况. 每次 http 请求都会新创建一个 client, 请求完毕之后主动关闭 http 连接, 由于这个过程极为频繁, TIME_WAIT 需要 2 MSL 的时间才会结束, 于是短时间形成了堆积.
在这个例子中, 我们可以使用 http.DefaultClient
代替 http.Client{}
, 每次请求的时候使用全局默认的 client,
避免频繁的开关连接, 使用 DefaultClient 本质就是使用了连接池, 而不是每次都新建连接.
四 模拟 CLOSE_WAIT
我们最常见 close wait 的情形是事务.
正确的事务代码例子:
transaction = db.begin()
try:
sql = 'update table set deleted = 1 where id = 1'
transaction.exec(sql)
transaction.commit()
catch:
transaction.rollback()
finally:
transaction.close()
错误的事务处理例子:
transaction = db.begin()
try:
sql = 'update table set deleted = 1 where id = 1'
transaction.exec(sql)
transaction.commit()
catch:
transaction.rollback()
在错误的例子中, 我们忘记了调用 transaction.close() 关闭事务连接或者回收事务占用的 tcp 连接
五 各个状态存在的生命周期
- time wait 的生存时间是 2 MSL. RFC 定义的 MSL 是 2 分钟, 因此总共 4 分钟; linux 默认实现是 60s (定义在 Linux 内核源码 /usr/src/linux/include/net/tcp.h 中).
- close wait 的生存时间是一直到 tcp 生命结束才会结束. 所以受到 tcp keep alive 时间限制, 以 centos 为力, tcp_keepalive_time = 1200 s, 这个配置可以更改. (KeepAlive并不是TCP协议规范的一部分,但在几乎所有的TCP/IP协议栈(不管是Linux还是Windows)中,都实现了KeepAlive功能)
附件一: time_wait.go
package main
import (
"net/http"
"io/ioutil"
"sync"
"log"
)
var (
goPool *GoPool
)
func main() {
goPool = NewGPool(100)
url := "http://www.ifeng.com"
req, _ := http.NewRequest("GET", url, nil)
for {
goPool.Add()
go HttpGet(req)
}
}
func HttpGet(req *http.Request) ([]byte, error) {
defer goPool.Done()
client := http.Client{}
var body []byte
var resp *http.Response
var err error
resp, err = client.Do(req)
if err != nil {
return body, err
}
log.Println("http status: ", resp.Status)
body, err = ioutil.ReadAll(resp.Body)
log.Println("http body:", string(body))
resp.Body.Close()
return body, err
}
type GoPool struct {
queue chan int
wg sync.WaitGroup
}
func NewGPool(size int) *GoPool {
if size <= 0 {
log.Panicln("Size must over than zero.")
}
return &GoPool{
queue: make(chan int, size),
wg: sync.WaitGroup{},
}
}
func (p *GoPool) Add() {
p.queue <- 1
p.wg.Add(1)
}
func (p *GoPool) Done() {
p.wg.Done()
<-p.queue
}
func (p *GoPool) Wait() {
p.wg.Wait()
}
以上所述就是小编给大家介绍的《Tcp 连接处于异常状态的一点总结 (close wait & time wait)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 支付宝小程序向个人开发者开放公测:处于限量状态
- JDK 11 已处于特性冻结状态,看看 Java 11 API 变更提案
- Android获取软键盘的高度、键盘的打开与关闭、监听键盘处于打开还是关闭状态
- AppEngine Channel API – 检查频道是否仍处于打开状态的最佳方式(服务器端)
- 解决VirtualBox升级到5.2.6后无法启动之前版本关闭的处于休眠状态的芯片组为ICH9的虚拟机报告错误...
- Python 3.7 上架微软商店,尚处于评估阶段
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法概论
Sanjoy Dasgupta、Christos Papadimitriou、Umesh Vazirani / 王沛、唐扬斌、刘齐军 / 清华大学出版社 / 2008-7 / 39.99元
《国外经典教材·算法概论》涵盖了绝大多数算法设计中的常用技术。在表达每一种技术时,阐述它的应用背景,强调每个算法运转背后的简洁数学思想,注意运用与其他技术类比的方法来说明它的特征,并提供了大量相应实际问题的例子。《国外经典教材·算法概论》同时也注重了对每一种算法的复杂性分析。全书共10章,从基本的数字算法人手,先后介绍了分治、图的遍历、贪心算法、动态规划、线性规划等技术,对NP完全问题进行厂基本而......一起来看看 《算法概论》 这本书的介绍吧!