简介这份文档面向电信业务支撑系统与计费领域的开发、运维及系统设计人员围绕OCS在线计费系统的计费原理与实现展开帮助读者建立从概念到落地的完整认知。内容从计费系统由离线批量向实时处理的演进讲起梳理TAG、业务用量、费用项、产品、订购、入帐关系等核心名词再深入事件捕获、事件处理、账单生成与结算的计费流程并介绍计费引擎、数据库、消息中间件等实现组件及安全机制。资源包内共1个doc文件约1.87MB为排版后的技术文档结构清晰、便于按章节查阅。目前已有297人学习下载适合需要理解实时计费业务逻辑、优化计费流程或进行系统设计参考的从业者阅读。1. OCS计费为什么一次通话能同时扣三种费用你打了一通5分钟的电话运营商怎么知道该从哪个账户扣钱更诡异的是同一通电话可能同时产生本地通话费、长途费、漫游费三笔账目分别从不同账户里扣除。这不是简单的“通话时长×费率”能解释的。OCS在线计费系统要解决的核心问题是在用户通话进行中实时判断余额够不够、该从哪些账户扣、按什么费率扣、扣多少。它不像离线计费那样事后算总账而是要在几百毫秒内完成一次“请求-计算-授权-扣费”的闭环。这套机制背后是一套从“原始计费”演进到“事件驱动模板化定价”的完整体系。搞懂它你就理解了电信计费从“一张费率表打天下”到“多业务实时融合”的底层逻辑。2. 从两张表到事件驱动计费系统到底在演进什么2.1 原始计费时代反算时长与欠费风险控制最早的计费系统只做一件事根据主被叫号码查费率然后扣钱。它用两张表就够了——用户表存余额费率表根据主被叫归属地、拜访地号码头查费率。但预付费业务有个致命问题用户打电话时余额不够怎么办这套系统用了一个叫“反算”的机制。用户发起呼叫前计费系统先根据余额算出可通话时长把时长返回给呼叫控制系统去监控。通话结束后呼叫监控系统上报实际通话时长再真正扣费。这就是最早的实时计费与欠费风险控制——先授权时长后扣费。这个阶段的问题很明显一个地区多个号段主被叫归属地、拜访地四个维度组合费率表记录数爆炸。局方每改一次费率要分析每个调整地区涉及的记录修改情况极不直观修改量大容易出错。2.2 简单计费时代号码分析与计费矩阵的分离为了解决费率表膨胀问题系统把查找费率拆成三步。第一步号码分析根据主被叫归属地、拜访地号码头得到主被叫归属地区号、拜访地区号把一个地区的多个号段归一。第二步计费矩阵把一次呼叫分成基本费、漫游费、长途费三种消费对应不同的费率索引ChargeClass根据地区号获得对应的消费类别费率列表。第三步费率表专门描述费率被计费矩阵引用。这个设计的精妙之处在于“抽离”。费率从计费中抽离出来局方改费率只需改费率表几条记录号码分析抽离出来新增号段只需在号码分析表配置。系统可维护性有了质的飞跃。2.3 复杂计费时代账户抽象与分档费率移动用户增长到一定程度后简单降价不能吸引入网。运营商开始用多元销售手段消费积分、专款专销、充值优惠、越打越便宜。原来的系统撑不住了。改造分三步。首先把计费系统一分为二实时计费模块负责每次呼叫的费率计算定期事务模块负责赠送和扣月租。其次把用户余额抽象成“账户”单独建表可以定义多种账户类型存放不同余额——长途免费通话时长、市话免费通话时长、充值赠送金额、累计消费金额。再次增强实时计费ChargeClass从纯粹费率索引扩展为“消费类别”定义消费类别只能在哪些账户上扣、入账优先级关系、费率。费率表扩展成多个分档实现越打越便宜。这一步实现了专款专销和消费累积。但到了3G时代业务内容越来越丰富这套系统又吃力了。2.4 OCS计费时代业务用量、计费事件与定价计划3G带来的挑战是根本性的。计费请求内容日趋复杂需要“一卡多用”——同一用户同时支持多种业务消费而原来的欠费风险机制一个账户同时只能被一个业务使用。计费请求单位不再只是呼叫时长还有短信条数、GPRS流量、ADSL上网流量、直接扣款金额。一次计费请求中可能包含多种消费既通话又视频。套餐推出越来越快原有系统调整ChargeClass的方式极不直观。后付费和预付费需要融合。OCS的改造思路是彻底抽象。把“消费类别”进一步抽象成“业务用量”包含两方面意思消费的业务是什么消费的量是多少。20分钟长途费消费、2M的GPRS流量消费都是业务用量。新增一种计费请求消费类别很容易扩展。把每种计费请求抽象成“计费事件”影响计费的参量抽象成“计费要素”。每种计费事件包含不同的计费要素和求解过程。新增计费请求种类只需新加代码不修改原有实现修改是“线性”的。把iUser-bill和iCharge融合它们仅仅是实现不同的计费功能。定期事务实现的是定期事务的计费能力iCharge实现的是根据业务用量进行批价的能力。这些计费能力抽象成可复用的功能模块叫“模板”或“策略模板”。定期赠送话费的计费能力做成“赠送模板”赠送内容做成参数呼叫提供按业务用量的计费模板费率和适配条件作为参数。每一次优惠活动和新套餐抽象成“定价计划”。定价计划通过调用多个模板实现新的资费优惠数据。比如“20元套餐赠送300分钟市话通话时长、200条网内短信、所有省内漫游低至1毛/分钟”可以调用赠送模板赠送内容参数配置成300分钟市话通话时长、200条网内短信调用呼叫计费模板传入费率参数1毛/分钟适配条件省内漫游。预先定义一系列不同计费能力的模板局方推出活动时只需新定义一个定价计划来调用这些模板。注意要在现网快速推出活动修改需要具有可测试性和兼容性。新增定价计划仅仅是新增数据不影响现有特性。采用订购方式用户只有订购上该定价计划才能享受优惠测试时只需将测试用户订购上不影响其他用户。后付费和预付费的统一靠的是业务用量类型划分请求业务用量、已使用业务用量、授权业务用量。预付费用户使用前业务控制系统发起计费请求传入请求业务用量大小。如果账户余额足够返回授权业务用量等于请求业务用量不够则根据余额计算授权业务用量。业务控制系统根据授权业务用量控制消费。后付费使用完成后将话单包含的业务使用量作为已使用业务用量系统根据已使用业务用量批价入账。批价入账动作对预付费和后付费完全一致局方推出的所有优惠资费及活动对后付费预付费都可以适用。通过预付费用户进行“请求”可使用消费量的方式实现一卡多用。用户有10元钱A业务发出呼叫5分钟请求需要消费1元还有9元可用同时B业务发起200M流量请求可以被响应。不像原先系统一定要等A业务呼叫完成B业务才能消费。3. 批价引擎一次呼叫如何算出三笔账3.1 业务识别从呼叫事件到业务用量批价的第一步是业务识别。当计费事件到达系统需要判断这次消费涉及哪些业务用量。以主叫呼叫为例系统会分析主叫是否有漫游、是否拨打长途。如果主叫漫游时拨打被叫长途5分钟那么基本费业务用量、长途费业务用量、漫游费业务用量都是300秒。如果用户没有漫游漫游业务用量为0秒。这些业务用量类别是设计时规划好的。在广东OCS中呼叫流程主叫子流程划分了5个业务用量用量名称TAG备注基本费时长2003长途费时长2005漫游费时长2004被叫漫游长途时长2311未用附加费业务量2317未用TAG即变量可以理解为原先SER中的CID。和CID不一样的是在CHG侧一般喜欢用数值来描述TAG而不喜欢像CID变量一样用名称描述。我们常常称TAG 1080存放SCP请求的呼叫时长值是300而不会说变量REQUIRED_CALL_DURATION值是300。业务识别的本质是把一次原始计费事件拆解成多个标准化的业务用量。每个业务用量有明确的TAG标识和数值。这个拆解过程由计费事件对应的计费要素求解过程完成。新增一种计费事件只需要定义它的计费要素和求解过程不需要修改已有事件的识别逻辑。3.2 批价处理费用项链表的生成业务识别完成后进入批价处理。批价的核心任务是对每个业务用量根据用户订购的定价计划计算出对应的费用项。费用项即消费明细可以理解为消费清单。批价完成之后会输出一系列费用项条目作为入账的输入。CBE依据此消费清单入到各种账户上把相关金额扣除。在广东版本中针对主叫呼叫设计了如下费用项1|本地通话费用项、2|漫游通话费用项、3|长途通话费用项。一次批价所输出的费用项采用链表方式实现记录此次计费流程业务用量的消费明细。假设主叫漫游时拨打被叫长途5分钟市话费率1毛1分钟、长途费率2毛1分钟、漫游费率3毛1分钟。费用项链表如下业务用量数值金额分费用项2003|基本费时长300501|本地通话费用项2005|长途费时长3001003|长途通话费用项2004|漫游费时长3001502|漫游通话费用项这个链表结构的设计意图很明确每个业务用量独立计算费用生成独立的费用项。费用项之间没有耦合可以分别入到不同的账户。入账关系说明消费明细应该在哪个账户上扣。比如本地通话费用项从基本账户扣长途通话费用项从长途免费通话时长账户扣漫游通话费用项从充值赠送金额账户扣。批价处理的核心逻辑可以用伪代码表示def rating(event): # 业务识别拆解计费事件为业务用量列表 usage_list identify_usage(event) # 初始化费用项链表 charge_items [] # 对每个业务用量独立批价 for usage in usage_list: # 查找用户订购的定价计划 pricing_plan get_pricing_plan(event.user, usage.type) # 调用定价计划中的计费模板 # 模板包含费率、适配条件、分档规则 amount pricing_plan.calculate(usage) # 生成费用项挂入链表 charge_items.append({ usage_tag: usage.tag, usage_value: usage.value, amount: amount, item_type: pricing_plan.item_type }) return charge_items这段逻辑的关键在于每个业务用量的批价是独立的但共享同一个定价计划体系。定价计划通过调用多个模板实现资费优惠。模板是可复用的计费能力模块费率和适配条件作为参数传入。新增套餐时只需新定义一个定价计划来调用已有模板不需要修改批价引擎代码。3.3 入账从费用项到账户扣款批价输出费用项链表后进入入账环节。入账关系定义了消费明细应该在哪个账户上扣。系统根据费用项的类型查找对应的入账关系确定目标账户和扣款优先级。入账的核心逻辑是对每个费用项按照入账关系找到目标账户列表按优先级依次扣款。如果第一个账户余额不足自动扣第二个直到费用项金额扣完或所有账户余额耗尽。这个机制实现了专款专销。长途通话费用项只能从长途免费通话时长、充值赠送金额、基本金额中扣取优先级是先扣长途免费通话时长扣完后从充值赠送金额、基本金额扣取。市话通话费用项只能从市话免费通话时长、基本金额中扣取。不同费用项的入账关系相互独立互不干扰。预付费和后付费在入账环节完全一致。区别只在于预付费是实时请求-授权-扣费后付费是事后话单批价入账。预付费批价入账之后只需要出话单后付费需要出账单、账单邮寄、欠费自动催缴等特性。4. 充值、月结与回赠定期事务的计费能力复用4.1 充值流程预处理与模板说明充值流程是OCS的另一类典型计费事件。用户充值100元系统需要完成预处理、批价、入账。预处理部分负责校验充值请求的合法性比如充值卡号是否有效、用户是否存在、充值金额是否在允许范围内。批价部分根据充值优惠策略计算实际到账金额。入账部分把金额加到用户账户。充值优惠是常见的营销手段比如充100送40分几个月赠送。这个需求通过赠送模板实现。赠送模板是一种计费能力模块赠送的内容做成参数。充值流程调用赠送模板传入赠送金额、赠送时间、分月赠送规则等参数。模板负责生成定期事务在指定时间把赠送金额入到指定账户。模板的设计意图是复用。赠送话费、赠送流量、赠送短信条数底层逻辑都是“在指定时间把指定资源入到指定账户”。把这些共性抽象成模板新增赠送活动时只需配置参数不需要开发新代码。4.2 月结流程定期事务的批量处理月结是定期事务模块的典型场景。每天后台自动执行检查需要赠送多少钱到哪个账户如果是月结需要扣取月租。月结流程的核心是批量处理扫描所有用户根据用户订购的定价计划判断是否需要执行月结操作。月结流程与呼叫流程的区别在于触发方式。呼叫流程由用户行为触发实时性要求高月结流程由定时任务触发批量处理对实时性要求低。但两者共享同一套计费能力模块——模板。月结调用扣月租模板传入月租金额、扣款账户、扣款优先级等参数。模板负责执行扣款动作。4.3 回赠消费累积与奖励发放回赠是消费积分制度的实现。用户消费到一定程度系统对用户进行奖励赠送鼓励继续消费。回赠流程需要累计用户的消费金额或消费次数达到阈值后触发赠送。累计项处理是回赠的基础。系统需要记录用户的累计消费金额、累计通话时长、累计短信条数等。这些累计项存储在用户账户的扩展属性中。每次计费事件完成后更新对应的累计项。当累计项达到阈值触发回赠模板生成赠送事务。回赠模板与赠送模板类似区别在于触发条件。赠送模板由充值或月结触发回赠模板由累计项阈值触发。两者都调用相同的底层入账能力把资源入到指定账户。5. 避坑OCS计费配置中容易翻车的几个点5.1 业务用量TAG配错导致费用项缺失现象用户通话后账单上只有本地通话费用项没有长途费用项但用户确实拨打了长途。原因业务识别阶段长途费时长的TAG配置错误或者计费事件的计费要素求解过程没有正确输出长途业务用量。系统在批价时找不到对应的业务用量自然不会生成长途费用项。解决检查计费事件的计费要素配置确认长途费时长的TAG与业务用量定义一致。用测试用户发起一次长途呼叫抓取批价日志确认业务用量列表中包含长途费时长。5.2 入账关系优先级配反导致扣错账户现象用户有长途免费通话时长但通话后基本账户被扣了钱免费时长没动。原因入账关系中长途通话费用项的扣款优先级配置错误基本账户的优先级高于长途免费通话时长账户。解决检查入账关系配置确认长途通话费用项的目标账户列表中长途免费通话时长账户的优先级最高。修改后用测试用户验证扣款顺序。5.3 定价计划未订购导致批价失败现象用户通话后没有产生费用项批价日志显示“未找到匹配的定价计划”。原因用户没有订购对应的定价计划。OCS采用订购方式用户只有订购上该定价计划才能享受优惠资费。测试时如果忘记给测试用户订购批价就会失败。解决检查用户的订购关系确认已订购对应的定价计划。测试新套餐时先将测试用户订购上再发起呼叫验证。5.4 分档费率边界条件配错导致越打越贵现象用户通话头3分钟4毛/分钟后10分钟应该2毛/分钟但实际后10分钟还是4毛/分钟。原因费率表的分档配置中分档的边界条件设置错误。比如第一档的结束时间配置成了0秒或者第二档的起始时间配置成了0秒导致分档逻辑没有正确切换。解决检查费率表的分档配置确认第一档的结束时间等于第二档的起始时间且时间单位一致。用测试用户发起一次超过第一档时长的呼叫验证分档费率是否正确切换。5.5 累计项未更新导致回赠不触发现象用户消费金额已达到回赠阈值但没有收到赠送。原因累计项处理逻辑没有正确更新用户的累计消费金额。可能是计费事件完成后更新累计项的步骤被跳过或者累计项的更新条件配置错误。解决检查累计项处理配置确认每次计费事件完成后都会更新对应的累计项。用测试用户发起多次消费观察累计项数值是否递增达到阈值后是否触发回赠。6. 设计取舍为什么OCS选择模板化定价而不是硬编码OCS的模板化定价体系本质上是在“灵活性”和“性能”之间做了一次取舍。硬编码费率逻辑性能最好但每次推出新套餐都要改代码、测试、上线周期长风险高。模板化定价把计费能力抽象成可复用的模块新增套餐只需配置数据不改代码。代价是批价时需要动态查找定价计划、匹配模板、解析参数性能开销比硬编码大。这个取舍在电信计费场景下是合理的。电信套餐变化频繁推出速度是核心竞争力。硬编码的交付周期以月计模板化配置以天计。性能开销可以通过缓存定价计划、预编译模板参数来优化。而且OCS的计费请求量虽然大但单次批价的计算复杂度可控模板化带来的额外开销在可接受范围内。另一个取舍是业务用量与费用项的分离。业务用量描述“消费了什么、消费了多少”费用项描述“该收多少钱、从哪个账户扣”。两者分离的好处是业务识别和批价处理可以独立演进。新增一种业务用量不影响已有费用项的计算逻辑新增一种费用项不影响已有业务用量的识别逻辑。代价是系统需要维护两套映射关系——业务用量到费用项的映射、费用项到账户的映射。映射关系配置错误就会出现前面提到的避坑场景。从源码实现角度看OCS的批价引擎通常采用责任链模式。计费事件到达后依次经过业务识别链、批价处理链、入账处理链。每个链由多个处理器组成每个处理器负责一个具体的计费能力。新增计费能力时只需在对应链上添加一个处理器不修改已有处理器。这种设计实现了“线性修改”——新增功能不影响已有功能符合OCS对兼容性和可测试性的要求。我一般会这么理解OCS的模板化定价它把计费系统从“写死的逻辑”变成了“可编排的规则”。模板是积木定价计划是图纸批价引擎是装配线。局方推出新套餐就是画一张新图纸用已有的积木拼出新组合。装配线不用改积木不用改只改图纸。这就是OCS能快速响应市场变化的底层原因。从那以后我每次看计费系统的配置都强制走一遍“业务用量→费用项→入账关系”的链路确认每一环的映射都正确。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?