Fastjson 很快,但不适合我....

这篇具有很好参考价值的文章主要介绍了Fastjson 很快,但不适合我....。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者:nyingping
来源:juejin.cn/post/7215886869199863869

记者:大爷您有什么特长呀?

FastJson:我很快。

记者:23423 乘以 4534 等于多少?

FastJson:等于 2343.

记者:??

FastJson:你就说快不快吧!

这个略显马丽苏的标题,各位看官将就着看吧。主要是怕被喷。FastJson 真的很好,我用不用我喜不喜欢的,太不重要了,我只是觉得不适合我而已。

话说以前 Gson 用得好好的,同事极力推荐我使用 FastJson,说很快云云。尽管我们的系统根本感知不出来这点速度差异。

之前也听说 FastJson 爆出来什么重大漏洞,但对我们基本没什么影响,所以这一点倒是没什么偏见。

然后在一个新项目上,脑抽抽,把 Gson 换成了 FastJson,Spring Boot 默认支持的 Jackson 换成了 FastJson。

然后就开始遇到了一些问题。先声明,这真不是尬黑,为了文章效果,故意网上扒些黑料拼凑起来,本文所提到的问题,都来源于本人最近项目的真实经历。

推荐一个开源免费的 Spring Boot 最全教程:

https://github.com/javastacks/spring-boot-best-practice

dateformat 优先级

本来是一个风和日丽的下午,一个非常简单的改动需求。接口返回的时间只需要年月日日期类型不需要时分秒。因为我配置全局时间格式化为yyyy-MM-dd HH:mmss,于是我愉快的在 javabean 的属性上加了个注解。

Fastjson 很快,但不适合我....

本地测试一下,没问题,提交到测试环境,搞定,完美。

然后就接到产品的疑问,改动呢?

我登上去看了一下,唉,没改到啊,日期还是带了时分秒。我大意了啊,这么小的改动,又是在测试环境,就没加验证。

那么现在的直接问题是:FastJson 关于时间配置在局部的配置没有生效,使用的还是全局配置。

现象是,开发环境 Windows 上没有问题,测试环境 Linux 上出现了问题。两者有什么区别呢?系统问题?

既然怀疑是两个系统导致的问题,那么就在 idea 里模拟一下 linux 系统。在 VM options 添加 -Dos.name=linux

这不能完全模拟 linux 系统,只针对通过System.getproperty("os.name")来判断当前系统做某些操作的时候有用。

通过这种方式没复现,我又想到了远程调试。

一阵操作猛如虎,远程调试倒是能进断点,只是断点进不了第三方 jar 包的源码。等于白搞。

得,还是回到源码吧。拉下源码,断点,观察 JSONSerializer 类,主要是writeWithFormat方法。没有发现问题。

因为怀疑是系统导致的,在源码中搜索'linux''unix'关键字,没有发现。断点整个流程重点观察了一下这部份也没有发现问题。

突然在 JSONSerializer.dateFormatPattern上发现了这段注释。

Fastjson 很快,但不适合我....

这部份涉及到了调整 dateformat 的问题,重点在这个#1868,这通常是 github 的问题编号。

1.对于开源项目来说,解决了 BUG,通常会把问题编号放到注释里面去。前提是注释有必要。通过问题编号可以看到问题的前因后果。

2.通常来说,对于 github 开源项目都有 issue 区,拿着这个到编号直接到 issue 一搜就能搜到。

3.但也有一些项级项目,如 spark,flink 是没有 issue 区的,它们的类型问题发现描述追踪都使用 jira 平台。如:

https://issues.apache.org/jira/browse/SPARK-38349

在提交 PR 的时候标题也严格按照[jira 编号][spark 子模块(如core/sql) title]的规则来。

所以拿着这个编号到issue区,不管有没有issue区,也都可以直接到pullrequest区直接搜索,就算 PR 标题里没有问题编号,PR 描述肯定也是有的,只要是有严格 PR 流程的开源项目。

