主頁 > 後端開發 > 輕量靈動: 革新輕量級服務開發

輕量靈動: 革新輕量級服務開發

2023-06-06 07:44:52 後端開發

概念篇

1、從JDK8->JDK17 你需要知道的

從 JDK 8 升級到 JDK 17 可以讓你的應用程式受益于新的功能、性能改進和安全增強,下面是一些 JDK 8 升級到 JDK 17 的最佳實戰:

1.1、確定升級的必要性:首先,你需要評估你的應用程式是否需要升級到 JDK 17,查看 JDK 17 的新特性、改進和修復的 bug,以確定它們對你的應用程式是否有實際的好處,

1.2、了解 JDK 8 到 JDK 17 的變化:詳細了解 JDK 8 和 JDK 17 之間的差異是非常重要的,熟悉 JDK 17 中引入的新特性、移除的特性以及可能影響現有代碼的變化,

1.3、解決向后不兼容的變化 更新依賴項和框架:在升級程序中,可能會遇到一些向后不兼容和框架不兼容的變化,例如,一些 API 的使用方式可能發生了變化,或者一些方法已被廢棄,在升級之前,你需要對這些變化進行仔細的檢查,并相應地修改你的代碼,

1.4、進行兼容性測驗:在升級之前,進行兼容性測驗是非常重要的,確保你的應用程式在 JDK 17 下能夠正常運行,并且沒有出現任何性能下降或功能問題,可以使用自動化測驗工具來簡化測驗程序,

1.5、逐步升級:對于大型應用程式或關鍵系統,建議逐步進行升級,可以先將應用程式遷移到較新的 JDK 版本,如 JDK 11 或 JDK 14,然后再逐步升級到 JDK 17,這樣可以降低升級程序中的風險,并使你能夠逐步解決遇到的問題,

1.6、監控和優化性能:升級到 JDK 17 后,你可能會注意到一些性能改進,然而,某些代碼可能會受到影響并表現出不同的行為,使用性能監控工具來檢測潛在的性能問題,并進行必要的調整和優化,

1.7、 更新部署和運維流程:升級 JDK 版本后,你可能還需要更新你的部署和運維流程,例如,JDK 17 中引入了一些新的命令列工具和管理選項

2、為什么要使用jdk17?

2.1、長期支持(LTS):JDK 版本中的一些版本被標記為長期支持版本,這意味著它們將獲得更長時間的支持和維護,JDK 17 是 OpenJDK 的一個 LTS 版本

2.2、生態系統支持:一些開源專案、框架和工具可能會更早地支持較新的 JDK 版本,以利用新的特性和改進,選擇較新的 JDK 版本可以使你能夠使用最新的工具和庫,并獲得更好的生態系統支持

2.3、新功能和改進:每個 JDK 版本都會引入新的功能、增強和改進

3、強強聯合GraalVM

GraalVM 是一種開源的 通用 虛擬機(通用: 它具有支持多種編程語言的能力 直接在 graalvm 運行 不需要額外的運行時環境),具有許多特性和優勢,使得它在特定的場景中成為一個有吸引力的選擇,以下是一些使用 GraalVM 的原因:

3.1、高性能:GraalVM 具有優化的即時編譯器,能夠將 Java 程式編譯成高效的機器碼,在許多情況下比傳統的 Java 虛擬機更快,

3.2、AOT 編譯:GraalVM 可以將 Java 程式靜態編譯成本地機器碼,這被稱為 Ahead-of-Time(AOT)編譯,AOT 編譯可以提供更快的啟動時間和更低的記憶體消耗,適用于一些對性能要求較高的場景,

3.3、生態系統支持:GraalVM 在開發者社區中有廣泛的支持和活躍的生態系統,許多開源專案和框架已經對 GraalVM 進行了優化和集成,使得使用 GraalVM 更加方便和無縫

3.4、嵌入式支持:GraalVM 提供了嵌入式 API,允許你將 GraalVM 作為庫集成到你的應用程式中,這意味著你可以將 GraalVM 作為運行時引擎嵌入到你的應用程式中,從而實作更高的靈活性和自定義性,

