日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

项目复盘思考

發(fā)布時(shí)間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 项目复盘思考 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

對(duì)自己所參與過(guò)的事物做個(gè)復(fù)盤(pán)是個(gè)好習(xí)慣,能讓自己對(duì)事物有個(gè)更深的了解。比如說(shuō),讀了一本書(shū),那么這個(gè)時(shí)候你需要回去思考:這本書(shū)講了些啥,對(duì)你有何影響;又或者,你參與了一個(gè)活動(dòng),你完了后,你也可以對(duì)其進(jìn)行復(fù)盤(pán),思考下這個(gè)活動(dòng)的意義,這個(gè)活動(dòng)是讓你增加見(jiàn)識(shí)了還是讓你放松心情了等;再或者,你參與了一個(gè)項(xiàng)目,這個(gè)時(shí)候還是可以復(fù)盤(pán),考慮項(xiàng)目的進(jìn)展中的難點(diǎn)等。其實(shí)復(fù)盤(pán),就是對(duì)自己經(jīng)歷過(guò)的事物進(jìn)行思考總結(jié)。是一個(gè)很好的自我矯正升華的方式。

下面我以一個(gè)程序員參與的項(xiàng)目的復(fù)盤(pán)來(lái)簡(jiǎn)要說(shuō)明下,復(fù)盤(pán)過(guò)程中可能思考的問(wèn)題和方向。

