Пример #1
0
def config_queue(request):
    """管理队列权重,提升队列权重或降低队列权重
       传入参数:http://server/taskqueues/q01/config?action=queue_down
    """
    queue_id = request.matchdict['id']
    url_action = request.params.get('action','')
    dispatcher_config = ztq_core.get_dispatcher_config()
    queue_weight = dispatcher_config['queue_weight']

    # 根据操作类型进行权重调整,
    if url_action == 'queue_down' : 
        queue_weight[queue_id] -= 1
        # 队列权重最少为1
        if queue_weight[queue_id] < 0: queue_weight[queue_id] = 0
        # 更新调度策略并进行调度
        ztq_core.set_dispatcher_config(dispatcher_config)
        utils.dispatch()
    elif url_action == 'queue_up' : 
        queue_weight[queue_id] += 1
        if queue_weight[queue_id] > 10: queue_weight[queue_id] = 10
        # 更新调度策略并进行调度
        ztq_core.set_dispatcher_config(dispatcher_config)
        utils.dispatch()
    elif url_action == 'from_right' : 
        utils.dispatch_single_queue(queue_id, from_right=True)
    elif url_action == 'from_left' : 
        utils.dispatch_single_queue(queue_id, from_right=False)   
    return HTTPFound(location = '/taskqueues') 
Пример #2
0
def init_job_threads(config_dict):
    # 启动工作线程
    set_job_threads(config_dict)
    # 保存信息
    config = {}
    for queue_name, values in config_dict.items():
        sleeps = [str(x['interval']) for x in values]
        config[queue_name] = ','.join(sleeps)

    CONFIG['queues'].update(config)

    # 将一些信息补全,让监视界面认为这个worker已经启动
    alias = CONFIG['server']['alias']
    # 初始化
    dispatcher_config = ztq_core.get_dispatcher_config()
    if not dispatcher_config: 
        dispatcher_config = {'queue_weight':{},'worker_weight':{}}
    # set dispatcher config
    worker_weight = dispatcher_config['worker_weight']
    if not worker_weight.get(alias, 0):
        worker_weight[alias] = 5 
        ztq_core.set_dispatcher_config(dispatcher_config)
    # set worker config
    worker_config = ztq_core.get_worker_config()
    worker_config[alias] = config_dict 
