Example #1
0
File: proxy.py Project: ljdog/burst
    def __init__(self, app):
        """
        构造函数
        :return:
        """
        self.app = app

        self.task_dispatcher = TaskDispatcher(self,
                                              self._on_workers_reload_over)
        self.stat_counter = StatCounter(
            self.app.config['TASKS_TIME_BENCHMARK'])
Example #2
0
    def __init__(self, app, host, port):
        """
        构造函数
        :return:
        """
        self.app = app
        self.host = host
        self.port = port

        self.task_dispatcher = TaskDispatcher(self, self._on_workers_reload_over)
        self.stat_counter = StatCounter(self.app.config['TASKS_TIME_BENCHMARK'])
Example #3
0
    def __init__(self, app, host, port):
        """
        构造函数
        :return:
        """
        self.app = app
        self.host = host
        self.port = port

        self.task_dispatcher = TaskDispatcher()
        self.stat_counter = StatCounter(
            self.app.config['TASKS_TIME_BENCHMARK'])
Example #4
0
class Proxy(object):
    """
    proxy相关
    """

    type = constants.PROC_TYPE_PROXY

    client_connection_factory_class = ClientConnectionFactory
    worker_connection_factory_class = WorkerConnectionFactory
    admin_connection_factory_class = AdminConnectionFactory
    master_connection_factory_class = MasterConnectionFactory

    app = None

    host = None
    port = None

    # 任务调度器
    task_dispatcher = None
    # 统计
    stat_counter = None

    # master的连接,因为一定只有一个,所以就一个变量即可
    master_conn = None

    def __init__(self, app, host, port):
        """
        构造函数
        :return:
        """
        self.app = app
        self.host = host
        self.port = port

        self.task_dispatcher = TaskDispatcher(self, self._on_workers_reload_over)
        self.stat_counter = StatCounter(self.app.config['TASKS_TIME_BENCHMARK'])

    def run(self):
        setproctitle.setproctitle(self.app.make_proc_name(self.type))

        # 主进程
        self._handle_proc_signals()

        ipc_directory = self.app.config['IPC_ADDRESS_DIRECTORY']
        if not os.path.exists(ipc_directory):
            os.makedirs(ipc_directory)

        # 启动监听master
        master_address = os.path.join(ipc_directory, self.app.config['MASTER_ADDRESS'])
        if os.path.exists(master_address):
            os.remove(master_address)
        reactor.listenUNIX(master_address, self.master_connection_factory_class(self))

        # 启动监听worker
        for group_id in self.app.config['GROUP_CONFIG']:
            ipc_address = os.path.join(ipc_directory, self.app.config['WORKER_ADDRESS_TPL'] % group_id)

            # 防止之前异常导致遗留
            if os.path.exists(ipc_address):
                os.remove(ipc_address)

            # 给内部worker通信用的
            reactor.listenUNIX(ipc_address, self.worker_connection_factory_class(self, group_id))

        # 启动对外监听
        reactor.listenTCP(self.port, self.client_connection_factory_class(self),
                          backlog=self.app.config['PROXY_BACKLOG'], interface=self.host)

        # 启动admin服务
        admin_address = self.app.config['ADMIN_ADDRESS']

        if admin_address:
            if isinstance(admin_address, (list, tuple)):
                # 说明是网络协议
                reactor.listenTCP(admin_address[1], self.admin_connection_factory_class(self),
                                  interface=admin_address[0])
            elif isinstance(admin_address, str):
                # 说明是文件
                admin_address = os.path.join(ipc_directory, admin_address)
                # 防止之前异常导致遗留
                if os.path.exists(admin_address):
                    os.remove(admin_address)
                reactor.listenUNIX(admin_address, self.admin_connection_factory_class(self))
            else:
                logger.error('invalid admin address. proxy: %s, admin_address: %s', self, admin_address)

        try:
            reactor.run(installSignalHandlers=False)
        except KeyboardInterrupt:
            pass
        except:
            logger.error('exc occur. proxy: %s', self, exc_info=True)

    def _handle_proc_signals(self):
        def stop_handler(signum, frame):
            """
            在centos6下,callFromThread(stop)无效,因为处理不够及时
            """
            try:
                reactor.stop()
            except:
                pass

        def safe_reload_handler(signum, frame):
            """
            让所有子进程重新加载
            """
            self.task_dispatcher.start_reload()

        # 强制结束,抛出异常终止程序进行
        signal.signal(signal.SIGINT, stop_handler)
        signal.signal(signal.SIGQUIT, stop_handler)
        # 直接停止
        signal.signal(signal.SIGTERM, stop_handler)
        # 忽略,因为这个时候是在重启worker
        signal.signal(signal.SIGHUP, safe_reload_handler)

    def _on_workers_reload_over(self):
        """
        当workers reload之后的操作
        需要给master通知,让master替换掉workers
        :return:
        """
        if self.master_conn and self.master_conn.transport:
            box = Box(dict(
                cmd=constants.CMD_MASTER_REPLACE_WORKERS
            ))
            self.master_conn.transport.write(box.pack())

    def __repr__(self):
        return '<%s name: %s>' % (
            type(self).__name__, self.app.name
        )
