使用Micronaut实现无服务器函数

微纳米无服务功能

Micronaut具有用于创建无服务器函数的功能。

无服务器函数

与Spring等其他框架相比,Micronaut具有以下优点:它在编译时解决依赖关系,具有较小的内存占用。

已创建的Function可以部署到AWS Lambda或OpenFaaS等平台。

部署函数

我想要简单尝试一下这个Micronaut的Serverless功能。

环境

这是我们的环境。

$ mn -V
| Micronaut Version: 1.0.4
| JVM Version: 1.8.0_191

项目创建

以function-aws为profile创建项目。

$ mn create-app --profile function-aws --build maven hello-function
$ cd hello-function

由于只能指定function-aws,因此可以推断出可以指定的function的Profile只有function-aws。

$ mn list-profiles
| Available Profiles
--------------------
  cli           The cli profile
  federation    The federation profile
  function-aws  The function profile for AWS Lambda
  kafka         The Kafka messaging profile
  profile       A profile for creating new Micronaut profiles
  service       The service profile

如果只是写了”function”之类的词,会被人生气地说:”没有这样的个人资料”。

$ mn create-app --profile function --build maven hello-function
| Error Profile [function] is designed only for extension and not direct usage

完成的项目中包括了测试代码等。

$ find -type f
./mvnw.cmd
./.mvn/jvm.config
./.mvn/wrapper/maven-wrapper.properties
./.mvn/wrapper/MavenWrapperDownloader.java
./.mvn/wrapper/maven-wrapper.jar
./.gitignore
./mvnw
./pom.xml
./micronaut-cli.yml
./src/main/java/hello/function/HelloFunctionFunction.java
./src/main/java/hello/function/Application.java
./src/main/resources/application.yml
./src/main/resources/logback.xml
./src/test/java/hello/function/HelloFunctionFunctionTest.java
./src/test/java/hello/function/HelloFunctionClient.java

骨架的功能大概是这样的。

src/main/java/hello/function/HelloFunctionFunction.java 的原生中文解释

package hello.function;

import io.micronaut.function.FunctionBean;
import java.util.function.Supplier;

@FunctionBean("hello-function")
public class HelloFunctionFunction implements Supplier<String> {

    @Override
    public String get() {
        return "hello-function";
    }
}

似乎有两种方法来定义函数,一种是将其创建为 FunctionBean,另一种是使用 Factory 创建。

功能豆

这次使用了FunctionBean来实现的方法,对吗?

在这种情况下,似乎需要实现函数接口,可用的接口有Supplier、Consumer、BiConsumer、Function、BiFunction。

有一个具有main方法的类,应该是这样的感觉。

src/main/java/hello/function/Application.java 的中文翻译是仅需一种选项。

package hello.function;

import io.micronaut.runtime.Micronaut;

public class Application {

    public static void main(String[] args) {
        Micronaut.run(Application.class);
    }
}

这个function是在配置文件中指定的。这是FunctionBean的名称,对吗?

主要/源文件/资源/application.yml

micronaut:
    function:
        name: hello-function

根据文件的内容,如果包含多个函数,似乎需要明确设置。

试着以CLI形式运行

我们将对其进行封装并执行。

作为命令行应用的功能

结果已经回来了。

$ java -jar target/hello-function-0.1.jar 
12:56:07.817 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [function]
hello-function

试试接收参数或者依赖注入其他Bean。

让我们稍微修改结构,尝试接收参数和注入其他Bean。

创建一个仅用于处理参数消息的Bean。

src/main/java/hello/function/MessageService.java的本地化中文解释

package hello.function;

import java.time.LocalDateTime;
import javax.inject.Singleton;

@Singleton
public class MessageService {
    public String wrap(String message) {
        return String.format("[%s] ★%s★", LocalDateTime.now(), message);
    }
}

让我们将原始的function实现为一个Bean,在运行时接受参数,并实现函数接口。

/src/main/java/hello/function/HelloFunctionFunction.java的功能

package hello.function;

import io.micronaut.function.FunctionBean;

import java.util.function.Function;
import java.util.function.Supplier;
import javax.inject.Inject;

@FunctionBean("hello-function")
public class HelloFunctionFunction implements Function<HelloFunctionFunction.Request, HelloFunctionFunction.Response> {
    @Inject
    MessageService messageService;

    @Override
    public Response apply(Request request) {
        String replyMessage = messageService.wrap(request.getMessage());

        return new Response(replyMessage);
    }

    public static class Request {
        String message;

        public String getMessage() {
            return message;
        }

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

    public static class Response {
        String message;

        public Response(String message) {
            this.message = message;
        }

        public String getMessage() {
            return message;
        }
    }
}

由于代码发生了变化,本次跳过测试直接打包。

$ ./mvnw package -DskipTests=true

进行。

$ echo '{"message": "こんにちは、世界"}' | java -jar target/hello-function-0.1.jar 
13:00:23.558 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [function]
{"message":"[2019-03-05T13:00:24.185] ★こんにちは、世界★"}

同时接受参数并进行其他Bean的依赖注入,可以执行操作。

现在似乎可以将该函数作为Web应用程序执行,但这次我们不需要。

将应用程序部署到执行环境中,很快就会完成。

广告
将在 10 秒后关闭
bannerAds