Gearman的Worker的多进程实现

Gearman中文手册,Gearman中文详解,gearman手册chm Gearman中文手册,gearman手册chm,Gearman中文详解,分享gearman技术心得,主要是为了分享技术,所以不要大家的资源分。 立即下载

前言

因为项目原因选择了gearman作为任务委派的中间件,但原生的python拓展包只支持单进程,

期间为了将gearman改造成自适应多进程的方式在实现方式上走进了些误区,

故在此记录这些误区的坑以及目前的最优解决方案。

实现思路

实现方式

  1. 主进程接收任务,子进程处理任务。以一个主进程作为任务委派的接收进程,接收到任务后将任务分派给子进程进行处理,处理完成后由该子进程直接返回任务结果给gearman。
  2. 多进程接收并处理任务。批量fork多个子进程注册任务,子进程间互不影响,各自完成接收、处理任务的过程。

先说说第一种实现方式的优缺点

优点:

  • 由于worker较多的时间是消耗在等待接收请求上,因此主进程只单一的进行轮训任务接收可以提高单条gearman请求通道的利用率。
  • 由子进程直接返回任务结果可分离主进程与子进程的作业,主进程无需关心任务的结果而只专注于接收任务。

缺点:

  • 主进程接收到任务请求后将请求转发给子进程处理任务,由于子进程处理任务完成后需要将任务结果返回给gearman,因此子进程需要将该任务请求对应的gearman socket传递给子进程,而该过程实现起来过于复杂。(通常具有socket的实例无法通过pickle传递给子进程,虽然Unix的sendmsg可以用来传递socket,但将传递的socket构造成一个GearmanWorker又是另外一件痛苦的事情)
  • 子进程通过传递的socket构造出GearmanWorker后,由于原socket的句柄仍被父进程持有,所以在等待结果的任务请求方无法收到子进程所返回的处理结果。

再来说说第二种实现方式的优缺点

优点:

  • 等价于fork多个原进程,逻辑、作业方式均无改变。
  • 可在fork子进程之前完成公有资源的加载而无需每个GearmanWorker匀加载一次。

缺点:

  • 子进程异常退出后主进程无法正确感知,虽然主进程会维持相同的子进程数,但是异常退出所重启的子进程没有正确注册到gearman接收任务。
  • 主进程异常退出后子进程无法感知,将导致出现僵尸进程。

选择第二种方案,针对缺点的解决办法

  1. 利用PID文件记录每个子进程的pid,确保主进程退出后仍能通过PID文件退出子进程。
  2. 利用Redis的发布订阅模式实现GearmanWorker的正常退出。

client 端代码: test_multi_gearman_worker.py
​

  1. #!/usr/bin/env python
  2. from gearman import GearmanClient 

  3. gearman_client = GearmanClient(['10.10.13.5:4730']) 


  4. new_jobs = [
  5.     dict(task='test_multi_gearman_worker', data='job-0.mp4'),
  6.     dict(task='test_multi_gearman_worker', data='job-1.mp4'),
  7.     dict(task='test_multi_gearman_worker', data='job-2.mp4'),
  8.     dict(task='test_multi_gearman_worker', data='job-3.mp4'),
  9.     dict(task='test_multi_gearman_worker', data='job-4.mp4'),
  10.     dict(task='test_multi_gearman_worker', data='job-5.mp4'),
  11.     dict(task='test_multi_gearman_worker', data='job-6.mp4'),
  12.     dict(task='test_multi_gearman_worker', data='job-7.mp4'),
  13.     dict(task='test_multi_gearman_worker', data='job-8.mp4'),
  14.     dict(task='test_multi_gearman_worker', data='job-9.mp4'),
  15.     dict(task='test_multi_gearman_worker', data='job-10.mp4'),
  16. ]


  17. completed_requests = gearman_client.submit_multiple_jobs(new_jobs)
  18. for current_request in completed_requests:
  19.     print (current_request.result)


  20. print ("Game over!")

