文章目录
- 背景介绍
- 整体需求
- 整体流程
- 数据结构
- 强平流程日志表(liq_flow_log)
- 强平请求日志表(liq_request_log)
- 强平步骤日志表(liq_step_log)
- 强平过程中永续活动订单日志表(lip_perp_order_log)
- 强平过程中永续仓位日志表(liq_perp_position_log)
- 强平过程中期权活动订单日志表(liq_option_order_log)
- 强平过程中期权仓位日志表(liq_option_position_log)
- 强平过程中RPC调用日志表(liq_rpc_invoke_log)
- 强平过程中RPC被调用日志表(liq_rpc_invoked_log)
- 强平过程中消息队列发送日志表(liq_message_send_log)
- 强平过程中消息队列接收日志表(liq_message_receive_log)
- 强平过程中强平核心类方法调用日志表(liq_method_invoke_log)
- 强平流程统计表(liq_flow_stat)
- 强平请求统计表(liq_request_stat)
- 强平步骤统计表(liq_step_stat)
- 强平过程中永续活动订单丢失统计表(liq_perp_order_stat)
- 强平过程中永续仓位丢失统计表(liq_perp_position_stat)
- 强平过程中期权活动订单丢失统计表(liq_perp_order_stat)
- 强平过程中期权仓位丢失统计表(liq_perp_position_stat)
- 强平过程中RPC调用统计表(liq_rpc_invoke_stat)
- 强平过程中RPC被调用统计表(liq_rpc_invoked_stat)
- 强平过程中消息队列发送统计表(liq_message_send_stat)
- 强平过程中消息队列接收统计表(liq_message_receive_stat)
- 强平过程中强平核心类方法调用统计表(liq_method_invoke_stat)
- 强平过程中账户资金丢失统计表(liq_account_stat)
- 非强平主流程日志(other_log)
- 模块功能
- 日志写入
- 日志查询
- 日志统计
- 统计比较
- 强平报警
- 流程还原
- 日志清理
- 日志开闭
- 强平流程总耗时太长,返回码异常,调用频率异常
- 强平请求总耗时太长,返回码异常,调用频率异常
- 强平每个请求间停留时间太长
- 强平步骤(每个状态)总耗时太长,返回码异常,调用频率异常
- 强平每个步骤间停留时间太长
- 强平过程中RPC调用总耗时太长,返回码异常,调用频率异常
- 强平过程中RPC被调用总耗时太长,返回码异常,调用频率异常
- 强平步骤中强平核心类方法总耗时太长,返回码异常,调用频率异常
- 强平路线异常(也就是状态变迁异常)
- 强平用户和接管户资金对账异常
- 价格大幅波动(比如一分钟时间窗口内最大值比当前值超过1%,或者当前值比最小值超过1%)
- 组合保证金模式下,用户下单成交后立即被强平(暂时无法监控)
- 接管户被创建多次异常(暂时无法监控,运营平台可以做幂等)
- 报警收敛
- 智能修复
- 容量估算
- 实施步骤
- 任务评估
- 编程方式
- FAQ
背景介绍
-
强平无效日志太多
- 强平产生日志量大,写入性能损耗大,日志存储空间大,机器不堪重负。
- 强平大部分日志为无效日志,比如检测程序每秒钟每个账户打印一次,循环频率高造成干扰。
- 强平单行日志有很多字段不是必备,或者说跟强平服务没有必然关系,比如已结盈亏,未结盈亏,结算货币。
- 强平产生大量文本和不合理的日志记录,不仅没有带来效率提升,反而是一个阻碍,从几百兆的文本日志里查找有价值的关键错误信息对任何人都是一个很大的挑战,更别说效率了。
-
强平关键日志太少
- 强平有效日志不超过10%,关键信息缺少,开发运维定位排查问题的难度非常大。
- 强平该打印的日志行没有打印,比如缺少强平流程执行前后的仓位状态,缺少流程每个步骤前后的仓位状态。
- 强平该打印的日志字段没有打印,比如缺少强平步骤前后的指数价和标记价。
-
强平对账困难
- 强平日志行缺乏,导致强平账户,接管户,资金池,对账困难。
-
强平很难复现问题
- 强平日志行缺乏,无法找到日志数据,则无法重现当时的场景,难于静态分析代码,无法本地环境debug跟踪,很多隐藏的bug无法找出来,系统隐患无处不在。
-
强平缺乏tracing功能
- 强平日志字段缺乏,无法还原全流程,或者说还原的全流程是错误的,定位排查问题非常耗时,比如没有指明这行日志属于哪个流程哪个步骤,在同一用户多次强平情况下,无法确认这行日志属于什么时候什么状态下发生的。
-
强平缺乏统计报表
- 强平日志行缺乏,引发无法完整统计指标或统计出错问题,比如开发不知道每个方法的性能,平均耗时,tp99%,一天有多少个异常,耗时大于1秒的调用一天有多少个。问题反馈到开发的时候,开发毫无准备,毫无安全感,不说疲于奔命,离从容应对还差十万八千里。
-
强平缺乏监控报警
- 强平日志行缺乏,日志字段缺乏,以及统计指标缺失,进而引发了监控报警不全或监控报警出错问题。从lark群消息可以看出,无法做到先于用户发现问题,发现问题的时间点严重滞后于端用户。开发运维无法第一时间感知情况下,又会导致信息流转,沟通不畅等成本。
-
强平缺乏自动修复策略
- 强平日志行缺乏,和监控报警缺失,导致系统无法根据异常码,自动尝试启动修复策略。
-
强平日志格式缺乏规范化
- 强平日志格式不统一,有些使用csv风格逗号分割,有些使用json格式,有些使用java方式,还有些通过log4j2提供的占位符方式随意定制格式。
- 强平日志格式不统一,对使用者阅读习惯造成困扰,开发运维提取关键信息困难,搜索效率极其低下,这,比如csv格式要先看代码才知道要找的那个值在第几个分隔符之间,看到一个值后也要查阅对应代码才能知道那个值代表什么。
- 强平日志格式不统一,导致搜索效率极低,比如日志中间件es查询匹配csv格式的账户余额字段困难,不好使,而es查询匹配json格式的账户余额字段则容易清晰很多。
-
强平日志分散
- 强平日志分散,强平服务依赖jraft,切主的时候会把不同流程的日志分散到不同的机器,甚至同一个强平流程的日志也可能分散到不同的机器,查询的时候先去jraft查找,再去对应的机器查找,查询效率低下。
-
强平日志逻辑错误
- 强平日志逻辑错误,日志埋点位置错误,一般是程序上设计的问题,比如程序上有throw new Exception,导致后面的日志无法打印,是不是在throw new Exception的前一行就应当详细记录现场呢?
-
强平太多无效日志问题
- https://confluence.yijin.io/pages/viewpage.action?pageId=71367702
-
强平日志指标缺乏,对账困难,还原生命周期图困难等问题
- https://c1ey4wdv9g.larksuite.com/wiki/wikusJzQYZ8Ag3YwWezvzQOhmCb?wiki_all_space_view_source=space_sidebar
当前日志精简图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-77WRiKFU-1656267188054)(C:/D/workspace/trade/doc/%E6%A6%82%E8%A6%81%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3/5.png)]
当前强平流程图
当前互斥模块流程图
入金和强平是互斥操作,同一时刻只能执行一个,入金的优先级更高,因此保证金服务要想入金需要进行入金申请操作,当前双方处理流程:
整体需求
功能需求
-
收集规则:收集强平过程状态变迁日志
-
日志类别:
-
强平流程日志表:包括强平流程配置,账户状态和性能监控
-
强平步骤日志表:包括强平流程每个步骤的账户状态和性能监控
- 权限判断步骤
- 延时爆仓步骤
- 初始化步骤
- 取消活动单步骤
- 安全降档步骤
- 有损降档部分减仓步骤
- 有损降档永续接管步骤
- 阶梯强平下平仓单步骤
- 阶梯强平转仓给做市商步骤
- 期权接管步骤
- 恢复步骤
-
强平过程中永续活动订单日志:包括合约名称,大小,方向,挂单价格,市场价格
-
强平过程中永续仓位日志
-
强平过程中期权活动订单日志
-
强平过程中期权仓位日志
-
强平过程中RPC调用日志:包括入参,出参,返回码和性能监控
- 永续禁止下单(取消开仓平仓权限)
- 永续取消活动订单
- 期权禁止下单(取消开仓平仓权限)
- 期权取消活动订单
- 永续安全降档processSetRiskId
- 永续有损降档部分减仓processSubPosition
- 永续有损降档永续接管processTakeOver
- 期权接管transferPosition
- 期权接管强平回执发撮合sendCrossMessage
- 期权接管透传回执保险池打钱riskPoolDeposit
- 永续恢复下单(恢复开仓平仓权限)
- 期权恢复下单(恢复开仓平仓权限)
-
强平过程中rpc被调用日志:包括入参,出参,返回码和性能监控
- CANCELED:期权取消活动单回执
- LIQUIDATION:期权接管强平回执,主要是仓位资产处理
- PASS_THROUGH:期权接管透传回执,主要是账户余额处理
- TRADING_RESULT_LIQ_CONVERT:交易结果回执
- PERP_LIQ_CANCEL_ORDER:永续取消开仓活动单回执
- PERP_LIQ_POSITION_PART_LIQ_FILL:永续减仓降档成功回执
- PERP_LIQ_POSITION_PART_LIQ_KILL:永续减仓降档失败回执
- PERP_LIQ_POSITION_TAKE_OVER:永续仓位接管回执
-
强平过程中消息队列发送日志:包括往kafka,rocketmq,springApplicationEvent,disruptor发送的日志
-
强平过程中收日志:包括从kafka,rocketmq,springApplicationEvent,disruptor接收的日志
-
强平过程中方法调用日志:包括入参,出参,返回码和性能监控
-
1号轮OptLiquidationWalContentCmp
-
1号轮TradingResultWalContentCmp
-
1号轮PerpLiquidationWalContentCmp
-
3号轮EnterLiqProcessTradingResultProcessCmp
-
3号轮ManualTakeOverProcessCmp
-
3号轮LiqTradingResultProcessCmp
-
3号轮PassThroughTradingResultProcessCmp
-
3号轮TradingResultLiqConvertProcessCmp
-
3号轮PerpTradingResultLiqCmp
-
3号轮LiqInfoUpdateProcessCmp
-
拦截器TradingResultLiqBizInterceptor
-
EnterLiqProcessServiceTrImpl
-
LiquidationServiceTrImpl
-
PassThroughServiceTrImpl
-
TradingResultLiqConvertServiceTrImpl
-
PerpTradingResultLiqImpl
-
LiqInfoUpdateServiceTrImpl
-
策略机EnterLiqProcessLiqStgCmp
-
策略机CancelOrderLiqStgCmp
-
策略机LiquidationLiqStgCmp
-
策略机PassThroughLiqStgCmp
-
策略机PerpLiquidationStgCmp
-
策略机PerpPartLiqStgCmp
-
策略机PerpTakeOverStgCmp
-
策略机LiqInfoUpdateStgCmp
-
状态机LiqStateMachineService
-
-
-
日志统计:
- 强平流程统计:包括统计年,月,周,日,小时,分钟维度的执行次数,不同异常码次数,平均耗时,TP90,TP95,TP99,TP99.99,
- 强平步骤统计:包括统计年,月,周,日,小时,分钟维度的执行次数和耗时
- 强平步骤中RPC调用统计:包括统计年,月,周,日,小时,分钟维度的执行次数和耗时
- 强平步骤中RPC被调用统计:包括统计年,月,周,日,小时,分钟维度的执行次数和耗时
- 强平步骤中消息队列发送统计:包括统计年,月,周,日,小时,分钟维度的执行次数和耗时
- 强平步骤中消息队列接收统计:包括统计年,月,周,日,小时,分钟维度的执行次数和耗时
- 强平步骤中强平核心类方法调用统计:包括统计年,月,周,日,小时,分钟维度的执行次数和耗时
-
监控报警:
-
grafana或悟空监控强平流程返回码,非0,非200则报警
-
grafana或悟空监控强平流程耗时,大于10秒则报警
-
grafana或悟空监控强平流程调用频次,每分钟总强平数大于1000次则报警
-
grafana或悟空监控强平请求返回码,非0,非200则报警
-
grafana或悟空监控强平请求耗时,大于10秒则报警
-
grafana或悟空监控强平请求调用频次,每分钟总强平数大于1000次则报警
-
grafana或悟空监控强平步骤返回码,非0,非200则报警
-
grafana或悟空监控强平步骤耗时,大于10秒则报警
-
grafana或悟空监控强平步骤调用频次,每分钟总强平数大于1000次则报警
-
grafana或悟空监控强平过程中rpc调用返回码,非0,非200则报警
-
grafana或悟空监控强平过程中rpc调用耗时,大于2秒则报警
-
grafana或悟空监控强平过程中rpc调用频次,每分钟总rpc调用大于10000次则报警
-
grafana或悟空监控强平过程中rpc被调用返回码,非0,非200则报警
-
grafana或悟空监控强平过程中rpc被调用耗时,大于2秒则报警
-
grafana或悟空监控强平过程中rpc被调用频次,每分钟总rpc调用大于10000次则报警
-
grafana或悟空监控强平过程中消息队列发送返回码,非0,非200则报警
-
grafana或悟空监控强平过程中消息队列发送耗时,大于2秒则报警
-
grafana或悟空监控强平过程中消息队列发送频次,每分钟总rpc调用大于10000次则报警
-
grafana或悟空监控强平过程中消息队列接收返回码,非0,非200则报警
-
grafana或悟空监控强平过程中消息队列接收耗时,大于2秒则报警
-
grafana或悟空监控强平过程中消息队列接收频次,每分钟总rpc调用大于10000次则报警
-
grafana或悟空监控强平过程中强平核心类调用返回码,非0,非200则报警
-
grafana或悟空监控强平过程中强平核心类调用耗时,大于2秒则报警
-
grafana或悟空监控强平过程中强平核心类调用频次,每分钟总强平核心类调用大于10000次则报警
-
grafana或悟空监控强平中入金插队行为,
-
grafana或悟空监控强平中交割插队行为
-
grafana或悟空监控强平中其他互斥操作行为
-
grafana或悟空监控接管户资金池数据一致性问题
-
-
动态开闭:
- 开启/关闭强平过程中永续活动订单日志
- 开启/关闭强平过程中永续仓位日志
- 开启/关闭强平过程中期权活动订单日志
- 开启/关闭强平过程中期权仓位日志
- 开启/关闭强平过程中rpc调用日志
- 开启/关闭强平过程中rpc被调用日志
- 开启/关闭强平过程中消息队列发送日志
- 开启/关闭强平过程中消息队列接收日志
- 开启/关闭强平过程中强平核心类方法调用日志
- 开启/关闭强平过程中接管户资金池转账日志
-
日志查询:
- 根据账户id查询有哪些强平流程
- 根据强平流程id查询有哪些强平步骤
- 根据强平流程id和强平步骤id查询强平步骤执行前有哪些永续活动订单
- 根据强平流程id和强平步骤id查询强平步骤执行后有哪些永续活动订单
- 根据强平流程id和强平步骤id查询强平步骤执行前有哪些永续仓位
- 根据强平流程id和强平步骤id查询强平步骤执行后有哪些永续仓位
- 根据强平流程id和强平步骤id查询强平步骤执行前有哪些期权活动订单
- 根据强平流程id和强平步骤id查询强平步骤执行后有哪些期权活动订单
- 根据强平流程id和强平步骤id查询强平步骤执行前有哪些期权仓位
- 根据强平流程id和强平步骤id查询强平步骤执行后有哪些期权仓位
- 根据强平流程id查询强平过程中有哪些rpc调用
- 根据强平流程id查询强平过程中有哪些rpc被调用
- 根据强平流程id查询强平过程中有哪些消息接收
- 根据强平流程id查询强平过程中有哪些消息发送
- 根据强平流程id查询强平过程中有哪些强平核心类方法调用
- 根据强平流程id查询强平过程中接管户资金池转账情况
-
图表展示:
- json文本数据
- 折线图
- 柱状图
- 饼状图
- 流程图:根据强平流程id还原强平流程图
-
统计比较
- 把统计指标和历史数据做对比(环比同比),波动幅度比较大可能存在变坏风险,应当予以提醒
质量需求
-
统一界面:根据metric,tracing,logging快速定位和排查问题,减少页面跳转,减少阅读难度。
-
日志精简:非关键行非关键字段不打印,减少网络io,减少存储,减少阅读难度。
-
日志完整:关键行关键字段必须打印,方便还原强平流程图,通过数据在IDE进行debug或静态跟踪代码。
-
异步写入:不影响主线程。
-
批量写入:减少网络IO。
-
实时处理:日志从产生,查询,统计,分析秒级完成。
-
存储方式:每种日志类型写入独立日志文件,日志文件按照时间日期分割,再按照大小分割。
-
业务拓展:适配未来日志中间件的变更,即使中间件推到重来,日志格式和日志内容也不需要大幅度变动。
-
日志格式:日志默认使用json,既有利于人类阅读,又支持常见日志中间件清洗转换搜索统计分析。
-
日志清理:过期日志,比如24小时以前的日志,可自动清理,节省存储空间。
-
分析审计:对数据有交互式分析能力,将结果以可视化方式展示。
-
数据挖掘:适配未来和数仓对接,对于大量的历史日志,可进行数据挖掘。
整体流程
日志流程
- 初始状态包括开始时间和入参
- 结束状态包括结束时间,耗时,处理结果
- 写入日志文件时,要针对每种日志类型,写入不同的日志文件,比如永续活动单写入永续活动单日志文件
日志写入交互时序
写入日志文件
-
通过本地日志文件存储日志
-
写入日志简单
-
查询日志困难
-
统计分析困难
-
异常报警困难
-
需要占用本地硬盘
-
高峰期时暂存硬盘
-
低峰期时同步至es
-
jraft切主时需要查询ip
-
此阶段为第一阶段,理解非常简单,
-
方便梳理流程和业务功能验证
-
难点是确定哪些情况需要写入日志
-
写入日志的字段必须满足后续的查询统计分析报警
-
无关字段避免写入
写入消息队列交互时序
-
系统已经存在内存数据发送到消息队列,直接把日志发送到消息队列,充分利用已有资源。
-
日志直接发送到消息队列,不再写本地日志,减少了一个旁路,数据一致性更加有保障
-
日志直接发送到消息队列,不需要耗费应用服务器硬盘,也不需要启动清理日志程序
-
日志直接发送到消息队列,要时刻依赖网络,系统稳定性要求更高一些,避免网络中断,导致数据丢失
-
日志直接发送到消息队列,没有优先级之分,高峰期会更加频繁的发送到消息队列,浪费宝贵的网络IO
-
日志直接发送到消息队列,要保障下游及时消费,防止消息堆积,导致数据丢失
-
日志直接发送到消息队列,虽然不必清理本地硬盘,但要经常清理margin-db(因为日志量比较大)
-
日志直接发送到消息队列,需要改造liqDigest对象,也可以新增对象新增tag
日志查询交互时序
从日志文件查询日志
-
查询搜索效率低下
-
缺少统计分析功能
-
缺少监控报警功能
从ES中查询日志
-
通过logstash收集日志,对应用无侵入性
-
通过kibana查询日志,拥有浏览器即可操作,直观清晰
-
日志文件被删除了也并不可怕,因为日志已经持久化到es了
-
日志持久化到了elasticsearch,可被Prometheus轻易采集到,并对异常情况报警通知
-
不管将来继续使用jraft还是使用其他服务编排方式,使用elk意味着我们查询业务日志时不再需要关注哪个机器生成的日志了,刀耕火种黑麻麻的命令行一去不复返,查找问题的速度和工作体验感暴增
从margin-db中查询日志
-
通过margin-db收集日志,对应用无侵入性
-
通过mysql客户端查询日志,拥有datagrid即可操作,直观清晰
-
消息队列的日志过期了也并不可怕,因为日志已经持久化到mysql了
-
日志持久化到了mysql,可被margin-validation定时任务轻易采集到,并对异常情况报警通知
-
不管将来继续使用jraft还是使用其他服务编排方式,使用margin-db后意味着我们查询业务日志时不再需要关注哪个机器生成的日志了,刀耕火种黑麻麻的命令行一去不复返,查找问题的速度和工作体验感暴增
日志统计和报警交互时序
通过业务代码内自定义metric推送到prometheus
-
应用程序编写复杂度变高,侵入性强,充斥着大量业务无关的代码
-
虽然是异步推送,但是总体看,还是要消耗宝贵的cpu内存网络资源,或者说跟核心应用争抢资源
通过elasticsearch_export插件从日志中采集metric
- 充分利用运维提供的基础设施,减少代码维护量,提供应用系统的资源利用率
- 输出到日志文件的数据应该是完整的,准确的,否则grafana也无能为力统计到有效的数据
通过悟空监控系统从日志中采集metric
- 架构简单
- 依赖日志文件中的metric
- 有些数据匹配难度大
通过margin-validation从mysql中采集metric
数据结构
强平流程日志表(liq_flow_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平流程日志id | liqFlowLogId | 123456 |
强平流程启动时间 | beginTime | 2022-03-02 18:00:00.000 |
强平流程总耗时 | duration | 纳秒,此时间为流程开始时间到流程彻底结束时间的差值 |
强平流程结束时间 | endTime | 该字段可省略,因为可通过强平流程启动时间和强平流程总耗时推断 |
账户Id | accountId | 12345678 |
保证金类型 | marginMode | 常规保证金RM 组合保证金PM 统一保证金UM |
强平模式 | liqMode | 常规强平=COMMON_LIQ, 人工接管=HANDLE_LIQ , 延迟爆仓=DELAY_LIQ |
强平触发原因 | cause | 行情价格反向波动事件 开仓平仓交割结束导致仓位变动事件 账户入金出金结束事件 杠杆变低结束事件 延时到期事件 |
强平流程执行前风险水位 | beforeLiqRiskLevel | MM_OVERFLOW_LEVEL |
强平流程执行前状态 | beforeLiqAccountStatus | OPTION_LIQ_SENT |
强平流程执行前chainName | beforeChainName | OPTION_LIQ_SENT,如果使用了literflow,填写该值 |
强平流程执行前运行的类名 | beforeClassName | OptionLiqCallBackCmp,如果使用了literflow,填写该值 |
强平流程执行前余额 | beforeMarginBalance | 1000.000 |
强平流程执行前净值 | beforeEquity | 1000.000 |
强平流程执行前初始保证金 | beforeIM | 0.0001 |
强平流程执行前维持保证金 | beforeMM | 0.0001 |
强平流程执行后风险水位 | afterLiqRiskLevel | MM_OVERFLOW_LEVEL |
强平流程执行前状态 | afterLiqAccountStatus | OPTION_LIQ_SENT |
强平流程执行后chainName | afterChainName | OPTION_LIQ_SENT,如果使用了literflow,填写该值 |
强平流程执行后运行的类名 | afterClassName | OptionLiqCallBackCmp,如果使用了literflow,填写该值 |
强平流程执行后余额 | afterMarginBalance | 1000.000 |
强平流程执行后净值 | afterEquity | 1000.000 |
强平流程执行后初始保证金 | afterIM | 0.0001 |
强平流程执行后维持保证金 | afterMM | 0.0001 |
返回码 | code | 0:执行成功,非0:执行失败 |
返回描述 | message | 比如异常详情 |
强平请求日志表(liq_request_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平请求日志id | liqRequestLogId | 12345678910,相当于强平子流程id,和RequestId保持一致 |
强平请求的服务动作 | serviceName | ENTER_LIQ_PROCESS,相当于强平请求名称,相当于强平子流程名称,这个值在单次请求中是不会改变的 |
所属强平流程日志id | liqFlowLogId | 123456 |
强平请求开始时间 | beginTime | 2022-03-02 18:00:00.000000 |
强平请求总耗时 | duration | 纳秒,请注意,强平流程的耗时并非所有强平请求的耗时总和 因为中间每个强平请求之间需要等待回执时间, 这些时间不属于任何请求的时间,但属于强平流程的时间 |
强平请求结束时间 | endTime | 该字段可省略,因为可通过强平请求开始时间和强平请求总耗时推断 |
账户Id | accountId | 12345678 |
强平请求入参Json | requestBodyJson | {},回执参数或者从消息队列接收的消息 |
强平请求执行前步骤日志id | beforeLiqStepLogId | |
强平请求执行前步骤日志名称 | beforeLiqStepLogName | |
强平请求执行前风险水位 | beforeLiqRiskLevel | MM_OVERFLOW_LEVEL |
强平请求执行前强平账户当前状态 | beforeLiqAccountStatus | OPTION_LIQ_SENT |
强平请求执行前chainName | beforeChainName | OPTION_LIQ_SENT,如果使用了literflow,填写该值 |
强平请求执行前运行的类名 | beforeClassName | OptionLiqCallBackCmp,如果使用了literflow,填写该值 |
强平请求执行前余额 | beforeMarginBalance | 1000.000 |
强平请求执行前净值 | beforeEquity | 1000.000 |
强平请求执行前初始保证金 | beforeIM | 0.0001 |
强平请求执行前维持保证金 | beforeMM | 0.0001 |
强平请求执行前永续订单个数 | beforePerpOrderCount | 1 |
强平请求执行前永续仓位个数 | beforePerpPositionCount | 1 |
强平请求执行前期权订单个数 | beforeOptionOrderCount | 1 |
强平请求执行前期权仓位个数 | beforeOptionPositionCount | 1 |
强平请求出参Json | responseBodyJson | {},处理结果 |
强平请求执行后步骤日志id | afterLiqStepLogId | |
强平请求执行后步骤日志名称 | afterLiqStepLogName | |
强平请求执行后风险水位 | afterLiqRiskLevel | MM_OVERFLOW_LEVEL |
强平请求执行后强平账户当前状态 | afterLiqAccountStatus | OPTION_LIQ_SENT, |
强平请求执行后chainName | afterChainName | OPTION_LIQ_SENT,如果使用了literflow,填写该值 |
强平请求执行后运行的类名 | afterClassName | OptionLiqCallBackCmp,如果使用了literflow,填写该值 |
强平请求执行后余额 | afterMarginBalance | 1000.000 |
强平请求执行后净值 | afterEquity | 1000.000 |
强平请求执行后初始保证金 | afterIM | 0.0001 |
强平请求执行后维持保证金 | afterMM | 0.0001 |
强平请求执行后永续订单个数 | afterPerpOrderCount | 1 |
强平请求执行后永续仓位个数 | afterPerpPositionCount | 1 |
强平请求执行后期权订单个数 | afterOptionOrderCount | 1 |
强平请求执行后期权仓位个数 | afterOptionPositionCount | 1 |
返回码 | code | 0:执行成功,非0:执行失败 |
返回描述 | message | 比如异常详情 |
强平步骤日志表(liq_step_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平步骤日志id | liqStepLogId | 12345678910 |
强平步骤日志名称 | liqStepLogName | 权限判断步骤 延时爆仓步骤 初始化步骤 取消活动单步骤 安全降档步骤 有损降档部分减仓步骤 有损降档永续接管步骤 阶梯强平下平仓单步骤 阶梯强平转仓给做市商步骤 期权接管步骤 恢复步骤 |
所属强平流程日志id | liqFowLogId | 123456 |
强平步骤开始时间 | beginTime | 2022-03-02 18:00:00.000000 |
强平步骤总耗时 | duration | 纳秒,假如忽略literflow的耗时,强平流程的耗时基本上可等同所有步骤的耗时总和 |
强平步骤结束时间 | endTime | 该字段可省略,因为可通过强平步骤开始时间和强平步骤总耗时推断 |
账户Id | accountId | 12345678 |
强平步骤执行前强平请求id | beforeRequestId | 12345678 |
强平步骤执行前服务动作 | beforeServiceName | ENTER_LIQ_PROCESS |
强平步骤执行前风险水位 | beforeLiqRiskLevel | MM_OVERFLOW_LEVEL |
强平步骤执行前强平账户当前状态 | beforeLiqAccountStatus | OPTION_LIQ_SENT |
强平步骤执行前chainName | beforeChainName | OPTION_LIQ_SENT,如果使用了literflow,填写该值 |
强平步骤执行前运行的类名 | beforeClassName | OptionLiqCallBackCmp,如果使用了literflow,填写该值 |
强平步骤执行前余额 | beforeMarginBalance | 1000.000 |
强平步骤执行前净值 | beforeEquity | 1000.000 |
强平步骤执行前初始保证金 | beforeIM | 0.0001 |
强平步骤执行前维持保证金 | beforeMM | 0.0001 |
强平步骤执行前永续订单个数 | beforePerpOrderCount | 1 |
强平步骤执行前永续仓位个数 | beforePerpPositionCount | 1 |
强平步骤执行前期权订单个数 | beforeOptionOrderCount | 1 |
强平步骤执行前期权仓位个数 | beforeOptionPositionCount | 1 |
强平步骤执行后强平请求id | afterRequestId | 12345678 |
强平步骤执行后服务动作 | afterServiceName | ENTER_LIQ_PROCESS |
强平步骤执行后风险水位 | afterLiqRiskLevel | MM_OVERFLOW_LEVEL |
强平步骤执行后强平账户当前状态 | afterLiqAccountStatus | OPTION_LIQ_SENT, |
强平步骤执行后chainName | afterChainName | OPTION_LIQ_SENT,如果使用了literflow,填写该值 |
强平步骤执行后运行的类名 | afterClassName | OptionLiqCallBackCmp,如果使用了literflow,填写该值 |
强平步骤执行后余额 | afterMarginBalance | 1000.000 |
强平步骤执行后净值 | afterEquity | 1000.000 |
强平步骤执行后初始保证金 | afterIM | 0.0001 |
强平步骤执行后维持保证金 | afterMM | 0.0001 |
强平步骤执行后永续订单个数 | afterPerpOrderCount | 1 |
强平步骤执行后永续仓位个数 | afterPerpPositionCount | 1 |
强平步骤执行后期权订单个数 | afterOptionOrderCount | 1 |
强平步骤执行后期权仓位个数 | afterOptionPositionCount | 1 |
返回码 | code | 0:执行成功,非0:执行失败 |
返回描述 | message | 比如异常详情 |
强平过程中永续活动订单日志表(lip_perp_order_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中永续活动订单日志id | liqPerpOrderLogId | 12345678911 |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
账户Id | accountId | 12345678 |
永续活动订单id | orderId | 123456 |
方向 | side | buy/sell |
数量 | size | 0.01 |
挂单价格 | orderPrice | 45000.123 |
当前指数价 | indexPrice | 48000.123 |
该永续活动订单占用的初始保证金 | orderIM | 1000.000 |
强平过程中永续仓位日志表(liq_perp_position_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中永续仓位日志id | liqPerpPositionLogId | 12345678912 |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
账户Id | accountId | 12345678 |
永续仓位id | poitionId | 123456 |
方向 | side | buy/side |
数量 | size | 0.01 |
仓位平均价 | avgPrice | 45000.134 |
当前指数价 | indexPrice | 48000.123 |
该永续仓位占用的初始保证金 | positionIM | 1000.000 |
该永续仓位占用的维持保证金 | positionMM | 1000.000 |
强平过程中期权活动订单日志表(liq_option_order_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中期权活动订单日志id | liqOptionOrderLogId | 12345678911 |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
账户Id | accountId | 12345678 |
期权活动订单id | orderId | 123456 |
产品类型 | type | call/put |
方向 | side | buy/sell |
数量 | size | 0.01 |
挂单价格 | orderPrice | 1.123 |
当前指数价 | indexPrice | 1000 |
当前标记价 | markPrice | 1.456 |
该期权活动订单占用的初始保证金 | orderIM | 10.000 |
强平过程中期权仓位日志表(liq_option_position_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中期权仓位日志id | liqOptionPositionLogId | 12345678913 |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
账户Id | accountId | 12345678 |
期权仓位id | poitionId | 123456 |
产品类型 | type | call/put |
方向 | side | buy |
数量 | size | 0.01 |
仓位平均价 | avgPrice | 1.123 |
当前指数价 | indexPrice | 1000 |
当前标记价 | markPrice | 1.456 |
该期权仓位占用的初始保证金 | positionIM | 1000.000 |
该期权仓位占用的维持保证金 | positionMM | 1000.000 |
强平过程中RPC调用日志表(liq_rpc_invoke_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中RPC调用日志id | liqRpcInvokeLogId | 12345678911 |
强平过程中RPC调用日志名称 | liqRpcInvokeLogName | 可填写RPC中文名称 |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
RPC调用开始时间 | beginTime | 2022-03-02 18:00:00.000 |
RPC调用总耗时 | duration | 纳秒 |
RPC调用结束时间 | endTime | 该字段可省略,因为可通过RPC调用开始时间和RPC调用总耗时推断 |
账户Id | accountId | 12345678 |
rpc方法 | rpcMethod | com.xxx.xxx(),主要是永续,期权,资产相关接口,比如打钱 |
请求体json | requestBodyJson | {} |
返回码 | code | 0:执行成功,非0:执行失败 |
返回描述 | message | 比如异常详情 |
响应体json | responseBodyJson | {} |
强平过程中RPC被调用日志表(liq_rpc_invoked_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中RPC被调用日志id | liqRpcInvokedLogId | 12345678911 |
强平过程中RPC被调用日志名称 | liqRpcInvokedLogName | 可填写RPC中文名称 |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
RPC被调用开始时间 | beginTime | 2022-03-02 18:00:00.000 |
RPC被调用总耗时 | duration | 纳秒 |
RPC被调用结束时间 | endTime | 该字段可省略,因为可通过RPC被调用开始时间和RPC被调用总耗时推断 |
账户Id | accountId | 12345678 |
rpc方法或ServiceAction | rpcMethod | com.xxx.xxx(),主要是CANCELED:期权取消活动单回执 LIQUIDATION:强平(期权交易回执),主要是仓位资产处理 PASS_THROUGH:透传(期权交易回执),主要是账户余额处理 TRADING_RESULT_LIQ_CONVERT:交易结果回执 PERP_LIQ_CANCEL_ORDER:永续取消开仓活动单回执 PERP_LIQ_POSITION_PART_LIQ_FILL:永续减仓降档成功回执 PERP_LIQ_POSITION_PART_LIQ_KILL:永续减仓降档失败回执 PERP_LIQ_POSITION_TAKE_OVER:永续仓位接管回执 |
请求体json | requestBodyJson | {} |
返回码 | code | 0:执行成功,非0:执行失败 |
返回描述 | message | 比如异常详情 |
响应体json | responseBodyJson | {} |
强平过程中消息队列发送日志表(liq_message_send_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中消息队列发送日志id | liqMessageSendLogId | 12345678911 |
强平过程中消息队列发送日志名称 | liqMessageSendLogName | |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
发送时间 | sendTime | 2022-03-02 18:00:00.000 |
账户Id | accountId | 12345678 |
主题 | topic | AccountEvent |
消息体Json | bodyJson | {} |
强平过程中消息队列接收日志表(liq_message_receive_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中消息队列接收日志id | liqMessageRreceiveLogId | 12345678911 |
强平过程中消息队列接收日志名称 | liqMessageRreceiveLogName | |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
接收时间 | receiveTime | 2022-03-02 18:00:00.000 |
账户Id | accountId | 12345678 |
主题 | topic | AccountEvent |
分区 | partition | 0 |
偏移 | offset | 123456 |
消息体Json | bodyJson | {} |
强平过程中强平核心类方法调用日志表(liq_method_invoke_log)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平过程中强平核心类方法调用日志id | liqMethodInvokeLogId | 12345678911 |
强平过程中强平核心类方法调用日志名称 | liqMethodInvokeLogName | |
所属强平流程日志id | liqFowLogId | 123456 |
所属强平请求日志id | liqRequestLogId | 12345678 |
所属强平步骤日志id | liqStepLogId | 12345678910 |
强平核心类方法执行开始时间 | beginTime | 2022-03-02 18:00:00.000 |
强平核心类方法总耗时 | duration | 纳秒 |
强平核心类方法执行结束时间 | endTime | 该字段可省略,因为可通过强平核心类方法执行开始时间和强平核心类方法总耗时推断 |
账户Id | accountId | 12345678 |
执行方法 | method | LiqStateMachineService#enterStateMachine |
入参Json | requestBodyJson | 如果没有参数,此字段为null, 如果只有1个参数,直接JsonUtil.toJson(XXX) 如果有多个参数,则{param1:XXX,param2:XXX}json格式表达 |
返回码 | code | 0:执行成功,非0:执行失败 |
返回描述 | message | 比如异常详情 |
出参Json | responseBodyJson | 如果没有参数,此字段为null, 如果只有1个参数,直接JsonUtil.toJson(XXX) |
强平流程统计表(liq_flow_stat)
字段(CN) | 字段(EN) | 示例 |
---|---|---|
强平流程统计统计id | id | 12345678911 |
统计维度 | dimension | 分钟:minute 小时:hour 每天:day 每周:week 每月:month 每年:year |
统计开始时间 | beginTime | 2022-03-02 00:00:00 |
统计结束时间 | endTime | 该字段可省略,因为可以从统计维度和统计开始时间推算出来 |
总次数 | totalCount | 分钟维度可通过定时任务统计, 其他维度可以以上一维度累加, 比如每小时,那么累加那一小时分钟维度的数据,累加60次即可, 同理天只需要累加24次,周只需要累加7次,月只需要累加当月天数 |
执行成功次数 | successCount | 必须使用统一的成功返回码,才能统计该字段 |
执行失败次数 | failCount | 必须使用统一的失败返回码,才能统计该字段 |
平均强平时间 | avgLiqTime | 单位为纳秒,统计方式和统计次数类似 |
最大强平时间 | maxLiqTime | 单位为纳秒,统计方式和统计次数类似 |
最小强平时间 | minLiqTime | 单位为纳秒,统计方式和统计次数类似 |
强平请求统计表(liq_request_stat)
字段同上
强平步骤统计表(liq_step_stat)
字段同上
强平过程中永续活动订单丢失统计表(liq_perp_order_stat)
字段同上
强平过程中永续仓位丢失统计表(liq_perp_position_stat)
字段同上
强平过程中期权活动订单丢失统计表(liq_perp_order_stat)
字段同上
强平过程中期权仓位丢失统计表(liq_perp_position_stat)
字段同上
强平过程中RPC调用统计表(liq_rpc_invoke_stat)
字段同上
强平过程中RPC被调用统计表(liq_rpc_invoked_stat)
字段同上
强平过程中消息队列发送统计表(liq_message_send_stat)
字段同上
强平过程中消息队列接收统计表(liq_message_receive_stat)
字段同上
强平过程中强平核心类方法调用统计表(liq_method_invoke_stat)
字段同上
强平过程中账户资金丢失统计表(liq_account_stat)
字段同上
非强平主流程日志(other_log)
非强平主流程日志,主要是系统设置相关的日志,缺少它们,强平服务也能运转。
设置强平模式为常规模式/人工接管/延时爆仓接口日志
设置接管户接口日志
设置延时时长日志
人工接管接口日志
不影响强平流程,暂略
模块功能
日志写入
强平流程执行前日志写入
-
第一次进入状态机时,写入强平流程日志,主要写入这些字段
强平流程日志id
强平流程启动时间
账户Id
保证金类型
强平模式
强平流程执行前余额
强平流程执行前净值
强平流程执行前初始保证金
强平流程执行前维持保证金
强平流程执行前风险水位//创建日志对象 LiqFlowLog liqFlowLog = new LiqFlowLog(); liqFlowLog.setLiqFlowLogId(new Snowflake(xxx).nextId()); liqFlowLog.setXXX(XXX); liqFlowLog.setYYY(YYY); //序列化成json写入对应的日志文件,方便es分析,方便prometheus统计 LiqLogConstant.LIQ_FLOW_LOG.info(new ObjectMapper().writeValueAsString(liqFlowLog));
强平流程执行后日志更新
-
流程结束时,更新强平流程日志,相比执行前日志,主要是新增了这些字段
强平流程日志id
强平流程总耗时
强平流程结束时间
账户Id
保证金类型
强平模式强平流程执行后余额
强平流程执行后净值
强平流程执行后初始保证金
强平流程执行后维持保证金
强平流程执行后风险水位
返回码
异常详情
强平请求执行前日志写入
强平请求执行后日志更新
强平步骤执行前日志写入
-
强平流程每个步骤执行前,写入强平步骤日志,主要写入这些字段
强平步骤日志id
所属强平流程日志id
强平步骤开始时间账户Id
强平步骤执行前服务动作
强平步骤执行前余额
强平步骤执行前净值
强平步骤执行前初始保证金
强平步骤执行前维持保证金
强平步骤执行前强平账户当前状态
强平步骤执行前风险水位当前chainName
当前运行的类名
强平步骤执行后日志更新
-
强平流程步骤结束时,更新强平流程步骤日志,相比执行前日志,主要是新增了这些字段
强平步骤日志id
所属强平流程日志id
强平步骤总耗时
强平步骤结束时间
账户Id
强平步骤执行后服务动作
强平步骤执行后余额
强平步骤执行后净值
强平步骤执行后初始保证金
强平步骤执行后维持保证金
强平步骤执行后强平账户当前状态
强平步骤执行后风险水位
当前chainName
当前运行的类名
返回码
异常详情
强平过程中永续活动订单日志写入
强平过程中永续仓位日志写入
强平过程中期权活动订单日志写入
强平过程中期权仓位日志写入
强平过程中RPC调用日志写入
强平过程中RPC被调用日志写入
强平过程中消息队列发送日志写入
强平过程中消息队列接收日志写入
强平过程中强平核心类方法调用日志写入
强平过程中接管户资金池日志写入
日志查询
根据账户id查询有多少强平流程
根据强平流程id查询强平步骤
根据强平流程id和强平步骤id查询永续活动订单列表
根据强平流程id和强平步骤id查询永续仓位列表
根据强平流程id和强平步骤id查询期权活动订单列表
根据强平流程id和强平步骤id查询永续仓位列表
根据强平流程id查询有哪些rpc调用
根据强平流程id查询有哪些消息发送
根据强平流程id查询有哪些消息接收
根据强平流程id查询有哪些方法调用
根据强平流程id查询有哪些资产或者资金转账
日志统计
统计指定时间段内有多少用户发生强平,多少用户强平成功,多少用户强平失败
统计每秒钟有多少用户强平
统计指定时间段内强平流程平均处理时间,最大处理时间
统计耗时最大的top10
统计比较
- 把统计指标和历史数据做对比(环比同比),波动幅度比较大可能存在变坏风险,应当予以提醒
强平报警
-
报警阈值类型:
-
根据绝对值报警,比较给定值过高或过低即报警
-
根据相对值报警,根据环比,同比指标报警,根据历史数据及波动情况,来判断当前的波动是否为异常,从而避免过高的“底线”就会导致误报,过低的“底线”漏掉很多需要预警的情况
流程还原
-
Tracing开发
-
功能上仿照springcoud的链路追踪方式,dashboard中自动还原强平流程图,
-
实现上仿照trace,span来进行流程跟踪,其中flowid充当traceid功能,stepid充当spanid的功能
-
分析日志,建立指标和flowid、stepid的关联关系
-
在报警发生时,通过指标查找到flowid和stepid,进而查找到所有log。
日志清理
-
日志文件按照日期优先,大小第二的方式分割
-
程序异步批量写入日志后,日志由logstash准实时收集到es
-
保留24小时内的日志文件
-
删除24小时以前的日志文件
-
确保强平日志量不会撑满硬盘
日志开闭
-
每一个日志表对应的一个Logger,对应一个日志文件
-
对一些非主要环节的日志,在运行稳定后可进行关闭,节省IO
-
在收到关闭消息后,应用程序停止写入对应的日志文件
-
对一些不稳定的功能,或新上线的功能,可进行开启,便于定位问题排查问题
-
在收到开启消息后,应用程序源源不断的写入对应的日志文件
-
可关闭的日志,包括但不限于以下几类:
-
强平过程中永续活动订单日志表
-
强平过程中永续仓位日志表
-
强平过程中期权活动订单日志表
-
强平过程中期权仓位日志表
-
日志开闭方式:
-
通过Nacos配置更改通知日志开闭
-
通过运营系统或其他系统,向kafka发送开闭消息,应用程序监听到开闭消息进行开闭
-
日志开关开启时,应用程序写入对应的日志文件
-
日志开关关闭时,应用程序停止写入对应的日志文件
强平流程总耗时太长,返回码异常,调用频率异常
强平请求总耗时太长,返回码异常,调用频率异常
强平每个请求间停留时间太长
强平步骤(每个状态)总耗时太长,返回码异常,调用频率异常
强平每个步骤间停留时间太长
强平过程中RPC调用总耗时太长,返回码异常,调用频率异常
强平过程中RPC被调用总耗时太长,返回码异常,调用频率异常
强平步骤中强平核心类方法总耗时太长,返回码异常,调用频率异常
强平路线异常(也就是状态变迁异常)
强平用户和接管户资金对账异常
价格大幅波动(比如一分钟时间窗口内最大值比当前值超过1%,或者当前值比最小值超过1%)
组合保证金模式下,用户下单成交后立即被强平(暂时无法监控)
接管户被创建多次异常(暂时无法监控,运营平台可以做幂等)
报警收敛
- 在上层的网络服务出现问题时,大量报警涌入
- 有一个小的窗口期来对它们做聚合,也就是进行报警收敛
- 将所有的、相关的报警收敛成一个消息通知用户
- 在哪个区间发生了多少报警、可能涉及到多少范围等,把更详细的信息发给用户,而不再单独通知所有人
智能修复
-
触发报警时自动尝试启动修复策略(自动尝试调用兜底方案)
-
启动修复策略前后发送通知
容量估算
在容量估算前,先把强平服务的日志分为3个等级,并估算每种等级需要多少行日志
等级 | 日志类型 | 预估日志行数 | 预估日志行数算法 |
---|---|---|---|
必备 | 强平流程日志 强平步骤日志 | 10行 | 每一个强平流程会生成二行记录 一行是强平流程前状态, 另一行是强平流程后状态 每一个强平流程会包含平均4个强平步骤 每个步骤又会生成二行记录 一行是强平步骤执行前状态, 另一行是强平步骤执行后状态 2+4X2=10行 |
中等 | 强平过程中RPC调用日志 强平过程中RPC被调用日志 强平过程中消息队列发送日志 强平过程中消息队列接收日志 强平过程中核心类方法调用日志 | 40行 | 5种日志在每个步骤生成2行记录 4步骤x5种日志x2行=40 |
全量 | 强平过程中永续活动订单日志 强平过程中永续仓位日志 强平过程中期权活动订单日志 强平过程中期权仓位日志 | 80行 | 总共8种,每种以10个订单或仓位估算 8x10=80 |
启用不同等级和不同存储格式需要的存储空间:
Json格式存储,每行记录不超过200字节,如果csv格式存储,字段以逗号分割,每行记录存储空间比json格式减半,1G可以存储多一倍强平日志
存储等级 | json格式存储 | 1G可以存储的强平日志数量 |
---|---|---|
必备 | 10X200=2k | 1G/2k=50万个强平 |
必备+中等 | 10X200+40X200=10k | 1G/10k=10万个强平 |
必备+中等+全量 | 10X200+40X200+80X200=16k | 1G/26k=38000个强平 |
日志同步到es后,需要清理,假若每天清理一次,每次清理时把24小时前的日志清空,那么10G硬盘对付强平日志绰绰有余,因为即使全量存储,10G也可以存储38万个强平
实施步骤
写入必备日志和中等日志
-
为每种类型的日志定义专门的Logger,写入专门的日志文件,包括:
- 强平流程日志写入liq_flow_log.log日志文件
- 强平请求日志写入liq_request_log.log日志文件
- 强平步骤日志写入liq_step_log.log日志文件
- 强平过程中rpc调用日志写入liq_rpc_invoke_log.log日志文件
- 强平过程中rpc被调用日志写入liq_rpc_invoked_log.log日志文件
- 强平过程中消息队列发送日志写入liq_message_send_log.log日志文件
- 强平过程中消息队列接收日志写入liq_message_receive_log.log日志文件
- 强平过程中强平核心类方法调用日志写入liq_method_invoke_log.log日志文件
-
写入之前,在java程序中定义专门的日志对象,从审美和对称性角度看,面向对象比log.info随机定义占位符变量好看很多,比如:
- LiqFlowLog代表强平流程日志
- LiqRequestLog代表强平请求日志
- LiqStepLog代表强平步骤日志
- LiqRpcInvokeLog代表强平过程中rpc调用日志
- LiqRpcInvokedLog代表强平过程中rpc被调用日志
- LiqMessageSendLog代表强平过程中消息队列发送日志
- LiqMessageReceiveLog代表强平过程中消息队列接收日志
- LiqMethodInvokeLog代表强平过程中强平核心类方法调用日志
-
在java对象中,重写toString方法
- 如果希望日志文件内容是json格式,那么toString方法则使用json方式序列化每个字段(默认使用)
- 如果希望日志文件内容是csv格式,那么toString方法则使用逗号分割每个字段
-
为每种类型的日志,打印日志文件,比如:
-
写入强平流程日志LiqLogConstant.LIQ_FLOW_LOG.info(liqFlowLog)
-
写入强平请求日志LiqLogConstant.LIQ_REQUEST_LOG.info(liqRequestLog)
-
写入强平步骤日志LiqLogConstant.LIQ_STEP_LOG.info(liqStepLog)
-
写入强平步骤执行中rpc调用日志LiqLogConstant.LIQ_RPC_INVOKE_LOG.info(liqRpcInvokeLog)
-
写入强平步骤执行中rpc被调用日志LiqLogConstant.LIQ_RPC_INVOKED_LOG.info(liqRpcInvokedLog)
-
写入强平步骤执行中消息队列发送日志LiqLogConstant.LIQ_MESSAGE_SEND_LOG.info(liqMessageSendLog)
-
写入强平步骤执行中消息队列接收日志LiqLogConstant.LIQ_MESSAGE_RECEIVE_LOG.info(liqMessageReceiveLog)
-
写入强平步骤执行中强平核心类方法调用日志LiqLogConstant.LIQ_METHOD_INVOKE_LOG.info(liqMethodInvokeLog)
-
配置悟空监控
配置grafana监控
删除以前日志写入方式
写入非必要日志
-
写入非必要日志(运行中途可关闭),为每种类型的日志定义专门的Logger,写入专门的日志文件,包括:
- 强平过程中永续活动订单日志写入lip_before_perp_order_log.log日志文件
- 强平过程中永续仓位日志写入liq_before_perp_position_log.log日志文件
- 强平过程中期权活动订单日志写入lip_before_option_order_log.log日志文件
- 强平过程中期权仓位日志写入liq_before_option_position_log.log日志文件
任务评估
任务 | 效果 | 时长 |
---|---|---|
写入强平流程日志 | 1日/人 | |
写入强平请求日志 | 2日/人 | |
写入强平步骤日志 | 2日/人 | |
写入强平过程中rpc调用日志 | 3日/人 | |
写入强平过程中rpc被调用日志 | 3日/人 | |
写入强平过程中消息队列发送日志 | 2日/人 | |
写入强平过程中消息队列接收日志 | 2日/人 | |
写入强平过程中强平核心类方法调用日志 | 3日/人 | |
配置开发测试预生产环境悟空监控和grafana监控 | 5日/人 | |
配置生产环境悟空监控和grafana监控 | 1日/人 | |
定时删除24小时以前日志 | 1日/人 | |
运行两周后,发现稳定则删除以前代码中的日志 | 1日/人 | |
代码评审 | 1日/人 | |
全程解答疑问 | 2日/人 | |
优化完善文档 | 2日/人 |
编程方式
-
30人日,3人投入,为期2周
-
其中1人为负责人:编写文档,优化完善文档,解答疑问,检查任务进度
-
另外两人为开发:严格按照文档参与编码,第一周完成日志埋点,第二周进行metric配置
-
结对编程,两个开发每天编码完成后,下班前审查对方的完成质量
FAQ
-
强平的关键日志数据有哪些?
-
能影响强平流程推进的数据都可认为关键日志数据,包括强平流程启动前的系统配置项。
-
编写单元测试需要的数据可认为是关键日志数据。
-
静态跟踪代码需要的数据可认为是关键日志数据。
-
出问题后让开发和运维从容面对说明存在完整的关键日志数据
-
出问题后让开发和运维手忙脚乱慌张不安说明缺少关键日志数据
-
-
日志埋点方案打算解决什么问题?
-
解决强平安稳中“强平流程状态不一致”,“强平流程停滞不推进”,“强平运维监控能力较弱”,“metric反查日志困难”等问题。
-
得到完整的关键的强平流程日志数据后,也为典型流程完善,单元单元测试编写,系分文档完善做好准备。
-
开展其他安稳工作,比如定期出强平安稳报表。
-
-
为什么发现问题和解决问题需要依赖日志?
-
强平的触发因素有很多,包括行情价格反向波动事件,开仓平仓交割结束导致仓位变动事件,账户入金出金结束事件,杠杆变低结束事件,延时到期事件。
-
影响强平的因素还包括保证金类型,风险类型,订单类型,仓位类型,成交方向等。
-
仅靠静态分析代码和现有文档很难确定上下文是否符合需求文档。很难定位排查问题。
-
最好的方式就是抓取完整的关键日志。
-
-
为什么不直接改造现有日志,而是重新日志埋点?
-
现有代码,现有日志,现有文档已经研读多次,能简单跟踪的强平流程也跟踪了,能简单画的图也画了,能发现的问题也提出来了
-
如果继续死磕,可能还是发现不了有价值的新问题,投入产出比不高
-
如果现有日志改造,只能从代码出发,从下而上,改造难度非常大,一不小心,就会脱离需求,掉进坑里面长时间爬不出来。
-
从代码库提交记录可以看出,现有代码日志已经改造多次,但无济于事,或者解决完这个问题,另外一个问题又冒出来,感觉就是问题永远解决不完
-
现有日志改动可能会影响开发环境,测试环境,生产环境,包括查询规则和已经配置好的监控报警
-
新的日志埋点方案,从需求出发,制订规范,把影响强平流程状态,影响强平推进的因素都考虑进来,更加容易发现新问题,解决不符合需求的问题。
-
新的日志埋点方案,不改动原有代码逻辑,原有日志方案还可以继续使用,可以动态关闭,甚至发现完问题不需要后可删除,影响面更小,试错成本低。
-
新的日志埋点不但会解决背景介绍列出的所有问题,还会更方便将来开展其他安稳工作。
-
-
新的日志埋点方案除了解决流程状态问题,怎么定期出安稳报告?
-
以测试环境为例:压力测试–>收集关键日志–>统计日志->监控报警
-
以生产环境为例:定期巡检–>收集关键日志–>统计日志->监控报警
-