无服务器,Java和FN项目的第一步

无服务器不是什么新事物,但是可以说,仍然有很多关于它的炒作,以及它将如何改变一切,以及未来将如何成为无服务器。 除了云提供商提供的无服务器/功能之外,还有越来越多的无服务器项目正在我们的路上,目的是使我们摆脱供应商锁定,甚至允许我们在内部运行无服务器。 让我们看一个这样的项目FN项目。

什么是FN项目

如果我们访问FN项目的官方网站http://fnproject.io/,我们可以看到以下内容:

“ Fn项目是一个开源的容器本地无服务器平台,您可以在任何地方运行-任何云或内部部署。 它易于使用,支持每种编程语言,并且具有可扩展性和高性能。”

FN Project是Oracle支持的开源项目,其功能基于容器。 因此,从理论上讲,任何可以成为容器并可以从stdin / stdout读写的东西都可以成为FN项目中的功能。 这是一个非常好的功能,因为这意味着从理论上讲,它可以支持任何编程语言,这与云提供商提供的无服务器/功能不同,在这种情况下,如果不支持您选择的语言,则无法与无服务器一起使用。

FN Project的另一个不错的功能是它可以在本地运行,也可以在云中运行,也可以在多个云中运行,也可以结合以上提到的全部运行。

初始化设定

FN项目的唯一先决条件是Docker 17.10.0-ce或更高版本。

要设置FN项目,我们只需要下载FN二进制文件

并将其添加到路径。 在此之后,我们准备开始使用FN。

FN项目的初始功能

我们需要做的第一件事是启动FN服务器。 为此,我们只需要在终端/控制台中键入

$ fn start

为了验证一切正常,我们可以运行以下命令

$ fn version

这将打印在计算机上运行的fn服务器和fn客户端的版本。 就我的笔记本电脑而言,我得到了这个值

$ fn version
  Client version: 0.5.15
  Server version: 0.3.595

一旦我们确认一切都很好,就可以开始创建我们的第一个功能。

FN项目的第一个功能

如前所述,FN项目是“不可知的语言” ,理论上它可以支持任何语言,但这并不意味着它目前支持所有语言。 要查看我们的版本支持哪些语言,我们可以运行下一个命令:

$ fn init --help

–runtime选项,它将列出我们计算机上所有可用的选项。 就我而言,我将选择Java编程语言。 因此,要在Java中创建第一个函数,我们只需要运行以下命令:

$ fn init --runtime java --trigger http function1

function1函数的名称,在这里我们输入要使用的名称。 选项–trigger http表示我们想为函数创建HTTP触发器,该触发器将允许我们通过HTTP(例如,通过curl)调用它。 运行此命令后,fn将为我们生成初始函数,并将其放置在名为函数的目录中,在本例中为function1

让我们看看产生了什么

$ cd function1
$ find .

./src/main/java/com/example/fn/HelloFunction.java
./src/test/java/com/example/fn/HelloFunctionTest.java
./pom.xml
./func.yaml

如果我们打开pom.xml文件,它将看起来像任何其他pom.xml文件。 只有FN项目的依赖项才是测试部件的依赖项,而构建或运行我们的java fn函数则没有依赖项。

如果打开HelloFunction.java ,我们将再次看到它是纯Java类,具有零依赖关系。

package com.example.fn;

    public class HelloFunction {

    public String handleRequest(String input) {
        String name = (input == null || input.isEmpty()) ? 
                                             "world" : input;

        return "Hello, " + name + "!";
    }
}

只有一个方法handleRequest可以将String作为输入并提供String作为输出。 这与在云提供程序的实现中编写函数非常不同,因为它们总是添加特定的库或其他类型的依赖关系,以使函数与系统配合使用。 在FN的情况下,由于没有依赖关系,因此它可以在任何地方运行而不会出现任何问题,并且您不会受到任何关注。

FN项目的“魔术”

那么,FN如何运作? 它如何知道如何运行我们的功能?

所有的魔术都在func.yaml文件中。 或者更确切地说,在FN项目中创建功能所需的所有配置。 让我们仔细看看。

$ cat func.yaml

schema_version: 20180708
name: function1
version: 0.0.1
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk9-1.0.75
run_image: fnproject/fn-java-fdk:jdk9-1.0.75
cmd: com.example.fn.HelloFunction::handleRequest
format: http-stream
triggers:
- name: function1-trigger
type: http
source: /function1-trigger

