0. 术语解释
坐席:客服
1. 场控指标中心定位
场控指标中心还充当数据中心的作用,提供实时数据监控看板的数据源来源,为其他外部系统系统提供RPC查询接口,例如统一路由需要查询坐席状态,为坐席安排IM会话or电话会话。 为呼叫中心两大核心能力,电话通信,IM通信提供实时数据查看能力。
场控需要监控的指标多达成百上千,每个指标底层的数据结构都不同,每个指标在redis里面存储的key也不同,所以需要设计一套模型来支撑成百上千个指标更新,删除,查询。
2. 明确需要的Redis数据类型
坐席休息列表
某个业务线下坐席休息列表,该指标的意思是某个业务线下处于休息状态的坐席列表。他是一个集合,集合下面存储的是忙碌的坐席信息。所以他需要用到的数据结构是 HASH,save命令是 HSET , query命令是 HGET,del命令是 HDEL。
key是 im:agent:agentRestList:businessLineId (businessLineId是业务线Id)
field 是 agentNum(坐席号)
value 是 businessLineId 业务线下 处于 忙碌状态的 坐席信息
save指标命令:
假如 32183821 业务线下的坐席( 坐席号是 12345 )从其他状态切换为休息状态,调用命令 HSET im:agent:agentRestList:32183821 12345 toJsonString(坐席信息), 表示把坐席加入到32183821业务线下坐席忙碌列表
del指标命令:
假如 32183821 业务线下的坐席( 坐席号是 12345 )从休息状态切换到其他状态,调用命令
HDEL im:agent:agentRestList:32183821 12345, 表示把坐席(12345)从32183821业务线下坐席忙碌列表移除
query指标命令:
假如 查询 32183821 业务线下的坐席列表,调用命令 HGETALL im:agent:agentRestList:32183821 表示查询 32183821 业务线下所有忙碌坐席列表。
坐席休息总人数
某个业务线下坐席休息人数,该指标的意思是某个业务线下面处于休息状态的坐席数量。我们可以看到这个指标只需要对上面的休息坐席列表求长度,所以需要用到的数据结构是 HASH,命令是 HLEN。
假如查询 业务线 32183821 下面的忙碌坐席人数。HLEN im:agent:agentRestList:32183821
坐席休息次数
某个业务线下某个坐席的休息次数,该指标的意思是某个业务线下某个坐席今天一共休息的次数。那么它需要用到的数据结构是 HASH,save指标需要用到的命令是 HINCRBY,query指标用到的命令是 HGET
key 是 im:agent:agentRestCount:businessLineId
field 是 agentNum (坐席号)
value 是 某业务线下某坐席当天的休息次数。
save指标
假如业务线下 32183821 的坐席( 坐席号是 12345 )切换为休息状态,那么 该坐席今天的休息次数 + 1,调用命令 HincrBy im:agent:agentRestCount:32183821 12345 1
query指标
假如查询业务线下 32183821 的坐席( 坐席号是 12345 )的休息次数, 调用命令
HGET im:agent:agentRestCount:32183821 12345
坐席单次休息时间
某个业务线下某个坐席的单次休息时间,该指标的意思是某个业务线下某个坐席单次休息的时间,save指标命令 HSET,query指标命令 HGET
key是 im:agent:agentSingleRestTime:businessLineId (businessLineId是业务线Id)
field 是 agentNum(坐席号)
value 是 businessLineId 业务线下 坐席 单次休息时间
save指标命令:
假如现在 32183821 业务线下的坐席(12345) 单次休息时长达到 30 分钟, 那么调用命令
HSET im:agent:agentSingleRestTime:32183821 12345 30
query指标命令 假如现在 需要查询 32183821 业务线下的坐席(12345) 单次休息时长
HGET im:agent:agentSingleRestTime:32183821 12345 得到结果
总结
综上,涉及到的数据结构主要是 HASH,涉及到的命令是 HDEL,HGET,HINCRBY,HSET,HGETALL......
3. 引入占位符
我们可以观察一下上面提到的几个指标:
key : im:agent:agentRestList:businessLineId -> 坐席休息列表
im:agent:agentRestCount:businessLineId -> 坐席休息次数
im:agent:agentSingleRestTime:businessLineId -> 坐席单次休息时长
我们可以看到,他们结构基本上一样,除了指标名字不同 也就是 agentRestList agentRestCount agentSingleRestTime不同。
同时,涉及到业务线维度 也会引起key的改变,
比如 12345 业务线下的 坐席休息列表,他的key是 im:agent:agentRestList:12345
比如 54321 业务线下的 坐席休息列表,他的key是 im:agent:agentRestList:54321
抽取这些改变的部分,那么我们可以把key简化为 im:agent:#metricsName#:#businessLineId#, 你可以理解为 ## 包括的部分就是需要动态改变的地方,这应该是一个指标的固有属性,属于指标元信息的一部分,也就是该指标在redis里面怎么存储。
假如其他系统需要查询 32183821 业务线下的坐席休息列表,那么他需要传的参数就是
- 指标名字 : agentRestList
- 业务线 : 12345
{
"metricsName": "agentRestList",
"params": {
"businessLineId": "32183821"
}
}
我们的处理流程应该是 根据指标名字 : agentRestList 查询到该指标的元信息,里面规定了 keyTemplate (im:agent:#metricsName#:#businessLineId#),那么根据
{
"metricsName": "agentRestList",
"params": {
"businessLineId": "32183821"
}
}
key会根据keyTemplate 就会被替换为 im:agent:agentRestList:32183821, 这个key在redis里面存储的就是 32183821 业务线下面的 坐席休息列表,也就是通过命令 HGETALL im:agent:agentRestList:32183821 就能拿到 32183821 业务线下面所有休息的坐席列表。
再举个例子:
指标坐席休息次数,他的 keyTemplate 也是 im:agent:#metricsName#:#businessLineId#, filedTemplate 是 #agentNum#
假如其他系统需要查询 32183821 业务线下 坐席(坐席号12345) 的休息次数,那么他需要传的参数是
{
"metricsName": "agentRestCount",
"params": {
"businessLineId": "32183821",
"agentNum": "12345"
}
}
那么 key根据keyTemplate 会被转化为 im:agent:agentRestCount:32183821, field根据fieldTemplate 会转化为 12345,然后通过命令 HGET im:agent:agentRestCount:32183821 12345 就获得了32183821 业务线下 坐席(坐席号12345) 的休息次数
4.redis命令路由
每种指标save,del,query的命令都不同,所以每个指标该使用什么命令也是指标的固有属性,也属于是指标的元信息。
然后我们系统会根据某个指标的执行命令,通过策略模式将他路由到具体的redis命令执行器去执行。
5.指标元信息最终
坐席休息次数
{
"id": 1,
"metricsName": "agentRestCount",
"metricsQueryMeta": {
"fieldTemplate": "#agentNum#",
"keyTemplate": "im:agent:#metricsName#:#businessLineId#",
"queryCommand": "HGET"
},
"metricsSaveAndDelMeta": {
"fieldTemplate": "#agentNum#",
"keyTemplate": "im:agent:#metricsName#:#businessLineId#",
"saveCommand": "HINCRBY"
}
}
例如 32183821 业务线下 坐席(坐席号12345),从其他状态切换为休息状态。那么首先会拿到指标 - 坐席休息次数的元信息,然后取 metricsSaveAndDelMeta,key 根据 im:agent:#metricsName#:#businessLineId# 替换为 im:agent:agentRestCount:32183821, filed 根据 #agentNum# 替换为 12345
最后调用命令 HINCRBY im:agent:agentRestCount:32183821 12345 1
上面这个逻辑是由MQ触发的,场控更新指标的逻辑都是由MQ触发,也就是场控是一套事件驱动的监控告警平台,特点是实时性极高
假如其他系统需要查询 32183821 业务线下 坐席(坐席号12345)的休息次数,那么他需要传的参数是:
{
"metricsName": "agentRestCount",
"params": {
"businessLineId": "32183821",
"agentNum": "12345"
}
}
那么首先会拿到指标 - 坐席休息次数的元信息,然后取 metricsQueryMeta,key 根据 im:agent:#metricsName#:#businessLineId# 替换为 im:agent:agentRestCount:32183821, filed 根据 #agentNum# 替换为 12345
最后调用命令 HGET im:agent:agentRestCount:32183821 12345 就可以得到 32183821 业务线下 坐席(坐席号12345)的休息次数。