登录
首页 >  Golang >  Go问答

唯一实例的HTTP客户端

来源:stackoverflow

时间:2024-03-01 15:39:24 366浏览 收藏

Golang不知道大家是否熟悉?今天我将给大家介绍《唯一实例的HTTP客户端》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!

问题内容

我正在创建一个类,其中包含调用一些 api 的函数,到目前为止我已经:

var client *http.client

func getclient() *http.client {
    if client == nil {
        client = &http.client{
            timeout: time.second * 30,
            transport: &http.transport{
                dial: (&net.dialer{
                timeout:   30 * time.second,
                keepalive: 30 * time.second,
            }).dial,
            tlshandshaketimeout: 10 * time.second,
            },
        }
    }
    return client
}

然后创建一个执行调用的函数:

func CallRestApi(request Request) (response Response) {
    getClient()
    req, err := http.NewRequest(request.Method, url, bytes.NewBuffer(request.Params))
    
    resp, err := client.Do(req)
    ...
}

我不确定这样是否可以创建一个单例 client 实例,以便从执行此函数的任何模块中使用该实例(如果该实例已存在)。


解决方案


如果您仅从单个 goroutine 调用 getclient(),您的解决方案将创建单个 http.client 实例。

如果您从多个 goroutine 调用它,那么这是一个数据竞争,因此是未定义的行为。

您可以将 client 作为程序包初始化的一部分进行初始化,如果您从那时起只阅读它,那么您将是安全的:

var client = getclient()

如果您不能或不想这样做,请稍后再使用 sync.Once 初始化您的 client,这样您就可以安全地并发使用:

var (
    once   sync.once
    client *http.client
)

func initclient() {
    once.do(func() {
        client = &http.client{
            timeout: time.second * 30,
            transport: &http.transport{
                dial: (&net.dialer{
                    timeout:   30 * time.second,
                    keepalive: 30 * time.second,
                }).dial,
                tlshandshaketimeout: 10 * time.second,
            },
        }
    })
}

这是一种更简单的方法:

var Client *http.Client= &http.Client{
            Timeout: time.Second * 30,
            Transport: &http.Transport{
                Dial: (&net.Dialer{
                Timeout:   30 * time.Second,
                KeepAlive: 30 * time.Second,
            }).Dial,
            TLSHandshakeTimeout: 10 * time.Second,
            },
        }
    }

您不需要单独的初始化函数来初始化变量。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>