Пример #3
0
def main(global_config, redis_host='127.0.0.1', redis_port='6379', \
        redis_db='0', frs_root='frs', init_dispatcher_config='true', \
        frs_cache='frscache', addon_config=None, work_enable=True, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    # 初始化Redis连接
    ztq_core.setup_redis('default', redis_host, port=int(redis_port), db=int(redis_db),)

    # 初始化权重数据数据,如果权重配置已经存在则pass
    if init_dispatcher_config.lower() == 'true':
        # init_dispatcher_config 是因为控制台可能没有运行服务, 这里去读取redis数据,会导致控制台起不来
        dispatcher_config = ztq_core.get_dispatcher_config()
        if not dispatcher_config: 
            dispatcher_config = weight = {'queue_weight':{},'worker_weight':{}}
            ztq_core.set_dispatcher_config(weight)

        queue_weight = dispatcher_config['queue_weight']
        if not queue_weight:
            queues_list = ztq_core.get_queue_config()
            for queue_name, queue_config in queues_list.items():
                queue_weight[queue_name] = queue_config.get('weight', 0)
            ztq_core.set_dispatcher_config(dispatcher_config)

    # # 开启后台服务
    # 初始化fts_web配置
    settings = dict(settings)
    settings.setdefault('jinja2.directories', 'ztq_console:templates')
    config = Configurator(settings=settings)
    config.begin()
    config.add_renderer('.html', pyramid_jinja2.renderer_factory)
    config.add_static_view('static', 'ztq_console:static')
    config.scan('ztq_console.views')  
    config.add_route('worker', '/worker/{id}', 
                    view='ztq_console.views.config_worker')
    config.add_route('end_thread', '/worker/{id}/{thread}/{pid}', 
                    view='ztq_console.views.stop_working_job')                    
    config.add_route('taskqueue', '/taskqueues/{id}')
    config.add_route('taskqueues_config', '/taskqueues/{id}/config', 
                    view='ztq_console.views.config_queue')
    config.add_route('taskqueue_action', '/taskqueues_action/{id}')
    config.add_route('errorqueues_job', '/errorqueues/{id}/job',
                    view='ztq_console.views.error_jobs_handler')    
    config.add_route('workerlog', '/workerlog/{page}')
    config.add_route('syslog', '/syslog/{page}')
    config.add_route('errorlog', '/errorlog/{page}')
    config.add_route('errorqueue', '/errorqueue/{id}/{page}')
    config.add_route('redo_all_error_for_queue', '/redo_all_error_for_queue/{id}')
    config.add_route('del_all_error_for_queue', '/del_all_error_for_queue/{id}')
    if addon_config is not None:
        addon_config(config)
    config.end()

    return config.make_wsgi_app()
Пример #4
0
def dispatch():
    """根据调度参数进行转换器和队列的调度
    """
    #获取调度参数
    dispatcher_config = ztq_core.get_dispatcher_config()
    worker_weight = dispatcher_config['worker_weight']
    if not worker_weight: return
    queue_weight = dispatcher_config['queue_weight']
    worker_list = ztq_core.get_all_worker()
    
    #生成新的转换器工作线程配置
    if worker_list:
        gen_worker_config(worker_weight, queue_weight, worker_list) 
Пример #5
0
def config_worker(request):
    """对worker进行配置管理
    """
    url_action = request.params.get('action','')

    dispatcher_config = ztq_core.get_dispatcher_config()
    worker_weight = dispatcher_config['worker_weight']
    # 获取用户请求操作
    worker_id = request.matchdict['id']
    # 根据操作类型进行权重调整,
    if url_action == 'stop_worker': 
        #停止worker
        worker_weight[worker_id] = 0
    elif url_action == 'enable': 
        #启用worker
        worker_weight[worker_id] = 5
    elif url_action == 'worker_down' : 
        #降低worker权重
        worker_weight[worker_id] -= 1
        if worker_weight[worker_id] < 1: worker_weight[worker_id] = 1
    elif url_action == 'worker_up' : 
        #提升worker权重
        worker_weight[worker_id] += 1
        if worker_weight[worker_id] >10: worker_weight[worker_id] = 10
    elif url_action == 'delete': 
        #删除还没启用的worker,删除操作不会导致调度配置更新
        if worker_id in worker_weight: # 没有启用的情况
            worker_weight.pop(worker_id)
        workers_dict = ztq_core.get_worker_state()
        del workers_dict[worker_id]
        worker_job = ztq_core.get_job_state(worker_id)
        for job_name, job_status in worker_job.items():
            del worker_job[job_name]
        ztq_core.set_dispatcher_config(dispatcher_config)
        return HTTPFound(location = '/workerstatus')
    elif url_action == 'update':
        # 发报告指令到各命令队列让worker报告自身状态
        worker_list = ztq_core.get_all_worker()
        for worker_name in worker_list:
            if worker_name == worker_id:
                utils.send_command(worker_name, 'report')
                time.sleep(1)
                return HTTPFound(location = '/workerstatus')
    # 更新调度策略并进行调度        
    ztq_core.set_dispatcher_config(dispatcher_config)
    utils.dispatch()
    return HTTPFound(location = '/workerstatus')
Пример #6
0
def get_taskqueues_list():
    # 队列情况列表
    dispatcher_config = ztq_core.get_dispatcher_config()
    queue_weight = dispatcher_config['queue_weight']
    queues_list = ztq_core.get_queue_config()

    # 排序
    sort_queue_name = {}
    for queue_name, queue_config in queues_list.items():
        sort_queue_name[queue_name] = len(ztq_core.get_error_queue(queue_name))
    
    for queue_name in sorted(sort_queue_name, 
                            key=lambda x: sort_queue_name[x], 
                            reverse=True):
        task_queue = {}
        task_queue['name'] = queue_name
        #task_queue['tags'] = queue_config.get('tags',())
        queue = ztq_core.get_task_queue(queue_name)
        # 任务数/错误数
        task_queue['length'] = len(queue)
        task_queue['error_length'] = sort_queue_name[queue_name]

        #任务首个时间
        task_queue['error_end'] = task_queue['first'] = ''
        first_job = queue[0]
        first_job= ztq_core.get_task_hash(queue_name).get(first_job)
        if first_job:
            task_queue['first'] = datetime.datetime.fromtimestamp(first_job['runtime'].get('create', 0))
        
        #错误最末一个的时间
        error_first_job = ztq_core.get_error_queue(queue_name)[0]
        error_first_job = ztq_core.get_error_hash(queue_name).get(error_first_job)
        if error_first_job:
            task_queue['error_end'] = datetime.datetime.fromtimestamp(error_first_job['runtime'].get('create', 0))

        task_queue['weight'] = queue_weight.get(queue_name, 0)
        # 获取worker工作线程配置
        workers_config = ztq_core.get_worker_config()
        task_queue['from_right'] = True
        for worker_name,worker_config in workers_config.items():
            task_queue['workers'] = []
            for config in worker_config.get(queue_name,[]):
                task_queue['workers'].append([worker_name+':', config['interval']])
                if 'from_right' in config:
                    task_queue['from_right'] = config['from_right']
        task_queue['buffer_length'] = len(ztq_core.get_buffer_queue(queue_name))
        yield task_queue
Пример #7
0
def get_worker_list():
    dispatcher_config = ztq_core.get_dispatcher_config()
    worker_weight = dispatcher_config['worker_weight']
    workers_dict = ztq_core.get_worker_state().items()
    for worker_name, worker_status in workers_dict:
        worker_status['_worker_name'] = worker_name
        worker_status['_started'] = \
            datetime.datetime.fromtimestamp(worker_status['started'])
        worker_status['_timestamp'] = \
            datetime.datetime.fromtimestamp(worker_status['timestamp'])
        worker_status['_worker_weight'] = worker_weight.get(worker_name, 0)
        # 检查worker是否在工作
        cmd_queue = ztq_core.get_command_queue(worker_name)
        # 如果指令队列不为空的话,意味着worker没工作,属于下线状态
        if cmd_queue: worker_status['_active'] = u'shutdown'
        elif worker_status['_worker_weight'] == 0:
            worker_status['_active'] = u'ldle'
        else:
            worker_status['_active'] = u'work'
        # 获取worker开了多少个线程
        worker_job = ztq_core.get_job_state(worker_name)
        worker_status['_threads'] = []
        for thread_name, thread_status in worker_job.items():
            thread_status['_detail'] = pprint.pformat(thread_status)
            thread_status['_name'] = thread_name
            thread_status['_comment'] = thread_status['kw'].get(
                'comment', thread_status['process'].get('comment', ''))
            thread_status['_pid'] = thread_status['process'].get('pid', -1)
            ident = unicode(thread_status['process'].get('ident', -1))
            if ident in worker_status['traceback']:
                thread_status['_thread_detail'] = pprint.pformat(
                    worker_status['traceback'][ident])
            # 任务进行了多少时间
            used_time = int(time.time()) - thread_status['process']['start']
            if used_time > 3600:
                used_time = u'%.2f小时' % (used_time / 3600.0)
            elif used_time > 60:
                used_time = u'%.2f分钟' % (used_time / 60.0)
            thread_status['_take_time'] = used_time

            worker_status['_threads'].append(thread_status)

        yield worker_status
Пример #8
0
def get_worker_list():
    dispatcher_config = ztq_core.get_dispatcher_config()
    worker_weight = dispatcher_config['worker_weight']
    workers_dict = ztq_core.get_worker_state().items()
    for worker_name, worker_status in workers_dict:
        worker_status['_worker_name'] = worker_name
        worker_status['_started'] = \
            datetime.datetime.fromtimestamp(worker_status['started'])
        worker_status['_timestamp'] = \
            datetime.datetime.fromtimestamp(worker_status['timestamp'])
        worker_status['_worker_weight'] = worker_weight.get(worker_name, 0)
        # 检查worker是否在工作
        cmd_queue = ztq_core.get_command_queue(worker_name)
        # 如果指令队列不为空的话,意味着worker没工作,属于下线状态
        if cmd_queue: worker_status['_active'] = u'shutdown'
        elif worker_status['_worker_weight'] == 0: 
            worker_status['_active'] = u'ldle'
        else: worker_status['_active'] = u'work'
        # 获取worker开了多少个线程
        worker_job = ztq_core.get_job_state(worker_name)
        worker_status['_threads'] = []
        for thread_name,thread_status in worker_job.items():
            thread_status['_detail'] = pprint.pformat(thread_status)
            thread_status['_name'] = thread_name
            thread_status['_comment'] = thread_status['kw'].get('comment',thread_status['process'].get('comment', ''))
            thread_status['_pid'] = thread_status['process'].get('pid', -1)
            ident = unicode(thread_status['process'].get('ident', -1))
            if ident in worker_status['traceback']:
                thread_status['_thread_detail'] = pprint.pformat(worker_status['traceback'][ident])
            # 任务进行了多少时间
            used_time = int(time.time())-thread_status['process']['start']
            if used_time > 3600:
                used_time = u'%.2f小时' % (used_time / 3600.0)
            elif used_time > 60:
                used_time = u'%.2f分钟' % (used_time / 60.0)
            thread_status['_take_time'] = used_time

            worker_status['_threads'].append(thread_status)

        yield worker_status
Пример #9
0
def init_job_threads(config_dict):
    # 启动工作线程
    set_job_threads(config_dict)
    # 保存信息
    config = {}
    for queue_name, values in config_dict.items():
        sleeps = [str(x['interval']) for x in values]
        config[queue_name] = ','.join(sleeps)
    set_config(config, 'queues')

    # 将一些信息补全,让监视界面认为这个worker已经启动
    alias = safe_get_host('server', 'alias')
    # 初始化
    dispatcher_config = ztq_core.get_dispatcher_config()
    if not dispatcher_config:
        dispatcher_config = {'queue_weight': {}, 'worker_weight': {}}
    # set dispatcher config
    worker_weight = dispatcher_config['worker_weight']
    if not worker_weight.get(alias, 0):
        worker_weight[alias] = 5
        ztq_core.set_dispatcher_config(dispatcher_config)
    # set worker config
    worker_config = ztq_core.get_worker_config()
    worker_config[alias] = config_dict
Пример #10
0
def main(global_config, frs_root='frs', init_dispatcher_config='true', \
        frs_cache='frscache', addon_config=None, work_enable=True, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    
    # 是否启用sentinel
    enable_sentinel = settings.get('enable_sentinel', 'false').lower() == 'true'
    # 如果启用sentinel,则关于redis的host,port,db都为对sentinel的配置
    if enable_sentinel:
        # 主机列表
        hosts = settings.get('sentinel_hosts', None)
        assert(hosts)
        # sentinel的所有services name
        services = settings.get('sentinel_names', None)
        assert(services)
        # 使用的数据库
        db = int(settings.get('sentinel_db', '0'))
        assert(db >= 0)

        services = services.split(',')
        ztq_core.setup_sentinel('default', 
                map(lambda x: (x[0], int(x[1])), [host.split(':') for host in hosts.split(',')]),
                services, db = db)
        # 如果启用了sentinel
        # servers 列表为所有的 services
        MENU_CONFIG['servers'] = services
        MENU_CONFIG['current_redis'] = services[0]
        MENU_CONFIG['enable_sentinel'] = True
    else:
        # 初始化servers
        # servers 格式
        # name:host:port:db:title, ......
        servers = settings.get('servers', None)
        # servers 作为必须的配置项
        # 取消原来的redis_host,redis_port,redis_db配置
        assert(servers)
        for server in servers.split(','):
            texts = server.split(':')
            # 单个server的配置项必须介于4-5之间
            assert(len(texts) >= 4 and len(texts) <= 5)
            # 添加到待管理的服务器列表中
            MENU_CONFIG['servers'].append({
                    'name'  : texts[0],
                    'host'  : texts[1],
                    'port'  : int(texts[2]),
                    'db'    : int(texts[3]),
                    'title' : texts[4] if len(texts) == 5 else texts[0],
                })
        # 默认将列表中的第一个服务器作为默认服务器
        current_redis = MENU_CONFIG['servers'][0]
        MENU_CONFIG['current_redis'] = current_redis['name']
        #
        # 初始化Redis连接
        ztq_core.setup_redis('default'
                , current_redis['host']
                , current_redis['port'], current_redis['db'])
        MENU_CONFIG['enable_sentinel'] = False

    # 初始化权重数据数据,如果权重配置已经存在则pass
    if init_dispatcher_config.lower() == 'true':
        # init_dispatcher_config 是因为控制台可能没有运行服务, 这里去读取redis数据,会导致控制台起不来
        dispatcher_config = ztq_core.get_dispatcher_config()
        if not dispatcher_config: 
            dispatcher_config = weight = {'queue_weight':{},'worker_weight':{}}
            ztq_core.set_dispatcher_config(weight)

        queue_weight = dispatcher_config['queue_weight']
        if not queue_weight:
            queues_list = ztq_core.get_queue_config()
            for queue_name, queue_config in queues_list.items():
                queue_weight[queue_name] = queue_config.get('weight', 0)
            ztq_core.set_dispatcher_config(dispatcher_config)

    # # 开启后台服务
    # 初始化fts_web配置
    authn_policy = AuthTktAuthenticationPolicy('sosecret', callback=groupfinder, hashalg='sha512')
    authz_policy = ACLAuthorizationPolicy()
    settings = dict(settings)
    settings.setdefault('jinja2.directories', 'ztq_console:templates')
    config = Configurator(settings=settings, root_factory='ztq_console.utils.models.RootFactory')
    config.set_authentication_policy(authn_policy)
    config.set_authorization_policy(authz_policy)
    config.begin()
    config.add_renderer('.html', pyramid_jinja2.renderer_factory)
    config.add_static_view('static', 'ztq_console:static')
    config.scan('ztq_console.views')  
    config.add_route('login', '/login')
    config.add_route('logout', '/logout')
    config.add_route('password', '/password' )
    config.add_route('worker', '/worker/{id}', 
                    view='ztq_console.views.config_worker')
    config.add_route('end_thread', '/worker/{id}/{thread}/{pid}', 
                    view='ztq_console.views.stop_working_job') 
    config.add_route('taskqueue', '/taskqueues/{id}')
    config.add_route('taskqueues_config', '/taskqueues/{id}/config', 
                    view='ztq_console.views.config_queue')
    config.add_route('taskqueue_action', '/taskqueues_action/{id}')
    config.add_route('errorqueues_job', '/errorqueues/{id}/job',
                    view='ztq_console.views.error_jobs_handler')    
    config.add_route('workerlog', '/workerlog/{page}')
    config.add_route('syslog', '/syslog/{page}')
    config.add_route('errorlog', '/errorlog/{page}')
    config.add_route('errorqueue', '/errorqueue/{id}/{page}')
    config.add_route('redo_all_error_for_queue', '/redo_all_error_for_queue/{id}')
    config.add_route('del_all_error_for_queue', '/del_all_error_for_queue/{id}')
    if addon_config is not None:
        addon_config(config)
    config.end()

    return config.make_wsgi_app()
Пример #11
0
def main(global_config, redis_host='127.0.0.1', redis_port='6379', \
        redis_db='0', frs_root='frs', init_dispatcher_config='true', \
        frs_cache='frscache', addon_config=None, work_enable=True, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    # 初始化Redis连接
    ztq_core.setup_redis(
        'default',
        redis_host,
        port=int(redis_port),
        db=int(redis_db),
    )

    # 初始化权重数据数据,如果权重配置已经存在则pass
    if init_dispatcher_config.lower() == 'true':
        # init_dispatcher_config 是因为控制台可能没有运行服务, 这里去读取redis数据,会导致控制台起不来
        dispatcher_config = ztq_core.get_dispatcher_config()
        if not dispatcher_config:
            dispatcher_config = weight = {
                'queue_weight': {},
                'worker_weight': {}
            }
            ztq_core.set_dispatcher_config(weight)

        queue_weight = dispatcher_config['queue_weight']
        if not queue_weight:
            queues_list = ztq_core.get_queue_config()
            for queue_name, queue_config in queues_list.items():
                queue_weight[queue_name] = queue_config.get('weight', 0)
            ztq_core.set_dispatcher_config(dispatcher_config)

    # # 开启后台服务
    # 初始化fts_web配置
    settings = dict(settings)
    settings.setdefault('jinja2.directories', 'ztq_console:templates')
    config = Configurator(settings=settings)
    config.begin()
    config.add_renderer('.html', pyramid_jinja2.renderer_factory)
    config.add_static_view('static', 'ztq_console:static')
    config.scan('ztq_console.views')
    config.add_route('worker',
                     '/worker/{id}',
                     view='ztq_console.views.config_worker')
    config.add_route('end_thread',
                     '/worker/{id}/{thread}/{pid}',
                     view='ztq_console.views.stop_working_job')
    config.add_route('taskqueue', '/taskqueues/{id}')
    config.add_route('taskqueues_config',
                     '/taskqueues/{id}/config',
                     view='ztq_console.views.config_queue')
    config.add_route('taskqueue_action', '/taskqueues_action/{id}')
    config.add_route('errorqueues_job',
                     '/errorqueues/{id}/job',
                     view='ztq_console.views.error_jobs_handler')
    config.add_route('workerlog', '/workerlog/{page}')
    config.add_route('syslog', '/syslog/{page}')
    config.add_route('errorlog', '/errorlog/{page}')
    config.add_route('errorqueue', '/errorqueue/{id}/{page}')
    config.add_route('redo_all_error_for_queue',
                     '/redo_all_error_for_queue/{id}')
    config.add_route('del_all_error_for_queue',
                     '/del_all_error_for_queue/{id}')
    if addon_config is not None:
        addon_config(config)
    config.end()

    return config.make_wsgi_app()