需求
- 计费时长(也叫计费账期)为1天,表示每天将用户资源费用入账一次(一般为每天凌晨统计前一天的费用),未到入账时长的暂不入账,等待下次账期或资源删除时入账
- 使用时长不足一个账期的资源费用按实际使用时长计算(如账期为1天,云主机使用了半小时就删除了,按半小时计算费用)
- 根据用户计费(user和project都要区分),费用情况包含总费用、单个资源费用、单个资源详单
- 目前仅支持对云主机、云硬盘两种资源进行计费,并且支持用户对不同规格、类型的资源设置计费单价,按秒设置计费单价(单价按cpu个数、内存大小、磁盘类型和大小进行设置,用户设置单价时可以按小时设置,页面提示按秒计费的费用,后台转换为以秒为单位的单价用于计算实际费用)
- 管理员可查询所有用户/租户账单,普通用户仅可查询当前用户/租户账单
- 用户账期为1个月,每月初执行一次出账任务,当月账单属于未出账状态,之前的账单属于已出账状态,可按月/季度/半年/1年查询用户已出账月账单,并支持导出
- 详单周期为1天,用户可按时间段(最短一天、最长一个月)查询费用详单,并支持导出
实现思路
基于当前已有的两个项目:yr-monitor-log和turtle,用户操作记录使用yr-monitor-log,计费服务整合到定时任务服务turtle中。
大致流程如下:
表结构概览
user_actions:与当前表结构保持一致,如有必要可做适当修改
bill_resource:
project
|
user
|
resource
|
date
|
start_time
|
end_time
|
resource_type
|
vcpu
|
mem
|
disk
|
flavor_type
|
---|---|---|---|---|---|---|---|---|---|---|
租户或项目id | 用户id | 计费资源UUID:
云主机或云硬盘UUID |
账期,一般为前一天日期:2017-10-27 | 云主机创建、修改规格、删除时间点,
或云硬盘创建、扩容、删除时间点,如没有创建操作则设置为前一天起始时间,如2017-10-27 00:00:00 |
同start_time,如果前一天没有删除操作,
则记录为前一天结束时间,如2017-10-27 23:59:59 |
计费资源类型:
云主机或云硬盘 |
vcpu规格 | 内存规格G | 磁盘规格G | 规格类型,比如容量型云硬盘,
或高性能cpu云主机,根据extra_specs确定 |
bill_overview:
project
|
user
|
month
|
cost
|
|||
---|---|---|---|---|---|---|
租户或项目id | 用户id | 月份:如2017-10 | 月度费用总和 | |||
注:上述表结构需要根据实际需要进行补充修改。
其他考虑
- 主要是计费准确性相关问题,比如如果用户创建了云主机或云硬盘,创建操作被成功记录,之后删掉了,但删除记录丢失(MQ异常或yr-monitor-log、turtle、数据库服务异常等),怎么避免该云主机或云硬盘的费用一直累积?---需要考虑审计服务
- 需要考虑费用记录保留时长,1年还是3年?还是更长?这个问题优先级不高,默认无限期保留吧,影响不大。
- 如何支持特殊规格的单价设置?感觉应该是在yr-monitor-log从MQ接收到用户操作时,从消息payload中获取规格的详情(包含extra-specs或云硬盘类型),然后保存到user_actions表,之后计费服务直接存储备用,但不确定payload中是否有这些信息,如果没有,则需要yr-monitor-log从nova或者cinder数据库中根据资源uuid查询对应的规格再保存,具体细节需要再考虑
- 服务异常导致前一天费用未入账,需要考虑如何解决(初步考虑了下,可以在审计服务中再次进行入账操作,并且将入账记录跟bill_resource表中的记录比较,如果还没有插入就补录一次,如果已经有了就忽略)
- 计费服务所在节点异常,由其他节点接管计费服务(turtle已实现该功能),如果计费服务正在运行过程中节点发送故障,则接管后也无法继续完成前一天的入账,应该是会在第二天开始继续入账(其他节点会发现今天的入账任务执行时间点已经过去了),如果是在计费服务已经运行完之后才发生异常,则应该没有影响
- 如果云主机或云硬盘前一天有一次扩容操作,则需要在bill_resource表中插入两个记录,start_time分别为前一天起始时间和扩容操作时间,end_time分别为扩容操作时间和前一天结束时间,有过N次修改规格或扩容操作,则需要插入N+1条记录
- 如果前一天没操作记录的资源,如何入账到bill_resource?不管有没有记录,都先查询nova、cinder表,获取当前未删除资源的UUID,以此为依据遍历user_actions表,找到相关记录,进行相关入账工作,如果未找到记录,则认为当天正常存续,按规格没有变化入账一条记录(开始结束时间分别为前一天0点到23点最后一秒)
- 还有很多细节需要仔细考虑
审计服务大概思路
在计费服务执行中新增一个费用审计任务,把所有已经创建但还没有标记为删除的云主机云硬盘资源,都跟nova或cinder库中记录比较一遍,如果发现已经删除了,则在user_actions插入一条资源删除的记录,云主机修改规格或云硬盘扩容操作的审计也是类似,插入bill_resource表之前从nova、cinder数据库中查询当前规格即可(主要用在user_actions表中当天没有操作记录场景下,有修改规格或扩容操作情况下,直接记录新规格即可)
审计服务可以设置到计费入账服务之后执行,比如入账1天一次,每天凌晨执行,审计每天一次,在中午执行,或者每天2次,上午下午各一次。审计服务也只审计前一天的入账记录。
审计服务还需要考虑审计月账单,也即每月初在出账完毕后,还需要审计bill_overview表,检查是否正常,可以设置在每月初在出账服务之后执行,可以多次审计。