电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

編寫高性能 Java 代碼的最佳實踐

瀏覽:84日期:2022-09-05 13:17:28

本文首先介紹了負載測試、基于APM工具的應用程序和服務器監控,隨后介紹了編寫高性能Java代碼的一些最佳實踐。最后研究了JVM特定的調優技巧、數據庫端的優化和架構方面的調整。以下是譯文。

編寫高性能 Java 代碼的最佳實踐

 介紹

在這篇文章中,我們將討論幾個有助于提升Java應用程序性能的方法。我們首先將介紹如何定義可度量的性能指標,然后看看有哪些工具可以用來度量和監控應用程序性能,以及確定性能瓶頸。

我們還將看到一些常見的Java代碼優化方法以及最佳編碼實踐。最后,我們將看看用于提升Java應用程序性能的JVM調優技巧和架構調整。

請注意,性能優化是一個很寬泛的話題,而本文只是對JVM探索的一個起點。

 性能指標

在開始優化應用程序的性能之前,我們需要理解諸如可擴展性、性能、可用性等方面的非功能需求。

以下是典型Web應用程序常用的一些性能指標:

應用程序平均響應時間系統必須支持的平均并發用戶數在負載高峰期間,預期的每秒請求數

這些指標可以通過使用多種監視工具監測到,它們對分析性能瓶頸和性能調優有著非常大的作用。

 示例應用程序

我們將使用一個簡單的Spring Boot Web應用程序作為示例,在這篇文章中有相關的介紹。這個應用程序可用于管理員工列表,并對外公開了添加和檢索員工的REST API。

我們將使用這個程序作為參考來運行負載測試,并在接下來的章節中監控各種應用指標。

 找出性能瓶頸

負載測試工具和應用程序性能管理(APM)解決方案常用于跟蹤和優化Java應用程序的性能。要找出性能瓶頸,主要就是對各種應用場景進行負載測試,并同時使用APM工具對CPU、IO、堆的使用情況進行監控等等。

Gatling是進行負載測試最好的工具之一,它提供了對HTTP協議的支持,是HTTP服務器負載測試的絕佳選擇。

Stackify的Retrace是一個成熟的APM解決方案。它的功能很豐富,對確定應用程序的性能基線很有幫助。 Retrace的關鍵組件之一是它的代碼分析功能,它能夠在不減慢應用程序的情況下收集運行時信息。

Retrace還提供了監視基于JVM應用程序的內存、線程和類的小部件。除了應用程序本身的指標之外,它還支持監視托管應用程序的服務器的CPU和IO使用情況。

因此,像Retrace這樣功能全面的監控工具是解鎖應用程序性能潛力的第一步。而第二步則是在你的系統上重現真實使用場景和負載。

說起來容易,做起來難,而且了解應用程序當前的性能也非常重要。這就是我們接下來要關注的問題。

 Gatling負載測試

Gatling的模擬測試腳本是用Scala編寫的,但該工具還附帶了一個非常有用的圖形界面,可用于記錄具體的場景,并生成Scala腳本。

在運行模擬腳本之后,Gatling會生成一份非常有用的、可用于分析的HTML報告。

定義場景

在啟動記錄器之前,我們需要定義一個場景,表示用戶在瀏覽Web應用時發生的事情。

在我們的這個例子中,具體的場景將是“啟動200個用戶,每個用戶發出一萬個請求。”

配置記錄器

根據“Gatling的第一步”所述,用下面的代碼創建一個名為EmployeeSimulation的scala文件:

class EmployeeSimulation extends Simulation { val scn = scenario("FetchEmployees").repeat(10000) {exec( http("GetEmployees-API") .get("http://localhost:8080/employees") .check(status.is(200))) } setUp(scn.users(200).ramp(100))}運行負載測試

要執行負載測試,請運行以下命令:

$GATLING_HOME/bin/gatling.sh-sbasic.EmployeeSimulation

對應用程序的API進行負載測試有助于發現及其細微的并且難以發現的錯誤,如數據庫連接耗盡、高負載情況下的請求超時、因為內存泄漏而導致堆的高使用率等等。

 監控應用程序

要使用Retrace進行Java應用程序的開發,首先需要在Stackify上申請免費試用賬號。然后,將我們自己的Spring Boot應用程序配置為Linux服務。我們還需要在托管應用程序的服務器上安裝Retrace代理,按照這篇文章所述的操作即可。