这里有多个字段:

  • schema_version指出用于生成该文件的Fn版本
  • 名称是我们功能的名称
  • 版本是我们功能的当前版本,并且在我们部署时会自动递增
  • 我们选择在其中编写函数的运行时语言
  • build_image用于构建函数的docker镜像当然取决于选择的语言
  • run_image用于运行函数的docker映像
  • cmd 入口指向我们的功能,执行我们的业务逻辑需要调用
  • 这里的触发器是调用函数的已定义触发器,在这种情况下,我们有HTTP触发器

FN项目中的单元测试

也许您注意到生成的文件之一是HelloFunctionTest.java ,该文件确实是我们函数的单元测试文件,该文件也为我们自动生成,并填充了一个简单的单元测试示例。 让我们看一下该文件。

public class HelloFunctionTest {

    @Rule
    public final FnTestingRule testing =   
                                FnTestingRule.createDefault();

    @Test
    public void shouldReturnGreeting() {
        testing.givenEvent().enqueue();
        testing.thenRun(HelloFunction.class, "handleRequest");

        FnResult result = testing.getOnlyResult();
        assertEquals("Hello, world!",
                     result.getBodyAsString());
    }
}

除了某些fn依赖关系和@Rule的一部分 ,其他所有内容都类似于Java中的任何其他JUnit测试。 该单元测试将仅调用我们的函数而不传递任何参数,并检查结果是否为“ Hello world!”。 该测试的最大优点是我们可以像运行其他任何单元测试一样运行它,可以以任何标准方式从maven或IDE调用它。

现在让我们编写测试,在其中传递一些参数,并验证我们的功能仍按预期运行。 为此,我们可以将此代码添加到测试类中

@Test
    public void shouldReturnGreetingwithBodyValue() {
        testing.givenEvent().withBody("Java").enqueue();
        testing.thenRun(HelloFunction.class, "handleRequest");

        FnResult result = testing.getOnlyResult();
        assertEquals("Hello, Java!",
                     result.getBodyAsString());
}

同样,我们可以像运行其他任何单元测试一样运行它,并验证一切都很好。

部署和调用FN功能

现在我们定义了函数,我们了解了生成了哪些文件以及它们的用途,我们还进行了单元测试。 然后是时候部署和调用该功能了。 我们可以将功能部署到云和docker注册表中,但是仅在本地部署它会更加容易和快捷,尤其是在我们忙于开发的时候。 要部署功能,我们只需要运行此命令

$ fn deploy --app myapp1 --local

在这里,我们告诉fn将功能部署到应用程序myapp1中 ,并通过提供选项–local来仅在本地部署它。 成功部署函数后,就可以调用它。 要调用它,我们可以运行下一个命令

$ fn invoke myapp1 function1

我们提供了应用程序的名称和函数的名称。 如果我们想为我们的职能提供投入,我们可以通过这种方式做到这一点

$ echo "Java is great" | fn invoke myapp1 function1

如果您还记得我们还创建了HTTP触发器,那么让我们使用它来调用我们的函数。

$ curl http://localhost:8080/t/myapp1/function1-trigger

带有FN的JSON函数

我们已经可以用它做很多事情了,但是让我们进入下一个级别,在这里我们将使用JSON作为FN函数的输入和输出。 首先,我们需要创建一个简单的POJO类,就像这样

public class Hello {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

现在我们可以修改函数以将该类作为输入和输出,因此该函数将如下所示

public Hello handleRequest(Hello input) {
    String name = (input == null || 
                     input.getMessage().isEmpty()) ? "world" :
                                           input.getMessage();

    Hello hello = new Hello();
    hello.setMessage(message + ", " + name + "!")

    return hello;
}

部署函数后,我们可以像这样调用它

$ curl -d '{"message":"JSON Input"}' \
              http://localhost:8080/t/myapp1/function1-trigger

参考资料和将来阅读

正如我们看到的那样,开始使用FN项目开发功能非常容易且有趣,而且在短时间内我们就可以创建功能强大的功能。

我们在这里看到的只是FN项目可能性的一部分,有关FN的一般信息以及有关可能性的更多信息,我建议您访问下面列出的网站

翻译自: https://www.javacodegeeks.com/2018/12/serverless-java-fn-project-first-steps.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值