之前写过一篇文章,它有个响亮的名字:Handling 1 Million Requests per Minute with Go使用 Go 每分钟处理百万请求

这是国外的一个作者写的,我做了一篇说明,起的也是这个标题。
没想到阅读量是我最好的一篇,果然文章都是靠标题出彩的…..

今天偶然看到另一篇文章(原文在文末[1])。两篇文章原理相似:有一批工作任务(job),通过工作池(worker-pool)的方式,达到多worker并发处理job的效果。

他们还是有很多不同的点,实现上差别也是蛮大的。

首先上一篇文章我放了一张图片,大概就是上篇整体的工作流。

  • 每个worker处理完任务就好,不关心结果,不对结果做进一步处理。

  • 只要请求不停止,程序就不会停止,没有控制机制,除非宕机。

这篇文章不同点在于:

首先数据会从generate(生产数据)->并发处理数据->处理结果聚合。
图大概是这样的,

然后它可以通过context.context达到控制工作池停止工作的效果。

最后通过代码,你会发现它不是传统意义上的worker-pool,后面会说明。

下图能清晰表达整体流程了。

顺便说一句,这篇文章实现的代码比 使用 Go 每分钟处理百万请求 的代码简单多了。

首先看job

这个可以简单过一下。最终每个job处理完都会包装成Result返回。

下面这段就是核心代码了。

整个WorkerPool结构很简单。jobs是一个缓冲channel。每一个任务都会放入jobs中等待处理woker处理。

results也是一个通道类型,它的作用是保存每个job处理后产生的结果Result

首先通过New初始化一个worker-pool工作池,然后执行Run开始运行。

初始化的时候传入worker数,对应每个g运行work(ctx,&wg,wp.jobs,wp.results),组成了worker-pool

同时通过sync.WaitGroup,我们可以等待所有worker工作结束,也就意味着work-pool结束工作,当然可能是因为任务处理结束,也可能是被停止了。

每个job数据源是如何来的?

对应每个worker的工作,

每个 worker 都尝试从同一个jobs获取数据,这是一个典型的fan-out模式。当对应的g获取到job进行处理后,会把处理结果发送到同一个results channel中,这又是一个fan-in模式。

当然我们通过context.Context可以对每个worker做停止运行控制。

最后是处理结果集合,

那么整体的测试代码就是:

看了代码之后,我们知道,这并不是一个传统意义的worker-pool。它并不像上篇这篇文章一样,初始化一个真正的worker-pool,一旦接收到job,就尝试从池中获取一个worker,把对应的job交给这个work进行处理,等work处理完毕,重新进行到工作池中,等待下一次被利用。

附录

[1]https://itnext.io/explain-to-me-go-concurrency-worker-pool-pattern-like-im-five-e5f1be71e2b0#fe56

最后,快进碗里来。

如何在 go 中实现一个 worker-pool?相关推荐

  1. 如何在Java中创建一个新的List

    本文翻译自:How to make a new List in Java We create a Set as: 我们创建一个Set为: Set myset = new HashSet() How d ...

  2. lin通信ldf文件解析_详细步骤讲解如何在CANoe中创建一个LIN通讯工程(多图+详解)...

    本文首发自微信公众号"汽车技术馆"! CANoe可以实现基于CAN通讯的通讯测试和仿真,同时也可以支持基于LIN通讯的通讯测试和仿真,如何在CANoe中建立一个基于LIN通讯的工程 ...

  3. python if语句多个条件-关于函数:如何在python中为一个if语句提供多个条件

    本问题已经有最佳答案,请猛点这里访问. 所以我在用python 3.1.5编写一些代码,这些代码需要有多个条件才能发生某些事情.例子: 1 2 3 4 5def example(arg1, arg2, ...

  4. ai中如何插入签名_如何在PDF中插入一个或多个空白页?

    在编辑或修改PDF文档时,一般都需要新增空白页后再添加文本或图片等内容,那么如何在PDF中插入一个或多个空白页呢? 首先打开极速PDF编辑器,或打开需要编辑的PDF文档后,点击右上角"文档& ...

  5. python中2d_【IT专家】如何在Python中复制一个2D数组?(复制)

    本文由我司收集整编,推荐下载,如有疑问,请与我司联系 如何在 Python 中复制一个 2D 数组? ( 复制 ) 如何在 Python 中复制一个 2D 数组 ?( 复制 )[ 英 ]How to  ...

  6. linux 杀掉php,Linux_在Linux系统中使用xkill命令杀掉未响应的进程,我们如何在Linux中杀掉一个资 - phpStudy...

    在Linux系统中使用xkill命令杀掉未响应的进程 我们如何在Linux中杀掉一个资源/进程?很明显我们会找出资源的pid然后用kill命令. 说的更明白一点,我们可以找到某个资源(比如termin ...

  7. 让一个图片填满一个控件_如何在Android中实现一个全景图控件(二)

    一.背景 在 如何在Android中实现一个全景图控件(一)中,介绍了项目的一些基本情况(有 demo 演示),如果项目对你有帮助,希望文章赏个赞,项目 star 一下. 项目地址:https://g ...

  8. linux强制移除pdf密码,分享|如何在 Linux 中从一个 PDF 文件中移除密码

    今天,我碰巧分享一个受密码保护的 PDF 文件给我的一个朋友.我知道这个 PDF 文件的密码,但是我不想透露密码.作为代替,我只想移除密码并发送文件给他.我开始在因特网上查找一些简单的方法来从 PDF ...

  9. 如何在xshell中创建一个SSH隧道

    之前讲过如何使用SSH协议连接远程,本集Xshell教程小编将深入讲解如何在xshell中创建一个SSH隧道. 在开始之前,请确保远程主机上的SSH服务器已经启用了X11 Forwarding.设置完 ...

最新文章

  1. 深蓝词库转换1.2版本发布——支持紫光拼音和拼音加加
  2. Dynamics CRM 2013 初体验(1):系统的安装
  3. JAVA Web基础6-EL表达式与JSTL标签库
  4. 响应式Bootstrap后台管理系统模板UI框架
  5. matlab中函数绝对值图像,ex的图像(绝对值的函数图像口诀)
  6. C++提高部分_C++函数模板_基本用法---C++语言工作笔记081
  7. linux 内核配置v4l2,深入理解linux内核v4l2框架之videobuf2【转】
  8. Struts2-01-数据访问
  9. 网络模型一般是指 OSI 七层参考模型和 TCP/IP 五层参考模型。
  10. 矩阵计算器+求线性代数n阶行列式代码
  11. 【考题·习题详解】数论知识+数学推导
  12. vant swipe点击切换
  13. 网络互联及Internet
  14. Git使用:在Git pull时遇到的Error及解决方法
  15. 有监督,无监督,半监督,弱监督、自监督学习
  16. Comparable的compareTo
  17. 6个超实用的自媒体工具,百万博主都在用
  18. 英语四六级常用八种时态
  19. 忆本科四年,感谢遇见 - 写在毕业一年后
  20. 機器學習基石 机器学习基石 (Machine Learning Foundations) 作业二 Q19-20 C++实现

热门文章

  1. Node.js--Stream
  2. DotText源码学习——从配置文件Web.config入手(一)
  3. 将Myeclipse非maven项目,导入到IDEA
  4. Android系统为例解读智能手机如何防盗
  5. 第一天:认识python
  6. html标签企业级命名规范
  7. 关于Javascript 中 setTimeout和setInterval的总结和思考
  8. 【TensorFlow】CNN
  9. mutable和volatile关键字
  10. SQL关键字Pivot(行变列)