亚洲精品久久久久久久久久久,亚洲国产精品一区二区制服,亚洲精品午夜精品,国产成人精品综合在线观看,最近2019中文字幕一页二页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一行l(wèi)og日志,引發(fā)了P1的線上事故

jf_ro2CN3Fa ? 來源:芋道源碼 ? 作者:芋道源碼 ? 2022-11-07 15:48 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群


線上事故回顧

前段時間同事新增了一個特別簡單的功能,晚上上線前review代碼時想到公司拼搏進取的價值觀臨時他加一行 log 日志,覺得就一行簡單的日志基本上沒啥問題,結果剛上完線后一堆報警,趕緊回滾了代碼,找到問題刪除了添加日志的代碼,重新上線完畢。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

情景還原

?

定義了一個 CountryDTO

?

publicclassCountryDTO{
privateStringcountry;

publicvoidsetCountry(Stringcountry){
this.country=country;
}

publicStringgetCountry(){
returnthis.country;
}

publicBooleanisChinaName(){
returnthis.country.equals("中國");
}
}

?

定義測試類 FastJonTest

?

publicclassFastJonTest{
@Test
publicvoidtestSerialize(){
CountryDTOcountryDTO=newCountryDTO();
Stringstr=JSON.toJSONString(countryDTO);
System.out.println(str);
}
}

運行時報空指針錯誤:

64775822-5d7b-11ed-a3b6-dac502259ad0.png空指針

通過報錯信息可以看出來是序列化的過程中執(zhí)行了isChinaName()方法,這時候this.country變量為空,那么問題來了:

  • 序列化為什么會執(zhí)行isChinaName()呢?
  • 引申一下,序列化過程中會執(zhí)行那些方法呢?

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權限、多租戶、數(shù)據(jù)權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

源碼分析

通過 debug 觀察調用鏈路的堆棧信息

652d8e80-5d7b-11ed-a3b6-dac502259ad0.png65920e46-5d7b-11ed-a3b6-dac502259ad0.jpg

調用鏈中的ASMSerializer_1_CountryDTO.writeFastJson使用asm技術動態(tài)生成了一個類ASMSerializer_1_CountryDTO。

?

asm技術其中一項使用場景就是通過到動態(tài)生成類用來代替java反射,從而避免重復執(zhí)行時的反射開銷

?

JavaBeanSerizlier序列化原理

通過下圖看出序列化的過程中,主要是調用JavaBeanSerializer類的write()方法。

65b3b3de-5d7b-11ed-a3b6-dac502259ad0.pngObjectSerializer實現(xiàn)類JavaBeanSerializer

JavaBeanSerializer主要是通過getObjectWriter()方法獲取,通過對getObjectWriter()執(zhí)行過程的調試,找到比較關鍵的com.alibaba.fastjson.serializer.SerializeConfig#createJavaBeanSerializer方法,進而找到 com.alibaba.fastjson.util.TypeUtils#computeGetters

publicstaticListcomputeGetters(Classclazz,//
JSONTypejsonType,//
MapaliasMap,//
MapfieldCacheMap,//
booleansorted,//
PropertyNamingStrategypropertyNamingStrategy//
){
//省略部分代碼....
Method[]methods=clazz.getMethods();
for(Methodmethod:methods){
//省略部分代碼...
if(method.getReturnType().equals(Void.TYPE)){
continue;
}
if(method.getParameterTypes().length!=0){
continue;
}
//省略部分代碼...
JSONFieldannotation=TypeUtils.getAnnotation(method,JSONField.class);
//省略部分代碼...
if(annotation!=null){
if(!annotation.serialize()){
continue;
}
if(annotation.name().length()!=0){
//省略部分代碼...
}
}
if(methodName.startsWith("get")){
//省略部分代碼...
}
if(methodName.startsWith("is")){
//省略部分代碼...
}
}
}

