OpenFaaS实战之七:java11模板解析
欢迎访问我的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的服务调用和容器运行原理已经了然于胸,可以更深入的研究和使用了OpenFaaS了;
- 想要更加自由的开发函数,加入更多符合业务需要的特性,显然官方提供的几个模板是无法满足咱们的需要,以欣宸熟悉的Java为例,现有的java11和java11-vert-x存在以下问题:
- 是基于Gradle的,而实际上习惯使用Maven的开发者并不少;
- 没有Spring、SpringBoot;
- 不支持类似dubbo、SpringCloud等分布式调用;
- 综上所述,java程序员常用的技术栈很难在OpenFaaS的官方模板得到支持,没关系,咱们可以自己开发模板支持上述能力,不过这不是本章的任务,本章的目标是一起深入了解java11模板,摸清官方套路,为后面的自定义模板开发做好充分的准备,本篇文章有以下内容:
- 解析Dockerfile
- Java源码学习
- 没错,java11模板很简单,很快就能了解其中原理;
解析Dockerfile
- 回顾of-watchdog的http模式内部架构,如下图:

- 从上图可见函数功能代码能被调用的关键有以下两点:
- 有微服务(child)在监听指定端口;
- of-watchdog(parent)收到外部请求会转发到微服务监听的端口;
- 最为关键的微服务和of-watchdog都聚集在同一个docker容器中,因此该docker镜像的Dockerfile文件就是一切的关键,接下来一起看看这个文件;
- 在OpenFaaS环境执行命令faas template pull可以拉取全部官方模板,在template/java11目录下是该模板的全部文件:
[root@node1 template]# tree java11
java11
├── build.gradle
├── Dockerfile
├── function
│ ├── build.gradle
│ ├── gradle
│ │ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle
│ └── src
│ ├── main
│ │ └── java
│ │ └── com
│ │ └── openfaas
│ │ └── function
│ │ └── Handler.java
│ └── test
│ └── java
│ └── HandlerTest.java
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── README.md
├── settings.gradle
└── template.yml
- 打开Dockerfile阅读,我在脚本的关键位置添加了注释辅助理解,如下所示:
# 使用multi-stage builds特性,将整个镜像构建分为多个阶段
# 名为builder的镜像里面会生成java代码编译构建出来的结果
FROM openjdk:11-jdk-slim as builder
ENV GRADLE_VER=6.1.1
# 应用更新,并且安装后面要用到的应用
RUN apt-get update -qqy \
&& apt-get install -qqy \
--no-install-recommends \
curl \
ca-certificates \
unzip
# 下载指定版本的gradle,并解压,再删除压缩包(避免镜像体积变大)
RUN mkdir -p /opt/ && cd /opt/ \
&& echo "Downloading gradle.." \
&& curl -sSfL "https://services.gradle.org/distributions/gradle-${GRADLE_VER}-bin.zip" -o gradle-$GRADLE_VER-bin.zip \
&& unzip gradle-$GRADLE_VER-bin.zip -d /opt/ \
&& rm gradle-$GRADLE_VER-bin.zip
# Export some environment variables
ENV GRADLE_HOME=/opt/gradle-$GRADLE_VER/
ENV PATH=$PATH:$GRADLE_HOME/bin
RUN mkdir -p /home/app/libs
ENV GRADLE_OPTS="-Dorg.gradle.daemon=false"
WORKDIR /home/app
# 把编译构建涉及的所有内容都复制到镜像的/home/app/目录,
# 包括配置文件、java源码等
COPY . /home/app/
# 开始编译构建
RUN gradle build
# 打印文件列表
RUN find .
# 名为watchdog的镜像,注意基础镜像是openfaas/of-watchdog
FROM openfaas/of-watchdog:0.7.6 as watchdog
# 这个ship才是最终的镜像,前面的builder和watchdog都是为ship准备内容的
# 为了控制体积,ship里面是jre,而非jdk
FROM openjdk:11-jre-slim as ship
RUN apt-get update -qqy \
&& apt-get install -qqy \
--no-install-recommends \
unzip
# 为了安全起见不使用root帐号,这里增加名为app的群组和用户
RUN addgroup --system app \
&& adduser --system --ingroup app app
# 从watchdog镜像获取可执行文件fwatchdog
COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
# 增加可执行权限
RUN chmod +x /usr/bin/fwatchdog
# 设置执行命令的目录
WORKDIR /home/app
# 从builder获取整个gradle项目的构建结果
COPY --from=builder /home/app/function/build/distributions/function-1.0.zip ./function-1.0.zip
# 执行运行容器进程的帐号是app
user app
# 解压构建结果
RUN unzip ./function-1.0.zip
WORKDIR /home/app/
# of-watchdog转发的地址,也就是微服务监听的地址
ENV upstream_url="http://127.0.0.1:8082"
# of-watchdog的模式
ENV mode="http"
# 微服务是java应用,要用到这个classpath
ENV CLASSPATH="/home/app/function-1.0/function-1.0.jar:/home/app/function-1.0/lib/*"
# 启动微服务的命令
ENV fprocess="java -XX:+UseContainerSupport com.openfaas.entrypoint.App"
# 对外暴露的端口,of-watchdog监听的
EXPOSE 8080
# 监控检查
HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1
# 容器启动时执行的命令,既启动of-watchdog
CMD ["fwatchdog"]
- 上述脚本的最后设置了好几个环境变量,这些环境变量的定义来自of-watchdog官方Github,地址是:https://github.com/openfaas/of-watchdog ,内容如下图:

