当前涉及到的产品罗列
计费流程说明
- 管理员在成本中心MIS侧配置单项规格,比如云服务器的单项规格类型有cpu,内存两种。
- 每个产品有哪些规格提前预设好,为系统初始化数据不能修改。 由成本中心产品经理沟通涉及到的产品线确认。
- 管理员在成本中心MIS侧选择不同的单项规格组成组合规格,各产品在资源申请时的规格列表就是从接口中获取这些配置好的组合规格。
- 用户在申请资源,升配/降配资源,销毁资源,修改资源的租户,项目,区域属性时,需要向rabbitmq中发送事件消息,成本中心会实时消费这些消息从而进行计费。
- 当前仅支持后付费模式。
文档说明
事件消息推送规范(使用RabbitMQ)
vhost name
dcloudexchange name
DCLOUD_EVENT_EXCHANGEexchange type
fanout
推送格式示例
必填项如下:
method, payload.occurTime, payload.chargeIds, payload.uuid,payload.tenantId,payload.projectId,payload.cate,payload.eventId 对于云硬盘,payload.specValue也是必填
{"method": "res_create", //事件类型,以_分割,前面是固定的res,后面是发生的动作,例如create/upgrade/downgrade/delete,create代表资源创建,upgrade代表升配,downgrade代表降配,delete代表资源销毁"payload":{"occurTime": 160698721, //事件发生的时间,时间戳,精确到秒,go语言对应Unix()"chargeIds": [3,2,1], //获取规格列表时会获得这个组合规格价钱的id,这里就传用户选择的组合规格对应的id,因为考虑到有些资源对应了多个不同的类型的组合规格,因此这里是个chargeId的列表。"specValue": 123, //对于连续型规格,需要将用户选择的值传进这个字段,例如云盘容量,选择了100G,那就传100。 容量的单位在MIS侧的规格已经固定,页面上相关的展示也从规格接口获取渲染。"name": "云盘名称","ident": "例如云主机的IP地址/在云盘创建情况下传递云盘的资源uuid","uuid": "UUID", //每个创建出来的资源实例的唯一id,一定要有,以后这个实例的所有事件都要使用这个resourceId"extend": "{ // 是个json格式的字符串,不是个json对象\"cpu\": 1, //cpu个数 ,若没有则写0\"mem\": \"4068Gi\", //内存大小,单位必须是Gi,若没有则传0Gi,单位仅支持K,M,G,T,P,Ki,Mi,Gi,Ti,Pi这几种,其他一律视为无效数据\"disk\": \"10086002Gi\", //存储容量,单位必须是Gi\"type\": \"hdd\", //磁盘类型,在创建云盘的时候需要传递,枚举类型hdd、ssd\"<key>"\: \"<value>\", //这里也可以是其他的规格类型kv组合}","eventId": "UUID", //为这个事件创建一个唯一的id,一定要有,与实例无关,每个事件的eventId都应该不一样,一样的就会被认为是重复数据"labels":"{}", //资源自定义的标签,是个字符串,没有就给{}"userId": 3, //创建人ID,A用户创建资源给B用户,这里面的userId写成A用户的ID"tenantId": 10, //A用户给B租户创建资源,这里写成B租户"projectId": 4, //A用户给B租户创建资源,这里写成B项目"region": "hnc", //资源申请时选择的区域,如果没有就不传。"cate" : "rds" // 枚举类型h3-virtual,h3-ebs,hw-virtual,hw-ebs,rds,redis,mongo,s3}}method,payload,occurTime,chargeId,uuid,eventId,tenantId,projectId,cate字段为必须且不可为空。
产品与cate字段的映射关系
| 产品 | cate |
|---|---|
| 多云主机 | h3-virtual, hw-virtual |
| 云硬盘 | ebs |
| RDS | rds |
| redis | redis |
| mongo | mongo |
| 裸金属 | bms |
| 容器 | container |
对于EXCHANGE的定义,需要所有人在声明时保持一致,否则声明那一步会失效ch.ExchangeDeclare(``exchange, ``//exchange name,名字``"fanout"``, ``//kind,类型,固定使用fanout``true``, ``//durable,持久化``false``, ``//autoDelete,自动删除``false``, ``//internal,是否为内置的``false``, ``//noWait,是否等待``nil) ``//args,扩展参数
前端获取组合规格列表接口返回格式供用户筛选
GET /api/billing/extern/specgroups?action=create&product=rds&parent=c1.g2.s3.twe (给前端调用)
注:对于云硬盘这个规格,在产品设计上属于连续规格,用户是手动填写的而不是选择套餐,因此需要前端判断下用户手动填写的值落在了哪个规格范围内, 详见params.specRange字段。此时params参数的长度一定是1.
action参数代表选择规格时正在执行的动作,枚举值为create/upgrade/downgrade,分别对应创建资源,升配资源,降配资源 parent参数用于有二级规格的情况,期望传入上级规格的name product为产品标识cate
{"dat": [{"id": 3, //对应chargeId,可能为0,对于计费系统0有特殊含义"groupId": 4,"name": "s3.sadlkfj.sdldfkj.sadlfkj","policyId": 1,"product": "rds","inner": 0, //0代表离散型规格, 1代表连续型"period": 3600, //计费周期,单位秒"price": 12.3, //对于离散型规格,计费周期内的单价,当前版本可忽略,因为不需要预算。"initPrice": 11.2, //对于连续型规格,计费周期内的单价"increasePrice": 0, //对于连续行规格,计费周期内的初始价格"specContent": "QPS:3000|Buffer:2", //前端展示的规格内容"params": [{ //组合规格中多个单项规格的列表"specName": "QPS", //规格名称,例如CPU(核),存储空间(G)这样"specIdent": "qps", //规格英文标识,代码用,需提前约定好"specValue": 200, //规格值,如果是cpu这种离散型规格,就取这个值"specRange": [1, 100], //规格范围,如果是云盘空间这种连续型的规格,需要取specRange的值//总体上,可以判断specRange字段是不是null,是null就取specValue, 不是null就取specRange,//对于specRange,第0个元素是最小值,第1个元素是最大值,例如[1,100]就代表了>=1且<100//对于连续型的规格,需要业务方在用户选取时判断这个值处于哪个规格的范围内,成本中心会保证连续型值的范围不会出现重叠。},{},{}]},{}],"err": ""}
后端根据id获取单个套餐详情
GET /v1/billing/specgroups?chargeId=3&groupId=10 (给后端调用)
Header: X-SRV-TOKEN: billing-builtin-token (后端调用时需要)
{"dat": {"id": 3, //对应chargeId,可能为0,对于计费系统0有特殊含义"groupId": 4,"policyId": 1,"product": "rds","inner": 0, //0代表离散型规格, 1代表连续型"period": 3600, //计费周期,单位秒"price": 12.3, //对于离散型规格,计费周期内的单价,当前版本可忽略,因为不需要预算。"initPrice": 11.2, //对于连续型规格,计费周期内的单价"increasePrice": 0, //对于连续行规格,计费周期内的初始价格"params": [{ //组合规格中多个单项规格的列表"specName": "QPS", //规格名称,例如CPU(核),存储空间(G)这样"specIdent": "qps", //规格英文标识,代码用,需提前约定好"specValue": 200, //规格值,如果是cpu这种离散型规格,就取这个值"specRange": [1, 100], //规格范围,如果是云盘空间这种连续型的规格,需要取specRange的值//总体上,可以判断specRange字段是不是null,是null就取specValue, 不是null就取specRange,//对于specRange,第0个元素是最小值,第1个元素是最大值,例如[1,100]就代表了>=1且<100//对于连续型的规格,需要业务方在用户选取时判断这个值处于哪个规格的范围内,成本中心会保证连续型值的范围不会出现重叠。},{},{}]},"err": ""}
后端获取组合规格列表接口返回格式供用户筛选
GET /v1/billing/specgroups/list?action=create&product=rds&parent=c1.g2.s3.twe (给后端调用)
注:对于云硬盘这个规格,在产品设计上属于连续规格,用户是手动填写的而不是选择套餐,因此需要前端判断下用户手动填写的值落在了哪个规格范围内, 详见params.specRange字段。此时params参数的长度一定是1.
action参数代表选择规格时正在执行的动作,枚举值为create/upgrade/downgrade,分别对应创建资源,升配资源,降配资源 parent参数用于有二级规格的情况,期望传入上级规格的name product为产品标识cate
{"dat": [{"id": 3, //对应chargeId,可能为0,对于计费系统0有特殊含义"groupId": 4,"name": "s3.sadlkfj.sdldfkj.sadlfkj","policyId": 1,"product": "rds","inner": 0, //0代表离散型规格, 1代表连续型"period": 3600, //计费周期,单位秒"price": 12.3, //对于离散型规格,计费周期内的单价,当前版本可忽略,因为不需要预算。"initPrice": 11.2, //对于连续型规格,计费周期内的单价"increasePrice": 0, //对于连续行规格,计费周期内的初始价格"specContent": "QPS:3000|Buffer:2", //前端展示的规格内容"params": [{ //组合规格中多个单项规格的列表"specName": "QPS", //规格名称,例如CPU(核),存储空间(G)这样"specIdent": "qps", //规格英文标识,代码用,需提前约定好"specValue": 200, //规格值,如果是cpu这种离散型规格,就取这个值"specRange": [1, 100], //规格范围,如果是云盘空间这种连续型的规格,需要取specRange的值//总体上,可以判断specRange字段是不是null,是null就取specValue, 不是null就取specRange,//对于specRange,第0个元素是最小值,第1个元素是最大值,例如[1,100]就代表了>=1且<100//对于连续型的规格,需要业务方在用户选取时判断这个值处于哪个规格的范围内,成本中心会保证连续型值的范围不会出现重叠。},{},{}]},{}],"err": ""}
成本中心MIS配置页测试地址:http://10.190.12.88:8016/bill/spec
联调测试地址
推送rdb的demo git地址:http://公司的git域名/ecmc/rabbitmq-product-demo/blob/master/rdb_rabbitmq-product.go
rabbitMQ测试联调地址: amqp://admin:admin_202009@10.178.24.110:8002/dcloud
计费使用EXCHANGE: DCLOUD_EVENT_EXCHANGE
计费接口联调地址:http://10.86.76.13:8035
