OpenFaaS實戰之九:終篇,自制模板(springboot+maven+jdk8)

程式設計師欣宸發表於2021-08-11

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;

OpenFaaS實戰系列文章連結

  1. 部署
  2. 函式入門
  3. Java函式
  4. 模板操作(template)
  5. 大話watchdog
  6. of-watchdog(為效能而生)
  7. java11模板解析
  8. OpenFaaS實戰之八:自制模板(maven+jdk8)
  9. 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"]

模板配置

  • 現在材料已經準備完畢了,再整理一下準備提交到github上,就可以作為OpenFaaS模板使用了;
  1. 新建一個資料夾,名為simplespringboot
  2. simplespringboot目錄下新建檔案template.yml,內容如下:
language: simplespringboot
welcome_message: |
  You have created a function using the java8 and maven and springboot template
  1. 將前面的Dockerfile檔案複製到simplespringboot目錄下;
  2. 前面我們們建立的springboot工程,最外層的資料夾名為jdk8mavenspringboot,請將此資料夾改名為function,然後將整個資料夾都複製到simplespringboot目錄下;
  3. 此刻的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
  1. 將這些內容全部上傳到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之路帶來一些參考,那將是我的榮幸;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 資料庫+中介軟體系列
  6. DevOps系列

歡迎關注公眾號:程式設計師欣宸

微信搜尋「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界...
https://github.com/zq2599/blog_demos

相關文章