golang 的 http 請求池

CrazyZard發表於2021-08-23

看到平臺銀行對接方案
寫的 demo 確實還不錯
記個筆記 互相學習學習

package api

import (
        "crypto/tls"
        "net"
        "net/http"
        "strings"
        "sync"
        "time"
)

// http連線池相關引數
const (
        defaultPoolSize         = 50
        defaultRequestTimeout   = 30 * time.Second
        defaultTLSShakeTimeout  = 5 * time.Second
        defaultConnectTimeout   = 5 * time.Second
        defaultKeepAliveTimeout = 15 * time.Second
)

var oneManager sync.Once
var connectManager *connectionManager

type connectionManager struct {
        clientPool map[string]*http.Client
        mapLock    sync.RWMutex
}

func NewConnectionManager() *connectionManager {
        oneManager.Do(func() {
                if connectManager == nil {
                        connectManager = &connectionManager{clientPool: make(map[string]*http.Client)}
                }
        })
        return connectManager
}

func (c *connectionManager) GetHttpClient(url string) *http.Client {
        c.mapLock.RLock()
        if _, ok := c.clientPool[url]; ok {
                client := c.clientPool[url]
                c.mapLock.RUnlock()
                return client
        }
        c.mapLock.RUnlock()
        innerContext := net.Dialer{
                // 建鏈超時時間
                Timeout: defaultConnectTimeout,
                // 連結生命週期
                KeepAlive: defaultKeepAliveTimeout}
        transport := &http.Transport{
                MaxIdleConnsPerHost: defaultPoolSize,
                MaxConnsPerHost:     defaultPoolSize,
                DialContext:         innerContext.DialContext}
        if isHttps(url) {
                transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
                transport.TLSHandshakeTimeout = defaultTLSShakeTimeout
        }
        tempClient := &http.Client{
                // 總超時時間=建鏈+重定向+讀取響應
                Timeout:   defaultRequestTimeout,
                Transport: transport,
        }
        c.mapLock.Lock()
        c.clientPool[url] = tempClient
        c.mapLock.Unlock()
        return tempClient

}

func isHttps(url string) bool {
        urlArray := strings.Split(url, ":")
        if urlArray[0] == "https" {
                return true
        }
        return false
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結
快樂就是解決一個又一個的問題!

相關文章