golang 高并发的http请求fasthttp

以前写接口测试的代码,用go自带的http库,当需要高并发的时候,报连接数不够的错误,无法满足要求,查阅相关资料,三方库fasthttp可以很好的支持高并发,区别在于fasthttp使用了连接池,达到了很好的连接复用的效果

源码:

fasthttp.AcquireResponse()

> AcquireResponse returns an empty Response instance from response pool.
> 
> The returned Response instance may be passed to ReleaseResponse when
> it is no longer needed. This allows Response recycling, reduces GC
> pressure and usually improves performance.

主要方法:

fasthttp.AcquireRequest()//获取Request连接池中的连接
fasthttp.ReleaseRequest(req) // 用完需要释放资源
fasthttp.AcquireResponse()//获取Response连接池中的连接
fasthttp.ReleaseResponse(resp) // 用完需要释放资源
fasthttp.Do(req, resp)

这样代码也非常简洁,逻辑非常清晰

直接上代码:

package request

import (
	"github.com/valyala/fasthttp"
	log "github.com/wonderivan/logger"
    // "time"
    // "github.com/tidwall/gjson"

)
var getcount int =1
var postcount int =1
/**
 * @description: test
 * @Author: WangZhouFeng
 * @param : 
 * @return: 
 * @Date: 2020-01-13 14:12:27
 */
func Post(url string){
    req := fasthttp.AcquireRequest()//获取Request连接池中的连接
    defer fasthttp.ReleaseRequest(req) // 用完需要释放资源    
    // 默认是application/x-www-form-urlencoded
    req.Header.SetContentType("application/json")
    req.Header.SetMethod("POST")    
    req.SetRequestURI(url)    
    // requestBody := []byte(`{"request":"test"}`)
    // req.SetBody(requestBody)
    resp := fasthttp.AcquireResponse()//获取Response连接池中的连接
    defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源
    if err := fasthttp.Do(req, resp); err != nil {//发送请求
		log.Error(err)
        return
    }
	b := resp.Body()
    // resp.Body()
    log.Info(b)
}
/**
 * @description: test
 * @Author: WangZhouFeng
 * @param : 
 * @return: 
 * @Date: 2020-01-13 14:12:21
 */
 //带HERDER和QUERY的get请求
