性能優化有感


性能優化有感

性能優化是個枯燥,卻又有趣的過程
性能優化我大致分為幾個方面

  • 代碼優化
  • 線程優化、異步
  • JVM優化
  • 數據庫優化
  • 緩存優化
  • 架構優化

下面來展開談談感悟,也可以參考美團技術團隊常見性能優化

代碼優化

代碼是跟我們接觸最多的東西,代碼優化主要有

  1. 代碼結構優化,可以方便日后擴展和代碼標准化
    • 是否可以進行抽象避免冗余代碼
    • 是否可以利用設計模式
    • 代碼是否遵循阿里巴巴Java開發手冊

這里可以采用阿里巴巴Java開發規范插件

  1. 代碼是否有多重循環,無效的查詢等
    • 多重循環可以根據數據量采用HashMap進行查詢,屬於利用空間換取時間
    • 無效的查詢等可以進行刪除
      這里推薦Findbugs

線程優化

線程優化是一個復雜的過程,多線程如何運用,如何避免死鎖、飢餓、活鎖等問題

  1. 線程使用的地方

    • 在查詢中可以運用到多線程,把串行化操作變化為並行化操作
    • I/O阻塞的操作,最經典的莫過於BIO
    • 計算量大的操作,使用多線程可以更好的運用CPU的運算能力
  2. 線程池
    需要了解線程池的狀態,線程池的參數,以及內部原理,並選擇合適的線程池
    這里推薦一篇文章Java線程池實現原理及其在美團業務中的實踐 再次感謝美團技術團隊

    • 線程池分為
      • newCachedThreadPool
      • newFixedThreadPool
      • newSingleThreadExecutor
      • newScheduleThreadPool
      • forkjoinPool
        注意:這里不建議使用Executors來創建線程池,方式OOM等問題,參考阿里巴巴開發規范,建議使用new ThreadPoolExecutor()
  3. 異步
    異步建議采用MQ,使用范圍例如insert、update操作,可以丟到MQ,這里要注意MQ消息丟失問題,同時MQ也可以實現延遲隊列,例如30分鍾關閉訂單,采用Job的方式並不是一個好的解決方案,可以采用MQ延時隊列實現,這里推薦rocketmq(阿里巴巴牛逼)

  4. 並發容器的選擇
    concurrenthashmap和synchronizedmap性能差距很大,建議選擇合適的並發容器

JVM優化

JVM優化這里本人也不是特別的熟練,只是講一些自己所知道的

  1. 無日志不優化
    在沒有日志的情況下,該怎么優化,如何優化,哪些方面需要優化,這里都是未知的,所以需要日志才能進行優化
  2. 工具
    優化要有趁手的工具,好在JDK本身就為我們提供了不少,在JDK的bin目錄下有一堆自帶的工具,這里介紹幾個我熟悉且用過的
    • jps:查看當前機器上的java程序
    • jcmd:跟jps差不多但是能看到啟動命令
    • jstat:查看JVM信息,例如GC信息
    • jinfo:查看JVM參數
    • jmap:JVM在內存中的情況,可以導出Dump
    • jstack:棧信息,可以用來查看死鎖等
    • jconsole:一個可視化工具
    • jvisualvm:也是一個可視化工具比jconsole功能強一些,但是都有局限性,在服務器上無法使用
    • eclipse memory analyer:分析dump文件
  3. 參數優化
    使用上面的工具對服務器進行監控,可以根據信息適當的調整堆大小,GC收集器等。建議開啟-XX:+HeapDumpOnOutOfMemoryError

數據庫優化

數據庫是優化中重要的一環,具體優化方法如下

  1. SQL優化:是否可以去掉不必要的查詢,使用explain對sql進行分析,避免回表等
  2. 分庫分表:一台數據庫可能存在性能瓶頸,可以采用分庫分表的方式,拆分主要采用冷熱數據分離、日期分割、HASH取模等。
  3. 讀寫分離:對數據的修改可以操作主庫,對數據的查詢可以操作從庫,進行讀寫分離
    分庫分表以及讀寫分離后可能會出現分布式事務、讀寫分離操作的復雜性等問題這里需要引入中間件例如:MyCat sharding jdbc

緩存優化

緩存是個優化的好辦法但是也有弊端

  1. 緩存分類
    • JVM緩存:concurrenthashmap、guava緩存
    • Redis等NoSQL數據庫
  2. 緩存拆分
    可以在代碼中對接口進行拆分,可以緩存的和不可以緩存的寫成多個方法,對可以緩存的進行緩存
  3. 緩存帶來的弊端
    緩存並不是越多越好,緩存給系統帶來了復雜性,例如:何時添加緩存、何時刪除緩存、緩存雪崩、緩存擊穿、緩存穿透、緩存預熱、Redis集群如何實現、Redis哨兵、Redis腦裂等問題

架構優化

架構優化其實就程序員來說能做的並不是很多

  1. 限流:GateWay進行限流,限流方法有滑動窗口、漏桶、令牌桶算法,這里建議采用合適的方法進行限流防止應用崩潰
  2. 熔斷:可以采用hystrix防止服務雪崩
  3. CDN優化:對靜態資源采用CDN可以提交響應速率
  4. DNS優化:這個暫時不熟可以交給運維處理
  5. 服務擴容:可以采用K8S和Docker的技術對服務進行動態擴容,這里也是運維實現

測試

優化了這么多,體現當然是壓力測試,這里因為不熟悉性能指標,單機TPS部分接口可以達到800+ RT在300ms以內,希望大家提供一個單機性能標准,以上采用的是LoadRuner測試的結果

洋洋灑灑寫了這么多,主要的還是平時的積累以及思考,也希望您對內容進行補充。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM