Fastjson は速いですが、私にとってはそうではありません...

著者:寧平
出典: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

日付形式の優先順位

もともとは晴れた午後、非常に単純な修正リクエストでした。インターフェイスによって返される時刻には、年、月、日の日付タイプのみが必要で、時、分、秒は必要ありません。グローバル時刻形式を として構成したためyyyy-MM-dd HH:mmss、Javabean のプロパティにメモを喜んで追加しました。

ローカルでテストして問題ありません。テスト環境に送信して完了です。完璧です。

それから、製品についての質問をいただきましたが、変更点はどうですか?

起きて確認してみましたが、残念ながら日付は変わっておらず、日付はまだ時、分、秒のままです。うっかりしていましたが、このような小さな変更はテスト環境でのものなので検証は追加していません。

したがって、当面の問題は、FastJson の時間設定のローカル設定が有効にならず、グローバル設定が依然として使用されていることです。

開発環境Windowsでは問題ないのに、テスト環境Linuxでは問題が発生するという現象です。両者の違いは何ですか? システムの問題?

問題の原因は 2 つのシステムにあると考えられるので、Linux システムを想定してシミュレーションしてみます。VMオプションに追加-Dos.name=linux

これは Linux システムを完全にシミュレートすることはできません。System.getproperty("os.name")現在のシステムが何らかの操作を実行するかどうかを判断する場合にのみ役立ちます。

この方法では再現せず、再度リモートデバッグを考えました。

しばらく操作は激しく、リモートデバッグはブレークポイントに入ることができましたが、サードパーティのjarパッケージのソースコードにブレークポイントが入ることができませんでした。それは何もしないのと同じだ。

さて、ソースコードに戻りましょう。ソース コードをプルダウンし、ブレークポイントを取得し、JSONSerializerクラス主にwriteWithFormatメソッド) を観察します。問題は見つかりませんでした。

システム側の原因と思われるので、ソースコード内でキーワード「linux」「unix」を検索してみましたが、見つかりませんでした。プロセス全体にブレークポイントを設定し、この部分の観察に集中しましたが、問題は見つかりませんでした。

突然、このメモJSONSerializer.dateFormatPatternを。

この部分には dateformat の調整の問題が含まれており、焦点は this にあります#1868。これは通常 github の号番号です。

1. オープンソース プロジェクトの場合、バグが解決された場合、通常は問題番号がコメントに記載されます。注釈が必要であることが前提となります。問題の原因と結果は、問題番号によってわかります。

2. 一般に、github オープンソース プロジェクトには Issue エリアがあり、この番号で Issue を直接検索することで見つけることができます。

3. ただし、spark や flink など、問題領域を持たないプロジェクト レベルのプロジェクトもいくつかあり、それらの問題の種類は jira プラットフォームを使用して検出、記述、追跡されます。好き:

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

PR を提出する際のタイトルも[jira 编号][spark 子模块(如core/sql) title]ルールに厳密に従ってください。

したがって、この番号を学区に持って行きます。学区がissueあるかどうかに関係なく、学区に直接行って直接検索できます。PR タイトルに問題番号がなくても、PR の説明が存在する必要があります。これは厳格な PR プロセスを備えたオープンソース プロジェクトであるためです。issuepullrequest

そこで質問は次のとおりです。

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

対応する PR は次のとおりです。

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

「問題」に記載されている既知の情報から、彼が遭遇した問題は私の問題と同じであることがわかり、この問題は 2018 年にはすでに提起されていました。しかし、問題の説明はあまり専門的ではなく、環境や FastJson の最も重要なバージョンには関係していません。

PR によると、この問題は 2020 年に最終的に解決される予定です。この期間中に、#1868 #1968 #2029 #2452ISSUES 領域で同様の問題が提起されたのは 4 件のみでした。

問題を解決するバージョンは 1.2.72 です。

この情報は重要です。開発環境のバージョンは1.2.72以降なので比較してみましたが、テスト環境としては問題ありません。

