java 获取ip地址_OpenFaaS实战之三:Java函数

欢迎访问我的GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类和汇总,及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

本篇概览

  1. 本文是《OpenFaaS实战》系列的第三篇,经过前文实战,咱们掌握了函数开发和部署的要领,作为一名Java程序员,当然迫切的希望用Java编写OpenFaaS函数,于是就有了本文;
  2. 本文开发一个Java函数,功能是解析请求body中的JSON字符串,再加上JVM进程ID、IP地址、当前时间一起拼成字符串,包装在JSON中返回;
  3. 平时写java代码会用各种二方库,这里引入jackson的库,作为OpenFaaS添加依赖的参考;

源码下载

  • 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示:
fde022f186f3cef745699e9d63393e1f.png
  • 这个git项目中有多个文件夹,本章的应用在openfaas文件夹下,如下图红框所示:
2c2e85274948a53553a19ca989316a80.png
  • openfaas里面有多个子文件夹,本篇的源码在currenttime中,如下图红框:
2676e44e5059587c3aa7fb323708423f.png

创建函数

  • 执行以下命令,即可创建名为faas-currenttime的函数,此函数的镜像前缀是bolingcavalry,语言类型为java11:
faas-cli new faas-currenttime --lang java11 -p bolingcavalry
  • 控制台响应如下:
[root@node1 20]# faas-cli new faas-currenttime --lang java11 -p bolingcavalry2020/11/20 15:47:50 No templates found in current directory.2020/11/20 15:47:50 Attempting to expand templates from https://github.com/openfaas/templates.git2020/11/20 15:47:56 Fetched 12 template(s) : [csharp dockerfile go java11 java11-vert-x node node12 php7 python python3 python3-debian ruby] from https://github.com/openfaas/templates.gitFolder: faas-currenttime created.  ___                   _____           ____ / _  _ __   ___ _ __ |  ___|_ _  __ _/ ___|| | | | '_  / _  '_ | |_ / _` |/ _` ___ | |_| | |_) |  __/ | | |  _| (_| | (_| |___) | ___/| .__/ ___|_| |_|_|  __,_|__,_|____/      |_|Function created in folder: faas-currenttimeStack file written: faas-currenttime.ymlNotes:You have created a function using the java11 template which uses an LTSversion of the OpenJDK.
  • 当前目录已经新增了文件faas-currenttime.yml和文件夹faas-currenttime
  • 文件夹faas-currenttime的内容如下,可见是个gradle工程:
faas-currenttime├── 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
  • 打开build.gradle文件,添加下图红框中的内容,即jackson和common库的依赖:
01f38c5d1f06e7f3f4438e3171cfc0f9.png
  • 进入文件夹faas-currenttime/src/main/java/com/openfaas/function/,可见已创建了默认的业务功能类Handler.java,打开看看OpenFaaS给的默认代码啥样的,如下所示:
package com.openfaas.function;import com.openfaas.model.IHandler;import com.openfaas.model.IResponse;import com.openfaas.model.IRequest;import com.openfaas.model.Response;public class Handler extends com.openfaas.model.AbstractHandler {    public IResponse Handle(IRequest req) {        Response res = new Response();            res.setBody("Hello, world!");            return res;    }}
  1. 把Handler.java的内容用以下代码替换掉,替换后的函数,其功能是取得请求参数,再把当前JVM的进程ID、IP地址、当前时间都拼接到一个字符串中返回,需要重点关注的有两点:将请求参数反序列化成Map实例,以及将Map序列化成JSON字符串返回:
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 allNetInterfaces = NetworkInterface.getNetworkInterfaces();            InetAddress ip = null;            while (allNetInterfaces.hasMoreElements()) {                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {                    continue;                } else {                    Enumeration 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 mapFromStr = mapper.readValue(req.getBody(),                    new TypeReference>() {});            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 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;    }}
  • 至此编码完成,接下来是制作镜像和部署;

部署

  • 在faas-currenttime.yml所在目录执行以下命令,即可开始制作镜像,制作过程中会有gradle的编译过程,如果编译失败会中断镜像制作:
faas-cli new faas-currenttime --lang java11 -p bolingcavalry
  • 镜像制作成功时,控制台输出类似如下信息:
Step 27/30 : ENV fprocess="java -XX:+UseContainerSupport com.openfaas.entrypoint.App"---> Running in 0f50636cc747Removing intermediate container 0f50636cc747---> 54a5c9a193c8Step 28/30 : EXPOSE 8080---> Running in 3252f165af15Removing intermediate container 3252f165af15---> c05afc826ec5Step 29/30 : HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1---> Running in 4106410be0a2Removing intermediate container 4106410be0a2---> 6d95b73b5f33Step 30/30 : CMD ["fwatchdog"]---> Running in 1606dbcd7003Removing intermediate container 1606dbcd7003---> 99a519ab82fdSuccessfully built 99a519ab82fdSuccessfully tagged bolingcavalry/faas-currenttime:latestImage: bolingcavalry/faas-currenttime:latest built.[0] < Building faas-currenttime done in 34.94s.[0] Worker done.Total build time: 34.94s
  • 将镜像推送到镜像仓库,以便Kubernetes可以下载到此镜像,我这里用的是hub.docker.com,因为我的ID是bolingcavalry,所执行以下命令即可推送成功:
docker push bolingcavalry/faas-currenttime:latest
  • 执行以下命令部署函数到OpenFaaS:
faas-cli deploy -f faas-currenttime.yml
  • 控制台响应如下,可见部署已经开始,并且给出了endpoint:
[root@node1 20]# faas-cli deploy -f faas-currenttime.ymlDeploying: faas-currenttime.WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates.Deployed. 202 Accepted.URL: http://192.168.133.187:31112/function/faas-currenttime.openfaas-fn
  • 打开web端,在页面上可见新增的函数,验证操作如下图所示,可见入参的JSON内容可以被正常解析:
f62345670b46104939b8ce2f3fae892d.png
  • 也可以在控制台用curl命令测试:
[root@node1 20]# curl > -H "Content-Type: application/json" > -X POST > --data '{"name":"Jerry}' > http://192.168.133.187:31112/function/faas-currenttime{"success":true,"message":"Hello anonymous, response from [10.233.90.79], PID [11], 2020-11-20 02:14:46"}
  • 执行命令faas-cli deploy -f faas-currenttime.yml开始部署,控制台返回信息如下,说明已经接受了部署请求,并给出了函数的endpoint:
[root@node1 20]# faas-cli deploy -f faas-currenttime.ymlDeploying: faas-currenttime.WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates.Deployed. 202 Accepted.URL: http://192.168.133.187:31112/function/faas-currenttime.openfaas-fn

清理

  • 删除函数的命令如下,依旧是faas-currenttime.yml所在目录:
faas-cli remove -f faas-currenttime.yml
  • 至此,最基本的Java函数的开发、部署、验证都已经完成,如果您也打算用Java开发OpenFaaS函数,希望本文能给您一些参考;

欢迎关注我的公众号:程序员欣宸

183347c6eb9aefda5f02de6c40251f29.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值