热烈欢迎浏览我的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掌握得差不多了,也该搞事了;
  • 做为一个Java程序猿,常常使用jdk8、maven、springboot这种物品,当然要关心官方网模版是不是适用,如下图,官方网文本文档表明对java程序猿的适用幅度不足:不兼容java8、用的是Gradle并非maven、不兼容springboot,仅用vertx架构来适用web服务:

在这里插入图片描述

  • 即然官方网模版不兼容,我们就自做模版来适用吧,秉着有的放矢的标准,这篇先做一个简易的模版:将官方网的java11模版维持作用不会改变,jdk版本更新改造成java8,并将Gradle改为maven;

  • 毫无疑问jdk8和maven早已一大把年龄了,新版本jdk和Gradle全是更强的挑选,但是这篇的关键是怎样自定模版,因此 还请您给与宽容...

  • 今日要做的事儿,如下图所显示,我们先做左侧深蓝色一部分,撰写模版编码,上传入github模版库房,再做右边翠绿色一部分,像前边文章内容中应用官方网模版那般去应用这一模版:

在这里插入图片描述

  • 下面的实战演练由以下几点构成:
  1. 建立java新项目,做为模版的基本源代码
  2. 开发设计Dockerfile
  3. 进行模版配备并提交
  4. 认证模版

建立java新项目

  • 制做模版时最重要的便是给予详细的模版编码,下面就来制做吧;
  • 我这边用的是IDEA,建一个空maven新项目,名叫java8maven,用的是JDK8:
  • 如下图,留意Language level要挑选8

在这里插入图片描述

  • pom.xml的內容以下,要留意的好多个点稍候会表明:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bolingcavalry</groupId>
    <artifactId>java8maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-math3</artifactId>
            <version>3.6.1</version>
        </dependency>

        <dependency>
            <groupId>com.Google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>com.openfaas</groupId>
            <artifactId>model</artifactId>
            <version>0.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.openfaas</groupId>
            <artifactId>entrypoint</artifactId>
            <version>0.1.0</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.10</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.openfaas.entrypoint.App</mainClass>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>.</Class-Path>
                        </manifestEntries>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
  • 以上pom.xml的內容中,有几个必须 留意:
  1. openfaas的model和entrypoint这两个jar是全部服务项目可运作的基本;
  2. 有一些常见的jar依靠也被添加了,您能够酌情考虑自主删改;
  3. 软件maven-compiler-plugin用于特定编译程序时的JDK版本号;
  4. 软件maven-dependency-pluginmaven-assembly-plugin用于将全部java编码和依靠库装包到一个jar文件中,那样制做Docker镜像系统会便捷许多;
  • 新创建一个java类:com.openfaas.function.Handler,源代码和《OpenFaaS实战之三:Java函数》中的Handler.java一模一样,以下:
package com.openfaas.function;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.openfaas.model.IRequest;
import com.openfaas.model.IResponse;
import com.openfaas.model.Response;
import org.apache.commons.lang3.StringUtils;

