作者:吕嘉伟
团队:大云虚拟网络团队
实验环境:openstack kilo
随着网络资源的丰富,使用neutron-client查询网络信息时,neutron-server会一次性返回大量数据,造成应用处理数据变慢。为此neutron-server提供了分页功能,可以根据请求将结果分段返回。
(1) 打开neutron-server的分页功能
<span style="font-size:18px;"># vim /etc/neutron/neutron.conf [DEFAULT] allow_pagination = True # service neutron-server restart </span>
如果需要使用排序功能,可配置allow_sorting为True。
(2) 使用neutron-client测试分页功能
在neutron-client中,使用到分页功能的一般是list方法(并非全部资源的list都有)。
<span style="font-size:14px;">neutronclient/v2_0/client.py def list(self, collection, path, retrieve_all=True, **params): if retrieve_all: res = [] for r in self._pagination(collection, path, **params): res.extend(r[collection]) return {collection: res} else: return self._pagination(collection, path, **params)</span><span style="font-size:18px;"> </span>
其中retrieve_all参数是指是否需要分页,其值为True时,代表获得全部结果。可以看出无论retrieve_all等于True或False,都要调用_pagination函数。
<span style="font-size:14px;">neutronclient/v2_0/client.py def _pagination(self, collection, path, **params): if params.get('page_reverse', False): linkrel = 'previous' else: linkrel = 'next' next = True while next: res = self.get(path, params=params) yield res next = False try: for link in res['%s_links' % collection]: if link['rel'] == linkrel: query_str = urlparse.urlparse(link['href']).query params = urlparse.parse_qs(query_str) next = True break except KeyError: break</span>
其中page_reverse控制访问数据的方向,也就是所谓的“上一页”和“下一页”,默认为False(下一页)。_pagination通过get方法取数据,并且返回一个生成器给list函数。当retrieve_all=True时,list会用for循环一直用该生成器取数据,最终获得所有数据。反之,list返回一个生成器。
应用实例:
<span style="font-size:14px;">pagination_test.py</span>
<span style="font-size:14px;"> import os from neutronclient.v2_0 import client as neutronclient username=os.environ.get('OS_USERNAME') password=os.environ.get('OS_PASSWORD') tenant_name=os.environ.get('OS_TENANT_NAME') auth_url=os.environ.get('OS_AUTH_URL') neutron = neutronclient.Client(username=username, password=password, tenant_name=tenant_name, auth_url=auth_url) params ={'limit':2} routers = neutron.list_routers(False, ** params) #return a generator print routers.next()</span><span style="font-size:18px;"> </span>
结果:
{u'routers':[{u'status': u'ACTIVE', u'external_gateway_info': {u'network_id':u'4dedcc58-00ff-4a1f-8ff5-0378d04e7150', u'enable_snat': True,u'external_fixed_ips': [{u'subnet_id': u'cc12669d-8753-4d42-b4d4-d493f98d67e5',u'ip_address': u'10.2.17.102'}]}, u'name': u'no_ha_router_002',u'admin_state_up': True, u'tenant_id': u'c2fcc259713d4c028a179123ff05066b',u'distributed': False, u'routes': [], u'ha': False, u'id':u'b0501981-127e-4a3a-884a-e89084930b8a'}, {u'status': u'ACTIVE',u'external_gateway_info': {u'network_id':u'4dedcc58-00ff-4a1f-8ff5-0378d04e7150', u'enable_snat': True,u'external_fixed_ips': [{u'subnet_id': u'cc12669d-8753-4d42-b4d4-d493f98d67e5',u'ip_address': u'10.2.17.101'}]}, u'name': u'no_ha_router_001',u'admin_state_up': True, u'tenant_id': u'c2fcc259713d4c028a179123ff05066b',u'distributed': False, u'routes': [], u'ha': False, u'id':u'b707d99e-9474-4da9-ae33-b58a1b0f478b'}],u'routers_links':[{u'href':u'http://vip_neutron:9696/v2.0/routers.json?limit=2&marker=b707d99e-9474-4da9-ae33-b58a1b0f478b',u'rel': u'next'}, {u'href':u'http://vip_neutron:9696/v2.0/routers.json?limit=2&marker=b0501981-127e-4a3a-884a-e89084930b8a&page_reverse=True',u'rel': u'previous'}]}
结果的前半段为获取的数据,共2条;后半段为分页信息,其中href为分页需要使用的信息,在_pagination函数有用到。如果通过json request获取的数据,那么可能没法通过生成器继续获取数据,为此若想访问下一页信息可使用{‘limit’:2,‘marker’: ‘b707d99e-9474-4da9-ae33-b58a1b0f478b’},前一页信息可使用{‘limit’:2, ‘marker’: ‘b0501981-127e-4a3a-884a-e89084930b8a’,‘page_reverse’: True}。
除分页功能外,neutron-server还提供了简单的排序和查找功能,只要将相关的参数写入到request请求中即可。一般排序的关键字有sort_key和sort_dir,其中sort_key表明排序的关键词,sort_dir表明排序的方向。查找则需要根据返回的结果,在request请求中填写相应关键词,具体还需再实验。
总结:
本文介绍了neutron-server的分页功能及其使用,该功能可减少数据处理的时间,降低使用neutron-server查询数据的负载,对设计前端界面的缓存功能有一定的帮助。
参考文献:
http://specs.openstack.org/openstack/neutron-specs/specs/api/networking_general_api_information.html