因公司业务需求想尝试使用go连接第三方公司的http api
现有业务访问api全是大量短连接 大量临时端口访问第三方的80端口
同时导致服务器上大量TIME_WAITE状态的进程
但是线下调试后发现并没什么卵用。。
必须sleep后 下一个线程才能复用前面的conn连接
原因:复用http conn 必须等待上一个请求完全结束response后,下一个线程才能复用。
结论:http不大适合长连接的某些应用,可能浏览器 作为客户端的时候keep_alive比较有用
package main
import (
"fmt"
"io/ioutil"
"net"
"net/http"
"strconv"
"time"
)
func doGet(client *http.Client, url string, id int) {
resp, err := client.Get(url)
if err != nil {
fmt.Println(err)
return
}
buf, err := ioutil.ReadAll(resp.Body)
fmt.Printf("ss %d: %s -- %v\n", id, string(buf), err)
if err := resp.Body.Close(); err != nil {
fmt.Println(err)
}
}
func PrintLocalDial(network, addr string) (net.Conn, error) {
dial := net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}
conn, err := dial.Dial(network, addr)
if err != nil {
return conn, err
}
fmt.Println("connect done, use", conn.LocalAddr().String())
return conn, err
}
const (
MaxIdleConns int = 100
MaxIdleConnsPerHost int = 100
IdleConnTimeout int = 90
)
func main() {
const URL = "http://dev.myspace.com/"
client := &http.Client{
Transport: &http.Transport{
Dial: PrintLocalDial,
// Proxy: http.ProxyFromEnvironment,
// DialContext: (&net.Dialer{
// Timeout: 30 * time.Second,
// KeepAlive: 30 * time.Second,
// }).DialContext,
MaxIdleConns: MaxIdleConns,
MaxIdleConnsPerHost: MaxIdleConnsPerHost,
IdleConnTimeout: time.Duration(IdleConnTimeout) * time.Second,
},
}
// doGet(client, URL+"?id="+strconv.Itoa(0), 0)
// doGet(client, URL+"?id="+strconv.Itoa(1), 1)
// doGet(client, URL+"?id="+strconv.Itoa(2), 2)
// doGet(client, URL+"?id="+strconv.Itoa(3), 3)
for i := 0; i < 100; i++ {
// doGet(client, URL+"?id="+strconv.Itoa(i), i)
go doGet(client, URL+"?id="+strconv.Itoa(i), i)
// if i < 2 {
// time.Sleep(1 * time.Second)
// }
}
time.Sleep(22 * time.Second)
}