前段时间,在一家公司呆了 20 多天,他们有个业务,需要定时更新业务的数据,更新的流程大概是,请求外部接口然后自行转换一下然后上报到百度那边。
但他们原本的处理和我写的补偿发放简易版不太一样,他们弄了个 HTML 来循环请求自己的接口,处理是同步的,并发是 1,所以有时候需要开几个电脑,然后每个电脑又是开几个浏览器,这样子一直来访问,相当于效率还是很低的,而且别人电脑也会占用到,影响了别人的工作进度。
当然,我已经离职很久了,这只是对之前的方案进行一个优化,不进行大的调整这是很重要的,毕竟很多人的业务也已经是屎山了。
大概思路是,利用 channel 的缓存来设定最大的并发数,配合上 sync.WaitGroup 来等待全部请求的完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| package main
import ( "fmt" "net/http" "sync" "time" )
var wg = sync.WaitGroup{}
var mux sync.Mutex
var channelNum = 100
var sendNum = 10000
var successNum = 0
var failNum = 0
var url = "https://tools.hongfs.cn/v2/ip"
func main() { ch := make(chan bool, channelNum)
for i := 0; i < sendNum; i++ { wg.Add(1)
go get(ch, int64(i)) }
wg.Wait() }
func get(ch chan bool, i int64) { defer wg.Done()
ch <- true
client := http.Client{ Timeout: 1 * time.Second, }
resp, err := client.Get(url)
if err == nil { defer resp.Body.Close() }
mux.Lock()
defer mux.Unlock()
if err != nil { failNum++ } else if resp.StatusCode != 200 { failNum++ } else { successNum++ }
fmt.Printf("I: %d, 成功数: %d,失败数:%d\n", i+1, successNum, failNum)
<-ch }
|
1 2 3 4 5 6 7 8 9 10 11 12
| $ go run main.go I: 9990, 成功数: 4085,失败数:5905 I: 9992, 成功数: 4085,失败数:5906 I: 9993, 成功数: 4085,失败数:5907 I: 9991, 成功数: 4085,失败数:5908 I: 9995, 成功数: 4085,失败数:5909 I: 9996, 成功数: 4085,失败数:5910 I: 9997, 成功数: 4085,失败数:5911 I: 9994, 成功数: 4085,失败数:5912 I: 9998, 成功数: 4085,失败数:5913 I: 9999, 成功数: 4085,失败数:5914 I: 10000, 成功数: 4085,失败数:5915
|