最近用到了 Go 从 Excel 导数据到服务器内部 用的是 http 请求

但是发现一个问题 从文件读取之后 新开 Goroutine 会无限制新增

导致全部卡在初始化请求 于是乎就卡死了

问题模拟

  • 模拟代码
func main() {
pool := sync.WaitGroup{}
for i := 0; i < 500; i++ {
pool.Add(1)
go func(i int) {
resp, err := http.Get("http://ip.3322.org")
if err != nil {
fmt.Println(i, err)
} else {
defer resp.Body.Close()
result, _ := ioutil.ReadAll(resp.Body)
fmt.Println(i, string(result))
}
pool.Done()
}(i)
}
pool.Wait()
}
  • 数量小的情况下 没有问题 但是数量比较大的情况 就会发现程序直接卡死 一段时间之后报错 并且没有发出任何请求

问题解决

  • 实际上看的出来 是应为同时发起了太多的HTTP请求 导致系统卡死 数据没有发送
  • 想到我在Java中用Thread提交请求 我就考虑 可不可限制 Goroutine 的数量
  • 使用强大的百度 果然找到了大佬已经写好的协程池
  • 代码如下 我加上了注释
package gopool

import (
"sync"
) // Pool Goroutine Pool
type Pool struct {
queue chan int
wg *sync.WaitGroup
} // New 新建一个协程池
func New(size int) *Pool {
if size <= 0 {
size = 1
}
return &Pool{
queue: make(chan int, size),
wg: &sync.WaitGroup{},
}
} // Add 新增一个执行
func (p *Pool) Add(delta int) {
// delta为正数就添加
for i := 0; i < delta; i++ {
p.queue <- 1
}
// delta为负数就减少
for i := 0; i > delta; i-- {
<-p.queue
}
p.wg.Add(delta)
} // Done 执行完成减一
func (p *Pool) Done() {
<-p.queue
p.wg.Done()
} // Wait 等待Goroutine执行完毕
func (p *Pool) Wait() {
p.wg.Wait()
}
  • 然后修改刚才的测试方法
package main

import (
"io/ioutil"
"log"
"net/http"
"yumc.pw/cloud/lib/gopool"
) func main() {
// 这里限制5个并发
pool := gopool.New(5)// sync.WaitGroup{}
for i := 0; i < 500; i++ {
pool.Add(1)
go func(i int) {
resp, err := http.Get("http://ip.3322.org")
if err != nil {
fmt.Println(i, err)
} else {
defer resp.Body.Close()
result, _ := ioutil.ReadAll(resp.Body)
fmt.Println(i, string(result))
}
pool.Done()
}(i)
}
pool.Wait()
}
  • 完美解决

通过 Channel 实现 Goroutine Pool的更多相关文章

  1. 如果裸写一个goroutine pool

    引言 在上文中,我说到golang的原生http server处理client的connection的时候,每个connection起一个goroutine,这是一个相当粗暴的方法.为了感受更深一点, ...

  2. fasthttp 的 goroutine pool 实现探究

    引言 fasthttp是一个非常优秀的web server框架,号称比官方的net/http快10倍以上.fasthttp用了很多黑魔法.俗话说,源码面前,了无秘密,我们今天通过源码来看一看她的gor ...

  3. goroutine pool,WaitGroup,chan 示例

    服务端高并发编程经常需要写很多goroutine来服务每一个连接,如何正确使用goroutine池是又拍云的工程师们需要考虑的问题,今天这篇文章,分享给同样需要使用go语言的小伙伴们. 文/陶克路 本 ...

  4. golang 部分理解:关于channel 和 goroutine 例子

    部分理解:关于channel 和 goroutine 例子package main import "strconv" import "fmt" func mai ...

  5. golang(8):channel读写 & goroutine 通信

    goroutine 1.进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位 B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独 ...

  6. golang如何使用channel控制goroutine退出

    最经典的处理方式: 在启动goroutine的时候,传递一个额外的chan型参数,用来接收退出信号,代码如下 func worker(name string, stopchan chan struct ...

  7. TODO:Go语言goroutine和channel使用

    TODO:Go语言goroutine和channel使用 goroutine是Go语言中的轻量级线程实现,由Go语言运行时(runtime)管理.使用的时候在函数前面加"go"这个 ...

  8. Go语言学习笔记(七)杀手锏 Goroutine + Channel

    加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 Goroutine Go语言的主要的功能在于令人简易使用的并行设计,这个方法叫做Goroutine,通过Gorou ...

  9. go语言之行--golang核武器goroutine调度原理、channel详解

    一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...

随机推荐

  1. 洛谷P3905 道路重建

    题目:https://www.luogu.org/problemnew/show/P3905 分析: 此题是显然的最短路算法,只是看到一起删掉的一堆边感到十分棘手,而且还要求出的是最短添加边的总长度 ...

  2. Netty-解码器架构与常用解码器

    任何数据类型想在网络中进行传输,都得经过编解码转换成字节流 在netty中,服务端和客户端进行通信的其实是下面这样的 程序 ---编码--> 网络 网路 ---解码--> 程序 对应服务端 ...

  3. Gym - 101194L World Cup 暴力

    World CupInput file: Standard InputOutput file: Standard OuptutTime limit: 1 second Here is World Cu ...

  4. e校帮V1.1使用指南

    2017年04月17日,e校帮正式版本V1.1.4正式上线了.大家可以在e校帮官网进行下载,http://exiaobang.top 或者在搜狗手机助手/搜狗输入法/酷安进行下载. e校帮简介: e校 ...

  5. [leetcode] 309. Best Time to Buy and Sell Stock with Cooldown(medium)

    原题 思路: 状态转移 出售股票的状态,最大利润有两种可能. 一,和昨天一样不动:二,昨天持有的股票今天卖掉. sell[i] = max(sell[i-1],buy[i-1] + prices[i] ...

  6. 微信小程序踩坑日记1——调用微信授权窗口

    0. 引言 微信小程序为了优化用户体验,取消了在进入小程序时立马出现授权窗口.需要用户主动点击按钮,触发授权窗口. 那么,在我实践过程中,出现了以下问题. . 无法弹出授权窗口 . 希望在用户已经授权 ...

  7. python中的元类(metaclass)

    认识python中元类的准备工作. 1,首先需要明白一个概念就是python中一切皆为对象. input: class Trick(object): pass ') print type(1234) ...

  8. CSS和html如何结合起来——选择符及优先级

       1.选择符     兼容性 统配选择符 *         元素选择符 body   类选择符 .class   id选择符 #id         包含原则符 p strong     (所有 ...

  9. 【iOS】iOS Error Domain=NSCocoaErrorDomain Code=3840 "未能完成操作。(“Cocoa”错误 3840。)"

    昨天遇到的这个问题,详细信息: ----->类和方法__25+[Manager noticeRequest:]_block_invoke399----->错误信息Error Domain= ...

  10. gdb调试和编译后运行结果不一致

    今天在看代码时,遇到这么一段代码,我但是用g++编译了,运行发现有Segmentation fault. 然后就用gdb跟进去看看,可是gdb却正常执行了.不知道什么原因. #include < ...