spring-native簡單實踐(實驗版)

1、試用環境準備

準備好

centos7

系統

安裝好

jdk17

安裝好

docker20

spring-native簡單實踐(實驗版)

2、編寫專案並構建native映象

專案準備

start。spring。io

建立一個新的專案,專案名為

mynative

,在

ADD DEPENDENCIES

中可以看到排在第一位的依賴就是

spring-native

,不過目前還處理試驗階段,要謹慎使用;

spring-native簡單實踐(實驗版)

新增幾個基礎依賴,主要是用來簡單測試一下一個

http

請求到

web

應用,並將請求資訊儲存到記憶體資料庫

h2

中,然後開啟記憶體資料庫的

console

控制檯查詢校驗資料,看資料是否正常;

spring-native簡單實踐(實驗版)

mynative

專案原始碼結果如下

spring-native簡單實踐(實驗版)

程式碼片斷

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 names = request。getHeaderNames(); StringBuilder builder = new StringBuilder(request。getRequestURL())。append(“\r\n”); while (names。hasMoreElements()) { String name = names。nextElement(); builder。append(name)。append(“ = ”)。append(request。getHeader(name))。append(“\r\n”); } entity。setContent(builder。toString()); entity。setLogDate(new Date()); requestLogRepository。save(entity); return HttpStatus。OK。toString(); }}——-RequestLog類——-@Getter@Setter@Entitypublic class RequestLog { @Id private String id; @Column(length = 1024) private String content; private Date logDate;}——-RequestLogRepository類——-@Repositorypublic interface RequestLogRepository extends JpaRepository {}——-MyNativeApplication類——-@EnableJpaRepositories@SpringBootApplicationpublic class MyNativeApplication { public static void main(String[] args) { SpringApplication。run(MyNativeApplication。class, args); }}——-application。yaml配置檔案——-server: port: 8888logging: level: root: infospring: h2: console: enabled: true settings: web-allow-others: true jpa: show-sql: true——-

簡單起見,需要在配置檔案中開啟記憶體資料庫

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

會隨檔案時間戳而變化

spring-native簡單實踐(實驗版)

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

,發現報異常了,不能正常開啟頁面,報錯如下

spring-native簡單實踐(實驗版)

4、解決native映象執行h2-console無法訪問的問題

根據報錯的提示跟蹤一下原始碼

org。h2。server。web。WebServer

spring-native簡單實踐(實驗版)

此處報空指標異常是

trans

null

,即說明

getFile

返回為

null

,跟蹤

getFile

方法,可以看到是透過

Utils。getResource(“/org/h2/server/web/res/” + file)

獲取,繼續跟蹤

getResource

方法可以發現資源是從

RESOURCES

中獲取,而這個資源是

loadResource

方法從

Utils。class。getResourceAsStream(“data。zip”)

此處獲取,即在

Utils

包的目錄下拿到一個

data。zip

檔案。

spring-native簡單實踐(實驗版)

接著開啟

h2-1。4。200。jar

包,進到目錄

org\h2\util

中可以找到

data。zip

spring-native簡單實踐(實驗版)

結果就清晰了,可能是

spring-native

構建映象的時候將此資原始檔排除了,將其放到專案的

resources/org/h2/util

中,再一次構建映象執行,就可以正常看到

h2

資料庫的控制檯了,多請求幾次測試

url

,即可查到資料。

spring-native簡單實踐(實驗版)

spring-native簡單實踐(實驗版)

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