利用 Micronaut 构建物联网与企业级微服务
1. 了解 Alexa 技能基础
在 Alexa 开发者控制台中,内置意图是构建技能的重要部分。例如,当有一个带有用户名、密码字段和提交按钮的登录网站时,在 Alexa 技能领域就会有一个提交意图。不过,用户可以用不同的方式表达提交,如“Submit”“submit it”“confirm”“ok”“get”“continue”等,这些不同的表达方式被称为表述(utterances)。每个意图都应包含一个表述列表,即用户可能用来触发这些意图的所有表述。意图还可以有称为槽(slots)的参数,但本章暂不讨论。
创建第一个 Alexa 技能的步骤如下:
1. 访问 https://developer.amazon.com/,选择 Amazon Alexa,点击“Create Alexa Skills”,打开 Alexa 开发者控制台。若没有亚马逊开发者账户,可免费创建。
2. 在创建技能界面,创建一个名为“Pet Clinic”的新技能,选择“Custom”模型,选择“Provision your own”来托管技能的后端资源,选择“Start from Scratch”模板。
3. 使用自定义语音交互模型,需要配置唤醒词、启动、调用名称、表述和意图。唤醒词为设备配置,对所有技能相同,无需更改。
4. 可以将技能调用名称设置为“pet clinic”并保存,选择“HelloWorldIntent”意图并将其重命名为“PetClinicWelcomeIntent”。可以手动修改意图中的示例表述,也可以使用 JSON 编辑器,从相关 GitHub 仓库复制 alexa_petclinic_intent_schema.json 代码。以下是意图的 JSON 架构示例:
{
"interactionModel": {
"languageModel": {
"invocationName": "pet clinic",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": [
"cancel"
]
},
{
"name": "PetClinicWelcomeIntent",
"slots": [],
"samples": [
"find near by pet clinics",
"find pet clinics"
]
}
],
"types": []
}
}
}
- 将 JSON 文件复制到 Alexa 开发者控制台的 JSON 编辑器后,点击“Save Model”,然后“Build Model”和“Evaluate Model”。
- 构建模型后,在 Alexa 开发者控制台点击“Test”,启用技能测试过程。
2. 开发后端代码
创建一个 Maven Java 项目,添加以下依赖:
<dependencies>
<dependency>
<groupId>com.amazon.alexa</groupId>
<artifactId>ask-sdk</artifactId>
<version>2.20.2</version>
</dependency>
</dependencies>
也可以使用 Gradle 配置依赖:
dependencies {
compile 'com.amazon.alexa:alexa-skills-kit:1.1.2'
}
为所有意图创建 Java 类。在 JSON 架构中定义了 CancelIntent 、 HelpIntent 、 StopIntent 、 NavigateHomeIntent 、 FallbackIntent 和 PetClinicWelcomeIntent 等意图,每个意图都需要创建一个处理程序。例如, PetClinicWelcomeIntent 应有 PetClicWelcomeIntentHandler 。还需要创建一个未在 JSON 架构中配置的额外处理程序 LaunchRequestHandler ,它是技能启动时触发的第一个意图。示例代码如下:
public class LaunchRequestHandler implements RequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput) {
return handlerInput.matches(requestType(LaunchRequest.class));
}
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
String speechText = "Welcome to Pet Clinic, You can say find near by Pet Clinics";
return handlerInput.getResponseBuilder()
.withSpeech(speechText)
.withSimpleCard("PetClinic", speechText)
.withReprompt(speechText)
.build();
}
}
创建完处理程序( CancelandStopIntentHandler 、 HelpIntentHandler 、 LaunchRequestHandler 、 PetClinicWelcomeIntentHandler 和 SessionEndedRequestHandler )后,需要创建 StreamHandler 。 StreamHandler 是 AWS Lambda 函数的入口点,所有用户发送给 Alexa 并触发技能的请求都将通过此类。需要在端点配置从 Amazon Alexa 开发者控制台复制的技能 ID。示例代码如下:
public class PetClinicStreamHandler extends SkillStreamHandler {
private static Skill getSkill() {
return Skills.standard()
.addRequestHandlers(
new CancelandStopIntentHandler(),
new PetClinicWelcomeIntentHandler(),
new HelpIntentHandler(),
new LaunchRequestHandler(),
new SessionEndedRequestHandler())
.withSkillId("amzn1.ask.skill.de392a0b-0a95-451a-a615-dcba1f9a42c6")
.build();
}
public PetClinicStreamHandler() {
super(getSkill());
}
}
3. 后续操作
接下来,创建包含依赖的 .jar 文件,执行 mvn assembly:assembly -DdescriptorId=jar-with-dependencies package 命令,该 .jar 文件将位于目标目录。
创建 Amazon Lambda 函数的步骤如下:
1. 访问 https://console.aws.amazon.com/lambda/ 创建函数,命名为 lambda_for_petclinic ,选择“Author from scratch”,运行时设置为 Java 11。
2. 创建触发器,将触发器配置设置为“Alexa Skills Kit”,从 Alexa 开发者控制台的端点屏幕复制 Alexa 技能 ID,从 Lambda 开发者控制台复制函数 ARN(Amazon Resource Name)属性到 Alexa 技能开发者控制台的端点屏幕。
3. 添加触发器并复制必要的技能 ID 和函数 ARN ID 到技能端点后,点击“Save Endpoints”。
4. 将 .jar 文件(如 petclinic-Alexa-maven-1.0-SNAPSHOT-jar-with-dependencies.jar )上传到 Lambda 函数。
测试代码可使用 Amazon Alexa 模拟器,位于开发者控制台。请求/响应测试屏幕接受文本或语音输入,输入“open pet clinic”和“find nearby pet clinics”,应能在 JSON 输出部分看到 Java 代码的响应。
以下是创建 Alexa 技能的流程图:
graph TD;
A[访问开发者网站] --> B[创建技能];
B --> C[配置技能信息];
C --> D[配置 JSON 架构];
D --> E[构建模型];
E --> F[开发后端代码];
F --> G[创建 Lambda 函数];
G --> H[上传代码];
H --> I[测试代码];
4. 集成 Micronaut 与 Alexa
Micronaut 提供了支持 Amazon Web Services (AWS) 的各种扩展,重点关注 AWS Lambda。 micronaut-function-aws-alexa 模块支持使用 Micronaut 构建 Alexa 技能。Micronaut Alexa 支持通过 AlexaFunction 连接 Alexa 应用,并支持以下类型的依赖注入:
- com.amazon.ask.dispatcher.request.handler.RequestHandler
- com.amazon.ask.dispatcher.request.interceptor.RequestInterceptor
- com.amazon.ask.dispatcher.exception.ExceptionHandler
- com.amazon.ask.builder.SkillBuilder
Java Maven 依赖如下:
<dependency>
<groupId>io.micronaut.aws</groupId>
<artifactId>micronaut-aws-alexa</artifactId>
</dependency>
要使任何 Alexa Java 处理程序能与 Micronaut 配合工作,只需添加必要的 @Singleton 注解(即 javax.inject.Singleton )。以下是带有 Singleton 注解的 LaunchRequestHandler 示例:
@Singleton
public class LaunchRequestHandler implements RequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput) {
return handlerInput.matches(requestType(LaunchRequest.class));
}
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
String speechText = "Welcome to Pet Clinic, You can say find near by Pet Clinics";
return handlerInput.getResponseBuilder()
.withSpeech(speechText)
.withSimpleCard("PetClinic", speechText)
.withReprompt(speechText)
.build();
}
}
借助 Micronaut,可以轻松对意图进行单元测试,因为 @MicronautTest 注解提供了无缝的单元测试功能。以下是一个单元测试示例:
@MicronautTest
public class LaunchRequestIntentHandlerTest {
@Inject
LaunchRequestHandler handler;
@Test
void testLaunchRequestIntentHandler() {
LaunchRequest request = LaunchRequest.builder().build();
HandlerInput input = HandlerInput.builder()
.withRequestEnvelope(
RequestEnvelope.builder()
.withRequest(request)
.build()
).build();
assertTrue(handler.canHandle(input));
Optional<Response> responseOptional = handler.handle(input);
assertTrue(responseOptional.isPresent());
Response response = responseOptional.get();
assertTrue(response.getOutputSpeech() instanceof SsmlOutputSpeech);
String speechText = "Welcome to Pet Clinic, You can say find near by Pet Clinics";
String expectedSsml = "<speak>" + speechText + "</speak>";
assertEquals(expectedSsml, ((SsmlOutputSpeech) response.getOutputSpeech()).getSsml());
assertNotNull(response.getReprompt());
assertNotNull(response.getReprompt().getOutputSpeech());
assertTrue(response.getReprompt().getOutputSpeech() instanceof SsmlOutputSpeech);
assertEquals(expectedSsml,((SsmlOutputSpeech) response.getReprompt().getOutputSpeech()).getSsml());
assertTrue(response.getCard() instanceof SimpleCard);
assertEquals("PetClinic", ((SimpleCard) response.getCard()).getTitle());
assertEquals(speechText, ((SimpleCard) response.getCard()).getContent());
assertFalse(response.getShouldEndSession());
}
}
可以在处理程序中连接到 Web 服务或后端数据库以发送请求并接收响应。例如,要查找宠物诊所的位置,可以调用 Web 服务并将其作为语音文本响应添加:
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
String speechText = service.getPetClinicLocation();
return handlerInput.getResponseBuilder()
.withSpeech(speechText)
.withSimpleCard("PetClinic", speechText)
.withReprompt(speechText)
.build();
}
5. 构建企业级微服务
使用 Micronaut 构建企业级微服务具有诸多好处:
- 现代基于 JVM 的全栈框架
- 易于测试的微服务
- 为无服务器应用程序构建
- 响应式栈
- 最小的内存占用和启动时间
- 云原生框架
- 多语言支持(Java、Groovy、Kotlin)
构建企业级微服务需要安装和设置以下工具:
| 工具 | 安装说明 |
| ---- | ---- |
| Java SDK | 版本 8 或以上(示例使用 Java 13) |
| Maven | 可选,若使用 Maven 作为构建系统则需安装,下载安装说明:https://maven.apache.org/download.cgi |
| 开发 IDE | 基于个人偏好,可使用任何 Java 开发 IDE,示例使用 IntelliJ |
| Git | 下载安装说明:https://git-scm.com/downloads |
| PostgreSQL | 下载安装说明:https://www.postgresql.org/download/ |
| MongoDB | MongoDB Atlas 提供免费在线数据库即服务,最多 512 MB 存储;若使用本地数据库,下载安装说明:https://docs.mongodb.com/manual/administration/install-community/ |
| REST 客户端 | 可使用任何 HTTP REST 客户端,示例使用 Advanced REST Client Chrome 插件 |
| Docker | 下载安装说明:https://docs.docker.com/get-docker/ |
| Amazon 账户 | 用于 Alexa 开发:https://developer.amazon.com/alexa |
回顾之前学习的内容,涵盖了使用数据库、Web 服务、容器、部署、测试、配置、监控、事件驱动架构、安全和 IoT 等创建企业应用所需的所有构建块。通过这些知识的整合,能更好地构建企业级微服务。
以下是构建企业级微服务的步骤总结:
1. 准备开发环境,安装所需工具。
2. 回顾和整合之前学习的微服务相关知识。
3. 基于 Micronaut 构建和架构企业微服务。
4. 理解和应用 Micronaut 的 OpenAPI。
5. 实现 Micronaut 微服务并进行测试和优化。
通过以上步骤和知识,能利用 Micronaut 构建出高效、稳定的企业级微服务,实现对 IoT 设备的语音控制和管理。
6. 架构企业微服务
在架构企业微服务时,我们需要将之前所学的知识融会贯通,以构建出高效、可扩展且稳定的系统。以下是架构企业微服务的关键要点:
6.1 整合已有知识
我们之前学习了微服务设计模式、数据访问、RESTful 服务、安全、事件驱动架构、测试、配置管理、部署、日志监控以及 IoT 等多个方面的知识。在架构企业微服务时,需要将这些知识有机地结合起来。例如,在设计数据访问层时,要考虑如何与 RESTful 服务进行交互,如何保证数据的安全性和一致性;在实现事件驱动架构时,要考虑如何与其他微服务进行集成,如何处理事件的并发和错误。
6.2 采用云原生架构
Micronaut 是一个云原生框架,具有轻量级、响应式和易于部署等特点。在架构企业微服务时,应充分利用 Micronaut 的这些特性,采用云原生架构。云原生架构包括容器化、编排、服务网格、无服务器等技术,可以提高系统的可扩展性、弹性和容错性。例如,使用 Docker 进行容器化,使用 Kubernetes 进行容器编排,使用 Istio 进行服务网格管理,使用 AWS Lambda 进行无服务器计算。
6.3 设计合理的服务边界
在架构企业微服务时,需要设计合理的服务边界。服务边界的设计应该基于业务功能和数据的独立性,每个微服务应该负责一个特定的业务功能,并且拥有自己独立的数据存储。例如,在一个电商系统中,可以将用户服务、商品服务、订单服务等分别设计为独立的微服务,每个微服务负责自己的业务逻辑和数据管理。
6.4 实现服务发现和治理
为了保证微服务之间的通信和协作,需要实现服务发现和治理。服务发现可以帮助微服务找到其他微服务的地址,服务治理可以帮助管理微服务之间的调用关系、流量控制、容错等。例如,可以使用 Consul 进行服务发现,使用 Hystrix 进行容错处理,使用 Spring Cloud Gateway 进行 API 网关服务。
7. 理解 Micronaut 的 OpenAPI
OpenAPI 是一种用于描述 RESTful API 的规范,它可以帮助开发者更好地设计、文档化和测试 API。Micronaut 支持 OpenAPI,可以帮助开发者快速生成 API 文档和客户端代码。
7.1 配置 OpenAPI
要在 Micronaut 项目中使用 OpenAPI,需要添加相应的依赖。以下是 Maven 依赖示例:
<dependency>
<groupId>io.micronaut.openapi</groupId>
<artifactId>micronaut-openapi</artifactId>
<version>3.7.0</version>
</dependency>
添加依赖后,需要在配置文件中进行相应的配置。例如,在 application.yml 中添加以下配置:
micronaut:
application:
name: my-microservice
server:
port: 8080
openapi:
enabled: true
path: /swagger
7.2 生成 API 文档
配置好 OpenAPI 后,Micronaut 会自动生成 API 文档。可以通过访问 /swagger 路径查看生成的 API 文档。API 文档中包含了 API 的详细信息,如接口定义、请求参数、响应参数、错误码等。
7.3 生成客户端代码
除了生成 API 文档,Micronaut 还可以帮助生成客户端代码。可以使用 Swagger Codegen 工具根据 API 文档生成客户端代码。以下是使用 Swagger Codegen 生成 Java 客户端代码的示例命令:
swagger-codegen generate \
-i http://localhost:8080/swagger \
-l java \
-o /path/to/output
8. 实现 Micronaut 的微服务
在理解了 Micronaut 的 OpenAPI 后,我们可以开始实现 Micronaut 的微服务。以下是实现 Micronaut 微服务的步骤:
8.1 创建 Micronaut 项目
可以使用 Micronaut CLI 或 IDE 创建 Micronaut 项目。以下是使用 Micronaut CLI 创建项目的示例命令:
mn create-app my-microservice --features=openapi
8.2 定义 API 接口
在项目中定义 API 接口。以下是一个简单的 API 接口示例:
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
@Controller("/hello")
public class HelloController {
@Get
public String hello() {
return "Hello, Micronaut!";
}
}
8.3 实现业务逻辑
在 API 接口中实现业务逻辑。可以调用其他微服务、访问数据库等。以下是一个调用数据库的示例:
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import javax.inject.Inject;
@Controller("/users")
public class UserController {
@Inject
private UserRepository userRepository;
@Get
public List<User> getUsers() {
return userRepository.findAll();
}
}
8.4 测试微服务
使用 JUnit 5 等测试框架对微服务进行测试。以下是一个简单的测试示例:
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import static org.junit.jupiter.api.Assertions.assertEquals;
@MicronautTest
public class HelloControllerTest {
@Inject
private HelloController helloController;
@Test
void testHello() {
String result = helloController.hello();
assertEquals("Hello, Micronaut!", result);
}
}
9. 总结与展望
通过以上步骤,我们学习了如何使用 Micronaut 构建物联网与企业级微服务。我们了解了 Alexa 技能的基础,开发了后端代码,创建了 Lambda 函数,测试了代码,并将 Micronaut 与 Alexa 进行了集成。同时,我们还学习了如何架构企业微服务,理解了 Micronaut 的 OpenAPI,实现了 Micronaut 的微服务。
Micronaut 作为一个现代的 JVM 全栈框架,具有诸多优势,如易于测试、响应式栈、最小的内存占用和启动时间等。通过使用 Micronaut,我们可以更好地构建企业级微服务,实现对 IoT 设备的语音控制和管理。
在未来的学习和实践中,我们可以进一步深入研究 Micronaut 的高级特性,如分布式事务处理、服务网格优化、多语言编程等。同时,我们还可以关注行业的最新发展趋势,如人工智能、区块链等,将这些技术与 Micronaut 相结合,构建更加智能、高效的企业级微服务系统。
以下是架构企业微服务的流程图:
graph TD;
A[准备开发环境] --> B[整合已有知识];
B --> C[采用云原生架构];
C --> D[设计合理服务边界];
D --> E[实现服务发现和治理];
E --> F[配置 OpenAPI];
F --> G[生成 API 文档和客户端代码];
G --> H[创建 Micronaut 项目];
H --> I[定义 API 接口];
I --> J[实现业务逻辑];
J --> K[测试微服务];
通过以上的学习和实践,我们可以利用 Micronaut 构建出高效、稳定的企业级微服务,为企业的数字化转型提供有力支持。
利用 Micronaut 构建物联网与企业微服务
超级会员免费看

52

被折叠的 条评论
为什么被折叠?



