cjhyy03 2017-11-28 09:54 采纳率: 0%
浏览 1304
已结题

gearmand 启动,work启动,客户端状态正常

2017-11-27 14:06:43.000000 [ main ] Accepted connection from 127.0.0.1:48546
NOTICE 2017-11-27 14:06:43.000000 [ proc ] accepted,job,3305825c-d37c-11e7-a5f2-00163e0df326,0 -> libgearman-server/server.cc:317
INFO 2017-11-27 14:06:43.000000 [ 3 ] Peer connection has called close()
INFO 2017-11-27 14:06:43.000000 [ 3 ] Disconnected 127.0.0.1:48546
INFO 2017-11-27 14:06:43.000000 [ 3 ] Gear connection disconnected: -:-
INFO 2017-11-27 14:46:43.899184 [ main ] Initializing Gear on port 4730 with SSL: false
INFO 2017-11-27 14:46:43.000000 [ main ] Starting up with pid 4427, verbose is set to INFO
ERROR 2017-11-27 14:47:04.000000 [ main ] Timeout occured when calling bind() for 127.0.0.1:4730 -> libgearman-server/gearmand.cc:688
INFO 2017-11-27 14:47:04.000000 [ main ] Shutdown complete
INFO 2017-11-27 14:48:43.000000 [ main ] Accepted connection from 127.0.0.1:49096
NOTICE 2017-11-27 14:48:43.000000 [ proc ] accepted,job,10d7eb2e-d382-11e7-a5f2-00163e0df326,0 -> libgearman-server/server.cc:317
INFO 2017-11-27 14:48:43.000000 [ 2 ] Peer connection has called close()
INFO 2017-11-27 14:48:43.000000 [ 2 ] Disconnected 127.0.0.1:49096
INFO 2017-11-27 14:48:43.000000 [ 2 ] Gear connection disconnected: -:-

  • 写回答

