使用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应用程序执行,但这次我们不需要。
将应用程序部署到执行环境中,很快就会完成。