优雅的控制协程(goroutine)的并发数量

对golang熟悉的小伙伴都知道,在go中开启go协程是一件简单的事,只需要一个关键字”go“。

并且相比于线程,所需要的系统资源非常少。于是在程序中我们总会开启协程去并发获取数据。

例如:

商城首页,每个商品需要获取图片、价格、销量、店铺、优惠等等一系列信息。

如果单个单个的请求,肯定会由于响应太慢,流失用户。

于是我们自然的会想到使用并发去获取数据,组装后在返回给前端展示。

不过在微服务中,一般信息不会都存在自己这里,会有下游服务进行提供,为了保护自己的系统不会被高流量打垮,下游一般都会限制请求的qps。

比如你有50个商品,但是下游限制10个并发。那么我们就需要一种控制并发数量的手段去请求下游。

在golang中,channel 和 waitgroup 就是常用的控制并发请求的手段。下面我们就来实现一个通用的并发控制方法。

//定义通用函数,包装用户的业务函数,返回单次执行的result和error
type fcWarp func(interface{}) (interface{}, error)/**goNum := 一共需要开启的协程数data  := 业务请求参数,必须是slicefc:定义通用函数,包装用户的业务函数,返回单次执行的result和error返回:result:slice类型,包含多次请求的结果resErrs :slice类型,包含多次请求中出现的err*/
func concurrent(goNum uint, data interface{}, fc fcWarp)(result []interface{},resErrs []error) {if goNum <= 0 {panic("goNum must positive")}vType := reflect.TypeOf(data)if vType.Kind() != reflect.Slice{panic("data must slice")}vValue := reflect.ValueOf(data)limiter := make(chan struct{},goNum)result = make([]interface{},vValue.Len())resErrs = make([]error,vValue.Len())var wg sync.WaitGroupwg.Add(vValue.Len())for i := 0; i < vValue.Len(); i++ {limiter <- struct{}{}go func(i int,d interface{}) {defer func() {<-limiterwg.Done()if err := recover();err != nil{resErrs[i] = fmt.Errorf("panic:%v",err)}}()res,err := fc(d)result[i] = resresErrs[i] = err}(i,vValue.Index(i).Interface())}wg.Wait()return result, resErrs
}

实际使用效果:

整体使用非常简单,只需要进行简单的断言就可以转化为原始数据进行处理。

并且可以通过下标获取到每次的请求res 和 err。

不需要去关心协程控制、错误处理

func main()  {data := []int{1,2,3}res,errs := concurrent(2,data, func(idata interface{}) (interface{}, error) {tmp := idata.(int)if tmp == 2 {panic("is 2")}tmp += tmpreturn tmp,nil})for i := 0; i < len(data); i++ {if errs[i] != nil{fmt.Println(errs[i])continue}fmt.Println(res[i])}
}

输出:

2
panic:is 2
6

推荐阅读

1、原来阿里字节员工简历长这样

2、一条SQL差点引发离职

3、MySQL并发插入导致死锁


如果你也觉得我的分享有价值,记得点赞或者收藏哦!你的鼓励与支持,会让我更有动力写出更好的文章哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Conda 使用environment.yml创建一个新的Python项目

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装Conda python运行的包和环境管理 入门Conda python管理环境environments 一 从入门到精通Conda python管理环境environments 二 从入门到精通Conda python管理环境environments 三 从入门到精通…

Ansible自动化运维(三)Playbook 模式详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

未来已来:OJAC诚邀您与张立赛博士解锁GPT Store的无限潜力!

亲爱的伙伴们&#xff01;本月31日晚上8:30&#xff0c;我们近屿智能OJAC的培训讲师——哈尔滨工业大学博士毕业生、前之江实验室资深研究员张立赛博士&#xff0c;将为我们带来一场深度技术更新讲座&#xff0c;深度探讨GPT Store的最新发展。 本次讲座将从GPT Store的基本概念…

Linux:shell脚本:基础使用(9)《数组》

数组就是一组数据类型相同集合 定义 数组名(元素内容…………) 如果没有元素内容就是空 arr1() # 定义了一个空数组 arr2(1 2 3 4 5 6 ) # 定义了一个元素是整形的数组 arr3("hello" "world" "你好" "世界") # 定义了一个元素为字符…

什么是互联网打工人都需要知道的API?电商API是什么?

我们生活在一个科技主导的世界。在这里&#xff0c;数据无处不在。作为许多不同产品的用户&#xff0c;我们所追寻的不再是某一个能将工作完成的最佳产品&#xff0c;而是一个不仅能有效完成工作&#xff0c;同时也与我们所使用的其他工具完美兼容的产品。因此&#xff0c;了解…

欧氏、曼哈顿、马氏距离

马氏距离&#xff08;Mahalanobis Distance&#xff09;、欧氏距离&#xff08;Euclidean Distance&#xff09;、曼哈顿距离&#xff08;Manhattan Distance&#xff09;是常用的距离度量方式&#xff0c;它们在数据分析、模式识别、聚类等领域中经常被使用。 欧氏距离&#…

3D建模素材网站的特点有哪些?

3D建模素材网站的特点主要包括丰富多样的模型种类、高质量的模型、实时预览功能、易于使用、价格合理以及社区互动等。这些特点使得3D建模素材网站成为设计师们不可或缺的资源之一&#xff0c;帮助他们快速高效地完成设计工作。 那么3D建模素材网站的特点有哪些? 1、模型种类丰…