Retrace代理和要監控的Java應用程序啟動后,我們就可以到Retrace儀表板上單擊AddApp按鈕添加應用了。添加應用完成之后,Retrace將開始監控應用程序了。

找到最慢的那個點

Retrace會自動監控應用程序,并跟蹤數十種常見框架及其依賴關系的使用情況,包括SQL、MongoDB、Redis、Elasticsearch等等。Retrace能幫助我們快速確定應用程序為什么會出現如下性能問題:

某個SQL語句是否會拖慢系統的速度?Redis突然變慢了嗎?特定的HTTP Web服務宕了,還是變慢了?

例如,下面的圖形展示了在一段給定的時間內速度最慢的組件。

編寫高性能 Java 代碼的最佳實踐

 代碼級別的優化

負載測試和應用程序監控對于確定應用程序的一些關鍵性能瓶頸非常有用。但同時,我們需要遵循良好的編碼習慣,以避免在對應用程序進行監控的時候出現過多的性能問題。

在下一章節中,我們將來看一些最佳實踐。

使用StringBuilder來連接字符串

字符串連接是一個非常常見的操作,也是一個低效率的操作。簡單地說,使用+=來追加字符串的問題在于每次操作都會分配新的String。

下面這個例子是一個簡化了的但卻很典型的循環。前面使用了原始的連接方式,后面使用了構建器:

public String stringAppendLoop() { String s = ""; for (int i = 0; i < 10000; i++) {if (s.length() > 0) s += ", ";s += "bar"; } return s;}public String stringAppendBuilderLoop() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10000; i++) {if (sb.length() > 0) sb.append(", ");sb.append("bar"); } return sb.toString();}

上面代碼中使用的StringBuilder對性能的提升非常有效。請注意,現代的JVM會在編譯或者運行時對字符串操作進行優化。

避免遞歸

導致出現StackOverFlowError錯誤的遞歸代碼邏輯是Java應用程序中另一種常見的問題。如果無法去掉遞歸邏輯,那么尾遞歸作為替代方案將會更好。

我們來看一個頭遞歸的例子:

public int factorial(int n) { if (n == 0) {return 1; } else {return n * factorial(n - 1); }}

現在我們把它重寫為尾遞歸:

private int factorial(int n, int accum) { if (n == 0) {return accum; } else {return factorial(n - 1, accum * n); }}public int factorial(int n) { return factorial(n, 1);}

其他JVM語言(如Scala)已經在編譯器級支持尾遞歸代碼的優化,當然,對于這種優化目前也存在著一些爭議。

謹慎使用正則表達式

正則表達式在很多場景中都非常有用,但它們往往具有非常高的性能成本。了解各種使用正則表達式的JDK字符串方法很重要,例如String.replaceAll()、String.split()。

如果你不得不在計算密集的代碼段中使用正則表達式,那么需要緩存Pattern的引用而避免重復編譯:

static final Pattern HEAVY_REGEX = Pattern.compile("(((X)*Y)*Z)*");

使用一些流行的庫,比如Apache Commons Lang也是一個很好的選擇,特別是在字符串的操作方面。

避免創建和銷毀過多的線程

線程的創建和處置是JVM出現性能問題的常見原因,因為線程對象的創建和銷毀相對較重。

如果應用程序使用了大量的線程,那么使用線程池會更加有用,因為線程池允許這些昂貴的對象被重用。

為此,Java的ExecutorService是線程池的基礎,它提供了一個高級API來定義線程池的語義并與之進行交互。

Java 7中的Fork/Join框架也值得提一下,因為它提供了一些工具來嘗試使用所有可用的處理器核心以幫助加速并行處理。為了提高并行執行效率,框架使用了一個名為ForkJoinPool的線程池來管理工作線程。

 JVM調優堆大小的調優

為生產系統確定合適的JVM堆大小并不是一件簡單的事情。要做的第一步是回答以下問題以預測內存需求:

計劃要把多少個不同的應用程序部署到單個JVM進程中,例如EAR文件、WAR文件、jar文件的數量是多少?在運行時可能會加載多少個Java類,包括第三方API的類?估計內存緩存所需的空間,例如,由應用程序(和第三方API)加載的內部緩存數據結構,比如從數據庫緩存的數據、從文件中讀取的數據等等。估計應用程序將創建的線程數。