所以这个问题在这里:

https://github.com/alibaba/fastjson/issues/1868

相应的 PR 在这里:

https://github.com/alibaba/fastjson/pull/2706

通过 ISSUES 描述的已知信息,可以看出他遇到的问题跟我是一样的,而这个问题早在 2018 年就提出了。但问题描述不太专业,没有涉及到环境以及最重要的 FastJson 的版本问题。

而通过 PR 可知,这个问题最终在 2020 才解决,期间仅在 ISSUES 区提出的相同问题就有 #1868 #1968 #2029 #24524 个。

解决问题的版本为:1.2.72.

这个信息很关键。我对照了我开发环境的版本,是高于 1.2.72 的,所以没有出现测试环境的问题。

所以,柯南告诉我们,排除了所有可能性,剩下的哪怕再可笑,也是最终问题所在。

那就是,测试环境所用的 FastJson 版本是低于 1.2.72 的。

这种可能性是存在的,因为我们用的是 maven 打代码包,依赖包单独存在。

我最终在测试环境的依赖包目录下发现了两个 Fastjson 包,果然不出所料,有一个 1.2.53 的低版本,它就是罪魁祸首。

所以,最终这个问题有相当大的程度是由于我们团队自身问题引发的。但通过解决这个问题的过程也发现了一些有意思的情况。

首先,FastJson 在某一个版本为什么会引发这个问题。它肯定是某个 PR 改出问题的,rv,testcase 覆盖没有到位。

其次,从试图解决这个问题的 3 个 PR 的时间线,分别在 2018 年,2019 年,2020 年。说明,FastJson 这个项目的 contributor 看起来有百来人,但其中过于依赖其中某 1 个或者某些主力人员。精力有限,某些优先级不那么高的 BUG 只能放任。

Fastjson 很快,但不适合我....

同时这个项目的荣誉感并没有那么高(或者叫并没有那么吸引高手),它并不是 Apache 顶级项目,要是其它诸如 Spark、Flink、Spring,哪怕是 Dubbo 呢,很想象这些项目会有一个并不算复杂的 BUG 悬而未决长达 3 年时间。在这些顶级开源项目,大家都是拼了老命的想找些 BUG 来提交 PR。

当然,以上只是我个人的一点猜测。

复盘,遇到 FastJson 的问题,一开始就应该奔着 github 的 issues 区,它大概率已经被前人踩坑了。

$ref 循环引用问题

Fastjson 很快,但不适合我....

以上测试接口返回前端什么?

Fastjson 很快,但不适合我....

我现在并不知道什么循环引用检测,这时候它是我的知识盲区。此时,我观察到的现象是,youngchildren两个 list 对象中均引用指向了王麻子这个对象。然后,在第 2 次children引用的时候它在序列化的时候直接指向了第 1 个young里相应对象引用。当然遇到这个问题的时候,我在仔细观察排除了非 fastjson 的问题以后,这次我学聪明了,我直接来到了 Github 的 issues 区,搜索$ref

Fastjson 很快,但不适合我....

果然有很多同道中人,近 150 个问题,从时间上来看还挺新鲜。我点击了 closed,既然关闭了,那肯定解决了吧。

我点进了 closed 区第一个问题,然后作者让升级到 fastjson2。???

Fastjson 很快,但不适合我....

如果我没有理解错,FastJson 和 FastJson2 可不是两个版本的区别,是两个项目也!据说 API 也有兼容性问题。直接这样升级过去,谈何容易!

我觉得这也是个槽点,FastJson 好像并没有一个稳定维护的版本,遇到问题总是在升级,升级的过程中也没做好质量控制,又引入了新的问题。

还是在当前项目寻求解决方法吧,哪怕升版本也好啊。终于在另一个问题下面找到了问题所在以及解决方案。

https://github.com/alibaba/fastjson/issues/3643

我现在知道这是由于循环引用检测引起的。通过设置SerializerFeature.DisableCircularReferenceDetect可以避免这个问题。