したがって、コナンは、あらゆる可能性を排除した上で、どんなにばかばかしいものであっても、何が残るかが究極の問題であると告げる。

つまり、テスト環境で使用される FastJson のバージョンは 1.2.72 未満です。

コードのパッケージ化に Maven を使用し、依存パッケージが個別に存在するため、この可能性が存在します。

最終的に、テスト環境の依存関係パッケージ ディレクトリで 2 つの Fastjson パッケージを見つけましたが、予想通り、1.2.53 という低バージョンが原因でした。

結局のところ、この問題は主にチーム内の問題によって引き起こされています。しかし、この問題を解決する過程で、いくつかの興味深い状況も見つかりました。

まず、FastJson が特定のバージョンでこの問題を引き起こすのはなぜでしょうか。これは PR の問題に違いありません。rv、テストケースのカバレッジが適切に設定されていません。

2 つ目は、2018 年、2019 年、2020 年のこの問題の解決に取り組む 3 人の広報のタイムラインからです。FastJson プロジェクトの貢献者は数百人いるようですが、彼らは 1 人または一部の主要担当者に依存しすぎていることを説明します。限られたエネルギーでは、優先度の低い一部のバグは手放すことしかできません。

同時に、このプロジェクトの名誉意識はそれほど高くなく(または専門家にとってそれほど魅力的ではなく)、Spark、Flink、Spring、さらにはDubboなどの他のプロジェクトである場合、トップのApacheプロジェクトではありません。これらのプロジェクトのいずれかが実現しないことは想像できます。複雑なバグは 3 年間保留されています。これらのトップのオープンソース プロジェクトでは、誰もが PR を提出するためにいくつかのバグを必死に見つけようとしています。

もちろん、上記は私の個人的な推測にすぎません。

リプレイ時にFastJsonで問題が発生した場合は最初からgithubのIssueエリアに行くと先人に踏みにじられている可能性が高いです。

$ref 循環参照の問題

上記のテスト インターフェイスはフロントエンドに何を返しますか?

循環参照検出が何なのかはわかりませんが、現時点では私の知識の盲点です。この時点で、 2 つのリスト オブジェクト内のyoung参照がこのオブジェクトを指していることがわかりました。次に、2 番目の参照では、シリアル化時に最初の参照の対応するオブジェクト参照を直接指します。もちろん、この問題に遭遇したときは、fastjson 以外の問題を注意深く観察して除外しましたが、今回は賢明に学び、Github の問題エリアに直接アクセスして検索しましたchildren王麻子childrenyoung$ref

案の定、同じ考えを持つ人がたくさんいて、質問数は 150 近くあり、時間的にはかなり新しいものです。「閉じる」をクリックしました。閉じられているので、解決する必要があります。

閉じられた領域で最初の質問をクリックすると、作成者は fastjson2 にアップグレードするように求めてきました。? ? ?

私の理解が正しければ、FastJson と FastJson2 は 2 つのバージョンの違いではなく、2 つのプロジェクトの違いです。APIには互換性の問題もあるといわれています。このように直接アップグレードするのは、言うは易く行うは難しです。

これもスロットだと思います。FastJson には安定して維持されているバージョンがないようです。問題が発生すると常にアップグレードされます。アップグレード プロセス中に、品質管理がうまく機能せず、新たな問題が発生しました。

バージョンアップしても、現在のプロジェクトで解決策を見つけてみましょう。最後に、別の質問で問題と解決策が見つかりました。

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

これは循環参照検出によるものであることがわかりました。この問題はを設定することで回避できますSerializerFeature.DisableCircularReferenceDetect

ただし、私のコードには実際には循環参照はなく、2 つのサブオブジェクトが同じオブジェクトを参照しているだけです。これは何ですか?間違って?

さらに重要なのは、一部の制御はユーザーの手に委ねるべきではないでしょうか?

