[golang] fasthttp 使用http代理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[golang] fasthttp 使用http代理相关的知识,希望对你有一定的参考价值。

参考技术A golang net/http标准库的client是可以配置各种代理的,http/https/sock5等,不过fasthttp仅支持配置sock5代理,通过定义fasthttp dialfunc实现:

项目中碰到的问题是,ops只提供了用squid搭建的http代理,所以是想重新定义一个http代理的dialfunc,找了fasthttp github仓库的issue,作者提供了一个dialFunc
https://github.com/valyala/fasthttp/issues/363#issuecomment-417868528

经测试,访问https的站点是OK的,访问http的站点不行,代理连接不上。先说一下http/https代理的区别,再说原因。

使用代理访问https网站时,会先发CONNECT请求,让代理与目标站点建立一个http tunnel,之后在这个tunnel基础上进行传输,对应到上面的dialFunc过程就是:

可以看到http站点是不需要发CONNECT请求的,而是直接将目标站点的url作为path 填写在http请求头中。

为何上面的dialfunc访问http站点不行呢,查了squid代理的文档,发现squid默认会禁止非https站点通过CONNECT方法建立通道,自己搭了个squid代理去掉配置项,发现上面的dialfunc是可以访问http、https站点的,就是说http,https都先建立通过,再请求。

看了fasthttp的源码,没办法在请求前修改request header中的path为目标站点url,所以如果需要通过fasthttp使用http代理,那么可以使用上面的dialfunc,同时代理需要允许非443端口的站点可以建立通道。如果做不到这一点,那么还是建议使用标准库net/http的client,会更方便一点。

Golang fasthttp请求非常慢

【中文标题】Golang fasthttp请求非常慢【英文标题】:Golang fasthttp very slow with request 【发布时间】:2017-02-14 16:29:30 【问题描述】:

我正在使用 fasthttp 包构建一个 Rest API。我有一个用来衡量性能的测试路线:

package main

import (
    "github.com/valyala/fasthttp"
    "runtime"
)

func main() 

    runtime.GOMAXPROCS(8)
    m := func(ctx *fasthttp.RequestCtx) 
        switch string(ctx.Path()) 
        case "/test":
            test(ctx)
        default:
            ctx.Error("not found", fasthttp.StatusNotFound)
        
    

    fasthttp.ListenAndServe(":80", m)


func test(ctx *fasthttp.RequestCtx) 
    println("HERE")

如果我向该路由发送请求,则需要 10 多秒才能到达测试函数中的 println("HERE")

我在 Node.js 中构建了一个类似的端点,这个完全相同的功能和路由需要 126 毫秒。 为什么在 Go 中调用这条路由指向的函数需要这么长时间?

【问题讨论】:

我刚刚使用您的确切代码进行了测试,几乎不需要时间(不到 1 秒)即可到达 println("HERE")。您的测试设置有多准确? 尝试我的示例并发布(添加评论)代码(2)输出 【参考方案1】:

对我来说,100000 http.Head 只需要 7.9454545 秒(每 http.Head 需要 79.454545us,运行这 1 和 2 个代码时,只有 2 个核心 CPU,负载为 77%)。

你不需要runtime.GOMAXPROCS(8),用fmt.Println()代替println()

1- 试试这个:

package main

import (
    "fmt"

    "github.com/valyala/fasthttp"
)

func main() 
    m := func(ctx *fasthttp.RequestCtx) 
        switch string(ctx.Path()) 
        case "/test":
            test(ctx)
        default:
            fmt.Println(i)
            ctx.Error("not found", fasthttp.StatusNotFound)
        
    
    fasthttp.ListenAndServe(":80", m)


func test(ctx *fasthttp.RequestCtx) 
    i++


var i int = 0

输出:

100000

2- 使用此获取:

package main

import (
    "fmt"
    "net/http"
    "time"
)

func main() 
    t := time.Now()
    for i := 0; i < 100000; i++ 
        read(`http://localhost/test`)
    
    fmt.Println(time.Since(t))
    read(`http://localhost/`)


func read(url string) 
    _, err := http.Head(url)
    if err != nil 
        fmt.Println(err)
    

输出:

7.9454545s

3-This code 的输出:

8.6294936s

【讨论】:

以上是关于[golang] fasthttp 使用http代理的主要内容,如果未能解决你的问题,请参考以下文章

一次golang fasthttp踩坑经验

Golang fasthttp请求非常慢

fasthttp性能真的比标准库http包好很多吗?一文告诉你真相!

字节跳动开源的一个 Golang 微服务 HTTP 框架

Fasthttp源码分析之http server源码分析

httprouter与 fasthttp 的性能对比