func Get(url string,header map[string]string,query map[string]string) ([]byte,error) {
    req := fasthttp.AcquireRequest()
    defer fasthttp.ReleaseRequest(req) // 用完需要释放资源
    
    // 默认是application/x-www-form-urlencoded
    // req.Header.SetContentType("application/json")
    req.Header.SetContentType("application/x-www-form-urlencoded")

    req.Header.SetMethod("GET")
    //set header
    for k, v := range header {
		req.Header.Set(k, v)
    }
    //set query
    if len(query) !=0{
        url = url + "?"
        url1 := ""
        for k,v := range query{
            temp := k+"="+v
            url1 = url1+"&"+temp
        }
        url1 = url1[1:len(url1)]
        url = url + url1
    }
    req.SetRequestURI(url)

    // log.Info(&req.Header)//获取header
    // log.Info(string(req.RequestURI()))//获取url
    // log.Info(string(req.Body()))//获取body

    resp := fasthttp.AcquireResponse()
    defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源

    if err := fasthttp.Do(req, resp); err != nil {
        log.Error(err)
        return nil,err
     
    }
    // for k,v :=range(query){
    //     log.Info(k+":"+v)
    // }
    body := string(resp.Body())
    // log.Info(body)
    log.Info(getcount)
    getcount++
	return []byte(body),nil
}
// 带header,form,query的post请求通用
func Postdata(header map[string]string,form map[string]string,data map[string]string,url string) (err error,body []byte) {
    req := fasthttp.AcquireRequest()
    defer fasthttp.ReleaseRequest(req) // 用完需要释放资源
    // 默认是application/x-www-form-urlencoded
    req.Header.SetContentType("application/x-www-form-urlencoded")
    req.Header.SetMethod("POST")
    req.Header.Set("Accept-language","zh-cn")

    // 拼接query
    if len(data) !=0{
        url = url + "?"
        url1 := ""
        for k,v := range data{
            temp := k+"="+v
            url1 = url1+"&"+temp
        }
        url1 = url1[1:len(url1)]
        url = url + url1
    }
    req.SetRequestURI(url)

    //添加header
	for k, v := range header {
		req.Header.Set(k, v)
    }
    //添加form
    if len(form) !=0{
        param :=""
        for k, v := range form {
            temp := k+"="+v
            param = param +"&"+temp
        }
        param = param[1:len(param)]
        req.SetBodyString(param)
    }
    // log.Info(&req.Header)//获取header
    // log.Info(string(req.RequestURI()))//获取url
    // log.Info(string(req.Body()))//获取body
    // log.Info(string(req.R()))//获取url

    resp := fasthttp.AcquireResponse()
    defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源

    if err := fasthttp.Do(req, resp); err != nil {
        log.Error(err)
        return err,nil
    }
    body = resp.Body()
    // log.Info(string(body))

    // if resp.StatusCode() != fasthttp.StatusOK {
    //     log.Error("ACTIVITY unexpected status code: %d\n", resp.StatusCode())
    //     return
    // }else{
    //     json := body
    //     //format需要的值,处理code,写 log
    //     code := gjson.Get(json, "code").Int()
    //     if code == 10000{
    //         log.Info(body)
    //         return 
    //     }else{

    //         return
    //     }
    // }
    log.Info(postcount)
    postcount++
    fasthttp.ReleaseRequest(req)
    fasthttp.ReleaseResponse(resp)
    return err,[]byte(body)
}


func Deletedata(header map[string]string,form map[string]string,data map[string]string,url string) (err error,body []byte) {
    req := fasthttp.AcquireRequest()
    defer fasthttp.ReleaseRequest(req) // 用完需要释放资源
    // 默认是application/x-www-form-urlencoded
    req.Header.SetContentType("application/x-www-form-urlencoded")
    req.Header.SetMethod("DELETE")
    req.Header.Set("Accept-language","zh-cn")

    // 拼接query
    if len(data) !=0{
        url = url + "?"
        url1 := ""
        for k,v := range data{
            temp := k+"="+v
            url1 = url1+"&"+temp
        }
        url1 = url1[1:len(url1)]
        url = url + url1
    }
    req.SetRequestURI(url)

    //添加header
	for k, v := range header {
		req.Header.Set(k, v)
    }
    //添加form
    if len(form) !=0{
        param :=""
        for k, v := range form {
            temp := k+"="+v
            param = param +"&"+temp
        }
        param = param[1:len(param)]
        req.SetBodyString(param)
    }
    // log.Info(&req.Header)//获取header
    log.Info(string(req.RequestURI()))//获取url
    // log.Info(string(req.Body()))//获取body

    resp := fasthttp.AcquireResponse()
    defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源

    if err := fasthttp.Do(req, resp); err != nil {
        log.Error(err)
        return err,nil
    }
    body = resp.Body()
    log.Info(string(body))

    // if resp.StatusCode() != fasthttp.StatusOK {
    //     log.Error("ACTIVITY unexpected status code: %d\n", resp.StatusCode())
    //     return
    // }else{
    //     json := body
    //     //format需要的值,处理code,写 log
    //     code := gjson.Get(json, "code").Int()
    //     if code == 10000{
    //         log.Info(body)
    //         return 
    //     }else{

    //         return
    //     }
    // }
    fasthttp.ReleaseRequest(req)
    fasthttp.ReleaseResponse(resp)
    return err,[]byte(body)
}




