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

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

背景


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


记得早些时候,被别人要求写算法代码没写出来,后来我刷了百道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?一旦出现生产事故,岂不是丢了排面?

相关文章
|
存储 安全 Java
如何避免 Java 中的“ArrayStoreException”异常
在Java中,ArrayStoreException异常通常发生在尝试将不兼容的对象存储到泛型数组中时。为了避免这种异常,确保在操作数组时遵循以下几点:1. 使用泛型确保类型安全;2. 避免生类型(raw types)的使用;3. 在添加元素前进行类型检查。通过这些方法,可以有效防止 ArrayStoreException 的发生。
213 3
|
项目管理
设置甘特图依赖关系技巧:项目管理高效指南
甘特图中的依赖关系是项目管理的关键,指任务间需按特定顺序执行的关系。依赖关系通常分为4种:Finish-to-Start(最常见)、Start-to-Start、Finish-to-Finish和Start-to-Finish。Zoho Projects提供了直观的甘特图工具,允许用户轻松设置和管理这些依赖关系,确保项目按需顺畅进行。理解并正确配置任务间的依赖对于项目成功至关重要。
363 1
|
存储 JSON 数据格式
效率工具RunFlow完全手册之进阶篇
RunFlow进阶指南包括搜索文件、计算器、解散文件夹、独立窗口运行、数据导入导出(JSON格式)及同步(本地及云服务如OneDrive)。此外,还提供定时任务功能,利用Cron表达式设定如每日12点执行清理。
185 1
效率工具RunFlow完全手册之进阶篇
|
机器学习/深度学习 自然语言处理
机器翻译句法层面
机器翻译句法层面
327 2
|
存储 JavaScript 前端开发
分享72个NodeJs项目源码总有一个是你想要的
分享72个NodeJs项目源码总有一个是你想要的
1178 0
|
存储 算法 Java
盘点Java集合(容器)概览,Collection和Map在开发中谁用的最多?
盘点Java集合(容器)概览,Collection和Map在开发中谁用的最多?
192 0
|
Web App开发
font-size 设置字体不生效解决方案(小于12px)
字体不变小的原因? 使用 font-size 设置小于 12px 的字体时,发现并不生效(字体不会再缩小了)。 原因是 Chrome 以及 Chromium 内核的浏览器在中文语言下最小字体只能是 12px,大部分浏览器都是如此,所以小于12px字体不会在变小,而是保持12px的大小
909 0
|
小程序 Java 应用服务中间件
Servlet1(1)
Servlet1(1)
128 0
|
监控 物联网 开发者
吃『派』那些事儿——阿里云物联网平台树莓派实战集锦
随着传统硬件开发到物联网开发的转型,小小的树莓派腾云驾雾,开始在各种物联网项目中崭露头角。它也成为了阿里云 IoT 开发者的常客,来自世界各地的开发者分享了他们基于树莓派和阿里云物联网平台的项目。
56781 2
吃『派』那些事儿——阿里云物联网平台树莓派实战集锦
|
Java 数据安全/隐私保护 Perl
常用的正则表达式大全
本文总结了常用的常用的正则表达式
229 0
常用的正则表达式大全