有段时间没写博客了,主要还是刚进新公司,多少有点不适应(真会给自己找理由,明明是手里没技术,肚子里没货,能写啥!)。前面几个星期都在修一修horizon的bug,这个没啥很大难度,就是用了一个django的框架,然后再嵌套一些js框架,简明易懂。不扯远了,来点干货。。

浏览器抓包可以看到,这样一个请求耗时2.4秒,再把日志打到horizon代码中,看下结果如何:

class GetVolumes(APIMeta):

    def handle(self):
status = self.request.POST.get('status', '')
tenant_id = self.request.POST.get('tenant_id', '')
data = []
instances_info = {}
LOG.error("step1:%s" % time.time())
# import pdb
# pdb.set_trace()
volumes_obj = api.cinder.volume_list(self.request,
{'all_tenants': 1})
LOG.error("step2:%s" % time.time())
volumes = filters.add_tenant_info(self.request,
volumes_obj,
"os-vol-tenant-attr:tenant_id")
LOG.error("step3:%s" % time.time())
instances = api.nova.server_list(self.request, all_tenants=True)
LOG.error("step4:%s" % time.time())
for ins in instances[0]:
instances_info[ins.id] = ins.name
if status:
volumes = filter(lambda x: status in x.status, volumes)
if tenant_id:
volumes = filter(lambda x: \
getattr(x, 'os-vol-tenant-attr:tenant_id') == tenant_id,
volumes)
LOG.error("step5:%s" % time.time())
for volume in volumes:
if volume.attachments:
instance_id = volume.attachments[0]['server_id']
instance_name = instances_info.get(instance_id,
instance_id)
else:
instance_name = ''
tenant = getattr(volume, 'tenant', '')
data.append({'volume_id': volume.id,
'display_name': volume.display_name,
'display_description': volume.display_description,
'bootable': volume.bootable,
'size': volume.size,
'status': volume.status,
'volume_type': volume.volume_type,
'host': getattr(volume,
"os-vol-host-attr:host", None),
'tenant_name': getattr(tenant, "name", None),
'tenant_id': getattr(tenant, "id", None),
'instance_name': instance_name,
})
LOG.error("step6:%s" % time.time())
return sorted(data, key = lambda x: x['display_name'], reverse = False)

测试结果如下:

-- ::, openstack_dashboard.dashboards.admin.volumes.json_views[line:] ERROR step1:1430963063.15
-- ::, openstack_dashboard.dashboards.admin.volumes.json_views[line:] ERROR step2:1430963064.71
-- ::, openstack_dashboard.dashboards.admin.volumes.json_views[line:] ERROR step3:1430963064.8
-- ::, openstack_dashboard.dashboards.admin.volumes.json_views[line:] ERROR step4:1430963066.29
-- ::, openstack_dashboard.dashboards.admin.volumes.json_views[line:] ERROR step5:1430963066.29
-- ::, openstack_dashboard.dashboards.admin.volumes.json_views[line:] ERROR step6:1430963066.29

可以看到,主要的耗时在step1-step2 step3-step4时间,定位到相应代码段:

# step1与step2之间耗时:
volumes_obj = api.cinder.volume_list(self.request,{'all_tenants': 1})
# step3与step4之间耗时:
instances = api.nova.server_list(self.request, all_tenants=True)

再在cinderclient做时间戳:

def volume_list(request, search_opts=None):
"""
To see all volumes in the cloud as an admin you can pass in a special
search option: {'all_tenants': 1}
"""
c_client = cinderclient(request)
if c_client is None:
return []
import time
LOG.error("horizon_start time: %s " % time.time())
result = c_client.volumes.list(search_opts=search_opts)
LOG.error("horizon_end time: %s " % time.time())
return result
# return c_client.volumes.list(search_opts=search_opts)

结果如下:

-- ::, openstack_dashboard.api.cinder[line:] ERROR horizon_start time: 1431069736.4
-- ::, openstack_dashboard.api.cinder[line:] ERROR horizon_end time: 1431069739.85