3.5、云原生支持:GraalVM 具有與云原生應用程式開發和部署相關的特性,它可以與 Docker 和 Kubernetes 配合使用,支持快速啟動和低記憶體消耗,適用于云環境中的微服務架構,

實戰篇

1、第一步建議先升級依賴項

如果你的專案基于java 8,在升級前最好先升級依賴項,從java 8升級到java 17是一個很大的跨越,依賴項不升級則出問題的概率會比較高,maven可以用mvn versions:display-dependency-updates命令檢查依賴項更新,輸出會類似這樣

然后可以把依賴項升級到輸出的對應版本,大部分包升級不會出問題,如果有問題,建議去出問題的依賴官方倉庫尋找解決方案,這個命令是直接查詢maven遠程倉庫,如果依賴項多的話會運行比較長的時間

或者 jdeps --jdk-internals --multi-release 17 --class-path . encloud-api.jar

javax.annotation.*被移除 可以手動倒入

dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
</dependency>

常見的標記為廢棄的引數 遷移前后的引數如下:

2、環境安裝

2.1、Jdk環境安裝 https://www.graalvm.org/downloads/

版本對比

升級時springboot和springcloud版本對應表 https://start.spring.io/actuator/info

2.2、maven環境安裝

https://maven.apache.org/download.cgi

GraalVM對maven沒有特定的版本要求,通常情況下,只要您使用的Maven版本足夠新并支持Java 8或更高版本,就可以與GraalVM一起使用,建議您使用Maven 3.5.x 或更高版本以確保與GraalVM的兼容性

啟動java器使用 GraalVM 默認編譯器 Graal 運行 JVM,安裝時檢查Java版本:

$JAVA_HOME/bin/java -version

3、二進制的生成

3.1、安裝本機映像

gu install native-image
該native-image工具安裝在$JAVA_HOME/bin目錄中

3.2、maven構建

mvn clean package -Pnative -Dmaven.test.skip=true

4、出現的坑點

4.1、對于mac 提前安裝 glibc-devel

4.2、對于 centos 提前安裝

yum install centos-release-scl

yum install devtoolset-8

source /opt/rh/devtoolset-8/enable

yum install zlib-devel

否則編譯出現 會編譯失敗 gcc需要升級到6.4以上

image
image

4.3、對于java 應用來說 打出來的二進制可能出現亂碼 因此需要強制指定

5、模塊化 初體驗

 git clone https://github.com/graalvm/graalvm-demos
 cd graalvm-demos/native-hello-module
 結構圖
 ├── hello
│   └── Main.java
│       > package hello;
│       > 
│       > public class Main {
│       >     public static void main(String[] args) {
│       >         System.out.println("Hello from Java Module: "
│       >             + Main.class.getModule().getName());
│       >     }
│       > }
│
└── module-info.java
    > module HelloModule {
    >     exports hello;
    > }
    
 mvn package
 $JAVA_HOME/bin/java --module-path target/HelloModule-1.0-SNAPSHOT.jar --module HelloModule
 $JAVA_HOME/bin/native-image --module-path target/HelloModule-1.0-SNAPSHOT.jar --module HelloModule
 ./hellomodule

6、編譯器操作模式

Graal 作為 HotSpot JIT 編譯器有兩種運行模式: libgraal:Graal 編譯器提前編譯到本地共享庫中,在這種運行模式下,共享庫由 HotSpot VM 加載,編譯器使用與 HotSpot 堆分開的記憶體,并且從一開始就運行得很快,因為它不需要預熱,這是默認和推薦的操作模式,

jargraal:Graal 編譯器經歷與 Java 應用程式的其余部分相同的預熱階段,也就是說,在編譯其熱方法之前首先對其進行解釋,-XX:-UseJVMCINativeLibrary使用命令列選項選擇此模式,這將延遲達到最佳性能的時間,

7、本機映像構建配置

maven常用配置
<buildArgs>
如果要將其他引數傳遞給本機影像生成器,請<buildArgs> 在插件的配置中使用
<buildArgs>
    <arg>--argument</arg>