Example #5
0
File: proxy.py Project: ljdog/burst
class Proxy(object):
    """
    proxy相关
    """

    type = constants.PROC_TYPE_PROXY

    client_tcp_connection_factory_class = ClientTCPConnectionFactory
    client_udp_connection_factory_class = ClientUDPConnectionFactory
    worker_connection_factory_class = WorkerConnectionFactory
    admin_connection_factory_class = AdminConnectionFactory
    master_connection_factory_class = MasterConnectionFactory

    app = None

    # 任务调度器
    task_dispatcher = None
    # 统计
    stat_counter = None

    # master的连接,因为一定只有一个,所以就一个变量即可
    master_conn = None

    def __init__(self, app):
        """
        构造函数
        :return:
        """
        self.app = app

        self.task_dispatcher = TaskDispatcher(self,
                                              self._on_workers_reload_over)
        self.stat_counter = StatCounter(
            self.app.config['TASKS_TIME_BENCHMARK'])

    def run(self):
        setproctitle.setproctitle(self.app.make_proc_name(self.type))

        # 主进程
        self._handle_proc_signals()

        ipc_directory = self.app.config['IPC_ADDRESS_DIRECTORY']
        if not os.path.exists(ipc_directory):
            os.makedirs(ipc_directory)

        # 启动监听master
        master_address = os.path.join(ipc_directory,
                                      self.app.config['MASTER_ADDRESS'])
        if os.path.exists(master_address):
            os.remove(master_address)
        reactor.listenUNIX(master_address,
                           self.master_connection_factory_class(self))

        # 启动监听worker
        for group_id in self.app.config['GROUP_CONFIG']:
            ipc_address = os.path.join(
                ipc_directory,
                self.app.config['WORKER_ADDRESS_TPL'] % group_id)

            # 防止之前异常导致遗留
            if os.path.exists(ipc_address):
                os.remove(ipc_address)

            # 给内部worker通信用的
            reactor.listenUNIX(
                ipc_address,
                self.worker_connection_factory_class(self, group_id))

        # 启动对外监听
        if self.app.config['TCP']:
            reactor.listenTCP(self.app.config['PORT'],
                              self.client_tcp_connection_factory_class(self),
                              backlog=self.app.config['PROXY_BACKLOG'],
                              interface=self.app.config['HOST'])

        if self.app.config['UDP']:
            reactor.listenUDP(self.app.config['PORT'],
                              self.client_udp_connection_factory_class(self),
                              interface=self.app.config['HOST'])

        # 启动admin服务
        admin_address = self.app.config['ADMIN_ADDRESS']

        if admin_address:
            if isinstance(admin_address, (list, tuple)):
                # 说明是网络协议
                reactor.listenTCP(admin_address[1],
                                  self.admin_connection_factory_class(self),
                                  interface=admin_address[0])
            elif isinstance(admin_address, str):
                # 说明是文件
                admin_address = os.path.join(ipc_directory, admin_address)
                # 防止之前异常导致遗留
                if os.path.exists(admin_address):
                    os.remove(admin_address)
                reactor.listenUNIX(admin_address,
                                   self.admin_connection_factory_class(self))
            else:
                logger.error(
                    'invalid admin address. proxy: %s, admin_address: %s',
                    self, admin_address)

        try:
            reactor.run(installSignalHandlers=False)
        except KeyboardInterrupt:
            pass
        except:
            logger.error('exc occur. proxy: %s', self, exc_info=True)

    def _handle_proc_signals(self):
        def stop_handler(signum, frame):
            """
            在centos6下,callFromThread(stop)无效,因为处理不够及时
            """
            try:
                reactor.stop()
            except:
                pass

        def safe_reload_handler(signum, frame):
            """
            让所有子进程重新加载
            """
            self.task_dispatcher.start_reload()

        # 强制结束,抛出异常终止程序进行
        signal.signal(signal.SIGINT, stop_handler)
        signal.signal(signal.SIGQUIT, stop_handler)
        # 直接停止
        signal.signal(signal.SIGTERM, stop_handler)
        # 忽略,因为这个时候是在重启worker
        signal.signal(signal.SIGHUP, safe_reload_handler)

    def _on_workers_reload_over(self):
        """
        当workers reload之后的操作
        需要给master通知,让master替换掉workers
        :return:
        """
        if self.master_conn and self.master_conn.transport:
            box = Box(dict(cmd=constants.CMD_MASTER_REPLACE_WORKERS))
            self.master_conn.transport.write(box.pack())

    def __repr__(self):
        return '<%s name: %s>' % (type(self).__name__, self.app.name)