再在cinder服务端设置时间戳:/cinder/api/v1/volumes.py

    def _items(self, req, entity_maker):
# import pdb
# pdb.set_trace()
"""Returns a list of volumes, transformed through entity_maker.""" #pop out limit and offset , they are not search_opts
LOG.debug(_("time1------------------------%s" % time.time()))
search_opts = req.GET.copy()
search_opts.pop('limit', None)
search_opts.pop('offset', None) if 'metadata' in search_opts:
search_opts['metadata'] = ast.literal_eval(search_opts['metadata']) context = req.environ['cinder.context']
remove_invalid_options(context,
search_opts, self._get_volume_search_options()) volumes = self.volume_api.get_all(context, marker=None, limit=None,
sort_key='created_at',
sort_dir='desc', filters=search_opts) volumes = [dict(vol.iteritems()) for vol in volumes]
LOG.debug(_("time2------------------------%s" % time.time())) for volume in volumes:
self._add_visible_admin_metadata(context, volume) limited_list = common.limited(volumes, req)
LOG.debug(_("time3------------------------%s" % time.time()))
req.cache_resource(limited_list)
res = [entity_maker(context, vol) for vol in limited_list]
LOG.debug(_("time4------------------------%s" % time.time()))
return {'volumes': res}

结果如下:

time1------------------------1431069737.57
time2------------------------1431069738.02
time3------------------------1431069738.02
time4------------------------1431069738.05

显而易见,时间都消耗在cinder服务端向cinder客户端返回数据上面了,下面分析一下返回的数据:

{'migration_status': None,
'availability_zone': u'nova',
'terminated_at': None,
'updated_at': datetime.datetime(, , , , , ),
'provider_geometry': None,
'snapshot_id': None,
'ec2_id': None,
'mountpoint': None,
'deleted_at': None,
'id': u'69400200-6dea-41ec-ab7f-e3719fc9b18f',
'size': 3L,
'user_id': u'33d5edff940f4812b5368e54499991e4',
'attach_time': None,
'attached_host': None,
'display_description': u'',
'encryption_key_id': None,
'project_id': u'01f2a2e8594342d78865376cd81e2c67',
'launched_at': datetime.datetime(, , , , , ),
'scheduled_at': datetime.datetime(, , , , , ),
'status': u'available',
'volume_type_id': u'3a255382-1da3-4449-ad5b-5f37a4cf3d2c',
'deleted': False,
'provider_location': None,
'host': u'test1',
'source_volid': None,
'provider_auth': None,
'display_name': u'disk-102',
'instance_uuid': None,
'bootable': False,
'created_at': datetime.datetime(, , , , , ),
'attach_status': u'detached',
'volume_type': <cinder.db.sqlalchemy.models.VolumeTypes object at 0x44277d0>,
'_name_id': None, 'volume_metadata': []},

上面字段基本都会用到,看来解决方案不能在精简数据上面了,或者可以在cinder客户端做一个缓存,未完待续。。