但是,我的代码其实并没有循环引用啊,只是两个子对象引用了同一个对象而已。这算什么?误伤吗?

更重要的,一些控制权应该在使用者手里?

比如,当前这个循环引用在序列化会出的问题,应该是用户手动去开启,而不是默认给用户开启。在优先级上,全局应该关闭,在有循环引用的地方,让用户选择局部开启。

现在我的前端并没有使用 FastJson,面对"$ref":"$.result.young[1]"这种文本,它能解析吗?它不能呀。

我测试了一下,好像使用 FastJson 也并不能解析回来:

Fastjson 很快,但不适合我....

:经提醒,这里应使用完整报文解析,经测试,确实可以。感谢提醒!

更可怕的问题是,刚好在测试环节有两个子对象引用了同一个对象,被我提前发现了。如果测试环境没有这样的情况,在生产环境刚好遇到了呢?那就是生产事故了呀。

本来是一个挺好的设计点,能起到锦上添花的作用,但它却可能暴雷,这是好心办坏事。

同样的,还有SerializerFeature.WriteMapNullValue。如果一个字段值为null,fastjson 默认就不返回该字段了。本来前后端约定好,如果为null就怎样处理的逻辑,可能在生产环境中突然暴雷啊。

就像WriteNullListAsEmpty就很好,不错的设计点,如果返回的 list 为null的时候,用户可以选择让它序列化为[],但它也不是默认开启的呀,给了用户额外的选择权,对吧。

总结

写到这里的时候,我是真心觉得 FastJson 有比竞品有些特色的地方。这真不是为了所谓的客观公正,非要负面写多点,再搞点正面的。

为了写文章,那肯定要去试验,得把竞品也拿出来测试一下,一测试发现并不是 FastJson 独有的,尴尬!

但我还是那句话,不管你信不信,对于开源项目,特别是这样一个广泛使用的开源项目,肯定有非常值得学习的地方。一个开源项目,如果整天拿着显微镜去观察,那肯定能找出不少毛病。

这里稍微总结一下本文的信息点。并不一定是某个具体 BUG,而是通过这个 BUG,解决这个 BUG 背后所展现出来的 FastJson 的信息或趋势。

  1. reviewtestcase 覆盖不是很到位
  2. contributor 看起来很多,但严重依赖主力人员。而主力精力有限,某些优先级不那么高的 BUG 只能放任。
  3. 这个项目的荣誉感并没有那么高,或者叫并没有那么吸引高手)。
  4. 有些功能点应该把控制主动权交给用户,如 DisableCircularReferenceDetectWriteMapNullValue 等。默认开启非常容易导致线上暴雷。
  5. 作者已经全面转向 fastjosn2,而且哪怕在这之前,对于 fastjson 没有一个稳定维护的版本,不断升级,不断引入新问题。

祝愿 fastjson2 越来越好,不要步 struts2 的后尘。

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!文章来源地址https://www.toymoban.com/news/detail-459592.html