</buildArgs>
<skipNativeBuild>
要跳過本機影像的生成,請在插件的配置中提供以下內容:
<skipNativeBuild>true</skipNativeBuild>
<skipNativeTests>
要跳過本機影像編譯測驗的生成和執行,請在插件的配置中提供以下內容:
<skipNativeTests>true</skipNativeTests>
<debug>
如果要啟用除錯資訊的生成,請在插件配置中提供以下內容:
<debug>true</debug>
<useArgFile>
如果要使用引數檔案構建原生影像,請在插件配置中提供以下內容:
<useArgFile>true</useArgFile>

8、日志記錄添加到本機可執行檔案

1、默認情況下,由 Native Image 生成的本機可執行檔案支持通過java.util.logging.*API 進行日志記錄,

2、本機可執行檔案中的默認日志記錄配置基于logging.properties在 JDK 中找到的檔案,該檔案配置了一個java.util.logging.ConsoleHandler只顯示該INFO級別及以上級別的訊息的檔案,如果您需要額外的日志記錄處理程式,則必須注冊相應的類以進行反射,例如,如果您使用java.util.logging.FileHandlerthen 提供以下反射配置:

{
    "name" : "java.util.logging.FileHandler",
    "methods" : [
      { "name" : "<init>", "parameterTypes" : [] },
    ]
  }

3、將以下 Java 代碼保存到名為LoggerRunTimeInit.java的檔案中,然后使用以下命令對其進行編譯javac

