Java:如何创建轻量级数据库微服务
基于云的Java數據庫應用程序的數量每分鐘都在增加。 許多組織部署了數百甚至數千個微服務實例。 但是,相對于運行時環境,大多數應用程序會帶來驚人數量的不必要開銷。 反過來,這會使應用程序運行更慢,運行成本更高。
在本文中,我將演示如何編寫比normal(*)小10倍的數據庫應用程序。 考慮到應用程序,第三方庫和Java運行時,存儲要求約為32 MB,而不是通常的(*)?300 MB。 另外,運行該應用程序所需的RAM也將減少25%。
(*)這些是以下完整JDK(不包括應用程序和第三方庫)的存儲要求:
jdk.8.0_191 360 MB jdk-9.0.4 504 MB adoptopenjdk-11 298 MB使用支持微服務的ORM
大多數傳統的ORM不支持Java模塊封裝。 通常,這需要交付大量不必要的代碼。
在本文中,我將使用基于流的開源Java ORM Speedment ,它的最新版本支持Java平臺模塊系統(JPMS)。 這使我們能夠僅使用我們的應用程序顯式使用的模塊來生成優化的自定義Java運行時環境(JRE,來自JDK的部分,用于運行應用程序)。
閱讀關于Speedment 3.2中的新功能, 這篇文章 。
應用程序
我們希望在本文中部署的整個應用程序位于
GitHub上的開源項目,位于子目錄“ microservice-jlink ”下。 它連接到托管在云中的MySQL“ Sakila”數據庫(包含有關電影的數據)的公共實例,并在控制臺上列出了十個最長的被評為“ PG-13”的電影。 數據模型已預先配置為適合此數據庫的數據結構。 如果要使用另一個數據庫創建自己的應用程序,請訪問Speedment初始化程序以專門為該數據庫配置項目。
該應用程序的main方法如下所示:
public final class Main {public static void main(String[] args) {final Speedment app = new SakilaApplicationBuilder().withPassword("sakila").build();final FilmManager films = app.getOrThrow(FilmManager.class);System.out.println("These are the ten longest films rated as PG-13:");films.stream() // 1.filter(Film.RATING.equal("PG-13")) // 2.sorted(Film.LENGTH.reversed()) // 3.limit(10) // 4.map(film -> String.format( // 5"%-18s %d min",film.getTitle(),film.getLength().orElse(0))).forEach(System.out::println); // 6} }首先,我們將數據庫密碼傳遞給Speedment構建器(Speedment從不在內部存儲密碼)。 使用配置文件中的數據庫IP地址,端口等對構建器進行了預配置。
然后,我們獲得FilmManager ,該FilmManager器隨后可用于創建與數據庫中的“ film”表直接對應的Java流。
最后,我們:
該應用程序本身非常易于理解。 還應注意,Speedment會在引擎蓋下將Java Stream呈現給SQL,如下所示:
SELECT `film_id`,`title`,`description`,`release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update` FROM `sakila`.`film` WHERE (`rating` = ? COLLATE utf8_bin) ORDER BY `length`IS NOT NULL, `length` DESC LIMIT ?, values:[PG-13, 10]這意味著僅從數據庫中提取了所需的電影實體。
直接在IDE下運行時,將產生以下輸出:
These are the ten longest films rated as PG-13: GANGS PRIDE 185 min CHICAGO NORTH 185 min POND SEATTLE 185 min THEORY MERMAID 184 min CONSPIRACY SPIRIT 184 min FRONTIER CABIN 183 min REDS POCUS 182 min HOTEL HAPPINESS 181 min JACKET FRISCO 181 min MIXED DOORS 180 min這看起來很完美。
模塊化項目
要使用模塊,我們需要在Java 9或更高版本下運行,并且我們的項目中必須有一個module-info.java文件:
module microservice.jlink {requires com.speedment.runtime.application;requires com.speedment.runtime.connector.mysql; // (*) }com.speedment.runtime.application模塊是任何Speedment應用程序始終需要的基本模塊。
(*)根據數據庫類型,您必須將MySQL模塊替換為數據庫的相應模塊。 在此處閱讀有關各種數據庫連接器模塊的所有信息。
建設項目
如前所述,完整項目可在GitHub上找到 。 這是您如何獲得的:
git clone https://github.com/speedment/user-guide-code-samples.git將目錄更改為相關的子項目:
cd user-guide-code-samples cd microservice-jlink生成項目(由于模塊系統,您必須使用Java 9或更高版本):
mvn clean install自定義JRE構建腳本
該項目還包含一個名為build_jre.sh的自定義JRE構建腳本, build_jre.sh包含以下命令:
#!/bin/bash SPEEDMENT_VERSION=3.2.1 JDBC_VERSION=8.0.18 OUTPUT=customjre echo "Building $OUTPUT..." MODULEPATH=$(find ~/.m2/repository/com/speedment/runtime -name "*.jar" \| grep $SPEEDMENT_VERSION.jar | xargs echo | tr ' ' ':') MODULEPATH=$MODULEPATH:$(find ~/.m2/repository/com/speedment/common -name "*.jar" \| grep $SPEEDMENT_VERSION.jar | xargs echo | tr ' ' ':') MODULEPATH=$MODULEPATH:$(find . -name "*.jar" | xargs echo | tr ' ' ':')$JAVA_HOME/bin/jlink \ --no-header-files \ --no-man-pages \ --compress=2 \ --strip-debug \ --module-path "$JAVA_HOME\jmods:$MODULEPATH" \ --add-modules microservice.jlink,java.management,java.naming,java.rmi,java.transaction.xa \ --output $OUTPUT該腳本是這樣工作的:
在設置了各種參數之后,該腳本通過添加speedment/runtime和speedment/common目錄的jar來構建模塊路徑。 即使我們添加了所有這些模塊,模塊系統也會在以后找出實際使用的模塊,并丟棄其他模塊。 MODULEPATH的最后一行將添加應用程序本身的JAR文件。
設置完所有參數后,我們將調用jlink命令,該命令將構建自定義JRE。 我使用了許多(可選)標志來減小目標JRE的大小。 因為JDBC驅動程序不支持JPMS,所以我在--add-modules參數下手動添加了驅動程序所需的一些模塊。
構建超緊湊型JRE
有了上面的腳本,我們可以使用一個命令為我們的云數據庫應用程序創建超緊湊的自定義JRE:
./build_jre.sh在我較舊的MacBook Pro上,構建僅需大約5秒鐘。 我們可以使用以下命令查看JRE / app的總大小:
du -sh customjre/這將產生以下輸出:
32M customjre/驚人的結果! 我們有一個功能齊全的JVM,其中包含垃圾回收,JIT編譯器,所有庫(JDBC驅動程序除外)以及應用程序本身僅包裝在32 MB的存儲中!
我們可以將它與JDK本身的未縮減大小進行比較,后者通常被用作云實例的基準。
du -sh $JAVA_HOME這將在筆記本電腦上產生以下輸出:
298M /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home/而且該數字甚至不包括應用程序或任何第三方庫。 因此,我們將存儲需求降低了大約10倍!
實際使用的模塊
要查看完成還原過程的模塊,我們可以發出以下命令:
cat customjre/release這將在我的機器上產生以下輸出(為了清晰起見,經過重新格式化和排序):
JAVA_VERSION="11.0.5" MODULES=" com.speedment.common.annotation com.speedment.common.function com.speedment.common.injector com.speedment.common.invariant com.speedment.common.json com.speedment.common.jvm_version com.speedment.common.logger com.speedment.common.mapstream com.speedment.common.tuple com.speedment.runtime.application com.speedment.runtime.compute com.speedment.runtime.config com.speedment.runtime.connector.mysql com.speedment.runtime.core com.speedment.runtime.field com.speedment.runtime.typemapper com.speedment.runtime.welcome java.base java.logging java.management java.naming java.prefs java.rmi java.security.sasl java.sql java.transaction.xa java.xml microservice.jlink "因此,自定義運行時未包括所有未使用的Java模塊(例如javax.crypto )。
運行應用程序
可以使用自定義JRE運行應用程序,如下所示:
customjre/bin/java --class-path ~/.m2/repository/mysql/mysql-connector-java/8.0.18/mysql-connector-java-8.0.18.jar -m microservice.jlink/com.speedment.example.microservices.jlink.Main首次構建項目時(即mvn clean install ),Maven自動將文件mysql-connector-java-8.0.18.jar下載到其本地存儲庫。 由于MySQL JDBC驅動程序尚未與Java平臺模塊系統兼容,因此我們不得不手動將其粘上。
運行時,程序會產生與上面相同的輸出,但運行時會小10倍:
These are the ten longest films rated as PG-13: GANGS PRIDE 185 min CHICAGO NORTH 185 min POND SEATTLE 185 min THEORY MERMAID 184 min CONSPIRACY SPIRIT 184 min FRONTIER CABIN 183 min REDS POCUS 182 min HOTEL HAPPINESS 181 min JACKET FRISCO 181 min MIXED DOORS 180 min內存使用情況
一個可能更重要的問題是云應用程序總共使用了多少應用程序內存(RSS)。 快速瀏覽一下,發現堆內存使用量也減少了:
標準JDK
Pers-MBP:speedment pemi$ jmap -histo 38715num #instances #bytes class name (module) -------------------------------------------------------1: 25836 3036560 [B (java.base@11.0.5)2: 2055 1639408 [I (java.base@11.0.5)3: 4234 511568 java.lang.Class (java.base@11.0.5)4: 21233 509592 java.lang.String (java.base@11.0.5)5: 196 270552 [C (java.base@11.0.5)6: 4181 245400 [Ljava.lang.Object; (java.base@11.0.5)7: 4801 153632 java.util.concurrent.ConcurrentHashMap$Node (java.base@11.0.5)8: 3395 135800 java.util.LinkedHashMap$Entry (java.base@11.0.5) … 1804: 1 16 sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo (jdk.localedata@11.0.5) Total 137524 7800144自定義JRE
Pers-MBP:speedment pemi$ jmap -histo 38783 | headnum #instances #bytes class name (module) -------------------------------------------------------1: 22323 1714608 [B (java.base@11.0.5)2: 4229 511000 java.lang.Class (java.base@11.0.5)3: 19447 466728 java.lang.String (java.base@11.0.5)4: 1776 424408 [I (java.base@11.0.5)5: 69 264656 [C (java.base@11.0.5)6: 4044 240128 [Ljava.lang.Object; (java.base@11.0.5)7: 4665 149280 java.util.concurrent.ConcurrentHashMap$Node (java.base@11.0.5)8: 3395 135800 java.util.LinkedHashMap$Entry (java.base@11.0.5) … 1726: 1 16 sun.util.resources.LocaleData$LocaleDataStrategy (java.base@11.0.5) Total 102904 5727960堆改善
堆使用量從7,800,144字節減少到5,727,960字節(減少了25%以上)!
注意:在運行jmap命令之前,我讓應用程序建議一個顯式的垃圾收集器,并等待幾秒鐘,以消除由可能早期調用垃圾收集器引起的任何差異。
總覽
以下圖表顯示了存儲需求的差異(越低越好):
這是另一個顯示RAM使用率差異的圖表(越低越好):
修改代碼
如果要修改代碼,則需要使用以下內容來重建應用程序:
mvn clean install然后刪除舊的customjre并創建一個新的:
rm -rf customjre/ ./build_jre.sh創建自己的數據庫應用程序
如果要連接到自己的數據庫并要編寫自己的應用程序邏輯,則可以輕松地選擇要使用的表和列,然后使用Speedment Tool自動生成自己的Java域模型和應用程序構建器:
本文演示的項目中使用的Speedment工具。 可以將該工具添加到pom.xml文件中的項目中,并由調用
mvn speedment:tool 。 訪問Speedment Initializer生成您自己的自定義pom.xml文件和應用程序模板。
可以通過自動Maven構建腳本簡化該過程,該腳本將識別任何應用程序依賴性以及自動生成的Docker實例,這些實例可以在自動構建后立即部署。 我將在以后的文章中寫更多有關此的內容。
結論
Java平臺模塊系統(JPMS)允許構建適用于云部署的高度優化的JRE。
可以減少存儲和RAM需求。
傳統的ORM不支持完整的Java模塊封裝
Speedment開源Stream ORM支持JPMS,可用于構建高效的數據庫云應用程序。
資源資源
JPMS模塊的基礎知識
在GitHub上加速
Speedment Initializer能夠生成項目pom.xml模板
翻譯自: https://www.javacodegeeks.com/2019/11/java-how-to-create-lightweight-database-microservices.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Java:如何创建轻量级数据库微服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机wifi信号差怎么解决
- 下一篇: 带有Prometheus的弹簧靴和千分尺