通过消息停止消费者中某个进程的方案

生产者代码

生产者将发送包含task_id的启动和停止任务的消息到RabbitMQ队列。

producer.py

import pika
import json
import time

# 连接到RabbitMQ服务器
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明一个队列
channel.queue_declare(queue='task_queue')


def send_task(task_id, task_type):
    task_message = {
        'task_id': task_id,
        'task_type': task_type
    }
    channel.basic_publish(
        exchange='',
        routing_key='task_queue',
        body=json.dumps(task_message),
        properties=pika.BasicProperties(
            delivery_mode=2,  # 持久化消息
        )
    )
    print(f" [x] Sent {task_message}")


# 发送启动任务消息
task_id = 1
send_task(task_id, 'START_TASK')

# 等待一些时间,让任务开始执行
time.sleep(5)

# 发送停止任务消息
send_task(task_id, 'STOP_TASK')

# 关闭连接
connection.close()

消费者代码

消费者将监听队列中的消息,并根据消息中的task_idtask_type来决定是启动还是停止指定的任务。

consumer.py

import time
import pika
import multiprocessing
import json
import os


# 定义一个函数来执行耗时任务
def do_long_running_task(task_id):
    print(f"Task {task_id} started with PID: {os.getpid()}")
    try:
        while True:
            time.sleep(1)  # 模拟耗时任务
    except KeyboardInterrupt:
        print(f"Task {task_id} stopped with PID: {os.getpid()}")


# 连接到RabbitMQ服务器
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明一个队列
channel.queue_declare(queue='task_queue')

# 存储进程的字典,以task_id为键
processes = {}


# 定义回调函数来处理接收到的消息
def callback(ch, method, properties, body):
    task_message = json.loads(body)
    task_id = task_message['task_id']
    task_type = task_message['task_type']

    if task_type == 'START_TASK':
        # 启动任务
        print(f"Received START_TASK for task_id {task_id}")
        process = multiprocessing.Process(target=do_long_running_task, args=(task_id,))
        process.start()
        processes[task_id] = process
    elif task_type == 'STOP_TASK' and task_id in processes:
        # 停止指定task_id的任务
        print(f"Received STOP_TASK for task_id {task_id}")
        processes[task_id].terminate()  # 终止进程
        processes[task_id].join()  # 等待进程终止
        del processes[task_id]  # 从字典中删除进程记录


# 使用basic_consume来监听队列
channel.basic_consume(
    queue='task_queue',
    on_message_callback=callback,
    auto_ack=True
)

print(' [*] Waiting for messages. To exit press CTRL+C')
try:
    channel.start_consuming()
except KeyboardInterrupt:
    channel.stop_consuming()
    for task_id in processes:
        processes[task_id].terminate()
        processes[task_id].join()
    print("Stopped consuming and all tasks have been terminated.")
finally:
    connection.close()

运行

shell1 启动消费者

$ python consumer.py
 [*] Waiting for messages. To exit press CTRL+C

shell2 启动生产者

$ python producer.py
 [x] Sent {'task_id': 1, 'task_type': 'START_TASK'}
 [x] Sent {'task_id': 1, 'task_type': 'STOP_TASK'}

shell1 输出

$ python consumer.py
 [*] Waiting for messages. To exit press CTRL+C
Received START_TASK for task_id 1
 [*] Waiting for messages. To exit press CTRL+C
Received STOP_TASK for task_id 1
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值