zl程序教程

您现在的位置是:首页 >  其他

当前栏目

分布式游戏服务框架设计

2023-09-14 09:05:37 时间

服务代码

# encoding:utf-8

from multiprocessing.managers import BaseManager
from multiprocessing import Queue
from functools import partial

args=locals()
# 为了避免一个用户在一个管道中发送多个消息所以处理结果要和待处理结果分开
# 子服务的put 和 用户的 get是一个管道
# 子服务的get 和 用户的 put 是一个管道
# 子服务计算管道 子服务才是真正的服务
for   i in range(2):
    server_name="get_child_queue{}".format(i)
    # 这些管道name名直接给用户配置好即可
    print(server_name)
    args[server_name] =Queue()
    server_name="put_child_queue{}".format(i)
    # 这些管道name名直接给用户配置好即可
    print(server_name)
    args[server_name] =Queue()
# 用户或者子服务 直接主动扫描子服务状态即可无需主服务控制,自行选择优良的服务,
# 主服务只有一个功能就是事先建立多个管道并汇集管理子服务。
class get_put_queue():
    def get_task_queue(self,k):
        # global task_queue
        return args["get_child_queue{}".format(k)]
    def put_task_queue(self,k):
        # global task_queue
        return args["put_child_queue{}".format(k)]





def startManager(host, port, authkey):
    # 把两个Queue都注册到网络上,callable参数关联了Queue对象,注意回调函数不能使用括号
    for i in range(2):
        BaseManager.register('get_task_queue{}'.format(i), callable=partial(get_put_queue().get_task_queue,i))
        BaseManager.register('put_task_queue{}'.format(i), callable=partial(get_put_queue().put_task_queue,i))
    # BaseManager.register('get_result_queue', callable=partial(get_queue().get_task_queue,1))
    # setattr(get_result_queue, "args", "result_queue")
    # setattr(get_result_queue, "args", "task_queue")
    # 设置host,绑定端口port,设置验证码为authkey
    manager = BaseManager(address=(host, port), authkey=authkey.encode('utf-8'))
    # 启动manager服务器
    manager.start()
    return manager


def put_queue(manager):
    # 通过网络访问queueu
    queue_list=[]
    for i in range(2):
        one=getattr(manager,"get_task_queue{}".format(i))()
        two=getattr(manager,"put_task_queue{}".format(i))()
        queue_list.append(one)
        queue_list.append(two)
    while 1:
        # 只检测信息
        for i in queue_list:
            print(i.qsize())




if __name__ == "__main__":
    host = '127.0.0.1'
    port = 5000
    authkey = 'abc'
    # 启动manager服务器
    manager = startManager(host, port, authkey)
    # 给task队列添加数据
    put_queue(manager)
    # 关闭服务器
    manager.shutdown

    # 首先明确的是主服务的管道一定是必须注册好的,管道必须和管道名必须注册事先,而连接的时候注册名可以动态所以子服务也不能动态新new 一个管道
    # 故而只能事先注册好了,所以用户要事先通过服务信息进行选择服务,而后才能进行服务。就像游戏选择一样
    # 而游戏服务区,和区之间不能共享信息

子服务代码

# encoding:utf-8
from multiprocessing.managers import BaseManager

def start_worker(host, port, authkey):
    # 由于这个BaseManager只从网络上获取queue,所以注册时只提供名字
    for i in range(2):
        server_name = "get_task_queue{}".format(i)
        BaseManager.register(server_name)
        server_name = "put_task_queue{}".format(i)
        BaseManager.register(server_name)

    # BaseManager.register('get_result_queue')
    print ('Connect to server %s' % host)
    # 注意,端口port和验证码authkey必须和manager服务器设置的完全一致
    worker = BaseManager(address=(host, port), authkey=authkey.encode('utf-8'))
    # 链接到manager服务器
    worker.connect()

    return worker


def get_queue(worker):
    get_queue_list=[]
    put_queue_list=[]

    for i in range(2):
        one=getattr(worker,"get_task_queue{}".format(i))()
        get_queue_list.append(one)
        one = getattr(worker, "put_task_queue{}".format(i))()
        put_queue_list.append(one)

    # queue_list = sorted(get_queue_list, key=lambda x: x.qsize())
    # 通道最小数据量也就是延迟最低
    # 推荐默认
    #子服务只服务一些用户所以默认 0-2
    while True:
        # 发送消息接收消息即可
        # 自己放里自己取
        for get_q,put_q in zip(get_queue_list,put_queue_list):
            # 子服务可以开启多进程处理
            if get_q.qsize():
                res=get_q.get()
                res["add"]+=1
                put_q.put(res)

            # put_best_qeue.put(1)
            # res=get_best_qeue.get()
            # print(res)


if __name__ == "__main__":
    host = '127.0.0.1'
    port = 5000
    authkey = 'abc'
    # 启动worker
    worker = start_worker(host, port, authkey)
    # 获取队列
    get_queue(worker)

用户代码

# encoding:utf-8
from multiprocessing.managers import BaseManager

def start_worker(host, port, authkey):
    # 由于这个BaseManager只从网络上获取queue,所以注册时只提供名字
    for i in range(2):
        server_name = "get_task_queue{}".format(i)
        BaseManager.register(server_name)
        server_name = "put_task_queue{}".format(i)
        BaseManager.register(server_name)

    # BaseManager.register('get_result_queue')
    print ('Connect to server %s' % host)
    # 注意,端口port和验证码authkey必须和manager服务器设置的完全一致
    worker = BaseManager(address=(host, port), authkey=authkey.encode('utf-8'))
    # 链接到manager服务器
    worker.connect()

    return worker


def get_queue(worker):
    get_queue_list=[]
    put_queue_list=[]

    for i in range(2):
        one=getattr(worker,"get_task_queue{}".format(i))()
        get_queue_list.append(one)
        one = getattr(worker, "put_task_queue{}".format(i))()
        put_queue_list.append(one)

    # queue_list = sorted(get_queue_list, key=lambda x: x.qsize())
    # 选择最优的服务器可以排序 queue_list
    # 通道最小数据量也就是延迟最低
    # 推荐默认
    get_best_qeue = get_queue_list[0]
    put_best_qeue = put_queue_list[0]
    while True:
        # 发送消息接收消息即可
        # 自己放里自己取
        # 这里要定义一些字典这样 这样子服务就知道怎么处理这些数据
        get_best_qeue.put({"add":1})
        res=put_best_qeue.get()
        print(res)


if __name__ == "__main__":
    host = '127.0.0.1'
    port = 5000
    authkey = 'abc'
    # 启动worker
    worker = start_worker(host, port, authkey)
    # 获取队列
    get_queue(worker)