1条回答

  • qq_15261069 2017-11-28 10:06
    关注

    worker向Gearman Server注册自身可以执行的功能
    worker尝试获取一个任务
    server通告worker暂无任务
    worker通告server:“我先睡会,有活干时再叫醒我”
    client向server发起任务请求
    server唤醒可以完成这项工作的worker(可能会唤醒多个woker)
    worker向server发起“饥饿”请求,尝试获得一个任务
    server选定一个worker,将该任务分配下去
    通告client:“我安排别人处理你的请求了,耐心等待吧”
    worker辛苦工作一段时间后,向server通告“干完了”
    server将结果反馈给用户
    值得说明的几点

    1. 任务分类: 按优先级分:普通(SUBMIT_JOB),高(SUBMIT_JOB_HIGH),低(SUBMIT_JOB_LOW) 按执行方式分:普通(_JOB_HIGH,_JOB_LOW),后台(_JOB_HIGH_BG,_JOB_LOW_BG) 最大区别在于,client可以跟踪前台任务的工作状态,而不能跟踪BG任务
    2. 任务工作状态的通告(worker-->server-->client): WORK_DATA WORK_WARNING WORK_STATUS 对于长任务,worker应该每隔一段时间通告任务状态 WORK_COMPLETE WORK_FAIL WORK_EXCEPTION
    3. Server监控 Gearman有“Administrative Protocol”专门用于对Gearman Server的监控,主要涉及以下几方面: status:所注册职能分类,worker总数目,处于工作状态的worker数目,可用worker数目等 worker的详细信息:所注册功能、IP server的缓存任务最大队列长度:可以被查询也可以被设定 该功能详见《Gearman使用》

    问题分析与研究
    Job Server 的单点问题
    实际上 Job Server 是存在单点问题的,我们只能通过增加冗余 Job Server 的方式来解决这个问题。
    我们可以通过配置域名、多个服务器配置列表等方法,在遇到其中一个 Job Server 失败时,将 Client 的请求转向另外的 Job Server。
    这种情况下,Job Server 中原来存在的任务会发生丢失,除非使用了数据库或其他类似的持久化方法。
    如果遇到正在连接的那个故障,由client、worker切换到好用的gearmand服务器,这样来完成high-avliable。
    可以看出这里实现的并不完善,需要客户端程序自己判断,而且也可以看出并不支持几个Job Server的负载均衡调用。

    Job Server 重启
    Job Server重启后,worker会自动重新注册。通过 gearmand -vvvvvvv 分析发现,如果 gearmand 关闭并重新启动后,原来的 worker 会马上与 Job Server 建立连接,并询问是否有任务。
    但是客户端client程序是不会自动重连的,这个要靠客户端程序中来判断重连。

    使用持久队列避免任务的丢失
    因为 Gearmand 的队列是放在内存中的,所以宕机或重启事件会导致队列的丢失。为了避免这种情况,可以使用持久队列,将队列存储在一个相对中立的位置。注意,持久队列只对于后台任务有效。

    Gearman Worker 的无缝重启
    我在实现Worker的过程中,采用了PHP脚本,脚本调用外部的配置文件。如果外部的配置文件修改后,需要重新启动脚本才能够使配置文件中修改的变量生效,所以想要坐到无缝的重启。即脚本Stop、Start的过程不会影响正在进行的业务。
    对于无缝重启的问题,我总结了如下几个思路进行处理,解决的方法:
    1、每次修改完代码后,Worker需要手工重启(先杀死然后启动)。
    2、在Worker中设置,单次任务循环完成后,就对Worker进行重启。
    3、在Worker中添加一个退出函数,如果需要Worker退出的时候,在Client端发送一个优先级比较高的退出调用。
    4、在Worker中检查文件是否发生变化,如果发生了变化,退出并重启自身。
    5、为Worker编写信号控制,接受重启指令,类似于 http restart graceful 指令

    多台Job Server客户端重连接问题
    Gearman在多个Job Server服务器之间并不通讯,而是运行多个Job Server服务器,通过client、worker连接多个服务器。
    客户端连接Job Server时,通过addJobServer或addJobServers的方式,为客户端增加多台Job Server服务器,客户端程序初始执行时不会真正的去连接所有的Job Server,只是打开连接符放到一个服务器连接列表中,当run_task时,才会真正的去连接服务器,首先向最后一台服务器发送,如果失败,客户端程序针对这笔当前的task不会自动切到另一台服务器,下一个task连接时发现这台服务器有问题就会自动切换到下个服务器,这样也是对的,因为当前这笔task的状态是不确定的,也许worker执行了返回没收到。这种情况只能是客户端程序自己判断。
    为验证这种情况,自己试验一下:
    在一台机上起两个gearmand(端口分别为4730和4830),在客户端把这2个gearmand都加到GearmanClient中,通过addJobServer或addJobServers的方式。
    正常的,GearmanClient会将任务发送到最后添加的JobServer(4830),把job发送过去。
    kill掉4830这个进程,log中报:
    PHP Warning: GearmanClient::do(): gearman_connection_read:lost connection to server
    当执行下一个任务时然后自动的采用第二个JobServer,任务发送到第二个JobServer上了。

    但是如果一个连接已经存在,要重复这个连接的使用,在发送Job的时候,不断的报错,不会自动切换到另一个好的JobServer上。
    还有一个问题就是,这时如果前面出错那台机器又恢复使用了,客户端程序可以继续向这台机器发task,但是首次的发送会收不到应答直到超时,然后下一笔就正常了,原因需要进一步验证。
    这种情况下客户端无法知道这笔task有没有被处理,这在业务上客户端必须加判断,不然一个任何有可能会被执行多次。

    对background_job的异步处理的返回
    待完善。。。

    Gearman 性能调优

    线程模型
    在大规模使用的时候,需要针对应用类型进行参数设置,以使Gearman的性能达到最优,这首先应该了解Gearman的线程模型。

    为确保具备对海量任务调度的支持能力,Gearman毫无悬念的选择libevent作为网络操作支撑库。因此Gearman的服务器Gearmand提供了三类线程角色:
    端口监听和管理线程,接受新连接请求并将之交给IO线程,1个 IO线程,完成实际的任务处理,包括命令解析,队列操作等,n个 处理线程,完成内部数据结构的管理,无系统调用尽可能简单,1个
    其中第1, 3种线程对全局处理性能没有直接影响,虽然处理线程有可能成为瓶颈,但他的工作足够简单消耗可忽略不计,因此我们的性能调优主要目标是在IO线程的数量。
    对每个IO线程来说,它都会有一个libevent的实例;所有Gearman的操作会以异步任务方式提交到处理线程,并由IO线程获取完成实际操作,因此IO线程的数量是与可并行处理任务数成正比。Gearmand 提供 -t 参数调整总IO线程数,需要使用 libevent 1.4 以上版本提供多线程支持。

    进程句柄数
    另外一个影响大规模部署的是进程句柄数,Gearman会为每一个注册的Worker分配一个fd(文件描述符),而这个fd的总数是受用户限制的,可以使用 ulimit -n 命令查看当前限制

    flier@debian:~$ ulimit -n
    1024
    flier@debian:~$ ulimit -HSn 4096 // 设置进程句柄数的最大软硬限制
    4096

    也就是说gearman缺省配置下,最多允许同时有小于1024个worker注册上来,fd用完之后的Worker和Client会出现连接超时或无响应等异常情况。因此,发生类似情况时,我们应首先检查 /proc/[PID]/fd/ 目录下的数量,是否已经超过 ulimit -n 的限制,并根据需要进行调整。而全系统的打开文件设置,可以参考 /proc/sys/fs/file-max 文件,并通过 sysctl -w fs.file-max=[NUM] 进行修改。
    flier@debian:~$ cat /proc/sys/fs/file-max
    24372
    flier@debian:~# sysctl -w fs.file-max=100000
    100000

    Gearmand 本身也提供了调整句柄数量限制的功能,启动时则可以通过 –file-descriptors 参数指定,但非特权进程不能设置超过soft limit的数额。
    -f [ --file-descriptors ] arg

    Number of file descriptors to allow for the process (total connections will be slightly less). Default is max allowed for user.
    轮询调度
    此外,Gearmand 还提供了一些增强任务调度公平性的参数,例如 0.13 里面新增的 round-robin 模式,允许将任务公平的调度到多个 Worker,而不是用缺省按 Worker 注册函数的顺序进行调度,避免工作过于集中在少数设备上。
    -R, –round-robin Assign work in round-robin order per
    workerconnection. The default is to assign work in
    the order of functions added by the worker.

    Gearmand 内部通过一个 Worker 队列,在 RR 模式下动态调整 Worker 的调度次序。

    受限唤醒
    而通过 –worker-wakeup 参数,则可以指定收到任务时,需要唤醒多少个 Worker 进行处理,避免在 Worker 数量非常大时,发送大量不必要的 NOOP 报文,试图唤醒所有的 Worker。

    -w, –worker-wakeup=WORKERS Number of workers to wakeup for each job received.
    The default is to wakeup all available workers.

    根据 Gearman 协议设计, Worker 如果发现队列中没有任务需要处理,是可以通过发送 PRE_SLEEP 命令给服务器,告知说自己将进入睡眠状态。在这个状态下,Worker 不会再去主动抓取任务,只有服务器发送 NOOP 命令唤醒后,才会恢复正常的任务抓取和处理流程。因此 Gearmand 在收到任务时,会去尝试唤醒足够的 Worker 来抓取任务;此时如果 Worker 的总数超过可能的任务数,则有可能产生惊群效应。

    除此之外,针对应用特点合理使用持久化队列,在大并发任务量的情况下对性能也会有直接影响。
    归根结底,需要根据自己的应用场景,合理设计一些测试用例和自动化脚本,通过实际的运行状态进行参数调整。

    评论

报告相同问题?

悬赏问题

  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站