worker端代码: multi-gearman-worker.py
​
  1. #!/usr/bin/env python

  2. import os
  3. import string
  4. import signal
  5. import threading
  6. import subprocess
  7. import multiprocessing

  8. import redis
  9. from gearman.worker import GearmanWorker, POLL_TIMEOUT_IN_SECONDS

  10. WORKER_PROCESS_PID = '/tmp/multi_gearman_worker.pid'


  11. class MultiGearmanWorker(GearmanWorker):
  12.     """ multi-process gearman worker """
  13.     def __init__(self, host_list=None, redis_host=None, redis_port=None, pid=WORKER_PROCESS_PID):
  14.         super(MultiGearmanWorker, self).__init__(host_list=host_list)
  15.         self.redis_host = redis_host
  16.         self.redis_port = redis_port
  17.         self.pid = pid

  18.     def work(self, poll_timeout=POLL_TIMEOUT_IN_SECONDS, process=multiprocessing.cpu_count()):
  19.         """
  20.         start working, blocking process first
  21.         :param poll_timeout: int , the connection time of gearman
  22.         :param process: int , the number of process for working , the default is the number of cpu-core
  23.         :return:
  24.         """
  25.         print('Clear last process.')
  26.         self.gearman_worker_exit()
  27.         print('Ready to start %d process for work.' % process)
  28.         gm_poll = multiprocessing.Pool(process)
  29.         for x in range(0, process):
  30.             print('start %d child process', x)
  31.             gm_poll.apply_async(gearman_work, (self, poll_timeout, self.pid))

  32.         gm_poll.close()
  33.         gm_poll.join()

  34.         # Delete the PID file if all sub-process exit normally
  35.         if os.path.isfile(self.pid):
  36.             os.remove(self.pid)

  37.         print('Multi gearman worker exit.')


  38.     def gearman_worker_exit(self):
  39.         """ Terminate sub-process """
  40.         if not os.path.isfile(self.pid):
  41.             return True

  42.         with open(self.pid, 'r+') as f:
  43.             for pid in f.readlines():
  44.                 pid = int(pid)
  45.                 try:
  46.                     os.kill(pid, signal.SIGKILL)
  47.                     print('Kill process %d.' % pid)
  48.                 except OSError:
  49.                     print('Process %d not exists' % pid)
  50.                     continue

  51.         os.remove(self.pid)
  52.         print('Remove process pid file.')
  53.         return True


  54. #The gearman job switch identifier used by the child process
  55. GEARMAN_CONTINUE_WORK = True


  56. def gearman_work(gm_worker, poll_timeout=POLL_TIMEOUT_IN_SECONDS, pid=WORKER_PROCESS_PID):
  57.     """ Open gearman;s worker in multiple processes """
  58.     try:
  59.         """ Record the child process pid, 
  60.              so that the main process is cleared by the supervisor 
  61.         to clear the child process did not exit the last time 
  62.         """
  63.         with open(pid, 'a+') as f:
  64.             f.write("%d%s" % (os.getpid(), os.linesep))

  65.         print('Child process start for work.')
  66.         continue_working = True
  67.         worker_connections = []
  68.         d = threading.Thread(name='monitor', target=gearman_monitor,
  69.                              args=(gm_worker.redis_host, gm_worker.redis_port))
  70.         d.start()

  71.         def continue_while_connections_alive(any_activity):
  72.             return gm_worker.after_poll(any_activity)

  73.         # Shuffle our connections after the poll timeout
  74.         while continue_working and GEARMAN_CONTINUE_WORK:
  75.             worker_connections = gm_worker.establish_worker_connections()
  76.             continue_working = gm_worker.poll_connections_until_stopped(
  77.                 worker_connections, continue_while_connections_alive, timeout=poll_timeout)

  78.         # If we were kicked out of the worker loop, we should shutdown all our connections
  79.         for current_connection in worker_connections:
  80.             current_connection.close()

  81.         print('Gearman worker closed')
  82.         return None
  83.     except Exception as e:
  84.         print(e)


  85. def gearman_monitor(redis_host, redis_port):
  86.     """ Listen to dynamic update instructions """
  87.     global GEARMAN_CONTINUE_WORK
  88.     print('Start gearman monitor.')
  89.     while GEARMAN_CONTINUE_WORK:
  90.         """To prevent abnormal operation caused by the thread is not monitoring the redis response after hanging up, 
  91.        exception handling on here, after an exception re-listen
  92.         """
  93.         try:
  94.             sub = redis.StrictRedis(redis_host, redis_port).pubsub()
  95.             sub.subscribe('hot')
  96.             for i in sub.listen():
  97.                 if isinstance(i.get('data'), str):
  98.                     if i.get('data') == 'exit':
  99.                         # worker???????????????????
  100.                         print('Gearman monitor receive restart signal.')
  101.                         GEARMAN_CONTINUE_WORK = False
  102.                         sub.unsubscribe('hot')
  103.                         break
  104.                 # ????????,?????????gearman worker????????

  105.         except Exception as e:
  106.             print(e)
  107.             try:
  108.                 sub.unsubscribe('hot')
  109.             except Exception:
  110.                 pass

  111.     print('Gearman monitor closed')


  112. if __name__ == '__main__':
  113.     def test_multi_gearman_worker(worker, job):
  114.         print('who ', worker) 
  115.         print('do what ', job.data)
  116.         print('Game over! ', job.data)
  117.         return job.data




  118.     gearman_worker = MultiGearmanWorker(('10.10.13.5:4730', ), '10.10.13.8', 6379)
  119.     gearman_worker.register_task('test_multi_gearman_worker', test_multi_gearman_worker)
  120.     gearman_worker.work(POLL_TIMEOUT_IN_SECONDS, 5)
