使用 Micronaut和OpenFaaS 構建無伺服器Java 應用程式 - openvalue
在Java生態系統中的微服務上工作時,尤其是使用Spring(Boot)時,您會注意到應用程式會有很長的啟動時間,更不用說它們將擁有高記憶體消耗了。每個微服務的開銷最終將在系統上承擔其成本。而諸如Micronaut之類的框架可以幫助減少這種開銷,而又不損失任何開發人員的生產力。使用Micronaut不僅可以構建“經典”應用程式,而且可以使用OpenFaaS在雲環境或Kubernetes上構建和部署無伺服器應用程式和功能。讓我們開始吧!
小注釋:在本文中,對Spring進行了一些參考和比較。因此,有關Spring的一些知識可能會很有用。
隆重介紹Micronaut
Micronaut是一個基於JVM的框架,旨在構建模組化微服務。當您開啟Micronaut專案時,乍看之下不會感到驚訝,它的外觀和感覺與Java世界中常見的Spring(引導)專案相同。但是,差異遠遠很小或微妙,在開始將此類專案投入生產之前,應該很好地理解它們。另一方面,開始發現Micronaut世界的過程將非常順利,並且隨著您逐步探索Micronaut世界,對它的理解也會隨之增長。
註釋和Micronaut
眾所周知,在執行時Spring會使用大量反射,而Micronaut所做的這些工作卻是編譯時已經完成。一個示例是執行時生成的Spring Data查詢,Micronaut將在編譯時生成相同的查詢,從而在執行時最大程度地減少使用的記憶體。建立的每個Bean都會在編譯時得到充實,從而建立一個所謂的BeanDefinition 類,其中包含Bean的需求及其建構函式。所有這些類都使用進行處理BeanDefinitionInjectProcessor。
而且,Micronaut依賴於Java EE依賴注入,因此可以使用@Singleton和使用@Inject對Bean進行註釋 。這些bean的生命週期將由Micronaut自己管理。
構建一個Micronaut元件
對於與Micronaut有關的所有事情,都可以使用CLI(命令列介面)工具。只需按照官方文件中的步驟安裝即可 。
對於使用Micronaut的任何專案,CLI工具都是一個很好的起點,它將生成專案的主幹結構以及一些有用的開發檔案。它為您完成整個腳手架。對於每種應用程式型別,可以設定功能列表以生成這些功能所需的所有必要配置。CLI工具支援三種JVM語言:Java,Kotlin和Groovy,以及兩種構建工具:Maven和Gradle。如果是Maven專案,則將生成Maven包裝器以及pom.xml。
緊接著,CLI工具將生成一個Micronaut-cli.yml,這將是CLI工具進行任何進一步操作的輸入,並將包含專案的名稱和配置檔案。
如果你來自Spring世界,會在Spring 的main / resources目錄中找到:application.yml。就像在Spring應用程式中一樣,此檔案包含該應用程式的所有配置設定。
示例
一個簡單的應用程式將為作者提供一本書。為此,它將呼叫一個返回作者所有書籍的函式。
在此示例中,應用程式將包含一個REST端點,以詢問特定作者的書。該端點必須呼叫一個函式來檢索此資訊。因此,該應用程式將是一個http伺服器以及一個http客戶端,並將部署在Kubernetes上。
因此,生成應用程式基礎的命令將是:
mn create-app bookstore-service --build=Maven --lang=java --features=Kubernetes,netflix-hystrix,http-server,http-client |
由於該服務呼叫一個函式,因此需要netflix-hystrix。一個函式需要一些時間才能啟動(預熱時間)。這並不意味著會花費很多時間,但是HTTP呼叫肯定會花費一些時間。為避免該函式直接返回狀態為500的HTTP響應,需要一種重試機制以確保在答案可用後立即對其進行檢索。
由於該應用程式將按函式指示部署在Kubernetes上Kubernetes,因此該create-app命令還將生成一個k8s.yml,它將作為部署的基礎。當然,必須根據部署環境的要求對其進行調整。該Kubernetes配置將具有部署和服務。
預設情況下,此應用程式將在埠8080上執行。要更改application.yml中的以下屬性,可以將其設定為首選值:
micronaut: server: port: 8081 |
現在是時候新增一個端點來檢索給定作者的所有書籍。為此,將使用Micronaut的HTTP函式。
package bookstore.service.store; import io.Micronaut.http.annotation.Controller; import io.Micronaut.http.annotation.Get; import io.Micronaut.http.annotation.PathVariable; @Controller("books") public class BookstoreController { @Get("/{author}") public Book retrieveBooksByAuthor() { return new Book("1000 new things", "John Doe"); } } |
這看起來很像Spring Controller,對嗎?除了使用Micronaut軟體包中的註釋外。
這裡引人注目的是BookDTO 的實現:
@Introspected public class Book implements Serializable { private String title; private String author; public Book(String title, String author) { this.title = title; this.author = author; } // some getters } |
@Introspected是反射DTO所需的註釋。在編譯時,將執行檢查以檢視是否可以為DTO初始化所有屬性。
構建一個函式來服務需要快速提供給我們應用程式的資料,而無需使用大量邏輯。在我們的示例中,該函式將返回給定作者姓名的書籍清單。讓我們從最簡單的情況開始:
mn create-function get-books-by-author --build=Maven --features=openfaas |
為了使該函式可構建,必須刪除一個AWS依賴項(在本示例中,將不使用任何AWS功能,並且它將返回類路徑錯誤),我們是為在OpenFaaS上構建執行的函式。:
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.0.0</version> <scope>runtime</scope> </dependency> |
在撰寫本文時,Dockerfile仍將存在一個錯誤。Dockerfile基於OpenJDK 8映像,但它應基於OpenJDK 13映像,以免遇到任何執行時/編譯問題。
在Dockerfile中的以下程式碼行中,必須刪除兩個標誌:
ENV fprocess="java -Dcom.sun.management.jmxremote -noverify -XX:TieredStopAtLevel=1 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar Handler.jar" |
-noverify和-XX:+UseCGroupMemoryLimitForHeapJDK 13中已棄用,因此不需要。程式碼行將變為:
ENV fprocess="java -Dcom.sun.management.jmxremote -XX:TieredStopAtLevel=1 -XX:+UnlockExperimentalVMOptions -jar Handler.jar" |
接下來,我們需要新增log4j2.xml作為log4日誌記錄的配置。
此外,還必須為jar中的日誌新增以下內容:
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>${exec.mainClass}</mainClass> <manifestEntries> <Multi-Release>true</Multi-Release> </manifestEntries> </transformer> |
現在,為方便起見,僅透過在Dockerfile中進一步更改fprocess命令,將日誌記錄級別設定為ERROR:
ENV fprocess="java -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=ERROR -Dcom.sun.management.jmxremote -XX:TieredStopAtLevel=1 -XX:+UnlockExperimentalVMOptions -jar Handler.jar" |
為了使函式儘可能簡單,函式類不會擴充套件 FunctionInitializer.
部署Micronaut
現在需要一個環境來部署它。OpenFaaS是在Kubernetes上部署應用程式或功能的不錯選擇。對於Micronaut功能,OpenFaaS將部署一個Pod。在此Pod上,直到呼叫終結點之前,任何內容都不會執行。屆時,應用程式將開始執行並返回端點呼叫。
安裝OpenFaaS非常容易,不應花費太多時間。在執行專案時,我想探索Micronaut功能。但是,不能選擇部署到AWS,而我的好奇心是由OpenFaaS觸發的。在本地安裝OpenFaaS非常容易。OpenFaaS使在現有Kubernetes叢集上輕鬆部署功能和應用程式變得容易。
此處 列出了安裝說明 。
簡而言之,從安裝CLI開始:
brew install faas-cli |
然後在安裝OpenFaaS之前,安裝Arkade(這是以後安裝OpenFaaS的最快選擇):
curl -SLsf https://dl.get-arkade.dev/ | sudo sh |
現在,您終於可以在本地Kubernetes叢集上安裝OpenFaaS了:
arkade install openfaas |
現在的訣竅是不要忽略安裝中出現的所有日誌記錄行,那裡有一些有用的說明可以幫助您完成安裝。首先要檢查所有部署是否都成功:
kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" |
成功的部署應該是:
NAME READY UP-TO-DATE AVAILABLE AGE alertmanager 1/1 1 1 6d21h basic-auth-plugin 1/1 1 1 6d21h faas-idler 1/1 1 1 6d21h gateway 1/1 1 1 6d21h nats 1/1 1 1 6d21h prometheus 1/1 1 1 6d21h queue-worker 1/1 1 1 6d21h |
現在必須採取最後一步。OpenFaaS使用的閘道器應轉發:
kubectl -n openfaas rollout status deploy/gateway kubectl -n openfaas port-foward svc/gateway 8080:8080 |
不要忘記設定登入名:
PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo) echo -n $PASSWORD | faas-cli login --username admin --password-stdin |
OpenFaaS現在應該已經啟動並執行!
部署Micronaut函式:在OpenFaaS上測試功能:OpenFaaS需要登錄檔來推送和部署功能。對於本地開發,可以在docker容器中啟動登錄檔:
sudo docker run -d -p 5000:5000 --name registry registry:2 |
在提供者描述(僅指定閘道器的端點)之後, 更仔細地看看function.yml,該功能被描述為必須執行的docker映像:
provider: name: openfaas gateway: http://127.0.0.1:8080 functions: get-books-by-author: lang: dockerfile handler: . image: localhost:5000/get-books-by-author:latest |
在此示例中,該映像的字首localhost:5000/是前一個bash命令啟動的本地登錄檔。
現在,讓我們使用的神奇命令faas-cli來部署和執行該函式:
faas-cli build -f function.yml faas-cli push -f function.yml faas-cli deploy -f function.yml |
現在透過OpenFaaS閘道器呼叫該函式:
curl -X GET http://127.0.0.1:8080/function/get-books-by-author -H 'Content-Type: application/json' -d $'{"name":"Piet"}' |
要驗證該功能正在執行:
kubectl -n openfaas-fn get pods |
現在,此函式已經有執行的Pod,一旦對端點進行REST呼叫後,pod將啟動應用程式。這是透過看門狗完成的 。
資源:
本文中的所有內容都是在以下環境下開發的:
- Mac OSX Catalina
- Docker桌面(Engine v.19.03.5,Kubernetes v1.15.5)
- OpenJDK的13.0.2
參考文獻:
相關文章
- 使用Java和Reactive Streams構建流式應用JavaReact
- 使用Rust和WebAssembly構建Web應用程式RustWeb
- 使用Java和Spring MVC構建Web應用JavaSpringMVCWeb
- Judo:使用無程式碼構建原生應用體驗
- 使用Java和Dapr構建雲原生應用簡介Java
- 使用React.js和應用快取構建快速同步應用程式ReactJS快取
- 使用SignalR構建聊天應用程式SignalR
- 使用Knative和Python的構建無伺服器事件驅動的應用 - Ron NagarPython伺服器事件
- 使用 IBM Bluemix 構建,部署和管理自定義應用程式IBM
- 使用 Docker 和 Elasticsearch 構建一個全文搜尋應用程式DockerElasticsearch
- 使用微服務構建現代應用程式微服務
- 在 IBM Lotus Domino Designer 中使用 Java 構建應用程式IBMJava
- 使用Java和Neo4j構建圖資料庫應用Java資料庫
- 使用 webpack 構建應用Web
- 使用汽車應用庫構建應用
- 使用 jQuery UI 和 jQuery 外掛構建更好的 Web 應用程式jQueryUIWeb
- 使用 SCons 代替 Makefile 快速構建應用程式
- 使用JHipster構建Spring和React構建電子商務應用程式原始碼 -DEVSpringReact原始碼dev
- Java應用構建並部署ECSJava
- 使用 Redis 和 Python 構建一個共享單車的應用程式RedisPython
- 使用SvelteKit構建實時websocket應用程式 - IngestWeb
- 【譯】如何使用PHP快速構建命令列應用程式PHP命令列
- 使用 Oracle XML Publisher 構建線上報表應用程式OracleXML
- 使用 nuxi build 命令構建你的 Nuxt 應用程式UXUI
- 【譯】使用 Webpack 和 Poi 構建更好的 JavaScript 應用WebJavaScript
- 使用Meteor和Node.js構建實時應用Node.js
- JavaFX桌面應用-構建程式框架Java框架
- 使用Java和Spring WebFlux構建響應式微服務JavaSpringWebUX微服務
- 使用webpack構建多頁應用Web
- 使用Golang快速構建WEB應用GolangWeb
- 使用React Native和Expo快速構建原生移動iOS和Android應用程式React NativeiOSAndroid
- 使用Spring Cloud Gateway代理.NET應用程式和無伺服器功能 – Richard SeroterSpringCloudGateway伺服器
- 在AWS無伺服器架構上實施應用程式介面伺服器架構
- [譯] 使用Capacitor 和 Vue.js 構建移動應用Vue.js
- 設定Jenkins伺服器構建Spring Boot應用程式 - MarcusJenkins伺服器Spring Boot
- 使用SlashDB,Go和Vue構建一個簡單的時間表應用程式GoVue
- 五、Spring Web應用程式構建SpringWeb
- 如何構建 Android MVVM 應用程式AndroidMVVM