OpenStack计费Billing功能前瞻(一)

问题导读: 1.openstack现阶段计费项目情况? 2.需要怎样的环境实现? 3.在没有cloudkitty的情况下如何实现? 4.最终的流程图是什么? 前言: OpenStack有个比较年轻的费用统计项目CloudKitty,但是它需要与Ceilometer进行结合。在实际的生产环境中,若整个集群资源不大(10台服务器以下)且服务器性能较低,不建议上ceilometer,我的想法主要是mongoDB数据量太大,且会影响前端dashboard拿ceilometer的监控数据,国内主流做OpenStack的公司上ceilometer项目的较少,大部分使用collectd等主流轻量级监控插件。 鉴于此情况,本文主要阐述在没有安装Cloudkitty以及Ceilometer情况下计费功能的实现。 核心思想: 本文描述的计费功能主要是通过虚拟机的vcpu、ram、disk来统计费用。 Nova(Mitaka): 在开始代码之前我们来了解一下nova写表的机制:每一次通过client对云主机进行操作即使用nova命令时,/usr/lib/python2.7/site-packages/nova/objects/instance.py文件中的save方法进行参数处理,部分代码如下: def save(self, expected_vm_state=None, expected_task_state=None, admin_state_reset=False): """Save updates to this instance Column-wise updates will be made based on the result of self.what_changed(). If expected_task_state is provided, it will be checked against the in-database copy of the instance before updates are made. :param:context: Security context :param:expected_task_state: Optional tuple of valid task states for the instance to be in :param:expected_vm_state: Optional tuple of valid vm states for the instance to be in :param admin_state_reset: True if admin API is forcing setting of task_state/vm_state """ # Store this on the class because _cell_name_blocks_sync is useless # after the db update call below. self._sync_cells = not self._cell_name_blocks_sync() context = self._context cell_type = cells_opts.get_cell_type() if cell_type is not None: stale_instance = self.obj_clone() cells_update_from_api = (cell_type == 'api' and self.cell_name and self._sync_cells) if cells_update_from_api: def _handle_cell_update_from_api(): cells_api = cells_rpcapi.CellsAPI() cells_api.instance_update_from_api(context, stale_instance, expected_vm_state, expected_task_state, admin_state_reset) updates = {} changes = self.obj_what_changed() for field in self.fields: # NOTE(danms): For object fields, we construct and call a # helper method like self._save_$attrname() if (self.obj_attr_is_set(field) and isinstance(self.fields[field], fields.ObjectField)): try: getattr(self, '_save_%s' % field)(context) except AttributeError: LOG.exception(_LE('No save handler for %s'), field, instance=self) except db_exc.DBReferenceError as exp: if exp.key != 'instance_uuid': raise # NOTE(melwitt): This will happen if we instance.save() # before an instance.create() and FK constraint fails. # In practice, this occurs in cells during a delete of # an unscheduled instance. Otherwise, it could happen # as a result of bug. raise exception.InstanceNotFound(instance_id=self.uuid) elif field in changes: if (field == 'cell_name' and self[field] is not None and self[field].startswith(cells_utils.BLOCK_SYNC_FLAG)): updates[field] = self[field].replace( cells_utils.BLOCK_SYNC_FLAG, '', 1) else: updates[field] = self[field] 即每对instance进行一次操作,save方法都会对这次操作即update进行一次处理并写入mariaDB表,而改变的状态则在obj_what_change中:

由此可见,我们只需要在client对instance进行操作时,nova在将update信息写入mariadb之前将信息过滤并进行处理同样写入一张billing表即可! 接下去就很简单了 如何实现?? 1.在mariadb中创billing的表及用户 mysql -uroot -pMARIADB_PWD <<EOF drop database if exists billing; create database billing; grant all privileges on billing.* to "billing"@"localhost" identified by "BILLING_PWD"; grant all privileges on billing.* to "billing"@"%" identified by "BILLING_PWD"; flush privileges; EOF 2.初始化表 在这里使用了python的mysql工具包sqlalchemy(http://www.sqlalchemy.org),可以直接通过python语言来定义mysql库及表。 a.init_db.py(DB中数据的状态记录以及使用记录初始化)

b.utils.py(主要是从billing表中拿数据并计算写入billing表)

在/etc/nova/nova.conf配置一下billing的参数: db_connection = mysql://billing:openstack@127.0.0.1/billing pool_recycle = 600 c.modules.py(定义billing表的title即里面数据的声明,三张表分别是Rate(单价)和Usage(使用量)和StatusRecord(状态记录))

3.Analysis 总体的设计思路是----- 1.部署时先python utils.py跑一遍代码,之后每通过client对云主机进行关机、删除、创建、迁移操作时会记录到billing表中; 2.可以在前端自定义费用模板(也可以直接写进billing.rate表中),后端可以拿到前端传过来的模板信息(rate.cpu、rate.ram、rate.disk)进行计算整合写入表并传给前端 4.WorkFlow

5.DB billing中有三张表,对应的是价格、状态记录和使用量

本文主要对billing功能进行前瞻,下一节主要讲计算api utils.py文件

计费功能最重要的是理清楚nova中虚拟机状态的变化,create, update,delete,resized等等,只要搞清楚里面的逻辑,对计费的计算一下就能搞清楚了。

原文发布于微信公众号 - about云(wwwaboutyuncom)

原文发表时间:2016-08-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python中文社区

那些年在win下填过的Django坑

專 欄 ❈ JacobYRJ,Python中文社区专栏作者 Python语言爱好者,目前在做Django项目。 Github博客:https://JacobY...

19970
来自专栏Golang语言社区

[Go语言]一种用于网游服务器的支持多路复用的网络协议处理框架

简介: 本文描述了使用Go语言实现的、适应于Go语言并发模型的一种支持多路复用的网络协议处理框架,并提供了框架的代码实现。作者将这种框架用于网络游戏服务器中的协...

386100
来自专栏从流域到海域

如何在Mule 4 Beta中实现自动流式传输

原文地址:https://dzone.com/articles/how-automatic-streaming-in-mule-4-beta-works

20750
来自专栏java达人

防止表单重复提交的思路和方法

作为一个软件开发者,绝不能奢望你的用户会规规矩矩地使用你的软件,他们一般都是缺乏耐心,“胡作非为”的。比如当他点击提交表单时,服务器处理比较慢, 页面上没有任何...

39580
来自专栏韩伟的专栏

如何设计一个 RPC 系统

RPC 是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高。本文就是通过分析几种流行的 RPC ...

10.9K90
来自专栏IT技术精选文摘

Java文件映射(mmap)全接触

前言 我们在平时的工作中大多都会需要处理像下面这样基于Key-Value的数据: ? 其中UID是数据唯一标识,FIELD[1]是属性值。以QQ用户的Sess...

1.6K60
来自专栏IT笔记

SpringBoot开发案例之整合mail队列篇

前段时间搞了个SpringBoot开发案例之整合mail发送服务,也是基于目前各项目平台的邮件发送功能做一个抽离和整合。

44380
来自专栏后端技术探索

http response code 301 和 302,你懂吗

一.官方说法 301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于: 301 redirect: 301 代表永久性转移(Per...

13010
来自专栏xcywt

程序员需要知道的十个操作系统的概念

说明:我之前在网上看到这篇文章觉得非常好,于是把它翻译了下来。当然很多地方翻译的很渣,见笑了。温馨提示,文章有点长。

12520
来自专栏IT笔记

SpringBoot开发案例之整合mail队列篇

? 科帮网邮件队列.png 前言 前段时间搞了个SpringBoot开发案例之整合mail发送服务,也是基于目前各项目平台的邮件发送功能做一个抽离和整合。 问...

74670

扫码关注云+社区

领取腾讯云代金券