注:
​1. 需要先有安装好的redis; 
​2. 需要先有安装好的gearman

PotPlayer播放4K HDR电影时,如何正确设置LAV解码器与MadVR渲染器避免色彩失真? 本文详细介绍了如何在PotPlayer中正确配置LAV解码器与MadVR渲染器,以解决播放4K HDR电影时的色彩失真问题。从组件安装、参数设置到显卡协同配置,提供了一套完整的端到端解决方案,帮助影音爱好者获得最佳的视觉体验。 阅读详情

相关推荐

ALSA音频开发实战:如何用snd_pcm_avail避免缓冲区溢出(附完整代码)

本文深入探讨了在ALSA音频开发中,如何利用`snd_pcm_avail`函数有效管理环形缓冲区,从而避免音频数据溢出或下溢。通过实战代码示例,详细解析了该函数在播放场景下的核心作用,即实时查询可写入的帧数,并构建了自适应写入循环以实现稳健的流量控制,确保音频流的平滑与稳定。

weixin_29183637的博客 461

GearmanWorker的多进程实现

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34096182的博客 320

CAN总线错误帧全解析:从数据包到硬件层的故障树分析

本文深入解析CAN总线错误帧的故障树分析方法,从数据包到硬件层全面剖析错误机制。通过物理层信号测试、数据链路层错误解码和应用层协议排查,提供系统化的诊断框架。结合CANoe配置和示波器波形分析,帮助工程师快速定位总线故障,提升系统可靠性。

weixin_26742753的博客 488

任务分发系统gearman

1 Gearman是什么 Gearman Job Server@http://gearman.org/。 Gearman 是一个任务分发系统,它提供了一个分发框架,能够分发某类任务到更适合处理这类任务的服务器上去处理。并且,它支持任务并行处理、负载均衡以及多语言调用。它的适用范围很广,从高可用性的网站到透明的数据库复制等。换句话说,它是一个强健的分布式通信处理系统。下面是官网上列举的优点:

breeze_life 8718

平行趋势检验没通过怎么办?别慌,试试三重差分DDD与事件研究法

本文探讨了当平行趋势检验未通过时,如何运用三重差分法(DDD)与事件研究法进行政策评估。通过Stata代码示例和实战案例,详细介绍了DDD的原理、适用场景及实现步骤,并提供了替代方案如合成控制法和匹配DID,帮助研究者获得更准确的因果推断结果。

weixin_28732953的博客 609

ESP32 IDF开发 应用篇⑲ 空中升级OTA

在实际产品开发过程中,在线升级可以远程解决产品软件开发引入的问题,更好地满足用户需求。OTA(空中)更新是使用 Wi-Fi 连接而不是串行端口将固件加载到 ESP 模块的过程。(1)、ESP32 的 OTA 升级有三种方式:·Arduino IDE:主要用于软件开发阶段,实现不接线固件烧写·Web Browser:通过 Web 浏览器手动提供应用程序更新模块·HTTP Server:自动使用http服务器 - 针对产品应用在三种升级情况下,必须通过串行端口完成第一个固件上传。

lu330274924的博客 3324

Gearman 性能调优

文章来自:http://blog.flier.lu/2010/04/gearman-performance-tunning/ Gearman是最早由LiveJournal内部开发并使用的一个通用并行任务调度框架,允许不同语言直接通过非常简单的方式进行互操作。前台提交工作任务(Task)和参数,由后台工作进程(Worker)完成实际工作。 例如前台提交用户需要进行渲染的图片,由Gearm...

