如何在Go中缓存/重用TLS连接

时间:2019-03-30 00:58:57

标签: ssl go tcp tls1.2

我遇到了一个问题,我在每个请求中创建一个新连接,效率非常低。

我想允许设置的最大TLS连接数立即在客户端上保持打开/缓存状态。当准备好传输数据时,它首先检查是否有空闲连接,然后检查是否可以创建新连接(即,打开的连接数<允许的最大值)。如果两者都为假,则必须等到连接变为空闲或打开的连接数减少为止。连接闲置一定时间后,也应终止它们。

这是我想到的一些(错误的)伪代码。我可以提出一些建议吗?

func newTLSConnection(netDialer, host, tlsConfig) (tls.Con) {

    // Set up the certs
    // ...

    // Make A TLS Connection
    con, _ := tls.DialWithDialer(netDialer, "tcp", host, tlsConfig)

    return con
}

func (con tls.Con) Do (someData []byte) {

    // If con 
    // Send some date to the server
    _, _ := con.Write(someData)

    // Get response from server
    response := make([]byte, 100)
    _, _ := io.ReadFull(con, response)

    return
}


main(){
    var cons []tls.Con
    maxConSize := 3

    while {

        if allConsInSliceAreBusy() && len(cons) < maxConSize{
            newCon = NewTLSConnection(...)
            cons = append(cons, newCon)
            conToUse := newCon

            conToUse.Do([]byte("stuff"))

        } else if !allConsInSliceAreBusy() {

            conToUse := firstOpenConInCons()

            conToUse.Do([]byte("stuff"))

        } else{
             // NOP. Max cons created and they are all busy.
             // Wait for one to become idle or close.
        }
    }
}

谢谢!

1 个答案:

答案 0 :(得分:0)

您询问的问题称为连接池。看看Fasthttp包的源代码:https://github.com/valyala/fasthttp/blob/master/client.go您甚至可以根据需要使用此库或另一个。

在第1252行,您可以找到all()函数,它完全满足您的需求:

  • 锁定连接池以允许并发执行。
  • 如果池为空(将新连接从池中拉出),则创建新连接。
  • 在TTL超时的情况下进行连接清理。