import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.LogManager;
 import java.util.logging.Logger;
    
 public class LoggerTest {
     public static void main(String[] args) throws IOException {
         LogManager.getLogManager().readConfiguration(LoggerRunTimeInit.class.getResourceAsStream("/logging.properties"));
         Logger logger = Logger.getLogger(LoggerRunTimeInit.class.getName());
         logger.log(Level.WARNING");
     }
 }

4、下載logging.properties資源檔案 ( https://www.graalvm.org/docs/reference-manual/native-image/assets/logging.properties )并將其保存在與LoggerRunTimeInit.java相同的目錄中,

5、構建并運行本機可執行檔案

 native-image LoggerTest -H:IncludeResources="logging.properties"
  ./LoggerTest

6、它應該產生類似于以下內容的輸出:

 WARNING

9、使用jdk17和graalvm 你可以體驗到:

1.啟動時間:GraalVM 提供了 Just-In-Time (JIT) 編譯和 Ahead-Of-Time (AOT) 編譯的能力,AOT 編譯可以將 Java 應用程式編譯成本地機器碼,從而加快應用程式的啟動時間,相比之下,傳統的 JIT 編譯需要一些啟動時間來進行動態編譯,因此,使用 GraalVM 的 AOT 編譯可能會顯著減少啟動時間,提高應用程式的回應性能,

2.記憶體占用:GraalVM 的 AOT 編譯可以減少應用程式的記憶體占用,因為本地機器碼通常比解釋執行的位元組碼更加緊湊,這可以提高應用程式的可擴展性和資源利用率,

3.即時編譯性能:GraalVM 的 JIT 編譯器在某些情況下可能會提供更好的性能,它可以對熱點代碼進行更優化的編譯,以提高執行速度,這可能在一些計算密集型任務或高并發場景中帶來性能提升,

4.應用本身大小:在真實環境下占用對比 且二進制版本是已經整合5個專案的完整專案 而jar只是其中1/5

10、demo開箱即體驗

經過真實專案驗證的框架demo已上傳至github、地址:kafka-stream 基于JDK17+springboot3.0.6+kafkaStream構成 支持 native-image打包 讓您下的開心 用的舒心 歡迎大家體驗

作者:京東科技 徐擁

來源:京東云開發者社區

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/554319.html

標籤:Java

上一篇:演算法 in Go:Binary Search(二分查找)

下一篇:返回列表

標籤雲
其他(160361) Python(38201) JavaScript(25475) Java(18187) C(15237) 區塊鏈(8269) C#(7972) AI(7469) 爪哇(7425) MySQL(7234) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5346) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4582) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1981) 功能(1967) HtmlCss(1952) Web開發(1951) C++(1929) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 輕量靈動: 革新輕量級服務開發

    從 JDK 8 升級到 JDK 17 可以讓你的應用程式受益于新的功能、性能改進和安全增強。下面是一些 JDK 8 升級到 JDK 17 的最佳實戰 ......

    uj5u.com 2023-06-06 07:44:52 more
  • 演算法 in Go:Binary Search(二分查找)

    # 演算法 in Go:Binary Search(二分查找) ## Binary Search(二分查找) ### Binary Search(二分查找) - 猜數 - 1、2、3、4、5、6、7、8 - 排好序一個集合,先從中間開始猜,根據提示就可以排除一半,在剩余的一半里,再從中間開始猜,依此類 ......

    uj5u.com 2023-06-06 07:44:33 more
  • 從原始碼分析 Go 語言使用 cgo 導致的執行緒增長

    TDengine Go 連接器 使用 cgo 呼叫 taos.so 中的 API,使用程序中發現執行緒數不斷增長,本文從一個 cgo 呼叫開始決議 Go 原始碼,分析造成執行緒增長的原因。 ## 轉換 cgo 代碼 對 driver-go/wrapper/taosc.go 進行轉換 `go tool cg ......

    uj5u.com 2023-06-06 07:44:29 more
  • 驅動開發:內核實作SSDT掛鉤與摘鉤

    在前面的文章`《驅動開發:內核決議PE結構匯出表》`中我們封裝了兩個函式`KernelMapFile()`函式可用來讀取內核檔案,`GetAddressFromFunction()`函式可用來在匯出表中尋找指定函式的匯出地址,本章將以此為基礎實作對特定`SSDT`函式的`Hook`掛鉤操作,與`《驅... ......

    uj5u.com 2023-06-06 07:43:02 more
  • C++面試八股文:如何在堆上和堆疊上分配一塊記憶體?

    某日二師兄參加XXX科技公司的C++工程師開發崗位6面: > 面試官: 如何在堆上申請一塊記憶體? > > 二師兄:常用的方法有malloc,new等。 > > 面試官:兩者有什么區別? > > 二師兄:malloc是向作業系統申請一塊記憶體,這塊記憶體沒有經過初始化,通常需要使用memset手動初始化。 ......

    uj5u.com 2023-06-06 07:42:49 more
  • 驅動開發:內核實作SSDT掛鉤與摘鉤

    在前面的文章`《驅動開發:內核決議PE結構匯出表》`中我們封裝了兩個函式`KernelMapFile()`函式可用來讀取內核檔案,`GetAddressFromFunction()`函式可用來在匯出表中尋找指定函式的匯出地址,本章將以此為基礎實作對特定`SSDT`函式的`Hook`掛鉤操作,與`《驅... ......

    uj5u.com 2023-06-05 09:18:22 more
  • 6種限流方式

    服務限流,是指通過控制請求的速率或次數來達到保護服務的目的,在微服務中,我們通常會將它和熔斷、降級搭配在一起使用,來避免瞬時的大量請求對系統造成負荷,來達到保護服務平穩運行的目的。下面就來看一看常見的6種限流方式,以及它們的實作與使用。 ......

    uj5u.com 2023-06-05 09:07:09 more
  • 6種限流方式

    服務限流,是指通過控制請求的速率或次數來達到保護服務的目的,在微服務中,我們通常會將它和熔斷、降級搭配在一起使用,來避免瞬時的大量請求對系統造成負荷,來達到保護服務平穩運行的目的。下面就來看一看常見的6種限流方式,以及它們的實作與使用。 ......

    uj5u.com 2023-06-05 08:50:27 more
  • day08-SpringCloud Gateway-服務網關

    # SpringCloud Gateway-服務網關 ## 1.Gateway介紹 ### 1.1引出問題 **沒有使用網關服務時:** **使用網關服務后:** ### 1.2Gateway網路拓撲圖 ![Gateway網路拓撲圖](https://liyuelian.oss-cn-shenzhe ......

    uj5u.com 2023-06-05 07:52:43 more
  • 【python基礎】復雜資料型別-串列型別(元組)

    # 1.初識元組 串列非常適合用于存盤在程式運行期間可能變化的資料集。串列是可以修改的。 然而,有時候需要創建一系列不可修改的元素,元組可以滿足這種需求 python將不能修改的值稱為不可變的,而不可變的串列被稱為元組。 元組看起來猶如串列,但使用圓括號而不是方括號來標識。 其語法格式:元組變數名 ......

    uj5u.com 2023-06-05 07:52:12 more