- 为了更清晰的看到脚本中三个任务是如何协同的,将整个Dockerfile的脚本用下图表示,可见最终的镜像来自ship,左侧的builder和watchdog都是为ship提供内容的:

java工程分析
- 从Dockerfile中得知微服务的启动命令如下:
java -XX:+UseContainerSupport com.openfaas.entrypoint.App
- 只要搞清楚上述命令对应的实现,整个java11模板就全部掌握了,接下来就来研究这个com.openfaas.entrypoint.App类;
- 打开文件template/java11/function/build.gradle,看到依赖关系如下图,红框中的库应该就是com.openfaas.entrypoint.App的来源了:

- 上图红框中的库,代码已经开源,地址是:https://github.com/openfaas/templates-sdk/tree/master/java11
- 打开App.java文件后,一切谜底都被揭开了,这个java11模板的源码还真是简单呀,先看入口的main方法:
public static void main(String[] args) throws Exception {
// 监听8082端口,和Dockerfile中of-watchdog转发请求的端口保持一致
int port = 8082;
// handler是真正处理请求的实例
HandlerProvider p = HandlerProvider.getInstance();
IHandler handler = p.getHandler();
// 配置监听对象,并将handler绑定过来
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
InvokeHandler invokeHandler = new InvokeHandler(handler);
// 设置path,开始监听
server.createContext("/", invokeHandler);
server.setExecutor(null); // creates a default executor
server.start();
}
- 有没有觉得上述代码和sockek编程很像;
- App.java中还有静态类InvokeHandler的定义,这个类的主要功能就是接收web请求的数据,加工成IRequest实例,丢给IHandler实例去处理,处理完成后包装http响应,核心代码片段如下:
// 把request内容封装到IRequest实例中
IRequest req = new Request(requestBody, reqHeadersMap,t.getRequestURI().getRawQuery(), t.getRequestURI().getPath());
// 执行业务逻辑处理请求
IResponse res = this.handler.Handle(req);
// 得到处理后的结果
String response = res.getBody();
...
- 上述代码可见业务逻辑的执行的关键是this.handler.Handle(req),而真正执行业务的代码是咱们自己写的Handler.java,要搞清楚它们之间的关系,就要看HandlerProvider.java,如下图,一些都清楚了,咱们开发函数时,编写的业务功能都在Handler.java中,而Handler是AbstractHandler的实现类,于是下图红框1中就会找到Handler,红框2可以返回Handler实例,在InvokeHandler执行this.handler.Handle(req)时,就是Handler实例在处理web请求了:

- 至此,java代码的分析就完成了,这个微服务其实很简单,就像咱们做Socket编程练习那样,自己编码监听端口并编写处理逻辑;
小结
最后做个小结,将前面展开的思路收敛起来,如下图:

看到这里,对于java11模板的内部实现及其执行原理,相信在您眼里应该没有什么秘密了,为了制作更好用的java模板,咱们已经做了充分准备,接下来的文章,请随欣宸一起实战自定义java模板;
你不孤单,欣宸原创一路相伴
欢迎关注公众号:程序员欣宸
微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...
https://github.com/zq2599/blog_demos
OpenFaaS实战之七:java11模板解析的更多相关文章
- OpenFaaS实战之四:模板操作(template)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之八:自制模板(maven+jdk8)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之九:终篇,自制模板(springboot+maven+jdk8)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之一:部署
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之二:函数入门
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之三:Java函数
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之五:大话watchdog
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- OpenFaaS实战之六:of-watchdog(为性能而生)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- [原创].NET 业务框架开发实战之七 业务层初步构想
原文:[原创].NET 业务框架开发实战之七 业务层初步构想 .NET 业务框架开发实战之七 业务层初步构想 前言:本篇主要讲述如何把DAL和BLL衔接起来. 本篇议题如下: 1. DAL ...
随机推荐
- Java实现工厂模式
工厂模式(Factory),当需要根据运行时的一些条件来决定创建具体对象时,就应该考虑使用工厂设计模式,将创建对象的任务交给工厂集中处理. 工厂模式有多种写法,总体分为简单工厂模式和抽象工厂模式 工厂 ...
- MySQL—Dos命令操作数据库
MySQL 是一个关系型数据库,存在表的概念 结构,数据库可以存放多张表,每个表可以存放多个字段,每个字段可以存放多个记录 Dos命令操作数据库 PhpStudy使用终端打开数据库 第一次打开默认的密 ...
- pip安装setuptools_rust报错
公司项目中有主备CDN存在,由于阿里云以及腾讯云的预热功能不支持自动(一般是云函数),所以就根据云厂商给的脚本稍作更改,手动传入数据来进行预热. 由于之前部署在centos7.7系统python2.7 ...
- 乘风破浪,下载安装体验Adobe XD流程,全新的引导和安装体验设计
简介 Adobe XD是一款适用于网站和应用程序等的快速且功能强大的UI/UX设计解决方案.可实现设计.线框.动画制作.原型创建.协作和共享等,功能一应俱全. https://www.adobe.co ...
- keycloak~账号密码认证和授权码认证
用户名密码登录 POST /auth/realms/demo/protocol/openid-connect/token 请求体 x-www-form-urlencoded grant_type:pa ...
- POJ 3984 迷宫(BFS)
入门BFS,第一次做,部分借鉴了大牛的 #include <iostream> #include <cstdio> #include <queue> using n ...
- 使用kubeadm进行k8s集群升级
一.目标 操作系统:CentOS Linux release 7.6.1810 (Core) 安装软件: docker:18.06.3-ce 从v1.15.5升级到v1.16.15 当前版本: [ro ...
- DL基础补全计划(二)---Softmax回归及示例(Pytorch,交叉熵损失)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- [心得]zookeeper
1. 什么是zookeeper? 分布式协调服务 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅.负载均衡.命名服务.分布式协调/通知.集群管 ...
- ctf实验吧Once More
题目链接:http://ctf5.shiyanbar.com/web/more.php 思路分析:显然是后台逻辑代码. 1.ereg函数有漏洞,可以使用%00截断,这个就做笔记了好吧.这个函数大致意思 ...