freespace 292

Arco Design Pro PC端商家后台框架 | Axure高保真原型库

摘要:本Axure原型设计方案基于字节跳动ArcoDesignPro规范,提供企业级后台快速搭建方案。包含动态表格、表单验证等核心组件,采用中继器驱动设计,支持响应式布局。方案覆盖80%后台常用交互,可节省60%原型制作时间,配套完整设计文档和组件库,实现原型到开发的高效衔接。特别适用于电商、SaaS等后台系统开发,支持权限管理、数据分析等场景,显著提升团队协作效率。

招风的黑耳优快云 3971

跨多种环境部署 Gearman -改善应用程序性能和降低服务器负载

您可能想要将工作扩散到一个大型机器群体中,或者想要在不同语言和环境之间共享功能,那么开放源码的 Gearman 服务可以让您轻松地将工作分布到网络中的其他机器。本文将介绍 Gearman 的一些典型应用,以及它如何解决现代应用程序中的各种问题。还将学习 Gearman 如何与其他工具(比如说 memcached)结合使用,帮助加速您的应用程序和处理需求。 简介 现代计算环境最大的挑战之一...

weixin_30265103的博客 132

人工智能技术基础系列之:迁移学习

作者:禅与计算机程序设计艺术 1.背景介绍 随着深度学习和神经网络的快速发展,越来越多的应用场景需要处理大量的数据和复杂的任务。然而,由于计算资源、存储空间等条件的限制,传统的人工智能方法往往不能满足实际需求。因此,为了提高效率和降低成本,研究人员提出了迁移学习的概念。本篇文章将详细介绍迁移学习的基

AI天才研究院 695

电动汽车远程监控与诊断软件:BMW ConnectedDrive EV远程监控二次开发_7.数据安全与隐私保护

数据加密是保护数据安全的重要手段之一。在电动汽车远程监控与诊断软件中,加密技术可以确保数据在传输过程中的安全性和完整性。常见的加密技术包括对称加密和非对称加密。

zhubeibei168的博客 884

Gearman分布式任务处理系统(一)基本介绍

Gearman介绍 Gearman是一个用来把工作委派给其他机器、分布式的调用更适合做某项工作的机器、并发的做某项工作在多个调用间做负载均衡、或用来在调用其它语言的函数的系统。 通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用 WebService 的方式来处理此类集成问题,但不管采用何种风格的WebService,如 RPC 风格,或者 REST 风格,其本身都有一定的复

很多时候,你缺少的不是知识而是热情 1万+

ESP8266-Arduino网络编程实例-异步TCP客户端

本次实例将使用ESPAsyncTCP库实现一个简单的客户端。

视觉与物联智能 1740

php多进程并发,PHP并发多进程处理利器Gearman使用介绍

工作中我们有时候会遇到比如需要同时发布数据到多个个服务器上,或者同时处理多个任务。可以使用PHP的curl_multi的方式并发处理请求,但是由于网络和数据以及各个服务器等等的一些情况导致这种并发处理的响应时间很慢,因为在并发请求的过程中还包括记录日志,处理数据等逻辑,等待处理结果并返回,所以也不能友好的满足后台操作的体验。现在有另外一种方案,利Gearman来实现并发的需求。通过Client将请...

weixin_29122543的博客 270

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

gearman php mysql_PHP利用Gearman实现异步/并行多进程处理数据

PHP使用Gearman下面的简单例子仅为说明PHP如何使用Gearman,不具备实际生产意义.一个简单的worker:[root@centos192 worker]# cat myworker.php$worker = new GearmanWorker();$worker->addServer('192.168.1.192', 4730);$worker->addFunction(...

weixin_32281549的博客 130

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

PHP利用Gearman来处理并行多进程问题

最近工作中开发的一套系统,其中很多都是需要操作多服务器的,比如需要同时发布数据到2000个服务器上,或者同时向2000个服务器拉取数据。刚开始的解决方案就是单纯用PHP的curl_multi的方式并发处理请求,而且参考了淘宝技术博客的《Rolling cURL: PHP并发最佳实践》,但是由于网络和数据以及各个服务器等等的一些情况导致这种并发处理的响应时间很慢,因为在并发请求的过程中还包括记录

大鹏 3045

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

[并发] -- PHP并发多进程处理利器Gearman

