一个由于侵入框架引起的故障

简介: 一个由于侵入框架引起的故障

背景


其实最近一直想写些帮助大家提高架构底蕴的东西。无奈最近当家的身体抱恙,我白天上班,晚上照顾病人,没有多余的精力 点、线、面的横向思考技术的问题。倒是“无为空自老,含叹负平生”的人生感慨多一些。今天还是谈谈点上的东西。


记得早些时候,被别人要求写算法代码没写出来,后来我刷了百道leetcode。算法题再也没难住我了。但是想来,平时工作中是还是真的少些这些底层代码为妙,业务代码有业务代码的写法。写业务代码最忌讳:“炫技”。和做人一样,讲究“技高不炫技”。下面来介绍一个由于侵入了框架内部引起的故障。

 

使用Java反射引起的报错


我们平时用Spring框架写Controller进行http请求处理时,框架帮我们做了JavaBean到传输数据的转换。在内部,实际上数据会先转成map再转成我们要处理的JavaBean。这次,在一个RPC泛化调用的场景(泛化调用主要用于没有接口API的情况下。不需要引入接口 jar 包,而是直接通过 通用接口来发起服务调用,参数及返回值中的所有 pojo均用 map 表示)。有个同学客户端处理时,自己写了一个JavaBean转成Map的方式,他是这么写的:


public static Map<String,Object> objectTpMap(Object obj) {
     Map<String,Object> map = new HashMap();
     Class objectClass = obj.getClass();
     while(objectClass != null) {
          Field[] declaredFields = objectClass.getDeclaredFields();
          for(Field field : declaredFields) {
               field.setAccessible(true);
               resultMap.put(field.getName(), field.get(object));
          }
     }
     return resultMap;
}


这里,在做JavaBean到Map转化时,用了反射的方法,将对象的所有属性(包含private final类型)都提取出来,传给服务端。服务端组件内部,开始时反序列化时,使用的是getField方法查找这个map中的每一个key。如果对象是private final类型是获取不到的,所以没有影响。后来组件升级,反序列化时,并没有使用getField方法,而是使用了getDeclaredField方法,就可以获取到private final类型的属性,进行赋值操作的时候就产生了问题。


这个bug经过了一两年时间才引起了事故。让人意想不到,恢复和排查的响应时间都会收到影响。

 

后记


能写出这样的代码,究其原因,大致有两种:一种遇到这个问题,经过搜索资料和思考,觉得这样可以实现,就没有做更多的思考;另一种是抱着学习的态度,想用一些之前不常用的技术解决问题。这两种原因写出的代码都是建立在对原理了解不透彻的基础上,相当危险。


最近在看《山河令》,里面有个诗词底蕴极高的温客行。说话时引经据典,天花乱坠。见到周子舒渡船,温客行说:“但度无所苦,我自迎接汝”。这本是大文豪王献之写给他的爱妾桃叶的诗。因为桃叶怕坐船,王献之就说了:“你只管渡江就好,不用想太多,我自然会在江边迎接你。”这里温客行用的隐隐表露出自己的小心思,倒也用的妙。


为了和温客行做对比,里面还出现了个爱附庸风雅的大白兔:曹蔚宁。小曹喜欢阿湘。于是跟阿湘夸她名字好:“九嶷缤兮并迎,灵之来兮如云。”句子里没有出现一个“湘”字。和湘沾边的是前半句“九嶷缤兮并迎“出自屈原的《九歌.湘夫人》。而后半句是曹植的《洛神赋》。洛神叫甄宓啊,和湘字没有半毛钱关系,纯粹是背诗背串了。所以温客行说听小曹背诗,屈原都能被气活过来。这境界反差出来了吧。


但是强如温客行,人家在河边喝水,他本是想打招呼示好的话。他来了一首:“沧浪之水清兮,可以濯我缨;沧浪之水浊兮,可以濯我足。”我只是觉得人家在喝水,你又是洗衣服又是洗脚的,这水喝着真倒胃口。你倒是来一首:“问渠那得清如许?为有源头活水来。” 也能让人觉得水的甘甜。或者来首:“秋水清无底,萧然静客心。” 也可在这炎炎夏日送上一抹凉意。也难怪周子舒不理他。


温客行的漏洞可不止这一处,温客行造了30个假的琉璃甲,带着周子舒去看狗咬狗。他在屋顶上说的是:“冲天香阵透岳阳,满城尽是琉璃甲”。这本是黄巢写菊花的诗:“冲天香阵透长安,满城尽带黄金甲。” 你要是改,也要改的彻底一点,人家菊花是香的,香阵一词用的妙,琉璃甲和香有什么关系吗?冲天香阵肯定是没有,冲天的杀气却是名副其实。说这么多,无非是想说明,还是要敬畏生产。不了解原理还是不要直接在要上生产的代码里尝试。侵入框架底层的代码最好不要写,尽量看看能否用写业务代码的方式来解决。连温客行身上都能找到这么多诗词的错处,平时咱们写的业务代码还怕找不出来Bug?一旦出现生产事故,岂不是丢了排面?

相关文章
|
3月前
|
存储 缓存 监控
分布式链路监控系统问题之kywalking在后期维护过程中可能会遇到中间件版本升级的问题如何解决
分布式链路监控系统问题之kywalking在后期维护过程中可能会遇到中间件版本升级的问题如何解决
|
3月前
|
监控 Java API
分布式链路监控系统问题之对Java应用实现字节码增强的方式的问题如何解决
分布式链路监控系统问题之对Java应用实现字节码增强的方式的问题如何解决
|
5月前
|
存储 运维 Prometheus
微服务监控:确保分布式系统的可观察性与稳定性
微服务监控:确保分布式系统的可观察性与稳定性
|
6月前
|
分布式计算 负载均衡 Java
构建高可用性Java应用:介绍分布式系统设计与开发
构建高可用性Java应用:介绍分布式系统设计与开发
71 0
|
6月前
|
域名解析 运维 网络协议
微服务常用故障处理机制
【2月更文挑战第11天】微服务系统可能出现故障的种类,主要有三种故障:集群故障、单 IDC 故障、单机故障。
|
6月前
|
存储 缓存 负载均衡
软件容错技术和方法在系统中的具体应用
软件容错技术和方法在系统中的具体应用
138 0
|
11月前
|
存储 前端开发 算法
微服务线上问题排查困难?不知道问题出在哪一环?那是你还不会分布式链路追踪
微服务线上问题排查困难?不知道问题出在哪一环?那是你还不会分布式链路追踪
129 1
|
运维 监控 Java
使用蓝鲸自愈平台完成java项目程序的自愈机制
使用蓝鲸自愈平台完成java项目程序的自愈机制 1.蓝鲸自愈平台 故障自愈是行业领先的"故障自动化处理"解决方案,提升企业的服务可用性和降低故障处理的人力投入,实现故障自愈从"人工处理"到"无人值守"的变革! 自愈平台可以根据连接配置好的监控平台,当收到我们指定要自愈的监控告警时,首先筛选出告警信息的ip地址,再匹配该服务器所在的集群节点,确认服务器信息,然后将服务器地址传到对应的作业平台的某个作业里,通过作业的具体恢复脚本,实现项目的故障资源机制。
555 0
使用蓝鲸自愈平台完成java项目程序的自愈机制
|
Kubernetes 负载均衡 Cloud Native
如何解决侵入性的问题呢?
如何解决侵入性的问题呢?
116 0