歡迎訪問我的GitHub
https://github.com/zq2599/blog_demos
內容:所有原創文章分類匯總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;
OpenFaaS實戰系列文章鏈接
- 部署
- 函數入門
- Java函數
- 模板操作(template)
- 大話watchdog
- of-watchdog(為性能而生)
- java11模板解析
- OpenFaaS實戰之八:自制模板(maven+jdk8)
- OpenFaaS實戰之九:終篇,自制模板(springboot+maven+jdk8)
本篇概覽
- 作為《OpenFaaS實戰》系列的終篇,在前八篇文章中,理論和實戰咱們已經做得夠多,最后就做個有實用價值的模板為整個系列划上句號吧;
- 《OpenFaaS實戰之八:自制模板(maven+jdk8)》中做了個java模板:JDK版本是8,編譯構建工具是maven,功能是通過編寫Handler.java提供web服務,這個模板並不實用,在實際的開發中java程序員喜歡用springboot框架,所以,今天咱們的任務是做一個自定義模板,jdk8、maven、springboot一樣都不少;
- 具體的實戰內容如下圖,先完成左側藍色部分,把模板做好,再執行右側綠色部分,開發一個函數驗證模板符合預期:
- 好吧,少一點套路,多一些真誠,不說閑話直接開始操作;
創建java項目
- 制作模板時最重要的就是提供完整的模板代碼,接下來就來制作吧;
- 我這邊用的是IDEA,建一個springboot項目,名為jdk8mavenspringboot,用的是JDK8:
- 項目基本設置如下圖:
- 項目的pom.xml內容如下,要注意的是spring-boot-maven-plugin插件增加了一個配置參數configuration.layers.enabled,這是制作鏡像時用到的,做出的jar文件可以從中提取出鏡像所需內容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bolingcavalry</groupId>
<artifactId>jdk8mavenspringboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jdk8mavenspringboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 新增一個controller,作為象征性的demo代碼:
package com.bolingcavalry.jdk8mavenspringboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
public class Hello {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "Hello world, " + new Date();
}
}
- pom.xml所在目錄下,新建文件夾m2,里面增加maven的配置文件settings.xml,該文件是在FaaS開發過程中,制作鏡像時用到的(制作鏡像時會編譯構建java項目),強烈建議在里面配置好您的maven私服,或者阿里雲鏡像,這樣制作鏡像時會快很多,我這里已經配置了阿里雲鏡像,依然耗時兩分多鍾(如下圖),所以如果您有nexus3私服一定要優先考慮:
- 修改配置文件src/main/resources/application.properties,增加一行端口配置,這是fwatchdog轉發到的端口:
server.port=8082
- 至此,編碼工作已完成,可見這就是個普通springboot工程,接下來要考慮的是如何制作Docker鏡像,即Dockerfile的編寫;
開發Dockerfile
- 前面的實戰中咱們已經體驗過,開發FaaS的時候會將代碼編譯構建制作成鏡像,因此對應的Dockerfile也要准備好,下面是完整的Dockerfile內容:
# 用maven鏡像作為基礎鏡像,用於編譯構建java項目
FROM maven:3.6.3-openjdk-8 as builder
WORKDIR /home/app
# 將整個項目都復制到/home/app目錄下
COPY . /home/app/
# 進入pom.xml所在目錄執行構建命令,指定m2/settings.xml文件作為配置文件,
# 請在settings.xml中配置好私服,否則構建速度極慢
RUN cd function && mvn clean package -U -DskipTests --settings ./m2/settings.xml
# 前面用maven編譯構建完畢后,這里將構建結果復制到指定位置用於提取文件
RUN cp /home/app/function/target/*.jar ./application.jar
# 通過工具spring-boot-jarmode-layertools從application.jar中提取拆分后的構建結果
RUN java -Djarmode=layertools -jar application.jar extract
# of-watchdog里面有二進制文件watchdog,制作鏡像時要用到
FROM openfaas/of-watchdog:0.7.6 as watchdog
# openjdk鏡像是容器的運行環境
FROM openjdk:8-jre-slim as ship
# 為了安全起見,在生產環境運行容器時不要用指root帳號和群組
RUN addgroup --system app \
&& adduser --system --ingroup app app
# 從of-watchdog鏡像中復制二進制文件fwatchdog,這是容器的啟動進程
COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
# 賦予可執行權限
RUN chmod +x /usr/bin/fwatchdog
WORKDIR /home/app
# 前面提取命令執行成功后取得的文件,用於鏡像中啟動應用所需
COPY --from=builder /home/app/dependencies/ ./
COPY --from=builder /home/app/spring-boot-loader/ ./
COPY --from=builder /home/app/snapshot-dependencies/ ./
COPY --from=builder /home/app/application/ ./
# 指定容器的運行帳號
user app
# 指定容器的工作目錄
WORKDIR /home/app/
# fwatchdog收到web請求后的轉發地址,java進程監聽的就是這個端口
ENV upstream_url="http://127.0.0.1:8082"
# 運行模式是http
ENV mode="http"
# 拉起業務進程的命令,這里就是啟動java進程
ENV fprocess="java org.springframework.boot.loader.JarLauncher"
# 容器對外暴露的端口,也就是fwatchdog進程監聽的端口
EXPOSE 8080
# 健康檢查
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1
# 容器啟動命令,這里是執行二進制文件fwatchdog
CMD ["fwatchdog"]
- 上述腳本中有提取和復制提取內容的操作,這是springboot官方從2.3版本為容器化提供的特性,詳情可以參考《體驗SpringBoot(2.3)應用制作Docker鏡像(官方方案)》
模板配置
- 現在材料已經准備完畢了,再整理一下准備提交到github上,就可以作為OpenFaaS模板使用了;
- 新建一個文件夾,名為simplespringboot;
- simplespringboot目錄下新建文件template.yml,內容如下:
language: simplespringboot
welcome_message: |
You have created a function using the java8 and maven and springboot template
- 將前面的Dockerfile文件復制到simplespringboot目錄下;
- 前面咱們創建的springboot工程,最外層的文件夾名為jdk8mavenspringboot,請將此文件夾改名為function,然后將整個文件夾都復制到simplespringboot目錄下;
- 此刻的simplespringboot目錄下應該是這些內容:
[root@hedy 003]# tree simplespringboot
simplespringboot
├── Dockerfile
├── function
│ ├── HELP.md
│ ├── jdk8mavenspringboot.iml
│ ├── m2
│ │ └── settings.xml
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── bolingcavalry
│ │ │ └── jdk8mavenspringboot
│ │ │ ├── controller
│ │ │ │ └── Hello.java
│ │ │ └── Jdk8mavenspringbootApplication.java
│ │ └── resources
│ │ ├── application.properties
│ │ ├── static
│ │ └── templates
│ └── test
│ └── java
│ └── com
│ └── bolingcavalry
│ └── jdk8mavenspringboot
│ └── Jdk8mavenspringbootApplicationTests.java
└── template.yml
17 directories, 12 files
- 將這些內容全部上傳到github上,我這里路徑是https://github.com/zq2599/openfaas-templates/tree/master/template,這里面已經有四個模板了,本次新增的如下圖紅框:
- 至此,模板制作完成,接下來驗證此模板是否可用;
驗證模板
- 接下來要做的,就是下圖右側的綠色部分:
- 登錄一台配好OpenFaaS客戶端的電腦,找個干凈目錄執行以下命令,將github上所有模板下載下來:
faas template pull https://github.com/zq2599/openfaas-templates
- 控制台響應如下,提示下載了四個模板,符合預期:
[root@hedy 07]# faas template pull https://github.com/zq2599/openfaas-templates
Fetch templates from repository: https://github.com/zq2599/openfaas-templates at
2021/03/07 20:30:24 Attempting to expand templates from https://github.com/zq2599/openfaas-templates
2021/03/07 20:30:29 Fetched 4 template(s) : [dockerfile java11extend simplejava8 simplespringboot] from https://github.com/zq2599/openfaas-templates
- 用faas new --list查看列表如下:
[root@hedy 07]# faas new --list
Languages available as templates:
- dockerfile
- java11extend
- simplejava8
- simplespringboot
- 看看template/simplespringboot目錄下的內容,和前面上傳的一模一樣:
[root@hedy 07]# tree template/simplespringboot/
template/simplespringboot/
├── Dockerfile
├── function
│ ├── m2
│ │ └── settings.xml
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── bolingcavalry
│ │ │ └── jdk8mavenspringboot
│ │ │ ├── controller
│ │ │ │ └── Hello.java
│ │ │ └── Jdk8mavenspringbootApplication.java
│ │ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── bolingcavalry
│ └── jdk8mavenspringboot
│ └── Jdk8mavenspringbootApplicationTests.java
└── template.yml
15 directories, 10 files
- 有了模板就可以創建函數了,執行以下命令創建名為faas-simplespringbootdemo的函數:
faas-cli new faas-simplespringbootdemo --lang simplespringboot -p bolingcavalry
- 控制台提示如下,此時當前目錄下新增文件夾faas-simplespringbootdemo,這就是新建函數的代碼目錄:
[root@hedy 07]# faas-cli new faas-simplespringbootdemo --lang simplespringboot -p bolingcavalry
Folder: faas-simplespringbootdemo created.
___ _____ ____
/ _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) | __/ | | | _| (_| | (_| |___) |
\___/| .__/ \___|_| |_|_| \__,_|\__,_|____/
|_|
Function created in folder: faas-simplespringbootdemo
Stack file written: faas-simplespringbootdemo.yml
Notes:
You have created a function using the java8 and maven and springboot template
- 文件夾faas-simplespringbootdemo的內容如下,現在妥了,用IDEA等IDE工具以maven工程形式導入,然后根據業務需求修改這個工程即可:
[root@hedy 07]# tree faas-simplespringbootdemo
faas-simplespringbootdemo
├── m2
│ └── settings.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── bolingcavalry
│ │ └── jdk8mavenspringboot
│ │ ├── controller
│ │ │ └── Hello.java
│ │ └── Jdk8mavenspringbootApplication.java
│ └── resources
│ └── application.properties
└── test
└── java
└── com
└── bolingcavalry
└── jdk8mavenspringboot
└── Jdk8mavenspringbootApplicationTests.java
14 directories, 8 files
- 現在可以開發業務了,這里為了測試,修改了Hello.java的接口返回內容,如下圖紅框:
- 開始編譯構建吧,執行以下命令:
faas-cli build -f ./faas-simplespringbootdemo.yml
- 構建完成后將鏡像推送到鏡像倉庫,以便Kubernetes可以下載到此鏡像,我這里用的是hub.docker.com,因為我的ID是bolingcavalry,所執行以下命令即可推送成功(要先執行docker login命令登錄):
docker push bolingcavalry/faas-simplespringbootdemo:latest
- 執行以下命令部署函數到OpenFaaS:
faas-cli deploy -f faas-simplespringbootdemo.yml
- 控制台響應如下,可見部署已經開始,並且給出了endpoint:
[root@hedy 07]# faas-cli deploy -f faas-simplespringbootdemo.yml
Deploying: faas-simplespringbootdemo.
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.
Deployed. 202 Accepted.
URL: http://192.168.50.75:31112/function/faas-simplespringbootdemo.openfaas-fn
- 在控制台用curl命令測試:
[root@hedy 07]# curl http://192.168.50.75:31112/function/faas-simplespringbootdemo.openfaas-fn/hello
Hello world 123456789, Sun Mar 07 13:17:06 UTC 2021
- 至此,驗證模板完成,符合預期
清理
- 刪除函數的命令如下,依舊是faas-simplespringbootdemo.yml所在目錄:
faas-cli remove -f faas-simplespringbootdemo.yml
- 至此,自制的springboot+maven+jdk8的模板,從開發到驗證咱們已經全部走了一遍,咱們的OpenFaaS實戰系列也圓滿收官,希望此系列能給您的Serverless之路帶來一些參考,那將是我的榮幸;
你不孤單,欣宸原創一路相伴
歡迎關注公眾號:程序員欣宸
微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢游Java世界...
https://github.com/zq2599/blog_demos