文章目录
- 什么是Micronaut?
- Micronaut的功能特性相较于Spring的优势
- Micronaut框架的使用
- 安装Micronaut cli
- 创建Micronaut项目
- Micronaut应用的部署
- micronaut反应式编程
MCNU云原生,文章首发地,欢迎微信搜索关注,更多干货,第一时间掌握!
什么是Micronaut?
Micronaut是一个创新性的、现代的、基于 JVM 的全堆栈云原生Java开发框架,旨在构建模块化、易于测试的 JVM 应用程序,支持 Java、Kotlin 和 Groovy 语言。
与传统的Java框架相比,Micronaut具有卓越的性能和低延迟,并支持云原生开发模式。它通过提前进行依赖注入、AOT(Ahead of Time)编译和减少反射使用等技术手段,显著减少了应用程序的启动时间和内存占用。
在传统Java领域Spring框架占据绝对的优势和市场占有率,但是在云原生时代Spring框架却有一些不足,例如占用内存比较高、启动时间长,面向云原生不够友好等,Micronaut的横空出世弥补了这些不足。
Micronaut Framework 由 Grails 框架的创建者开发,并从多年来使用 Spring、Spring Boot 和 Grails 构建从单体到微服务的实际应用程序的经验教训中汲取灵感,使用 Micronaut 框架,可以构建基于消息驱动的应用程序、命令行应用程序、HTTP 服务器等,同时对于微服务,Micronaut 框架还提供丰富的功能,如:
- 分布式配置
- 服务发现
- HTTP路由
- 客户端负载均衡
同时,Micronaut Framework 旨在通过提供以下能力来避免 Spring、Spring Boot 和 Grails 等框架的缺点:
- 快速启动时间
- 减少内存占用
- 最少使用反射
- 最少使用代理
- 没有运行时字节码生成
- 简单的单元测试
这是通过在编译时预先计算框架基础设施来实现的,减少了应用程序在运行时运行所需的逻辑。
总之,Micronaut是云原生时代一个非常不错的框架,社区非常活跃,目前github Star 5.7K,contributor达到368人,热度还是挺高的,是一个非常值得尝试的项目。
Micronaut的功能特性相较于Spring的优势
作为一个Java框架,在云原生时代必然是要有独特的功能特点,否则就是重复造轮子,自然不会有人关注了,何况已经有了Spring这么一位老大哥。那么Micronaut框架具有哪些独特的功能特性,相对于Spring有哪些优势呢?
-
快速启动时间和低内存占用
Micronaut使用AOT编译,在编译时处理依赖注入和其他框架功能,从而大大减少了运行时反射的使用,提高了应用程序的启动时间和内存效率,提高了性能和安全性,特别适用于云原生和微服务场景。
-
云原生支持
Micronaut天生支持云原生开发模式,提供了与Docker、Kubernetes、服务注册中心等的无缝集成,以便快速构建和部署可扩展的微服务应用程序。
-
微服务友好
Micronaut提供了用于构建和部署微服务的工具和功能,包括服务发现、负载均衡、分布式配置和监控等。
-
轻量级和可扩展
框架本身非常轻量级,并且具有可扩展性,开发人员可以根据项目需求选择所需的功能和库。
-
响应式编程支持
Micronaut对响应式编程模型提供了支持,它集成了响应式流处理库,允许开发人员使用异步和非阻塞的方式处理请求和响应。通过使用反应式编程,您可以实现高吞吐量和低延迟的应用程序,以更好地应对并发和负载压力。
-
无侵入式开发
Micronaut的依赖注入机制是基于编译时进行的,不需要使用代理类或字节码增强,因此对代码的侵入性更低。
-
模块化和可选功能
Micronaut框架采用模块化的设计,开发人员可以根据项目需求选择所需的功能和库,避免了不必要的依赖和复杂性。
-
配置管理
Micronaut提供了灵活的配置管理机制,允许从多种来源(如环境变量、属性文件、配置中心等)加载配置信息。我们可以使用注解和类型安全的配置类来定义和读取配置,以及通过属性覆盖和动态刷新来实现配置的灵活性和可管理性。
-
测试支持
Micronaut提供了丰富的测试支持,包括单元测试、集成测试和端到端测试。它提供了模拟对象、依赖注入的替代方案和方便的测试工具,以帮助您编写可靠、可测试的代码,并进行各种层次和维度的测试。
-
服务注册与发现
Micronaut集成了服务注册与发现机制,可以与服务注册中心(如Consul、Eureka等)进行无缝集成。这使得在微服务架构中部署和管理Micronaut应用程序变得更加容易。
-
容器日志集成
Micronaut支持与常见的容器日志收集工具(如ELK Stack、Fluentd等)进行集成,方便应用程序的日志管理和监控。
Micronaut框架的使用
下面以创建一个demo为例,一起来看看Micronaut的使用方法,这个demo展示了如何创建一个简单的HTTP服务,一切都显得非常简单。
首先,我们需要安装Micronaut cli客户端,这个工具可以非常方便地支持我们创建micronaut应用。
安装Micronaut cli
Micronaut cli的安装支持SDKman、Homebrew、MacPorts、Chocolatey、Binary和Source等多种方式,支持Windows、Mac、Linux等平台。
在Linux下最常用的是SDKman和Binary两种安装模式。
SDKman安装模式:
执行以下命令即可安装并验证micronaut。
$ sdk update
$ sdk install micronaut
$ mn
| Starting interactive mode...
| Enter a command name to run. Use TAB for completion:
mn>
Binary安装模式:
从官方网站下载相应版本的二进制包,创建MICRONAUT_HOME
变量并指向解压后的目录,更新PATH
,追加%MICRONAUT_HOME%\bin
,如下所示:
export MICRONAUT_HOME=/root/micronaut
export PATH="$PATH:$MICRONAUT_HOME/bin"
最好将其放到~/.bashrc
中,使用source ~/.bashrc
使其永久生效。
创建Micronaut项目
使用mn
命令创建一个新的Micronaut项目。打开终端,并执行以下命令:
mn create-app example.micronaut.demo --features=micronaut-http-server
进入项目目录:
cd example.micronaut.demo
创建一个新的Controller类。在src/main/java目录下创建一个名为HelloController的Java类,代码如下:
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.QueryValue;
@Controller("/hello")
public class HelloController {
@Get("/{name}")
public String sayHello(@PathVariable String name, @QueryValue(defaultValue = "en") String lang) {
if (lang.equals("en")) {
return "Hello, " + name + "!";
} else {
return "你好,"+ name + "!";
}
}
}
启动应用程序,在终端执行以下命令:
./gradlew run
应用程序启动后,可以使用任何HTTP客户端工具或浏览器来访问服务。例如,通过浏览器访问以下URL:http://localhost:8080/hello/Lucas?lang=en
应该会返回以下响应:Hello, Lucas!
这个示例演示了如何使用Micronaut框架创建一个简单的HTTP服务,并根据URL路径和查询参数返回不同的问候语。可以看到以上非常简单,也不需要引入过多的依赖内容。
Micronaut应用的部署
Micronaut应用的部署方式与其他Java应用程序类似。只需要将Micronaut应用打包为可执行的JAR文件,然后在目标环境中运行。
-
打包应用程序。在终端执行以下命令:
./gradlew assemble
-
在build/libs目录下找到生成的JAR文件(例如:example.micronaut.demo-0.1-all.jar)。
-
将JAR文件复制到目标环境中。
-
在目标环境中运行应用程序。在终端执行以下命令:
java -jar example.micronaut.demo-0.1-all.jar
-
应用程序将在目标环境中启动,并监听指定的端口(默认为8080)。使用浏览器或者curl工具进行验证。
以上就完成了Micronaut应用程序的部署过程。但是,我们讲到实际上micronaut向云而生,肯定要支持容器化的部署。
当将Micronaut应用程序打包为Docker镜像时,可以使用Micronaut提供的构建工具(如Gradle或Maven)结合Docker插件来完成此过程。以下是一个示例,演示了如何使用Gradle和Docker插件将Micronaut应用程序打包为Docker镜像:
- 首先,确保在Micronaut项目的构建文件中添加Docker插件的依赖。在Gradle项目中,可以在
build.gradle
文件中添加以下内容:
plugins {
id 'com.palantir.docker' version '0.26.0'
}
docker {
// Docker镜像的配置
name 'my-micronaut-app'
files fileTree('src/main/docker/')
// 更多配置项...
}
task buildDockerImage(type: com.palantir.gradle.docker.DockerTask, dependsOn: build) {
description 'Builds a Docker image for the project'
doFirst {
copy {
from jar
into "${buildDir}/docker/"
rename { fileName ->
fileName.replace('-all.jar', '.jar')
}
}
}
}
- 在Micronaut项目的根目录下创建一个
src/main/docker
目录,并在其中创建一个名为Dockerfile
的文件。Dockerfile
用于定义构建Docker镜像的步骤和配置,例如:
FROM adoptopenjdk:11-jre-hotspot
COPY build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
- 执行以下命令来构建Docker镜像:
./gradlew buildDockerImage
上述步骤将会使用Gradle和Docker插件构建一个名为my-micronaut-app
的Docker镜像,其中包含了Micronaut应用程序。
如果要使用kubernetes来部署micronaut的话也很简单。
- 首先,确保已经安装并配置好Kubernetes集群,并且具备访问该集群的权限。
- 创建一个名为
deployment.yaml
的文件,用于定义Kubernetes的部署配置。例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: micronaut-app
spec:
replicas: 1
selector:
matchLabels:
app: micronaut-app
template:
metadata:
labels:
app: micronaut-app
spec:
containers:
- name: micronaut-app
image: my-micronaut-app
ports:
- containerPort: 8080
上述配置将创建一个名为micronaut-app
的Deployment,其中包含一个Pod,使用之前构建的Docker镜像my-micronaut-app
。
- 在终端中,执行以下命令来部署应用程序到Kubernetes集群:
kubectl apply -f deployment.yaml
Kubernetes将会根据配置文件创建一个Deployment,并自动启动一个Pod来运行您的Micronaut应用程序。
micronaut反应式编程
Micronaut对反应式编程提供了内置支持,包括响应式流处理和异步非阻塞的编程模型。下面是一个具体的编程案例,演示了如何在Micronaut中使用反应式编程:
假设我们有一个需求,需要编写一个异步的REST API端点,该端点返回一个特定字符串。我们将使用Micronaut的反应式流处理来实现这个功能。
- 首先,创建一个新的Micronaut项目并添加必要的依赖。确保在
build.gradle
(如果使用Gradle)或pom.xml
(如果使用Maven)文件中添加以下依赖:
implementation "io.micronaut:micronaut-http-server-netty"
implementation "io.micronaut:micronaut-runtime"
implementation "io.micronaut.rxjava3:micronaut-rxjava3"
implementation "io.reactivex.rxjava3:rxjava:3.1.1"
- 创建一个名为
CalculateController
的REST控制器,并在其中添加一个异步的端点。示例代码如下:
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.reactivex.rxjava3.core.Single;
@Controller("/calculate")
public class CalculateController {
@Get("/add/{a}/{b}")
@Produces(MediaType.TEXT_PLAIN)
public Single<String> add(int a, int b) {
return Single.just(a + b);
}
}
在上述代码中,我们使用了io.reactivex.rxjava3.core.Single
类型来表示异步操作的结果。通过Single.just(a + b)
,我们将两个数字相加的结果包装为一个Single对象。启动应用程序并使用浏览器或类似的工具访问http://localhost:8080/math/add/1/2
,我们将获得响应内容为3。
这里我们使用了io.reactivex.rxjava3.core.Single
类型来实现异步非阻塞的编程。当然还可以使用诸如Project Reactor或Java 9的Flow API等其他的一部编程框架,与Micronaut集成来实现相同的效果。
通过使用Micronaut的反应式编程支持,您可以轻松地处理并发操作、异步任务和流式数据,从而实现高性能和高吞吐量的应用程序。
以上的案例都非常简单,但是相信通过这些案例可以看到直观感受到这个框架的易用和丰富的能力,目前已经有不少互联网头部公司在使用micronaut,有兴趣的童鞋们欢迎关注交流~