PHP并发多进程处理利器Gearman 工作中我们有时候会遇到比如需要同时发布数据到多个个服务器上,或者同时处理多个任务。可以使用PHP的curl_multi的方式并发处理请求,但是由于网络和数据以及各个服务器等等的一些情况导致这种并发处理的响应时间很慢,因为在并发请求的过程中还包括记录日志,处理数据等逻辑,等待处理结果并返回,所以也不能友好的满足后台操作的体验。 现在有另外一

lmjy102的博客 659

php 守护 gearman work,PHP Gearman重复任务

我得到了:Debian 6nginx 1.2.6PHP 5.3.20-1~docdeb.0(fpm-fcgi)(建于2012年12月24日11:53:16)gearmand 1.1.4pecl gearman ext 1.1.1我有两个脚本(可能是我从php复制它们)。客户端:$gmc= new GearmanClient();$gmc->addServer();$gmc->setCo...

weixin_31043555的博客 175

gearman php使用,gearman管理工具GearmanManager的安装与php使用方法示例

本文实例讲述了gearman管理工具GearmanManager的安装与php使用方法。分享给大家供大家参考,具体如下:一、gearman自带了一个gearadmin工具查看帮助信息> gearadmin --help查看状态> gearadmin --status查看worker信息> gearadmin --workers二、为什么要用GearmanManager为什么要用G...

weixin_39962153的博客 295

php安装gearman扩展实现异步分步式任务

一、简介 Gearman是一个分发任务的程序框架,它会对作业进行排队自动分配到一系列机器上。gearman跨语言跨平台,很方便的实现异步后台任务。php官方收录:http://php.net/manual/zh/book.gearman.php 如上图,一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。 Client:请求的

继续微笑lsj 1085

[转]PHP利用Gearman来处理并行多进程问题

From : http://www.yuansir-web.com/2013/11/25/php%E5%88%A9%E7%94%A8gearman%E6%9D%A5%E5%A4%84%E7%90%86%E5%B9%B6%E8%A1%8C%E5%A4%9A%E8%BF%9B%E7%A8%8B%E9%97%AE%E9%A2%98/ 最近工作中开发的一套系统,其中很多都是需要操作多服务器的,比如需要同...

weixin_34311757的博客 129

mysql任务分发_Gearman——分布式任务分发框架

工作中我们有时候会遇到比如需要同时发布数据到多个个服务器上,或者同时处理多个任务。可以使用PHP的curl_multi的方式并发处理请求,但是由于网络和数据以及各个服务器等等的一些情况导致这种并发处理的响应时间很慢,因为在并发请求的过程中还包括记录日志,处理数据等逻辑,等待处理结果并返回,所以也不能友好的满足后台操作的体验。现在有另外一种方案,利Gearman来实现并发的需求。通过Client将请...

weixin_34476045的博客 297

gearman消息发送示例

Gearman介绍 Gearman提供了一种通用的程序框架来将你的任务分发到不同的机器或者不同的进程当中。它提供了你进行并行工作的能力、负载均衡处理的能力,以及在不同程序语言之间沟通的能力。Gearman能够应用的领域非常广泛,从高可用的网站到数据库的复制任务。总之,Gearman就是负责分发处理的中枢系统,它的优点包括:      开源:Gearman免费并且开源而且有一个非常活跃的

992

cnetos下Gearman安装使用

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34044273的博客 109

php swoole gearman,swoole-jobs

swoole-jobs基于swoole类似gearman的分布式任务处理系统高性能/动态多woker进程消费队列,加速后端耗时服无需像gearman一个worker配置一条crontab,swoole-jobs负责管理所有worker状态独立的swoole http api 入队列,api不依赖php-fpm1. 说明web中较慢的逻辑,比如统计/email/短信/图片处理等;支持redis/ra...

weixin_39983563的博客 168

gearman扩展实现异步分步式任务--php

一、简介 Gearman是一个分发任务的程序框架,它会对作业进行排队自动分配到一系列机器上。gearman跨语言跨平台,很方便的实现异步后台任务。php官方收录:http://php.net/manual/zh/book.gearman.php 如上图,一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。 Client:请求的发起者,可以是C

我的的博客 1306
上一篇: 在linux服务器上安装单机版redis
下一篇: Gearman的源码编译与安装
北雨南萍
北雨南萍 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄20年 2665粉丝 453原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北雨南萍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值