如果沒有經過真實場景的測試,這些數字很難估計。

要獲得有關應用程序需求的最好最可靠的方法是對應用程序執行實際的負載測試,并在運行時跟蹤性能指標。我們之前討論的基于Gatling的測試就是一個很好的方法。

選擇合適的垃圾收集器

Stop-the-world(STW)垃圾收集的周期是影響大多數面向客戶端應用程序響應和整體Java性能的大問題。但是,目前的垃圾收集器大多解決了這個問題,并且通過適當的優化和大小的調整,能夠消除對收集周期的感知。

分析器、堆轉儲和詳細的GC日志記錄工具對此有一定的幫助作用。再一次注意,這些都需要在真實場景的負載模式下進行監控。

有關不同垃圾收集器的更多信息,請查看這個指南。

 JDBC性能

關系型數據庫是Java應用程序中另一個常見的性能問題。為了獲得完整請求的響應時間,我們很自然地必須查看應用程序的每一層,并思考如何讓代碼與底層SQL DB進行交互。

連接池

讓我們從眾所周知的事實開始,即數據庫連接是昂貴的。 連接池機制是解決這個問題非常重要的第一步。

這里建議使用HikariCP JDBC,這是一個非常輕量級(大約130Kb)并且速度極快的JDBC連接池框架。

JDBC批處理

持久化處理應盡可能地執行批量操作。 JDBC批處理允許我們在單次數據庫交互中發送多個SQL語句。

這樣,無論是在驅動端還是在數據庫端,性能都可能得到顯著地提升。 * PreparedStatement*是一個非常棒的的批處理命令,一些數據庫系統(例如Oracle)只支持預處理語句的批處理。

另一方面,Hibernate則更加靈活,它允許我們只需修改一個配置即可快速切換為批處理操作。

語句緩存

語句緩存是另一種提高持久層性能的方法,這是一種鮮為人知但又容易掌握的性能優化方法。

只要底層的JDBC驅動程序支持,你就可以在客戶端(驅動程序)或數據庫端(語法樹甚至執行計劃)中緩存PreparedStatement。

規模的縮放

數據庫復制和分片是提高吞吐量非常好的方法,我們應該充分利用這些經過實踐檢驗的架構模式,以擴展企業應用的持久層。

 架構改進緩存

現在內存的價格很低,而且越來越低,從磁盤或通過網絡來檢索數據的性能代價仍然很高。緩存自然而然的變成了在應用程序性能方面不能忽視的關鍵。

當然,在應用的拓撲結構中引入一個獨立的緩存系統確實會增加架構的復雜度,所以,應當充分利用當前使用的庫和框架現有的緩存功能。

例如,大多數的持久化框架都支持緩存。 Spring MVC等Web框架還可以使用Spring中內置的緩存支持,以及基于ETags的強大的HTTP級緩存。

橫向擴展

無論我們在單個實例中準備了多少硬件,都會有不夠用的時候。簡而言之,擴展有著天生的局限性,當系統遇到這些問題時,橫向擴展是處理更多負載的唯一途徑。這一步肯定會相當的復雜,但卻是擴展應用的唯一辦法。

對大多數的現代框架和庫來說,這方面還是支持得很好的,而且會變得越來越好。 Spring生態系統有一個完整的項目集,專門用于解決這個特定的應用程序架構領域,其他大多數的框架也都有類似的支持。

除了能夠提升Java的性能,通過集群進行橫向擴展也有其他的好處,添加新的節點能產生冗余,并更好的處理故障,從而提高整個系統的可用性。

 結論

在這篇文章中,我們圍繞著提升Java應用的性能探討了許多概念。我們首先介紹了負載測試、基于APM工具的應用程序和服務器監控,隨后介紹了編寫高性能Java代碼的一些最佳實踐。最后,我們研究了JVM特定的調優技巧、數據庫端的優化和架構方面的調整。

原文:https://dzone.com/articles/how-to-improve-the-performance-of-a-java-applicati