获取云硬盘列表bug的更多相关文章

  1. 复盘价值1000万的腾讯云硬盘固件"BUG"

    摘要: 除了吃瓜,还是得吸取教训啊同学们! 这次,我从纯技术角度分析腾讯云与前沿数控的磁盘数据丢失事件,不站队. 硬盘门 这里说的硬盘门不是10年前陈老师的那一次,而聊的是最近"腾讯云&qu ...

  2. 阿里云使用js 实现OSS图片上传、获取OSS图片列表、获取图片外网访问地址(读写权限私有、读写权限公共);

    详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...

  3. [转] Android SDK manager 无法获取更新版本列表

      打开这个网址(LINK)就可以看到adt的详细信息. 或者直接在你的eclipse的Help > Install New Software里面add,地址直接输入 https://dl-ss ...

  4. android SDK manager 无法获取更新版本列表【转载】

    http://mirrors.neusoft.edu.cn/eclipse/releases/luna/打开这个网址就可以看到adt的详细信息:  http://developer.android.c ...

  5. OpenStack实践系列⑨云硬盘服务Cinder

    OpenStack实践系列⑨云硬盘服务Cinder八.cinder8.1存储的三大分类 块存储:硬盘,磁盘阵列DAS,SAN存储 文件存储:nfs,GluserFS,Ceph(PB级分布式文件系统), ...

  6. 完整部署CentOS7.2+OpenStack+kvm 云平台环境(2)--云硬盘等后续配置

    继上一篇博客介绍了完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建,本篇继续讲述后续部分的内容 1 虚拟机相关1.1 虚拟机位置介绍 openstack上创建的 ...

  7. 容器服务 TKE 存储插件与云硬盘 CBS 最佳实践应用

    引言 随着自研上云的深入,越来越多的有状态服务对于在 TKE 集群中使用云上存储能力的需求也越来越强烈. 目前腾讯云容器服务 TKE(Tencent Kubernetes Engine已支持在 TKE ...

  8. 云硬盘error、error deleting、deleting状态(数据库基本操作小记)

    起因是发现云硬盘显示删光了,但还是创建不了新的云硬盘,在api节点上用cinder list可以看到已经没有硬盘了,但是创建硬盘时,还是会提示配额满了,这是因为数据库里的记录没有更新,对数据库的操作记 ...

  9. Discuz! X3.1直接进入云平台列表的方法

    Discuz! X3.1已经改版,后台不能直接进云平台列表,不方便操作,操作云平台服务时,大家可以这样操作: 1.登录后台:2.访问域名进入云平台列表http://你域名/admin.php?fram ...

随机推荐

  1. webpack导入es6的简单应用

    1.先全局安装babel的需要文件 npm install -g babel-cli npm install --save-dev babel-preset-es2015 babel-core bab ...

  2. iOS: ios视频播放(MPMediaPlayerController,AVPlayer,AVPlayerViewcontroller、ffmpeg-AVPlayer)

    介绍: 和音频播放一样,ios也提供个很多的API.如mediaPlayer.framework下的MPMediaPlayerController.AVFounditon.framework下的AVP ...

  3. 使用unity3d开发app

    做过一些项目,参入过一些项目的计划安排.总觉得一些工具用起来很麻烦,要么是要收费,要么很大很重.没有针对小团队的简单易用的任务管理工具,也可能是找了些不能适合自己的习惯. 所有准备开始自己开发一款项目 ...

  4. solr 统计频率(term frequency)

    1.统计单词在某个字段出现的频率次数 term frequency实现使用了function query. 例如统计‘公司’这个关键字在text这个字段中出现的次数 在返回的时候进行计算统计,即在返回 ...

  5. cadvisor详解

    一. cadvisor和k8s的耦合 cadvisor是一个谷歌开发的容器监控工具,它被内嵌到k8s中作为k8s的监控组件.现在将k8s中的cadvisor实现分析一下. k8s中和cadvisor的 ...

  6. sqoop操作与使用

    sqoop只要安装到集群中的一台节点就可以了 1.上传sqoop到节点中 2.安装和配置 在添加sqoop到环境变量到/etc/profile中 将数据库连接驱动拷贝到$SQOOP_HOME/lib里 ...

  7. (转)Vue.use源码分析

    我想有过vue开发经验的,对于vue.use并不陌生.当使用vue-resource或vue-router等全局组件时,必须通过Vue.use方法引入,才起作用.那么vue.use在组件引入之前到底做 ...

  8. windowsclient开发--使用、屏蔽一些快捷键

    每一个windowsclient都有自己的一些快捷键,有的是windows系统提供的. 今天就要与大家分享一下.在windowsclient开发过程中对按键的处理. ESC按键 Duilib这个库中, ...

  9. ajax不运行success回调而是运行error回调

    调试代码遇到一个问题,就是前台运行删除操作后,controller返回数据,但前台接收时,ajax不运行success回调,总是弹出失败的对话框.接收数据类型是json. 先看看我的前台代码. if ...

  10. JAVA加解密 -- Base64加解密

    Base64算法实现:可以将任意的字节数组数据,通过算法,生成只有(大小写英文.数字.+./)(一共64个字符)内容表示的字符串数据. private static final String str ...