拋出問(wèn)題

  • 為什么要做這個(gè)項(xiàng)目?
  • 項(xiàng)目是怎么選型的?
  • 項(xiàng)目的規(guī)模(數(shù)據(jù)量、并發(fā)量、增量)?
  • 項(xiàng)目中遇到了什么難點(diǎn)?是如何解決這些問(wèn)題的?
  • 項(xiàng)目還有什么不足?有什么解決方案?
  • 問(wèn)題解答

    這里以之前我做過(guò)的一個(gè)出單項(xiàng)目為例子簡(jiǎn)單說(shuō)一下可能的問(wèn)題思考總結(jié)。


    為什么要做這個(gè)項(xiàng)目

    面對(duì)日益增加的互聯(lián)網(wǎng)合作伙伴對(duì)接平安的出單系統(tǒng),原有的系統(tǒng)已經(jīng)無(wú)法完全滿足與日俱增出單壓力。對(duì)此,針對(duì)保險(xiǎn)單較為單一的投保,分離業(yè)務(wù),做成一個(gè)互聯(lián)網(wǎng)出單系統(tǒng)。快速響應(yīng)合作伙伴的出單需求.

    項(xiàng)目是怎么選型的

    SpringCloud: 成熟的為服務(wù)體系,JAVA生態(tài),成員已有springboot基礎(chǔ). 公司內(nèi)部已有基于springcloud的成功案例.
    MongoDB: 簡(jiǎn)單保單類型適合嵌套文檔形式存儲(chǔ). 分布式(支持分片,可擴(kuò)展), 高可用(可配置副本)
    RockMq: 在保證了可靠性的前提下,隊(duì)列特性足夠豐富,可運(yùn)維程度比較高。其快速橫向擴(kuò)展的能力,也能保證未來(lái)幾年我們對(duì)其性能的要求。RocketMQ基于Java語(yǔ)言開(kāi)發(fā)

    RabbitMQ由于采用同步刷盤(pán),其可靠性非常強(qiáng)(采用ACK機(jī)制),但是性能卻是這三款開(kāi)源產(chǎn)品中最差的,在實(shí)際的測(cè)試中也能很輕易的得到驗(yàn)證。所以RabbitMQ更適合使用在對(duì)消息可靠性要求很高,但對(duì)消息吞吐量不太敏感的場(chǎng)景中。這里額外提一下一個(gè)個(gè)人經(jīng)驗(yàn),我們?cè)趯?duì)開(kāi)源產(chǎn)品選型時(shí),建議大家需要了解該產(chǎn)品是基于什么協(xié)議/規(guī)范實(shí)現(xiàn)的,這樣大致就清楚了這款開(kāi)源產(chǎn)品可以解決什么問(wèn)題,適用于哪些場(chǎng)景。例如消息中間件領(lǐng)域的AMQP、JMS、STOMP協(xié)議,工作流領(lǐng)域的bpmn2.0標(biāo)準(zhǔn)。
    Kafka是由LinkedIn開(kāi)發(fā)的一個(gè)分布式的消息系統(tǒng),使用Scala編寫(xiě),它以可水平擴(kuò)展和高吞吐率而被廣泛使用。目前越來(lái)越多的開(kāi)源分布式處理系統(tǒng)如Cloudera、Apache Storm、Spark都支持與Kafka集成。Kafka的高吞吐是其最重要的一個(gè)特點(diǎn),這也帶來(lái)了一個(gè)潛在隱患在異常情況下,其消息丟失率較高。所以它比較適用于將高吞吐作為首要考慮,能容忍少量消息丟失的場(chǎng)景。例如作為大數(shù)據(jù)平臺(tái)數(shù)據(jù)傳輸?shù)牧魇焦艿?#xff0c;其在日志采集場(chǎng)景中也被廣泛應(yīng)用。
    RocketMQ的核心架構(gòu)設(shè)計(jì)參考了Kafka,有網(wǎng)友甚至提出它是Kafka Java版本的實(shí)現(xiàn)。不可否認(rèn)的是RocketMQ的設(shè)計(jì)實(shí)現(xiàn)的確參考了很多Kafka的設(shè)計(jì)思想,比如說(shuō)均采用了基于文件的存儲(chǔ)方案、Topic的并行化操作、底層網(wǎng)絡(luò)協(xié)議均基于TCP (RocketMQ使用netty成熟的解決方案,Kafka使用一套自行設(shè)計(jì)的基于TCP層的協(xié)議),但兩者之間相對(duì)特點(diǎn)還是比較明顯,RocketMQ在犧牲了部分性能的前提下,提供了更多的機(jī)制來(lái)保證消息的可靠性,同時(shí)也提供了更為豐富和實(shí)用的消息隊(duì)列特性。比如說(shuō)消息的查詢、消息的回溯。這些接口的提供,極大的便利了消息中間件的運(yùn)維,提高了在一些異常場(chǎng)景中的故障恢復(fù)速度。
    最終選擇了RocketMQ,理由是RocketMQ在保證了可靠性的前提下,隊(duì)列特性足夠豐富,可運(yùn)維程度比較高。其快速橫向擴(kuò)展的能力,也能保證未來(lái)幾年我們對(duì)其性能的要求。另外RocketMQ基于Java語(yǔ)言開(kāi)發(fā),也降低了我們后續(xù)對(duì)其進(jìn)行擴(kuò)展和二次開(kāi)發(fā)的難度。

    項(xiàng)目的規(guī)模(數(shù)據(jù)量、并發(fā)量、增量等)

    1wQPS, 每日單量60w、目前已有6000w單量.
    還有比如說(shuō)項(xiàng)目部署的規(guī)模等情況(eg. 服務(wù)器多少臺(tái),緩存服務(wù),消息中間件等是如何部署的)

    項(xiàng)目中遇到了什么難點(diǎn)?是如何解決這些問(wèn)題的

    壓測(cè)監(jiān)控查看各方面的系統(tǒng)資源并未達(dá)到瓶頸,但是并發(fā)量達(dá)不到預(yù)期

    問(wèn)題解決和排查思路: 老一套方案,首先定位性能瓶頸: CPU/內(nèi)存/IO等

  • ps aux | grep appname 查看進(jìn)程ID

  • top -H pid查看cpu和內(nèi)存的使用情況(未發(fā)現(xiàn)應(yīng)用服務(wù)器的cpu和內(nèi)存有較高的使用率)
    cpu繁忙一般可能的情況如下:

    • 線程中的不合理循環(huán)
    • 發(fā)生了頻繁的full gc
    • 多線程的上下文頻繁切換
  • 通過(guò)jmap/jstack命令查看內(nèi)存/線程信息(可能是線程出現(xiàn)等待導(dǎo)致,所以也需要查看線程信息)

  • 通過(guò)Arthas工具查看接口執(zhí)行過(guò)程中每個(gè)方法的耗時(shí)情況

    $trace xxx #cost
    方法內(nèi)部調(diào)用路徑,并輸出方法路徑上的每個(gè)節(jié)點(diǎn)上耗時(shí), trace 命令能主動(dòng)搜索 class-pattern/method-pattern 對(duì)應(yīng)的方法調(diào)用路徑,渲染和統(tǒng)計(jì)整個(gè)調(diào)用鏈路上的所有性能開(kāi)銷和追蹤調(diào)用鏈路。trace 能方便的幫助你定位和發(fā)現(xiàn)因 RT 高而導(dǎo)致的性能問(wèn)題缺陷,但其每次只能跟蹤一級(jí)方法的調(diào)用鏈路

    結(jié)果如下(包名經(jīng)過(guò)處理):

    +---[0.001162ms] com.xxx.service.dto.ApplyResultDTO:setApplyPolicyNo()+---[0.511972ms] com.xxx.service.apply.save.ApplySaveService:fillApplyPolicyNo()+---[19.709352ms] com.xxx.service.apply.save.ApplySaveService:saveContractDTOInfo()+---[1.313593ms] com.xxx.service.apply.save.ApplySaveService:saveApplyParameterInfo()+---[min=4.35E-4ms,max=9.48E-4ms,total=0.002326ms,count=3] java.lang.StringBuilder:<init>()+---[min=5.1E-4ms,max=0.00146ms,total=0.004705ms,count=6] java.lang.StringBuilder:append()+---[0.001361ms] com.xxx.base.dto.BaseInfoDTO:getTransactionNo()+---[min=4.86E-4ms,max=6.61E-4ms,total=0.001777ms,count=3] java.lang.StringBuilder:toString()+---[523.544075ms] com.xxx.common.service.redis.RedisService:stringSet()+---[9.91E-4ms] com.xxx.common.util.StringUtils:isNotBlank()+---[min=6.07E-4ms,max=7.75E-4ms,total=0.001382ms,count=2] java.lang.String:equals()+---[min=5.03E-4ms,max=6.95E-4ms,total=0.001198ms,count=2] java.lang.Integer:intValue()+---[min=592.763104ms,max=868.853641ms,total=1461.616745ms,count=2] com.xxx.common.service.redis.RedisService:ObjectSet()
  • 通過(guò)trace 定位到是redis耗時(shí)后,定位redis問(wèn)題

  • 查看redis服務(wù)器狀態(tài),發(fā)現(xiàn)壓測(cè)時(shí)有臺(tái)服務(wù)器的 查看redis服務(wù)器狀態(tài),發(fā)現(xiàn)壓測(cè)時(shí)有臺(tái)服務(wù)器的CPU達(dá)到70%左右
  • slowlog get 命令獲取redis慢查詢定位到是某個(gè)key的讀取導(dǎo)致, 到此發(fā)現(xiàn)是redis數(shù)據(jù)的熱點(diǎn)問(wèn)題
  • 解決方案

  • 出現(xiàn)該問(wèn)題是有工具類濫用redis的問(wèn)題,每次獲取數(shù)據(jù)都從redis獲取。首先,調(diào)整代碼,增加內(nèi)存緩存。redis緩存刷新時(shí)發(fā)布事件動(dòng)態(tài)刷新內(nèi)存緩存; 然后,優(yōu)化存儲(chǔ)的dto,只緩存必要的數(shù)據(jù)。減小數(shù)據(jù)量;最后,替換序列化工具,將jackson序列化替換為fastjson.
  • 流程中部分耗時(shí)的IO操作線程異步后臺(tái)處理
  • 項(xiàng)目還有什么不足?有什么解決方案?

  • 缺少網(wǎng)關(guān)限流

    spring-cloud-zuul-ratelimit、 針對(duì)不同合作伙伴分別限流

  • 使用了較多的內(nèi)存緩存,這些緩存通常無(wú)需改變

    調(diào)整jvm參數(shù),如增加老年代比例。減少gc耗時(shí)停頓時(shí)間

  • 使用緩存時(shí)沒(méi)考慮并發(fā)問(wèn)題導(dǎo)致的數(shù)據(jù)不一致性

    目前使用緩存的時(shí)候,策略是先刪除緩存后更新數(shù)據(jù)庫(kù)的,在并發(fā)情況下,可能會(huì)導(dǎo)致緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)不一致,該問(wèn)題需要解決。目前考慮的解決方案有如下幾種:

    • 在寫(xiě)數(shù)據(jù)庫(kù)操作的時(shí)候。利用Redis加鎖,使得數(shù)據(jù)更新完成之后才能讀緩存
    • 寫(xiě)數(shù)據(jù)庫(kù)后,啟動(dòng)一個(gè)延遲定時(shí)任務(wù),定時(shí)任務(wù)負(fù)責(zé)讀取數(shù)據(jù)庫(kù)的最新數(shù)據(jù)更新Redis中的緩存
    • Redis讀寫(xiě)請(qǐng)求入隊(duì)列,根據(jù)請(qǐng)求類型決定是否需要阻塞等待,以保證數(shù)據(jù)的一致性

  • 總結(jié)

    上面只是給了一個(gè)例子,還有更多的思考點(diǎn)等著自己去發(fā)掘。再者每個(gè)人的經(jīng)歷也不一樣,思考方向也許也會(huì)有更多的不同,但是最重要的是一個(gè)保持思考總結(jié)的習(xí)慣,該習(xí)慣并不是一定要等事情完結(jié)后才去考慮,在過(guò)程中我們也需要不斷的思考總結(jié)。
    人會(huì)在思考總結(jié)中進(jìn)步,如果只是走馬觀花一般,那就真的像網(wǎng)上傳的一樣(十年工作經(jīng)驗(yàn),其實(shí)就是一年的工作經(jīng)驗(yàn)重復(fù)可十年)。希望大家不是活成了段子,而是在不斷的進(jìn)步,看到越來(lái)越好的自己。

    總結(jié)

    以上是生活随笔為你收集整理的项目复盘思考的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。