import java.lang.management.ManagementFactory;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class Handler extends com.openfaas.model.AbstractHandler {

    private static final String PARAM_USER_NAME = "name";

    private static final String RESPONSE_TEMPLETE = "Hello %s, response from [%s], PID [%s], %s";

    private ObjectMapper mapper = new ObjectMapper();

    /**
     * 获得该设备IP地址
     * @return
     */
    public static String getIpAddress() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip = null;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    continue;
                } else {
                    Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                    while (addresses.hasMoreElements()) {
                        ip = addresses.nextElement();
                        if (ip != null && ip instanceof Inet4Address) {
                            return ip.getHostAddress();
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("IP地址获得不成功"   e.toString());
        }
        return "";
    }

    /**
     * 回到当今过程ID
     * @return
     */
    private static String getPID() {
        return ManagementFactory
                .getRuntimeMXBean()
                .getName()
                .split("@")[0];
    }


    private String getUserName(IRequest req) {
        // 假如从要求body中取不上userName,就用
        String userName = null;

        try {
            Map<String, Object> mapFromStr = mapper.readValue(req.getBody(),
                    new TypeReference<Map<String, Object>>() {});

            if(null!=mapFromStr && mapFromStr.containsKey(PARAM_USER_NAME)) {
                userName = String.valueOf(mapFromStr.get(PARAM_USER_NAME));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        // 假如从要求body中取不上userName,就给个初始值
        if(StringUtils.isBlank(userName)) {
            userName = "anonymous";
        }

        return userName;
    }

    public IResponse Handle(IRequest req) {

        String userName = getUserName(req);

        System.out.println("1. ---"   userName);

        // 回到信息内容携带当今JVM所属设备的IP、过程号、時间
        String message = String.format(RESPONSE_TEMPLETE,
                userName,
                getIpAddress(),
                getPID(),
                new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss" ).format(new Date()));

        System.out.println("2. ---"   message);

        // 回应內容也是JSON文件格式,因此 先存进map,随后再实例化
        Map<String, Object> rlt = new HashMap<>();
        rlt.put("success", true);
        rlt.put("message", message);

        String rltStr = null;

        try {
            rltStr = mapper.writeValueAsString(rlt);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Response res = new Response();
        res.setContentType("application/json;charset=utf-8");
        res.setBody(rltStr);

	    return res;
    }
}
  • pom.xml所属文件目录下,加密文件夹m2,里边提升maven的环境变量settings.xml,该文件是在FaaS开发设计全过程中,制做镜像系统时使用的(制做镜像系统的时候会编译程序搭建java新项目),强烈要求在里面配备好您的maven传奇sf,或是阿里云镜像,那样制做镜像系统的时候会快许多,我这里早已配备了阿里云镜像,仍然用时四分多钟(如下图),因此 假如您有nexus3传奇sf一定要优先选择考虑到:

在这里插入图片描述

  • 到此,编号工作中顺利完成,由此可见这就是个一般maven工程项目,来试一下能否一切正常运作;
  • 运行命令mvn clean package -U -DskipTests,取得成功之后在target目录生成文档java8maven-1.0-SNAPSHOT-jar-with-dependencies.jar
  • 运作以上jar文件,指令是java -jar java8maven-1.0-SNAPSHOT-jar-with-dependencies.jar
  • 以上jar运作起來后会监视8082端口号的POST要求,我这里用postman来试一下,如下图,能够接到后台管理回到的最新数据:

在这里插入图片描述

    • 后台管理控制面板也会打印出出预估的內容:

在这里插入图片描述

    • 编码写完了,下面要考虑到的怎么制作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 

# 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

# 前边用maven编译程序搭建结束后,这儿将搭建結果拷贝到镜像系统中
COPY --from=builder /home/app/function/target/java8maven-1.0-SNAPSHOT-jar-with-dependencies.jar ./java8maven-1.0-SNAPSHOT-jar-with-dependencies.jar
# 特定器皿的运作账号
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 -jar java8maven-1.0-SNAPSHOT-jar-with-dependencies.jar"

# 器皿对外开放曝露的端口号,也就是fwatchdog过程监视的端口号
EXPOSE 8080

# 健康体检
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1

# 器皿启动命令,这儿是实行二进制文件fwatchdog
CMD ["fwatchdog"]

模版配备

  • 如今原材料早已提前准备结束了,再梳理一下提前准备递交到github上,就可以做为OpenFaaS模版应用了;
  1. 新创建一个文件夹名称,名叫simplejava8
  2. simplejava8文件目录下新建文件template.yml,內容以下:
language: simplejava8
welcome_message: |
  You have created a function using the java8 and maven template
  1. 将前边的Dockerfile文档拷贝到simplejava8文件目录下;
  2. 前边我们建立的maven工程项目,最表层的文件夹名称名叫java8maven,请将此文件夹名称更名为function,随后将全部文件夹名称都拷贝到simplejava8文件目录下;
  3. 此时的simplejava8文件目录下应该是这种內容:
[root@hedy 002]# tree simplejava8
simplejava8
├── Dockerfile
├── function
│   ├── java8maven.iml
│   ├── m2
│   │   └── settings.xml
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── com
│       │   │       └── openfaas
│       │   │           └── function
│       │   │               └── Handler.java
│       │   └── resources
│       └── test
│           └── java
└── template.yml

11 directories, 6 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 08:44:29 Attempting to expand templates from https://github.com/zq2599/openfaas-templates
2021/03/07 08:44:32 Fetched 3 template(s) : [dockerfile java11extend simplejava8] from https://github.com/zq2599/openfaas-templates
  • faas new --list查询目录以下:
[root@hedy 07]# faas new --list
Languages available as templates:
- dockerfile
- java11extend
- simplejava8
  • 看一下template/simplejava8文件目录下的內容,和前边提交的一模一样:
[root@hedy 07]# tree template/simplejava8/
template/simplejava8/
├── Dockerfile
├── function
│   ├── java8maven.iml
│   ├── m2
│   │   └── settings.xml
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── openfaas
│                       └── function
│                           └── Handler.java
└── template.yml

8 directories, 6 files
  • 拥有模版就可以建立涵数了,实行下列指令建立名叫faas-simplejava8demo的涵数:
faas-cli new faas-simplejava8demo --lang simplejava8 -p bolingcavalry
  • 控制面板提醒以下,这时文件列表下增加文件夹名称faas-simplejava8demo,这就是新创建涵数的编码文件目录:
[root@hedy 07]# faas-cli new faas-simplejava8demo --lang simplejava8 -p bolingcavalry
Folder: faas-simplejava8demo created.
  __.                   _____           ____
 / _ \ _ ._   __. _ ._ |  __.|_ _  ._ _/ __.|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \__. \
| |_| | |_) |  ._/ | | |  _| (_| | (_| |__.) |
 \__./| .._/ \__.|_| |_|_|  \._,_|\._,_|____/
      |_|


Function created in folder: faas-simplejava8demo
Stack file written: faas-simplejava8demo.yml

Notes:
You have created a function using the java8 and maven template
[root@hedy 07]# ls
faas-simplejava8demo  faas-simplejava8demo.yml  template
  • 文件夹名称faas-simplejava8demo的內容以下,如今妥了,用IDEA等IDE专用工具以maven工程项目方式导进,随后依据业务流程要求改动这一工程项目就可以:
[root@hedy 07]# tree faas-simplejava8demo
faas-simplejava8demo
├── java8maven.iml
├── m2
│   └── settings.xml
├── pom.xml
└── src
    └── main
        └── java
            └── com
                └── openfaas
                    └── function
                        └── Handler.java

7 directories, 4 files
  • 现在可以开发设计业务流程了,这儿为了更好地检测,增加了一行编码,如下图白框:

在这里插入图片描述

  • 逐渐编译程序搭建吧,实行下列指令:
faas-cli build -f ./faas-simplejava8demo.yml
  • 搭建进行后将镜像系统消息推送到镜像系统库房,便于Kubernetes可以下载到此镜像系统,我这里用的是hub.docker.com,由于我的ID是bolingcavalry,所实行下列指令就可以消息推送取得成功(要先实行docker login指令登陆):
docker push bolingcavalry/faas-simplejava8demo:latest
  • 实行下列指令布署涵数到OpenFaaS:
faas-cli deploy -f faas-simplejava8demo.yml
  • 控制面板回应以下,由此可见布署早已逐渐,而且得出了endpoint:
[root@hedy 07]# faas-cli deploy -f faas-simplejava8demo.yml
Deploying: faas-simplejava8demo.
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-simplejava8demo.openfaas-fn
  • 开启web端,在网页页面上由此可见增加的涵数,认证实际操作如下图所显示,由此可见入参的JSON內容能够被一切正常分析:

在这里插入图片描述

  • 还可以在控制面板用curl指令检测:
[root@hedy 07]# curl \
> -H "Content-Type: application/json" \
> -X POST \
> --data '{"name":"Jerry}' \
> http://192.168.50.75:31112/function/faas-simplejava8demo
{"success":true,"foo":"bar","message":"Hello anonymous, response from [10.244.0.168], PID [14], 2021-03-07 03:32:15"}

清除

  • 删掉涵数的指令以下,依然是faas-simplejava8demo.yml所属文件目录:
faas-cli remove -f faas-simplejava8demo.yml
  • 到此,自做的maven jdk8的模版,从开发设计到认证我们早已所有离开了一遍,坚信您对OpenFaaS的了解也早已更为全方位和深层次了,这篇是为开发设计模版练习用的,实际意义并不大,下面的文章内容我们要做一个好用的模版:jdk8 maven springboot

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

  1. Java系列
  2. Spring系列
  3. Docker系列产品
  4. kubernetes系列
  5. 数据库查询 分布式数据库系列产品
  6. DevOps系列

热烈欢迎扫码关注:程序猿欣宸

搜索微信「程序猿欣宸」,我是欣宸,希望与您一同遨游Java世界...
https://github.com/zq2599/blog_demos

评论(0条)

刀客源码 游客评论