<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      這下對(duì)阿里java這幾條規(guī)范有更深理解了

      背景

      阿里java開發(fā)規(guī)范是阿里巴巴總結(jié)多年來的最佳編程實(shí)踐,其中每一條規(guī)范都經(jīng)過仔細(xì)打磨或踩坑而來,目的是為社區(qū)提供一份最佳編程規(guī)范,提升代碼質(zhì)量,減少bug。
      這基本也是java業(yè)界都認(rèn)可的開發(fā)規(guī)范,我們團(tuán)隊(duì)也是以此規(guī)范為基礎(chǔ),在結(jié)合實(shí)際情況,補(bǔ)充完善。最近在團(tuán)隊(duì)遇到的幾個(gè)問題,加深了我對(duì)這份開發(fā)規(guī)范中幾個(gè)點(diǎn)的理解,下面就一一道來。

      日志規(guī)約

      這條規(guī)范說明了,在異常發(fā)送記錄日志時(shí),要記錄案發(fā)現(xiàn)場信息和異常堆棧信息,不處理要往上throws,切勿吃掉異常。
      堆棧信息比較好理解,就是把整個(gè)方法調(diào)用鏈打印出來,方便定位具體是哪個(gè)方法出錯(cuò)。而案發(fā)現(xiàn)場信息我認(rèn)為至少要能說明:“誰發(fā)生了什么錯(cuò)誤”。
      例如,哪個(gè)uid下單報(bào)錯(cuò)了,哪個(gè)訂單支付失敗了,原因是什么。否則滿屏打印:“user error”,看到你都無從下手。

      在我們這次出現(xiàn)的問題就是有一個(gè)feign,調(diào)用外部接口報(bào)錯(cuò)了,降級(jí)打印了不規(guī)范日志,導(dǎo)致排查問題花了很多時(shí)間。偽代碼如下:

      	@Slf4j
      	@Component
      	class MyClientFallbackFactory implements FallbackFactory<MyClient> {		
      
      		@Override
      		public MyClient create(Throwable cause) {
      			return new MyClient() {
      				@Override
      				public Result<DataInfoVo> findDataInfo(Long id) {
      					log.error("findDataInfo error");
      					return Result.error(SYS_ERROR);
      				}
      			};
      		}
      	}
      

      發(fā)版后錯(cuò)誤日志開始告警,打開kibana看到了滿屏了:“findDataInfo error”,然后開始一頓盲查。
      因?yàn)檫@個(gè)接口本次并沒有修改,所以猜測(cè)是目標(biāo)服務(wù)出問題,上服務(wù)器curl接口,發(fā)現(xiàn)調(diào)用是正常的。
      接著猜測(cè)是不是熔斷器有問題,熔斷后沒有恢復(fù),但重啟服務(wù)后,還是繼續(xù)報(bào)錯(cuò)。開始各種排查,arthas跟蹤,最后實(shí)在沒辦法了,還是老老實(shí)實(shí)把異常打印出來,走發(fā)版流程。

      log.error("{} findDataInfo error", id, cause);
      

      有了異常堆棧信息就很清晰了,原來是返回參數(shù)反序列失敗了,接口提供方新增一個(gè)不兼容的參數(shù)導(dǎo)致反序列失敗。(這點(diǎn)在下一個(gè)規(guī)范還會(huì)提到)
      可見日志打印不清晰給排查問題帶來多大的麻煩,記住:日志一定要打印關(guān)鍵信息,異常要打印堆棧。

      二方庫依賴

      上面提到的返回參數(shù)反序列化失敗就是枚舉造成的,原因是這個(gè)接口返回新增一個(gè)枚舉值,這個(gè)枚舉值原本返回給前端使用的,沒想到還有其它服務(wù)也調(diào)用了它,最終在反序列化時(shí)就報(bào)錯(cuò)了,找不到“xxx”枚舉值。
      比如如下接口,你提交一個(gè)不認(rèn)得的黑色BLACK,就會(huì)報(bào)反序列錯(cuò)誤:

      	enum Color {
      		GREEN, RED
      	}
      
      	@Data
      	class Test {
      		private Color color;
      	}
      
      	@PostMapping(value = "/post/info")
      	public void info(@NotNull Test test) {
      
      	}
      
      	curl --location 'localhost/post/info' \
      	--header 'Content-Type: application/json' \
      	--data '{
          	"testEnum": "BLACK"
      	}'
      

      關(guān)于這一點(diǎn)我們看下作者孤盡對(duì)它的闡述:

      這就是我們出問題的場景,提供方新增了一個(gè)枚舉值,而使用方?jīng)]有升級(jí),導(dǎo)致錯(cuò)誤。可能有的同學(xué)說那通知使用方升級(jí)不就可以了?是的,但這出現(xiàn)了依賴問題,如果使用方有成百上千個(gè),你會(huì)非常頭痛。

      那又為什么說不要使用枚舉作為返回值,而可以作為輸入?yún)?shù)呢?
      我的理解是:作為枚舉的提供者,不得隨意新增/修改內(nèi)容,或者說修改前要同步到所有枚舉使用者,讓大家知道,否則使用者就可能因?yàn)椴徽J(rèn)識(shí)這個(gè)枚舉而報(bào)錯(cuò),這是不可接受的。
      但反過來,枚舉提供者是可以將它作為輸入?yún)?shù)的,如果調(diào)用者傳了一個(gè)不存在的值就會(huì)報(bào)錯(cuò),這是合理的,因?yàn)樘峁┱卟]有說支持這個(gè)值,調(diào)用者正常就不應(yīng)該傳遞這個(gè)值,所以這種報(bào)錯(cuò)是合理的。

      ORM映射

      以下是規(guī)范里的說明:
      1)增加查詢分析器解析成本。
      2)增減字段容易與 resultMap 配置不一致。
      3)無用字段增加網(wǎng)絡(luò)消耗,尤其是 text 類型的字段。

      這都很好理解,就不過多說明。
      在我們開發(fā)中,有的同學(xué)為了方便,還是使用了select *,一直以來也風(fēng)平浪靜,運(yùn)行得好好的,直到有一天對(duì)該表加了個(gè)字段,代碼沒更新,報(bào)錯(cuò)了~,你沒看錯(cuò),代碼沒動(dòng),加個(gè)字段程序就報(bào)錯(cuò)了。
      報(bào)錯(cuò)信息如下:

      數(shù)組越界!問題可以在本地穩(wěn)定復(fù)現(xiàn),先把程序跑起來,執(zhí)行 select * 的sql,再add column給表新增一個(gè)字段,再次執(zhí)行相同的sql,報(bào)錯(cuò)。

      具體原因是我們程序使用了sharding-jdbc做分表(5.1.2版本),它會(huì)在服務(wù)啟動(dòng)時(shí),加載字段信息緩存,在查詢后做字段匹配,出錯(cuò)就在匹配時(shí)。
      具體代碼位置在:com.mysql.cj.protocol.a.MergingColumnDefinitionFactory#createFromFields

      這個(gè)緩存是跟數(shù)據(jù)庫鏈接相關(guān)的,只有鏈接失效時(shí),才會(huì)重新加載。主要有兩個(gè)參數(shù)和它相關(guān):
      spring.shardingsphere.datasource.master.idle-timeout 默認(rèn)10min
      spring.shardingsphere.datasource.master.max-lifetime 默認(rèn)30min

      默認(rèn)緩存時(shí)間都比較長,你只能趕緊重啟服務(wù)解決,而如果服務(wù)數(shù)量非常多,又是一個(gè)生產(chǎn)事故。
      我在sharding sphere github搜了一圈,沒有好的處理方案,相關(guān)鏈接如:
      https://github.com/apache/shardingsphere/issues/21728
      https://github.com/apache/shardingsphere/issues/22824

      大體意思是如果真想這么做,數(shù)據(jù)庫ddl需要通過sharding proxy,它會(huì)負(fù)責(zé)刷新客戶端的緩存,但我們使用的是sharding jdbc模式,那只能老老實(shí)實(shí)遵循規(guī)范,不要select * 了。如果select具體字段,那新增的字段也不會(huì)被select出來,和緩存的就能對(duì)應(yīng)上。
      那么以后面試除了上面規(guī)范說到的,把這一點(diǎn)親身經(jīng)歷也擺出來,應(yīng)該可以加分吧。

      總結(jié)

      每條開發(fā)規(guī)范都有其背后的含義,都是經(jīng)驗(yàn)總結(jié)和踩坑教訓(xùn),對(duì)于團(tuán)隊(duì)的開發(fā)規(guī)范我們都要仔細(xì)閱讀,嚴(yán)格遵守。可以看到上面每個(gè)小問題都可能導(dǎo)致不小的生產(chǎn)事故,保持敬畏之心,大概就是這個(gè)意思了吧。

      更多分享,歡迎關(guān)注我的github:https://github.com/jmilktea/jtea

      posted @ 2023-12-04 10:11  jtea  閱讀(1006)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久精品无码免费不卡| 麻豆国产黄色一级免费片| 国产线播放免费人成视频播放| 国产又色又爽无遮挡免费动态图| 久久免费观看午夜成人网站| 国产中文三级全黄| 中国老熟女重囗味hdxx| 国产精品中文字幕第一区| 中文字幕av无码不卡| 久久人人爽人人人人爽av| 亚洲国产成人不卡高清麻豆| 日韩在线观看精品亚洲| 国产成人啪精品午夜网站| 国产无遮挡无码视频在线观看 | 日韩国产成人精品视频| 免费人妻无码不卡中文18禁| 国产午精品午夜福利757视频播放| 动漫AV纯肉无码AV电影网| 日韩亚av无码一区二区三区| 久久99精品久久久久久青青| 岛国最新亚洲伦理成人| 亚洲ΑV久久久噜噜噜噜噜| 白丝乳交内射一二三区| 精品人妻蜜臀一区二区三区| 好紧好爽午夜视频| 风流少妇又紧又爽又丰满| 99久久精品国产一区二区蜜芽| 久久96国产精品久久久| 久久精品熟妇丰满人妻久久| 乱妇乱女熟妇熟女网站| 国产午夜福利免费入口| 国产自拍偷拍视频在线观看| 国产女人喷潮视频免费| 日韩av一区二区三区不卡| 国产午夜亚洲精品国产成人| 浦北县| 欧美人人妻人人澡人人尤物| 少妇人妻偷人精品视蜜桃| 最新国产精品亚洲| 99九九热久久只有精品| 国产精品va在线观看无码不卡|