たとえば、シリアル化における循環参照という現在の問題は、デフォルトで有効にするのではなく、ユーザーが手動で有効にする必要があります。優先順位の点では、グローバルをオフにする必要があります。循環参照がある場合は、ユーザーがローカルでオンにすることを選択できるようにします。

現在、私のフロントエンドは FastJson を使用せず、"$ref":"$.result.young[1]"この種のテキストに直面していますが、解析できますか? それはできません。

テストしてみたところ、FastJson を使用しても解析できないようです。

: ここでは完全なメッセージ分析を使用する必要があることに注意してください。テスト後、実際にそれが可能です。思い出させてくれてありがとう!

さらに恐ろしい問題は、テスト中に 2 つのサブオブジェクトが同じオブジェクトを参照することです。これは事前に発見されました。テスト環境ではそのような状況がなかった場合、本番環境ではどうなるでしょうか? それは製造上の事故でした。

元々は良いデザインポイントであり、飾りの役割を果たすことができますが、雷雨を引き起こす可能性があり、善意で行われた悪い行為です。

同様に、 もありますSerializerFeature.WriteMapNullValueフィールド値が の場合null、fastjson はデフォルトではフィールドを返しません。もともとフロントエンドとバックエンドで合意があり、nullどう対処するかというロジックであれば、本番環境に突然の雷雨が発生する可能性があります。

これは優れた設計ポイントのようなものですWriteNullListAsEmpty。返されたリストが の場合null、ユーザーはそれをシリアル化することを選択できます[]が、デフォルトでは有効になっていません。ユーザーに追加のオプションを提供します。

要約する

これを書いていると、FastJson には競合製品と比べていくつかのユニークな機能があると実感します。これは本当にいわゆる客観性や公平性のためではなくて、ネガティブなことをもっと書いて、その後にポジティブなことを少し書く必要がある。

記事を書くためにはテストが必要で、競合製品もテストしなければなりませんが、テスト後は FastJson 特有のものではなく、恥ずかしいです。

しかし、信じられないかもしれませんが、オープンソース プロジェクト、特にこのように広く使用されているオープンソース プロジェクトには、学ぶ価値のある何かがあるに違いないと私は今でも言います。オープンソースプロジェクトを一日中顕微鏡で観察すると、必ず多くの問題が見つかります。

この記事の情報ポイントを簡単にまとめます。必ずしも特定のバグではありませんが、このバグを通じて、このバグの背後にある FastJson 情報または傾向を解決します。

  1. reviewtestcase補償が適用されていません
  2. contributor大変なことのように思えますが、主力製品に大きく依存しています。しかし、主力のエネルギーには限りがあり、優先度がそれほど高くない一部のバグは放置するしかありません。
  3. このプロジェクトの名誉感はそれほど高くないか、専門家にとってはそれほど魅力的ではありません)。
  4. 一部の関数ポイントでは、制御の主導権をユーザーに与える必要がありますDisableCircularReferenceDetectWriteMapNullValueデフォルトで有効になっている場合、オンラインで雷雨が非常に簡単に発生します。
  5. 著者は全面的に fastjosn2 に注目しましたが、それ以前でさえ、fastjson の安定した保守バージョンは存在せず、常にアップグレードされ、新しい問題が発生していました。

私は fastjson2 がますます良くなることを望みますが、struts2 の足跡をたどることはありません。

最近のおすすめ記事:

1. 1,000 を超える Java 面接の質問と回答 (2022 年最新バージョン)

2.素晴らしい!Java コルーチンが登場します。

3. Spring Boot 2.x チュートリアル、包括的すぎる!

4.画面を爆発や爆発で埋め尽くさないで、デコレーターモードを試してください。これがエレガントな方法です。

5.最新リリースの「Java 開発マニュアル (松山編)」をすぐにダウンロードしてください!

気分がいいので、「いいね!」+「転送」を忘れないでください!

おすすめ

転載: blog.csdn.net/youanyyou/article/details/130879651