標簽: Java
相關文章:
主站蜘蛛池模板: 自动部分收集器,进口无油隔膜真空泵,SPME固相微萃取头-上海楚定分析仪器有限公司 | 洛阳防爆合格证办理-洛阳防爆认证机构-洛阳申请国家防爆合格证-洛阳本安防爆认证代办-洛阳沪南抚防爆电气技术服务有限公司 | 美的商用净水器_美的直饮机_一级代理经销商_Midea租赁价格-厂家反渗透滤芯-直饮水批发品牌售后 | 阳光模拟试验箱_高低温试验箱_高低温冲击试验箱_快速温变试验箱|东莞市赛思检测设备有限公司 | 天津电机维修|水泵维修-天津晟佳机电设备有限公司 | 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 山东限矩型液力偶合器_液力耦合器易熔塞厂家-淄博市汇川源机械厂 | 酒吧霸屏软件_酒吧霸屏系统,酒吧微上墙,夜场霸屏软件,酒吧点歌软件,酒吧互动游戏,酒吧大屏幕软件系统下载 | 玉米深加工设备-玉米深加工机械-新型玉米工机械生产厂家-河南粮院机械制造有限公司 | 动物解剖台-成蚊接触筒-标本工具箱-负压实验台-北京哲成科技有限公司 | 智能交通网_智能交通系统_ITS_交通监控_卫星导航_智能交通行业 | 对夹式止回阀_对夹式蝶形止回阀_对夹式软密封止回阀_超薄型止回阀_不锈钢底阀-温州上炬阀门科技有限公司 | 东莞猎头公司_深圳猎头公司_广州猎头公司-广东万诚猎头提供企业中高端人才招聘服务 | 环氧铁红防锈漆_环氧漆_无溶剂环氧涂料_环氧防腐漆-华川涂料 | 吊篮式|移动式冷热冲击试验箱-二槽冷热冲击试验箱-广东科宝 | 节流截止放空阀-不锈钢阀门-气动|电动截止阀-鸿华阀门有限公司 | 天空彩票天下彩,天空彩天空彩票免费资料,天空彩票与你同行开奖,天下彩正版资料大全 | 深圳诚暄fpc首页-柔性线路板,fpc柔性线路板打样生产厂家 | 并离网逆变器_高频UPS电源定制_户用储能光伏逆变器厂家-深圳市索克新能源 | 两头忙,井下装载机,伸缩臂装载机,30装载机/铲车,50装载机/铲车厂家_价格-莱州巨浪机械有限公司 | 尊享蟹太太美味,大闸蟹礼卡|礼券|礼盒在线预订-蟹太太官网 | R507制冷剂,R22/R152a制冷剂厂家-浙江瀚凯制冷科技有限公司 | 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | PTFE接头|聚四氟乙烯螺丝|阀门|薄膜|消解罐|聚四氟乙烯球-嘉兴市方圆氟塑制品有限公司 | 佛山市钱丰金属不锈钢蜂窝板定制厂家|不锈钢装饰线条|不锈钢屏风| 电梯装饰板|不锈钢蜂窝板不锈钢工艺板材厂家佛山市钱丰金属制品有限公司 | 上海赞永| 单级/双级旋片式真空泵厂家,2xz旋片真空泵-浙江台州求精真空泵有限公司 | 合肥地磅_合肥数控切割机_安徽地磅厂家_合肥世佳电工设备有限公司 | 球磨机,节能球磨机价格,水泥球磨机厂家,粉煤灰球磨机-吉宏机械制造有限公司 | 耐酸碱泵-自吸耐酸碱泵型号「品牌厂家」立式耐酸碱泵价格-昆山国宝过滤机有限公司首页 | 丙烷/液氧/液氮气化器,丙烷/液氧/液氮汽化器-无锡舍勒能源科技有限公司 | 称重传感器,测力传感器,拉压力传感器,压力变送器,扭矩传感器,南京凯基特电气有限公司 | 农业四情_农业气象站_田间小型气象站_智慧农业气象站-山东风途物联网 | 科威信洗净科技,碳氢清洗机,超声波清洗机,真空碳氢清洗机 | 同学聚会纪念册制作_毕业相册制作-成都顺时针宣传画册设计公司 | 浙江筋膜枪-按摩仪厂家-制造商-肩颈按摩仪哪家好-温州市合喜电子科技有限公司 | 上海赞永| 工装定制/做厂家/公司_工装订做/制价格/费用-北京圣达信工装 | 家乐事净水器官网-净水器厂家「官方」 | 信阳市建筑勘察设计研究院有限公司 | 光栅尺厂家_数显表维修-苏州泽升精密机械|