到了这里,关于Fastjson 很快,但不适合我....的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 文心一言作画:有点东西但不多...

    随着ChatGPT的持续火热 与AI领域有关的话题 是越来越热闹了 前几天百度发布 “文心一言” 自然也成了网友们 重点关注的对象 不过大家的目光主要还是集中在 文心一言的绘画功能上 在人工智能加成下出来的画面 一个比一个绝 成功颠覆 大家对绘画的认知 生意火爆的商铺 只

    2024年02月09日
    浏览(30)
  • 前端异常错误处理(包括但不限于react,vue)

    错误异常发生 页面js报错 请求报错 页面资源加载报错 promise异常 iframe加载异常 页面奔溃卡顿异常 处理异常的方法 1、react 自带的errorBoundaries 2、 react 自定义Hooks 3、 vue errorHandler 4、try catch 对特定的代码进行捕获 5、window.addEventListerner 6、window.onerror 7、 window.unhandledrejection 8、

    2024年02月16日
    浏览(45)
  • vue项目页面空白但不报错产生的原因分析

    为了避免这种情况我们可以在新页面写一些文字等进行页面展示 如果配置两个路由是重复的,比如配置了两个path:\\\'/user\\\' ,那么访问就会看到空白页面,这时候删除一个重复的配置路由即可 把app.js看成是顶级的路由,再次创建的路由是属于二级路由 路由导航守卫中,next()相当

    2024年02月11日
    浏览(44)
  • 秋招看到github上不错的项目,但不知道该咋学?

    作者:阿秀 阿秀的学习笔记:https://interviewguide.cn 你好,我是阿秀。 昨天的文章中提到了校招过程中简历上相对而言比较重要的两个地方: 实习经历和项目经历 ,昨天已经聊过实习相关话题:超级纠结!又想去实习又想全力准备秋招...今天来聊一聊项目经历。 打算找开发技

    2023年04月08日
    浏览(27)
  • 用 ChatGPT 尝试 JavaScript 交互式学习体验,有用但不完美

    很好,但还不能取代专家导师,有时还会犯错! ChatGPT 教小狗编程( Midjourney 创作) GPT-4刚刚发布,相较于GPT-3.5,它有显著的增强功能。其中之一是它在更长时间的交互和更大的提示下,能够更好地保持连贯性。 多年来,我一直致力于建立前端教学网站,为JavaScript开发人员

    2024年02月02日
    浏览(47)
  • 程序员都熟悉但不一定说得清的操作系统基本概念

    任何计算机系统都包含一个名为操作系统的基本程序集合。在这个集合里,最重要的程序称为内核(kernel)。当操作系统启动时,内核被装入到RAM中,内核中包含了系统运行所必不可少的很多核心过程(procedure)。其他程序是一些不太重要的使用程序,尽管这些程序为用户提

    2024年02月02日
    浏览(45)
  • x86 32 64 Arm这些听过但不懂,都是什么?是架构还是系统?一文梳理

    x86 听过吗? 64位操作系统知道吧 和x86什么关系 32和64都是什么东西? 曾经的我也一头雾水,今天我才来整理一下,惭愧惭愧! 今天带着沉重的心情来梳理一下学习内容吧 如果你很熟悉很了解计算机的话,应该知道,处理器、操作系统、驱动、软件都有32位和64位之分,只不

    2024年04月29日
    浏览(55)
  • 开机自启动,自动运行的脚本具有管理员权限(即root权限),但不希望手动输入密码

    板端的发布程序自启动: 1、可以选择将应用程序和依赖打包到rootfs中,或者放到单独的eMMC分区中 2、自启动,在rootfs的 /etc/init.d/rcS 或者/etc/inittab 3、配置systemctl 自启动 参考:https://blog.csdn.net/kuangguiyun/article/details/125089060 参考:https://blog.csdn.net/cdnight/article/details/87717644 aut

    2024年02月22日
    浏览(50)
  • 苹果mac怎么打开任何来源(Mac打开允许任何来源的方法)

    很多网友想要知道苹果mac怎么打开任何来源,如果你想在苹果mac电脑上安装或运行一些第三方应用程序,你可能会遇到一个问题:系统提示你无法打开该应用,因为它来自未知的开发者或者包含恶意软件。 这是因为苹果mac系统默认只允许从App Store或者已知的开发者来源安装应

    2024年02月07日
    浏览(51)
  • 微信小程序涉嫌通过中断用户体验、限制用户操作的方式,收集与服务无关的用户个人信息,包括但不限于,手机号、

    微信小程序涉嫌通过中断用户体验、限制用户操作的方式,收集与服务无关的用户个人信息,包括但不限于,手机号、身份证号、生日、住址等,违反《微信小程序平台运营规则》及相关规则,建议尽快整改。具体运营规范:xxxxxxx 解决方法: 如下图所示: 比如健康宝在获取

    2023年04月13日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包