OpenStack中一种资源队列的应用

OpenStack中一种资源队列的应用

前言

在分析L3的路由功能时,我们看到在L3Agent中有一种资源队列的应用,当对资源有申请和操作时会将信息存入到队列中,再根据规则进行提取;当执行失败后会重新将任务存入队列,等待下次提取重新创建。

queue

L3的调用

在l3agent初始化时

neutron.agent.l3.agent
from neutron.agent.common import resource_processing_queue as queue
class L3NATAgent():
	def __init__():
		......
		self._queue = queue.ResourceProcessingQueue()	#实例化
neutron.agent.common.resource_processing_queue

from six.moves import queue as Queue
class ResourceProcessingQueue(object):
    def __init__(self):
        self._queue = Queue.PriorityQueue()

    def add(self, update):
        update.tries -= 1
        self._queue.put(update)
        # add 增加到队列

    def each_update_to_next_resource(self):
        next_update = self._queue.get()
		# 从队列取,然后执行这个消息
        with ExclusiveResourceProcessor(next_update.id) as rp:
            rp.queue_update(next_update)

            for update in rp.updates():
                yield (rp, update)

队列介绍

class PriorityQueue(Queue):
	# Queue 会初始化一个队列__init__(self, maxsize=0)
	# 本例中通过deque创建一个无大小限制的队列
    def _init(self, maxsize):
        self.queue = []

    def _qsize(self, len=len):
        return len(self.queue)	#查询队列内消息个数

    def _put(self, item, heappush=heapq.heappush):
        heappush(self.queue, item)	
        # 将item事件推到队列中
        # 注:本例中heappush为append到队列后,排序,排序的具体方法将以后介绍。暂未搞清:(

    def _get(self, heappop=heapq.heappop):
        return heappop(self.queue)
        # 从队列取事件,能按照排序的方法取出位于堆最上方的值

l3对队列的操作

下面举几个例子
下面都是加入队列的操作,包括路由增删和同步,都会向对列传入;本例中根据update信息中优先级PRIORITY来排序。

neutron.agent.l3.agent
class L3NATAgent():
    def router_deleted(self, context, router_id):
        update = queue.ResourceUpdate(router_id,
                                      PRIORITY_RPC,
                                      action=DELETE_ROUTER)
        self._queue.add(update)

    def routers_updated(self, context, routers):
        if routers:
            if isinstance(routers[0], dict):
                routers = [router['id'] for router in routers]
            for id in routers:
                update = queue.ResourceUpdate(
                    id, PRIORITY_RPC, action=ADD_UPDATE_ROUTER)
                self._queue.add(update)

    def _resync_router(self, router_update,
                       priority=PRIORITY_SYNC_ROUTERS_TASK):
        if router_update.hit_retry_limit():
                        router_update.id, router_update.action)
            if router_update.action != DELETE_ROUTER:
                self._safe_router_removed(router_update.id)
            return
        router_update.timestamp = timeutils.utcnow()
        router_update.priority = priority
        router_update.resource = None  # Force the agent to resync the router
        self._queue.add(router_update)

提取:用popleft,从最左侧提取

	之前文章写过启动l3-agent有进程不停执行_process_router_update去执行路由操作
    def _process_router_update(self):
        for rp, update in self._queue.each_update_to_next_resource():

总结

在OpenStack中,对路由进行操作时,首先将update的信息存入到队列queue中,然后通过其他进程不停对队列进行提取,提取的策略为根据信息的优先级来进行提取;提取后再进行操作;这样的好处有:

  1. 可以根据路由优先级执行;
  2. 将创建失败的信息重复加入到队列中;

后记

需要将队列排序的方法进一步分析:

heapq.py
def _siftup(heap, pos):

def _siftdown(heap, startpos, pos):

发布了11 篇原创文章 · 获赞 0 · 访问量 730

猜你喜欢

转载自blog.csdn.net/mr1jie/article/details/102796082