python:独立进程通信消息订阅发布实现(1)

目录

一、系统架构

二、Broker启动方式

2.1 linux后台启动:

2.2 windows后台启动: 

2.3 后台运行

三、判断Broker运行状态

四、Broker启动方法


在日常工作中,免不了两个进程之间进行通信,例如:a程序需要拉取b程序的配置数据,b程序更新配置数据时,a程序也需要及时更新。

需要完成该需求,我们则需要进行两个进程之间的通信。网络上比较常用的方式有两种:

方式一:使用multiprocessing进行子进程,创建,再进行进程通信;

方式二:利用redis等其他中间件进行通信。

进程通信方式对比
redismultiprocessing
进程解耦两个或多个进程可以独立运行并通信必须启动一个主进程,再运行子进程
搭建方式需要独立安装redis无需搭建第三方,直接调用
性能内存级别,需要连接开销内存级别,无需连接开销

以上两种方式都有优缺点,如果使用redis,必须系统中集成redis;但使用multiprocessing,就必须存在一个主进程,这样进程直接就被主进程绑定在了一起,如果主进程死掉,就都死了。

结合以上两点,我的需求是无需搭建第三方服务并可在独立进程之间进行通信。

想要实现独立进程间通信,无外乎需要第三方的一个程序去管理消息,我第一时间想到的就是socket,利用socket搭建一个消息订阅平台,且全部使用python,自动运行自动处理。

一、系统架构

简单的架构如上所示,当subscribe和publish任何一方,在需要订阅和发布时,去检查Broker的启动情况,如果Broker未启动,则去启动并等待连接;如果Broker启动,则直接连接。

通过Broker的转发,将消息发送给相应的订阅方,订阅方和发布方不做任何联系,双方对对方无感。

本案例不做任何消息缓存,即发布方发布时,如果没有任何订阅方进行订阅,则该消息就会丢失。

二、Broker启动方式

Broker将以socketserver的方式启动,使用后台方式进行运行。

import socketserver

2.1 linux后台启动:

os.system("sudo xxx.python3 xxx.py&")

2.2 windows后台启动: 

1、利用bat运行python程序;

2、python调用bat文件。

为了使用bat进行后台运行,我需要在启动broker之前创建一份bat文件,代码如下:

def create_run_bat(py_path, broker_path):
    """
    创建bat
    :param py_path: 当前python地址
    :param broker_path: 当前broker的python文件地址
    :return: bat的地址
    """
    global RUN_BAT_PATH # 固定的bat文件地址

    if not os.path.exists(RUN_BAT_PATH):
        with open(RUN_BAT_PATH, "w") as f:
            f.write("@echo off\n")
            f.write(
                f'mshta vbscript:createobject("wscript.shell").run("{py_path} {broker_path}",0)(window.close)&&exit')

    return RUN_BAT_PATH

当bat还未存在时,将会去创建一个固定的bat文件地址,但该地址中的python可执行文件地址和咱们Broker文件地址是动态传入的。

2.3 后台运行

def run_broker():
    """
    根据当前系统后台运行Broker
    :return:
    """
    global CURRENT_FOLDER_PATH # 当前目录地址

    py_path = os.sys.executable # 获取当前python可执行文件地址
    broker_path = f"{CURRENT_FOLDER_PATH}/Broker.py" # Broker的python文件地址
    if platform.system() == 'Windows':
        py_path = py_path.replace("python.exe", "pythonw.exe") # windows中使用pythonw.exe执行程序
        bat_path = create_run_bat(py_path, broker_path) # 获取或创建bat文件
        os.system(f"{bat_path}")
    else:
        os.system(f"sudo {py_path} {broker_path}&")

我们的将创建一个Broker.py来承载我们的Broker程序,使用上面代码就可以实现自动后台运行咱们的Broker。

三、判断Broker运行状态

为了能够实现查看Broker是否正在运行,使用socket回包的形式进行判断,因此不管是端口占用还是程序未启动,我都能因此来判断Broker的运行情况:

def check_broker_active():
    """
    判断Broker是否活跃
    :return: 
    """
    global PORT # 定义自己的端口
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        s.connect(("127.0.0.1", PORT))
    except:
        return False

    s.sendall(b"PyMQ test") # 给Broker发送特定语句

    time.sleep(0.01)

    try:
        res = s.recv(1024)
        if res != b"Yes": # 当Broker未回复特定语句Yes,则开端口的程序非我们的Broker
            return False
    except:
        return False

    s.close()
    return True

四、Broker启动方法

def run_server():
    """
    启动Broker
    :return: 
    """
    if not check_broker_active(): # 查看Broker的运行情况
        try:
            radio_func_dic = {} # 广播字典
            server = MQThreadingTCPServer(
                ('127.0.0.1', PORT), Handle, radio_func_dic=radio_func_dic
            )

            radio_thread = threading.Thread(target=global_radio_handle, args=(radio_func_dic,)) # 广播订阅消息线程
            radio_thread.start()

            server.serve_forever()
        except Exception as e:
            return False

    return True


if __name__ == '__main__':
    run_server()

关于radio_func_dic和radio_thread用途后面介绍。

未完待续

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值