func Putdata(header map[string]string,form map[string]string,data map[string]string,url string) (err error,body []byte) {
    req := fasthttp.AcquireRequest()
    defer fasthttp.ReleaseRequest(req) // 用完需要释放资源
    // 默认是application/x-www-form-urlencoded
    req.Header.SetContentType("application/x-www-form-urlencoded")
    req.Header.SetMethod("PUT")
    req.Header.Set("Accept-language","zh-cn")

    // 拼接query
    if len(data) !=0{
        url = url + "?"
        url1 := ""
        for k,v := range data{
            temp := k+"="+v
            url1 = url1+"&"+temp
        }
        url1 = url1[1:len(url1)]
        url = url + url1
    }
    req.SetRequestURI(url)

    //添加header
	for k, v := range header {
		req.Header.Set(k, v)
    }
    //添加form
    if len(form) !=0{
        param :=""
        for k, v := range form {
            temp := k+"="+v
            param = param +"&"+temp
        }
        param = param[1:len(param)]
        req.SetBodyString(param)
    }
    // log.Info(&req.Header)//获取header
    log.Info(string(req.RequestURI()))//获取url
    // log.Info(string(req.Body()))//获取body

    resp := fasthttp.AcquireResponse()
    defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源

    if err := fasthttp.Do(req, resp); err != nil {
        log.Error(err)
        return err,nil
    }
    body = resp.Body()
    log.Info(string(body))

    // if resp.StatusCode() != fasthttp.StatusOK {
    //     log.Error("ACTIVITY unexpected status code: %d\n", resp.StatusCode())
    //     return
    // }else{
    //     json := body
    //     //format需要的值,处理code,写 log
    //     code := gjson.Get(json, "code").Int()
    //     if code == 10000{
    //         log.Info(body)
    //         return 
    //     }else{

    //         return
    //     }
    // }
    fasthttp.ReleaseRequest(req)
    fasthttp.ReleaseResponse(resp)
    return err,[]byte(body)
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
golang中,高并发项目实战可以通过使用goroutines和channels来实现。其中,goroutines是轻量级的线程,可以并发执行多个任务,而channels则用于goroutines之间的通信。 一个常见的高并发项目实战是使用golang开发网络爬虫。网络爬虫是一种通过自动化程序浏览互联网,并从网页中提取数据的技术。在golang中,可以使用第三方的爬虫框架来简化开发过程,如引用所提到的爬虫框架。 在这个项目中,可以将爬虫框架的处理模块分为下载器、分析器和条目处理器。下载器负责从指定的URL下载网页内容,分析器用于解析网页并提取需要的数据,而条目处理器则对提取的数据进行处理。此外,还需要一个调度和协调这些处理模块运行的控制模块来确保它们按照预期的方式运行。 为了实现高并发,可以将每个任务(即要爬取的URL)分配给一个goroutine来执行。可以使用goroutine和channel的组合来实现任务的并发执行和结果的收集。引用中给出了一个示例函数CheckWebsites,该函数接收一个WebsiteChecker函数和一个URL列表,并返回一个映射,其中URL与检查结果对应。 在该示例函数中,使用了一个resultChannel来收集每个URL的检查结果。通过使用goroutine,在遍历URL列表时,可以将每个URL的检查结果发送到resultChannel中。然后,通过在循环中使用<-resultChannel来接收结果,并将结果存储在一个map中。 通过这种方式,可以实现高并发的URL检查,并在所有检查完成后返回结果。 总之,golang高并发项目实战可以通过使用goroutines和channels来实现并发执行任务和结果的收集。网络爬虫是一个常见的高并发项目实战示例,通过使用爬虫框架和适当的并发控制,可以实现高效的网页数据提取。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [golang GRPC 高并发实战1:基础环境搭建](https://blog.csdn.net/xatop/article/details/123326480)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [golang爬虫框架,golang高并发实战](https://download.csdn.net/download/weixin_44772356/87273641)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [golang高并发的思想与实践](https://blog.csdn.net/m0_58181788/article/details/123938547)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值