從代碼中大致分為三種情況:

  • @JSONField(.serialize = false, name = "xxx")注解
  • getXxx() : get開頭的方法
  • isXxx():is開頭的方法

序列化流程圖

65d61064-5d7b-11ed-a3b6-dac502259ad0.png序列化流程圖

示例代碼

/**
*case1:@JSONField(serialize=false)
*case2:getXxx()返回值為void
*case3:isXxx()返回值不等于布爾類型
*case4:@JSONType(ignores="xxx")
*/
@JSONType(ignores="otherName")
publicclassCountryDTO{
privateStringcountry;

publicvoidsetCountry(Stringcountry){
this.country=country;
}

publicStringgetCountry(){
returnthis.country;
}

publicstaticvoidqueryCountryList(){
System.out.println("queryCountryList()執(zhí)行!!");
}

publicBooleanisChinaName(){
System.out.println("isChinaName()執(zhí)行!!");
returntrue;
}

publicStringgetEnglishName(){
System.out.println("getEnglishName()執(zhí)行!!");
return"lucy";
}

publicStringgetOtherName(){
System.out.println("getOtherName()執(zhí)行!!");
return"lucy";
}

/**
*case1:@JSONField(serialize=false)
*/
@JSONField(serialize=false)
publicStringgetEnglishName2(){
System.out.println("getEnglishName2()執(zhí)行!!");
return"lucy";
}

/**
*case2:getXxx()返回值為void
*/
publicvoidgetEnglishName3(){
System.out.println("getEnglishName3()執(zhí)行!!");
}

/**
*case3:isXxx()返回值不等于布爾類型
*/
publicStringisChinaName2(){
System.out.println("isChinaName2()執(zhí)行!!");
return"isChinaName2";
}
}

運行結果為:

isChinaName()執(zhí)行!!
getEnglishName()執(zhí)行!!
{"chinaName":true,"englishName":"lucy"}

代碼規(guī)范

可以看出來序列化的規(guī)則還是很多的,比如有時需要關注返回值,有時需要關注參數(shù)個數(shù),有時需要關注@JSONType注解,有時需要關注@JSONField注解;當一個事物的判別方式有多種的時候,由于團隊人員掌握知識點的程度不一樣,這個方差很容易導致代碼問題,所以盡量有一種推薦方案。

這里推薦使用@JSONField(serialize = false)來顯式的標注方法不參與序列化,下面是使用@JSONField注解后的代碼,是不是一眼就能看出來哪些方法不需要參與序列化了。

publicclassCountryDTO{
privateStringcountry;

publicvoidsetCountry(Stringcountry){
this.country=country;
}

publicStringgetCountry(){
returnthis.country;
}

@JSONField(serialize=false)
publicstaticvoidqueryCountryList(){
System.out.println("queryCountryList()執(zhí)行!!");
}

publicBooleanisChinaName(){
System.out.println("isChinaName()執(zhí)行!!");
returntrue;
}

publicStringgetEnglishName(){
System.out.println("getEnglishName()執(zhí)行!!");
return"lucy";
}

@JSONField(serialize=false)
publicStringgetOtherName(){
System.out.println("getOtherName()執(zhí)行!!");
return"lucy";
}

@JSONField(serialize=false)
publicStringgetEnglishName2(){
System.out.println("getEnglishName2()執(zhí)行!!");
return"lucy";
}

@JSONField(serialize=false)
publicvoidgetEnglishName3(){
System.out.println("getEnglishName3()執(zhí)行!!");
}

@JSONField(serialize=false)
publicStringisChinaName2(){
System.out.println("isChinaName2()執(zhí)行!!");
return"isChinaName2";
}
}

三個頻率高的序列化的情況

65fbca66-5d7b-11ed-a3b6-dac502259ad0.png三個頻率高的序列化的情況