【漏洞复现】上海冰峰ICEFLOW VPN信息泄露漏洞

Nx01 产品简介 上海冰峰计算机网络技术有限公司是国内VPN、流量管理、行为管理、链路负载均衡、下一代防火墙设备供应商和IT价值解决方案提供商。冰峰网络reporter系统是一套数据报表管理系统。 Nx02 漏洞描述 上海冰峰计算机网络技术有限公司ICEFLOW VPN Router系统存在信息泄…

gdb设置core文件生成路径

1.产生core首先需要允许生成core文件&#xff0c;查看方法如下 ulimit -c 如果结果为0&#xff0c;说明关闭了生成core的选项。可以使用以下命令打开 ulimit -c ulimited 或者 ulimit -c 1024 这两个的区别为&#xff0c;ulimited不限制其大小&#xff0c;而1024则设置core最大…

eNSP学习——利用单臂路由实现VLAN间路由

目录 原理概述 实验内容 实验目的 实验步骤 实验拓扑 实验编址 配置步骤 创建VLAN并配置Access、Trunk接口 配置路由器子接口和IP地址 配置路由器子接口封装VLAN 测试结果 原理概述 在以太网中&#xff0c;通常会使用VLAN技术隔离二层广播域来减少广播的影响&#…

langchain + hugginface入门体验

简介 本文记录一次使用langchain调用openai并部署在huggingface上的经历 安装环境依赖 我的python版本是3.9 pip install langchain pip install openai代码 app.py import streamlit as st # from langchain_community.chat_models import ChatOpenAI from langchain_openai …

w23靶场安装

一、实验环境 服务器&#xff1a;phpstudyv8.1.13 靶场&#xff1a;Bees、sdcms、cpms、khbc二、实验目的 提供一个靶场环境 三、实验步骤 bees靶场安装 1.启动小皮的apache和mysql 2.在小皮V8.1.1.3版本上创建bees网站&#xff0c;选择的php版本最好在5.x&#xff0c;不…

聚道云软件连接器:打通金蝶云星空与招商银行CBS,提升企业财务和银行业务效率

【客户介绍】 某企业是一家从事电子商务的企业&#xff0c;随着业务的不断扩大&#xff0c;对于财务管理和银行业务的需求也越来越高。该企业希望能够实现财务和银行业务的自动化处理&#xff0c;提高工作效率。由于业务的不断发展&#xff0c;企业面临着越来越多的资金管理挑…

C++提高编程——STL:函数对象

本专栏记录C学习过程包括C基础以及数据结构和算法&#xff0c;其中第一部分计划时间一个月&#xff0c;主要跟着黑马视频教程&#xff0c;学习路线如下&#xff0c;不定时更新&#xff0c;欢迎关注。 当前章节处于&#xff1a; ---------第1阶段-C基础入门 ---------第2阶段实战…

强化学习14——DDPG算法

在线策略算法的样本效率比较低&#xff0c;而在DNQ算法中&#xff0c;做到了离线策略学习&#xff0c;但是只能处理动作空间有限的环境。如果动作空间无限&#xff0c;可将动作空间离散化&#xff0c;但比较粗糙&#xff0c;无法惊喜控制。深度确定性策略梯度DDPG&#xff08;d…

网站SSL证书怎么获取?

获取SSL证书的途径通常包括以下几种&#xff1a; 1. 通过受信任的证书颁发机构&#xff08;CA&#xff09;购买&#xff1a; - 你可以直接从知名的证书颁发机构如JoySSL、GeoTrust、DigiCert等处购买。 - 这些机构提供不同类型的SSL证书&#xff0c;包括域名验证(DV)、组…

「JavaSE」抽象类接口3

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;快来卷Java啦 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 抽象类&接口3 &#x1f349;Clonable 接口和深拷贝&#x1f34c;浅拷贝和深拷贝 &#x1f349;Object类&#x1f349;抽象类…

Leetcode131.分割回文串-Palindrome Patitioning-Python-回溯法

解题思路&#xff1a; 1.切割回文串&#xff0c;可以用解决找组合问题的思路解决&#xff0c;而解决组合问题&#xff0c;可以用回溯法&#xff0c;故本题选择回溯法。 2.理解两个事情&#xff1a;1.递归函数里的for循环是横向遍历给定字符串s的每一个字母。2.针对s的每一个字…

HCIP-BGP实验

实验拓扑 实验需求 1.r1上有两个换汇分别为192.168.1.0/24和192.168.2.0/24只允许学到汇总和1.0 2.r7上有两个还回172.16.1.0/24和172.16.2.0/24要求全部宣告&#xff0c;但是只有2.0可以通过 3.全网可达 实验思路 配置IP地址 BGP配置 实验步骤 配置IP地址 BGP配置 在…

RabbitMQ死信交换机

目录 1.死信交换机介绍 2.TTL 3.延迟队列 4.消息堆积问题 5.惰性队列 6.代码实战 1.死信交换机介绍 当一个队列中信息满足下列情况之一时&#xff0c;可以成为死信&#xff08;dead letter&#xff09; &#xff08;1&#xff09;消费者使用basic.reject&#xff08;Reject…