1、試用環境準備
準備好
centos7
系統
安裝好
jdk17
安裝好
docker20
2、編寫專案並構建native映象
專案準備
從
start。spring。io
建立一個新的專案,專案名為
mynative
,在
ADD DEPENDENCIES
中可以看到排在第一位的依賴就是
spring-native
,不過目前還處理試驗階段,要謹慎使用;
新增幾個基礎依賴,主要是用來簡單測試一下一個
http
請求到
web
應用,並將請求資訊儲存到記憶體資料庫
h2
中,然後開啟記憶體資料庫的
console
控制檯查詢校驗資料,看資料是否正常;
mynative
專案原始碼結果如下
程式碼片斷
RequestLogController類——-@Slf4j@RestController@RequestMapping(“/”)public class RequestLogController { @Autowired private RequestLogRepository requestLogRepository; @GetMapping(“/log”) public String log(HttpServletRequest request) { RequestLog entity = new RequestLog(); entity。setId(UUID。randomUUID()。toString()。toUpperCase()); Enumeration
簡單起見,需要在配置檔案中開啟記憶體資料庫
h2
的管理控制檯,並且允許
web
訪問(不僅是透過
localhost
),如上面的
application。yaml
配置
編譯專案
mvn spring-boot:buid-image
首次編譯期間會去下載以下映象,耗時較長,而且這個構建過程比較耗
cpu
資源,其使用率經常保持在較高的水平,大概10分鐘左右完成映象的構建;
docker。io/paketobuildpacks/builder:tinydocker。io/paketobuildpacks/run:tiny-cnb
構建映象片斷
[INFO] > Pulling builder image ‘docker。io/paketobuildpacks/builder:tiny’ 59%[INFO] > Pulling builder image ‘docker。io/paketobuildpacks/builder:tiny’ 71%[INFO] > Pulling builder image ‘docker。io/paketobuildpacks/builder:tiny’ 84%[INFO] > Pulling builder image ‘docker。io/paketobuildpacks/builder:tiny’ 100%[INFO] > Pulled builder image ‘paketobuildpacks/builder@sha256:782b8eff60d91ae734bd82c40c973b0f002c16ca881e91aeb977984699af666b’[INFO] > Pulling run image ‘docker。io/paketobuildpacks/run:tiny-cnb’ 100%[INFO] > Pulled run image ‘paketobuildpacks/run@sha256:ecc1c097c43a313151bbcb544b4b6c17ec808e93707a777e01c1e5b37d4dd6bc’……[INFO] [creator] ===> EXPORTING[INFO] [creator] Reusing layer ‘paketo-buildpacks/ca-certificates:helper’[INFO] [creator] Adding 1/1 app layer(s)[INFO] [creator] Adding layer ‘launcher’[INFO] [creator] Adding layer ‘config’[INFO] [creator] Reusing layer ‘process-types’[INFO] [creator] Adding label ‘io。buildpacks。lifecycle。metadata’[INFO] [creator] Adding label ‘io。buildpacks。build。metadata’[INFO] [creator] Adding label ‘io。buildpacks。project。metadata’[INFO] [creator] Adding label ‘org。opencontainers。image。title’[INFO] [creator] Adding label ‘org。opencontainers。image。version’[INFO] [creator] Adding label ‘org。springframework。boot。version’[INFO] [creator] Setting default process type ‘web’[INFO] [creator] Saving docker。io/library/native:0。0。1。。。[INFO] [creator] *** Images (9ebd0ad2764f):[INFO] [creator] docker。io/library/native:0。0。1[INFO] [creator] Reusing cache layer ‘paketo-buildpacks/bellsoft-liberica:native-image-svm’[INFO] [creator] Reusing cache layer ‘paketo-buildpacks/syft:syft’[INFO] [creator] Adding cache layer ‘paketo-buildpacks/native-image:native-image’[INFO] [INFO] Successfully built image ‘docker。io/library/native:0。0。1’
編譯成功後生成了一個native:0。0。1映象如下,可以看到映象大小有145M,可以看到created時間不對,這裡是
42 years age
相應的解析
https://medium。com/buildpacks/time-travel-with-pack-e0efd8bf05db
,大意是構建映象的
sha
會隨檔案時間戳而變化
3、執行native並觀察結果
執行native映象
docker run -it ——rm -p 8888:8888 native:0。0。1
可以看到啟動速度非常快,在1秒內完成了啟動,正常透過
java -jar target/native-0。0。1。jar
啟動需要約5秒鐘,有顯著的差異,啟動的過程中有一個細節可以看到
H2 console available at ‘/h2-console’。 Database available at ‘jdbc:h2:mem:f3f1583f-1323-4dbe-914d-cc342d73a3d3’
,由於在
spring。datasource。url
沒有指定路徑,所以預設會隨機生成一個
uuid
字元作為資料庫名稱,若指定一個數據庫名則會直接使用指定的名稱;
模擬資料
透過
curl http://192。168。91。132:8888/log
模擬訪問先造一些資料,可以看到控制檯會有一些
insert sql
語句打印出來,資料可以正常寫入了。然後開啟H2控制檯
http://192。168。91。132:8888/h2-console
,發現報異常了,不能正常開啟頁面,報錯如下
4、解決native映象執行h2-console無法訪問的問題
根據報錯的提示跟蹤一下原始碼
org。h2。server。web。WebServer
此處報空指標異常是
trans
為
null
,即說明
getFile
返回為
null
,跟蹤
getFile
方法,可以看到是透過
Utils。getResource(“/org/h2/server/web/res/” + file)
獲取,繼續跟蹤
getResource
方法可以發現資源是從
RESOURCES
中獲取,而這個資源是
loadResource
方法從
Utils。class。getResourceAsStream(“data。zip”)
此處獲取,即在
Utils
包的目錄下拿到一個
data。zip
檔案。
接著開啟
h2-1。4。200。jar
包,進到目錄
org\h2\util
中可以找到
data。zip
結果就清晰了,可能是
spring-native
構建映象的時候將此資原始檔排除了,將其放到專案的
resources/org/h2/util
中,再一次構建映象執行,就可以正常看到
h2
資料庫的控制檯了,多請求幾次測試
url
,即可查到資料。
5、最新版支援AOP切面
編寫一個日誌切面
用此切面攔截
Controller
中的日誌
log
請求,檢視效果
package com。minxyz。mynative。aspect;import lombok。extern。slf4j。Slf4j;import org。aspectj。lang。ProceedingJoinPoint;import org。aspectj。lang。annotation。Around;import org。aspectj。lang。annotation。Aspect;import org。springframework。stereotype。Component;@Slf4j@Aspect@Componentpublic class LogAspect { @Around(“execution(* com。minxyz。mynative。controller。RequestLogController。log(。。))”) public Object processInsertRoleConfig(ProceedingJoinPoint point) throws Throwable { log。info(“enter LogAspect function”); Object[] args = point。getArgs(); return point。proceed(args); }}
同時需在啟動類中增加
@AotProxyHint
註解配置,指定類
@AotProxyHint(targetClass=com。minxyz。mynative。controller。RequestLogController。class,proxyFeatures = ProxyBits。IS_STATIC)
附:原始碼 https://gitee。com/viturefree/spring-native-test。git