以上流程基本遵循,發(fā)現(xiàn)問題 --> 原理分析 --> 解決問題 --> 升華(編程規(guī)范)。

  • 圍繞業(yè)務上:解決問題 -> 如何選擇一種好的額解決方案 -> 好的解決方式如何擴展 n 個系統(tǒng)應用;
  • 圍繞技術上:解決單個問題,順著單個問題掌握這條線上的原理。

但其實這段代碼我并不滿意,原因是和 FastJson 依賴太高了。我想要的效果是,不依賴任何特定的 JSON 序列化框架。當我需要替換掉它的時候,隨時可以替換掉。

并且在寫代碼時,不要過于依賴日志。打日志只需要打緊要且關鍵的信息即可,不要什么日志都打,我曾見過一個系統(tǒng),一個小時,把 128G 磁盤跑滿的管理系統(tǒng)。幾乎沒啥并發(fā),但幾乎每個請求都輸出幾 M 的日志,這件事我后面會單獨拿出來講講。

關于@JSONField@JSONType等特性注解,后面我會在團隊內規(guī)范并給出新的解耦方案,把它們移除掉。



審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4928

    瀏覽量

    72768
  • 日志
    +關注

    關注

    0

    文章

    145

    瀏覽量

    11019

原文標題:一行l(wèi)og日志,引發(fā)了P1的線上事故

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    韓國交通部部長一行參訪小馬智

    10月17日,韓國國土交通部部長金潤德一行抵達北京亦莊參觀小馬智,并試乘了無人駕駛Robotaxi。小馬智副總裁高天帶隊接待了代表團一行。隨團參訪成員包括韓國國土交通部移動出行與汽
    的頭像 發(fā)表于 10-24 16:59 ?916次閱讀

    P1電表:歐洲能源管理的工業(yè)級“解碼引擎”

    下,智能電表上不起眼的P1端口,成了破解精細化能源管理難題的關鍵入口。 什么是P1電表? P1電表是種專業(yè)級能源監(jiān)測設備,通過智能電表上的標準化P
    的頭像 發(fā)表于 10-13 16:00 ?211次閱讀
    <b class='flag-5'>P1</b>電表:歐洲能源管理的工業(yè)級“解碼引擎”

    廣西政府領導一行到訪西井科技

    近日,廣西壯族自治區(qū)人民政府副秘書長,自治區(qū)大數(shù)據(jù)發(fā)展局黨組書記、局長趙志剛一行到訪西井科技上??偛?。
    的頭像 發(fā)表于 07-26 15:30 ?893次閱讀

    東鴻ES-P1P1智能電表的&quot;數(shù)據(jù)破壁者&quot;

    東鴻ES-P1電能追蹤器解決歐洲P1電表數(shù)據(jù)獲取難題。即插即用接口,直連歐洲電表P1端口。無線同步實時用電數(shù)據(jù)至本地設備,隨時查看能耗趨勢與成本分析,為節(jié)能管理提供智能化方案。產品兼容歐洲主流電表標準,安裝便捷且保障數(shù)據(jù)安全,適
    的頭像 發(fā)表于 06-23 17:33 ?630次閱讀

    上海雷克薩斯一行到訪中汽中心

    近日,雷克薩斯(上海)新能源有限公司(以下簡稱“上海雷克薩斯”)總經理加藤武郎一行到訪中汽中心,與中汽中心黨委副書記王曉杉進行了座談交流。
    的頭像 發(fā)表于 06-13 15:18 ?793次閱讀

    中汽中心一行到訪理想汽車

    近日,中汽中心副總經理周華一行赴理想汽車走訪交流,受到理想汽車總裁馬東輝等領導的熱情接待。
    的頭像 發(fā)表于 06-11 13:45 ?570次閱讀

    全棧開發(fā)進階指南:LuatOS-log庫從入門到實戰(zhàn)!

    本文將帶你深入探索LuatOS系統(tǒng)中log庫的核心原理與實戰(zhàn)技巧,通過代碼示例解析日志管理、錯誤追蹤及性能優(yōu)化的最佳實踐,助力全棧工程師構建更穩(wěn)健的物聯(lián)網應用。 今天,我們起來認識LuatOS
    的頭像 發(fā)表于 05-15 16:12 ?2561次閱讀
    全棧開發(fā)進階指南:LuatOS-<b class='flag-5'>log</b>庫從入門到實戰(zhàn)!

    全球能源巨頭沙特阿美一行到訪維智科技

    近日,場意義非凡的交流在上海維智科技總部展開。全球能源巨頭沙特阿美執(zhí)行副總裁兼首席技術官Ahmed Al-Khowaiter、中東知名科技投資基金 P7 管理人Raed Twaily一行到訪,雙方圍繞時空人工智能技術的全球化應
    的頭像 發(fā)表于 05-14 09:41 ?690次閱讀

    解鎖LuatOS-log庫:全棧工程師的日志管理實戰(zhàn)課!

    針對全棧開發(fā)者設計的實戰(zhàn)教程,本文聚焦LuatOS平臺log庫的高效使用,從基礎配置到高級調試策略,手把手教你搭建可擴展的日志系統(tǒng),提升項目維護效率。 今天,我們起來認識LuatOS的log
    的頭像 發(fā)表于 05-12 15:23 ?1222次閱讀
    解鎖LuatOS-<b class='flag-5'>log</b>庫:全棧工程師的<b class='flag-5'>日志</b>管理實戰(zhàn)課!

    打造AI工控新高度:基于此芯P1的EVB設計方案

    此芯P1的EVB設計方案以其強大的算力、豐富的接口和低功耗特性,為AI工控、邊緣計算等領域提供了全新的解決方案。如果您正在尋找款高性能、靈活適配的計算平臺,此芯P1無疑是您的不二之選。
    的頭像 發(fā)表于 05-12 11:30 ?900次閱讀
    打造AI工控新高度:基于此芯<b class='flag-5'>P1</b>的EVB設計方案

    浙江大學師生一行蒞臨行芯科技參觀交流

    日前,浙江大學竺可楨學院師生一行來到杭州芯科技有限公司參觀交流。
    的頭像 發(fā)表于 05-06 10:28 ?757次閱讀

    越南副總理一行到訪商湯科技

    近日,越南副總理阮志勇率代表團一行到訪商湯。深圳商湯總經理李廷波主介紹、商湯科技首席人力資源官張春娟及商湯科技聯(lián)合創(chuàng)始人、元蘿卜智能科技有限公司總裁馬堃等陪同熱情接待考察團一行
    的頭像 發(fā)表于 03-24 10:01 ?792次閱讀

    此芯首款高算力AI SoC芯片P1:性能與應用全解析

    此芯推出首款高算力AI SOC芯片P1,采用6nm工藝,集成45TOPS AI算力,支持100億參數(shù)以內的大模型部署,適配計算機視覺、自然語言處理等多場景。P1搭載Armv9架構CPU,8性能核+4
    的頭像 發(fā)表于 03-14 16:32 ?1361次閱讀
    此芯首款高算力AI SoC芯片<b class='flag-5'>P1</b>:性能與應用全解析

    Linux實時查看日志的四種命令詳解

    如何在Linux中實時查看日志文件的內容?那么有很多實用程序可以幫助用戶在文件更改或不斷更新時輸出文件的內容。在Linux中實時顯示文件內容的常用命令是tail命令(有效地管理文件)。 1
    的頭像 發(fā)表于 01-13 10:45 ?3810次閱讀
    Linux實時查看<b class='flag-5'>日志</b>的四種命令詳解

    TFP401AMP第一行丟失4個像素是什么原因導致的?

    PC送出來的HDMI信號通過TFP401AMP轉RGB后送到LCD,發(fā)現(xiàn)圖片第一行會有4個像素丟失,經過邏輯分析儀抓取HS信號發(fā)現(xiàn):HS在DE信號low的時間段里周期為31.774
    發(fā)表于 12-30 08:39