SpringBoot与Nacos整合实践:配置管理与动态更新
### 摘要
本文将探讨如何将SpringBoot与Nacos进行整合,主要涉及以下内容:首先,介绍Nacos的配置管理功能,特别是如何监听Nacos中的配置变更。其次,阐述当配置发生变动时,如何精确识别变更的配置项,并据此减少更新范围。接着,讨论利用Java反射机制更新变量,包括静态变量的刷新方法。对于老项目或特定编码风格中遇到的静态配置问题,反射特性提供了一种有效的解决方案。最后,提供Nacos的一键安装指南,以及整合Nacos作为配置中心和注册中心的完整项目资源链接。
### 关键词
SpringBoot, Nacos, 配置管理, 反射机制, 一键安装
## 一、Nacos配置管理基础
### 1.1 Nacos简介与配置管理功能
Nacos 是一个用于动态服务发现、配置管理和服务管理的平台,旨在帮助开发者更轻松地构建云原生应用。Nacos 的配置管理功能尤为强大,它允许开发者在运行时动态修改配置,而无需重启应用程序。这一特性极大地提高了系统的灵活性和可维护性。Nacos 支持多种配置格式,如 JSON、YAML 和 Properties,使得配置管理更加灵活多样。
### 1.2 配置中心的搭建与配置项的基本操作
搭建 Nacos 作为配置中心的第一步是安装 Nacos 服务器。Nacos 提供了一键安装脚本,简化了安装过程。安装完成后,可以通过 Nacos 控制台或 API 进行配置项的管理。基本操作包括添加、修改和删除配置项。例如,可以通过以下命令添加一个新的配置项:
```bash
curl -X POST 'http://localhost:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=exampleContent'
```
此外,Nacos 还支持配置项的版本管理和历史记录,方便开发者追踪配置的变化。
### 1.3 监听Nacos配置变更的实现方式
为了确保应用程序能够及时响应配置变更,Nacos 提供了配置监听机制。开发者可以在 SpringBoot 应用中通过 `@Value` 注解或 `@ConfigurationProperties` 注解来绑定配置项,并使用 `@RefreshScope` 注解来实现配置的自动刷新。例如:
```java
@RestController
@RefreshScope
public class ConfigController {
@Value("${example.config}")
private String exampleConfig;
@GetMapping("/config")
public String getConfig() {
return exampleConfig;
}
}
```
当 Nacos 中的配置发生变化时,SpringBoot 应用会自动接收到通知并更新相应的配置项,从而实现配置的动态更新。
### 1.4 配置变更的实时性与动态更新机制
Nacos 的配置变更监听机制确保了配置的实时性和动态更新。当配置发生变更时,Nacos 会通过长轮询或 WebSocket 等方式将变更信息推送到客户端。客户端接收到变更通知后,会立即更新配置项,从而保证应用程序始终使用最新的配置。
为了进一步优化性能,Nacos 提供了精确识别变更配置项的功能。通过这种方式,可以减少不必要的更新范围,提高系统的响应速度。例如,当某个配置项发生变化时,Nacos 只会更新该配置项,而不会影响其他未变化的配置项。
此外,对于老项目或特定编码风格中遇到的静态配置问题,Java 反射机制提供了一种有效的解决方案。通过反射,可以动态地更新静态变量,从而实现配置的热更新。例如:
```java
Field field = ExampleClass.class.getDeclaredField("staticConfig");
field.setAccessible(true);
field.set(null, "newConfigValue");
```
以上代码片段展示了如何使用反射机制更新静态变量,这对于某些特定场景下的配置管理非常有用。
通过这些机制,Nacos 不仅提供了强大的配置管理功能,还确保了配置变更的实时性和动态更新,为开发者带来了极大的便利。
## 二、精确识别配置变更
### 2.1 配置变更的精准识别技术
在现代微服务架构中,配置管理的实时性和准确性至关重要。Nacos 通过其强大的配置变更监听机制,不仅能够实时捕获配置的变化,还能精准识别具体的变更项。这种精准识别技术的核心在于 Nacos 的事件驱动模型和高效的配置变更检测算法。
当配置发生变化时,Nacos 会生成一个变更事件,并将其推送给所有订阅该配置的应用实例。每个应用实例接收到事件后,会通过内部的配置管理模块进行处理。Nacos 的配置管理模块会对比当前配置与新配置,找出具体的变化点。这一过程不仅提高了配置更新的效率,还减少了不必要的资源消耗。
例如,假设有一个配置文件包含多个配置项,其中一个配置项发生了变化。Nacos 会精确识别出这个变化的配置项,并只更新这一项,而不是整个配置文件。这种精准识别技术不仅提高了系统的响应速度,还降低了因全量更新带来的潜在风险。
### 2.2 减少更新范围以提高应用性能
在实际应用中,频繁的全量配置更新可能会导致系统性能下降,尤其是在高并发环境下。因此,减少更新范围成为了提高应用性能的关键。Nacos 通过其精准识别技术,能够有效减少更新范围,从而提升系统的整体性能。
具体来说,当配置发生变化时,Nacos 会生成一个变更事件,并将该事件推送给所有订阅该配置的应用实例。每个应用实例接收到事件后,会通过内部的配置管理模块进行处理。配置管理模块会对比当前配置与新配置,找出具体的变化点,并只更新这些变化点。这样,即使配置文件中有多个配置项,也只有发生变化的配置项会被更新,从而减少了不必要的资源消耗。
此外,Nacos 还支持配置项的版本管理和历史记录,方便开发者追踪配置的变化。通过这种方式,开发者可以更好地理解配置变更的影响范围,从而做出更合理的优化决策。
### 2.3 配置变更影响的范围分析与案例
配置变更的影响范围分析是确保系统稳定性的关键步骤。Nacos 提供了丰富的工具和方法,帮助开发者准确分析配置变更的影响范围。通过这些工具,开发者可以快速定位到受影响的模块和组件,从而采取相应的措施。
例如,假设一个大型电商系统中有一个配置项用于控制订单处理的超时时间。如果这个配置项发生变化,可能会影响到订单处理模块的性能。通过 Nacos 的配置变更影响范围分析工具,开发者可以快速定位到所有依赖该配置项的模块,并评估变更对这些模块的影响。这样,开发者可以在变更前做好充分的准备,避免因配置变更导致的系统故障。
另一个案例是,假设一个分布式系统中有一个配置项用于控制缓存的过期时间。如果这个配置项发生变化,可能会影响到缓存的命中率和系统的整体性能。通过 Nacos 的配置变更影响范围分析工具,开发者可以快速定位到所有依赖该配置项的缓存模块,并评估变更对这些模块的影响。这样,开发者可以在变更前做好充分的准备,确保系统的稳定性和性能。
### 2.4 高效配置更新的策略与实践
为了确保配置更新的高效性和可靠性,Nacos 提供了一系列最佳实践和策略。这些策略不仅涵盖了配置变更的监听和处理,还包括配置项的版本管理和历史记录,以及配置变更的影响范围分析。
首先,建议开发者在应用中使用 `@RefreshScope` 注解来实现配置的自动刷新。通过这种方式,当 Nacos 中的配置发生变化时,SpringBoot 应用会自动接收到通知并更新相应的配置项,从而实现配置的动态更新。
其次,建议开发者使用 Nacos 的配置项版本管理和历史记录功能。通过这种方式,开发者可以更好地追踪配置的变化,了解每次变更的具体内容和影响范围。这不仅有助于问题的排查,还可以为未来的优化提供参考。
最后,建议开发者定期进行配置变更的影响范围分析。通过这种方式,开发者可以提前发现潜在的问题,采取相应的措施,确保系统的稳定性和性能。
总之,通过 Nacos 的高效配置更新策略和实践,开发者可以更好地管理配置变更,提高系统的灵活性和可维护性,从而为用户提供更优质的服务。
## 三、Java反射机制在配置更新中的应用
### 3.1 Java反射机制概述
Java反射机制是一种强大的工具,它允许程序在运行时动态地访问类的信息和对象的方法。通过反射,开发者可以创建和操作对象,调用方法,甚至修改私有字段的值。这一机制在许多场景下都非常有用,特别是在需要高度灵活性和动态性的应用中。Nacos 利用反射机制,实现了配置变量的动态更新,从而解决了传统配置管理中的许多难题。
### 3.2 使用反射更新配置变量
在 SpringBoot 与 Nacos 的整合过程中,反射机制发挥了重要作用。当配置发生变化时,Nacos 会推送变更事件给客户端。客户端接收到事件后,需要及时更新配置变量。传统的做法是重启应用或手动更新配置,但这种方式显然不够灵活。通过反射机制,可以动态地更新配置变量,而无需重启应用。
例如,假设有一个配置项 `example.config`,我们可以通过以下代码片段使用反射机制更新该配置项:
```java
import java.lang.reflect.Field;
public class ConfigUpdater {
public static void updateConfig(String fieldName, String newValue) throws NoSuchFieldException, IllegalAccessException {
Field field = ExampleClass.class.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, newValue);
}
}
// 调用示例
ConfigUpdater.updateConfig("exampleConfig", "newConfigValue");
```
这段代码展示了如何使用反射机制动态地更新 `ExampleClass` 中的 `exampleConfig` 字段。通过这种方式,可以实现配置的热更新,提高系统的灵活性和响应速度。
### 3.3 静态变量的刷新方法与案例分析
在某些情况下,配置项可能是静态变量。静态变量在类加载时被初始化,并且在整个应用生命周期中保持不变。然而,在某些特殊场景下,可能需要动态地更新静态变量。反射机制提供了一种解决方案。
例如,假设有一个静态配置项 `staticConfig`,我们可以通过以下代码片段使用反射机制更新该静态变量:
```java
import java.lang.reflect.Field;
public class StaticConfigUpdater {
public static void updateStaticConfig(String fieldName, String newValue) throws NoSuchFieldException, IllegalAccessException {
Field field = ExampleClass.class.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, newValue);
}
}
// 调用示例
StaticConfigUpdater.updateStaticConfig("staticConfig", "newStaticConfigValue");
```
这段代码展示了如何使用反射机制动态地更新 `ExampleClass` 中的 `staticConfig` 字段。通过这种方式,可以实现静态配置的热更新,解决老项目中常见的配置管理问题。
### 3.4 反射机制在老项目中的应用挑战
尽管反射机制在配置管理中具有显著的优势,但在老项目中应用反射机制也面临一些挑战。首先,反射机制的使用增加了代码的复杂性,可能导致代码难以理解和维护。其次,反射操作通常比直接操作更慢,可能会影响应用的性能。此外,反射机制的安全性也是一个需要考虑的问题,不当的使用可能导致安全漏洞。
为了应对这些挑战,建议在使用反射机制时遵循以下最佳实践:
1. **最小化反射使用**:尽量减少反射的使用频率,只在必要时使用反射机制。
2. **代码注释**:在使用反射的地方添加详细的注释,解释为什么需要使用反射,以及反射的具体作用。
3. **性能优化**:对反射操作进行性能测试,确保反射不会显著影响应用的性能。
4. **安全性检查**:对反射操作进行安全性检查,防止潜在的安全漏洞。
通过这些最佳实践,可以在老项目中安全、高效地使用反射机制,实现配置的动态更新。
## 四、Nacos一键安装指南
### 4.1 环境要求与准备工作
在开始安装 Nacos 之前,确保您的环境满足以下要求。Nacos 支持多种操作系统,包括 Windows、Linux 和 macOS。以下是安装 Nacos 所需的基本环境配置:
- **Java 版本**:Nacos 需要 Java 8 或更高版本。您可以使用以下命令检查 Java 版本:
```bash
java -version
```
- **操作系统**:Nacos 支持 Windows、Linux 和 macOS。推荐使用 Linux 系统,因为它在生产环境中更为稳定。
- **内存**:建议至少分配 2GB 的内存给 Nacos 服务器,以确保其正常运行。
- **磁盘空间**:Nacos 需要足够的磁盘空间来存储配置数据和日志文件。建议至少预留 5GB 的磁盘空间。
- **网络**:确保 Nacos 服务器能够访问互联网,以便下载必要的依赖包和更新。
在准备工作方面,您需要下载 Nacos 的安装包。Nacos 提供了多种安装方式,包括单机模式和集群模式。对于初学者,建议从单机模式开始,逐步过渡到集群模式。您可以从 Nacos 的官方 GitHub 仓库下载最新版本的安装包:
```bash
wget https://github.com/alibaba/nacos/releases/download/2.0.3/nacos-server-2.0.3.zip
```
### 4.2 安装步骤与配置
安装 Nacos 的步骤相对简单,以下是详细的安装步骤:
1. **解压安装包**:将下载的 Nacos 安装包解压到指定目录。
```bash
unzip nacos-server-2.0.3.zip -d /opt/nacos
```
2. **启动 Nacos 服务器**:进入 Nacos 的 bin 目录,根据您的操作系统选择相应的启动脚本。
- **Linux/MacOS**:
```bash
cd /opt/nacos/bin
sh startup.sh -m standalone
```
- **Windows**:
```cmd
cd \opt\nacos\bin
startup.cmd -m standalone
```
3. **配置 Nacos**:Nacos 的配置文件位于 `conf` 目录下,主要包括 `application.properties` 和 `cluster.conf`。对于单机模式,您只需要编辑 `application.properties` 文件,设置数据库连接等基本信息。
```properties
# application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos
db.password=nacos
```
4. **验证安装**:打开浏览器,访问 `http://localhost:8848/nacos`,使用默认用户名和密码 `nacos/nacos` 登录 Nacos 控制台。如果页面正常显示,说明 Nacos 安装成功。
### 4.3 验证安装成功与常见问题解决
安装完成后,验证 Nacos 是否正常运行是非常重要的一步。以下是一些常见的验证方法和问题解决技巧:
1. **验证配置管理功能**:在 Nacos 控制台中,创建一个新的配置项并保存。然后,通过 API 或者控制台查看配置项是否正确保存。
```bash
curl -X POST 'http://localhost:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=exampleContent'
```
2. **验证配置变更监听**:在 SpringBoot 应用中,使用 `@Value` 或 `@ConfigurationProperties` 注解绑定配置项,并使用 `@RefreshScope` 注解实现配置的自动刷新。修改 Nacos 中的配置项,观察应用是否能够及时接收到变更通知。
```java
@RestController
@RefreshScope
public class ConfigController {
@Value("${example.config}")
private String exampleConfig;
@GetMapping("/config")
public String getConfig() {
return exampleConfig;
}
}
```
3. **常见问题及解决方法**:
- **无法连接到 Nacos 服务器**:检查网络连接和防火墙设置,确保 Nacos 服务器端口(默认 8848)开放。
- **配置项无法保存**:检查数据库连接配置是否正确,确保数据库服务正常运行。
- **配置变更不生效**:确保应用中使用了 `@RefreshScope` 注解,并且 Nacos 服务器和客户端的时间同步。
### 4.4 自动化部署与运维实践
在生产环境中,自动化部署和运维是确保系统稳定性和可维护性的关键。以下是一些自动化部署和运维的最佳实践:
1. **使用 Docker 部署 Nacos**:Docker 化 Nacos 可以简化部署过程,提高环境一致性。您可以使用官方的 Nacos Docker 镜像进行部署。
```bash
docker run --name nacos -p 8848:8848 -e MODE=standalone nacos/nacos-server
```
2. **配置管理工具**:使用 Ansible、Terraform 等配置管理工具,自动化 Nacos 的安装和配置过程。这些工具可以帮助您快速部署和管理多个 Nacos 实例。
3. **监控与告警**:集成 Prometheus 和 Grafana 等监控工具,实时监控 Nacos 的运行状态。设置告警规则,及时发现和处理潜在问题。
4. **备份与恢复**:定期备份 Nacos 的配置数据和日志文件,确保在发生故障时能够快速恢复。您可以使用脚本自动化备份过程。
5. **日志管理**:使用 ELK(Elasticsearch、Logstash、Kibana)或 Fluentd 等日志管理工具,集中管理和分析 Nacos 的日志文件。这有助于快速定位和解决问题。
通过以上自动化部署和运维实践,您可以确保 Nacos 在生产环境中的稳定性和可靠性,为您的应用提供强大的配置管理支持。
## 五、整合Nacos的项目资源链接
### 5.1 项目结构设计与组件介绍
在将 SpringBoot 与 Nacos 整合的过程中,合理的设计项目结构和组件是确保项目顺利进行的关键。一个良好的项目结构不仅能够提高代码的可读性和可维护性,还能为后续的扩展和优化打下坚实的基础。
#### 项目结构设计
1. **模块划分**:将项目划分为多个模块,每个模块负责不同的功能。例如,可以将配置管理、服务发现、健康检查等功能分别放在不同的模块中。这样的设计使得各个模块之间的职责明确,便于团队协作和代码管理。
2. **依赖管理**:使用 Maven 或 Gradle 进行依赖管理,确保项目中使用的库和框架版本一致。在 `pom.xml` 或 `build.gradle` 文件中,明确列出所有依赖项及其版本号,避免因版本不一致导致的问题。
3. **配置文件管理**:将配置文件集中管理,使用 Nacos 作为配置中心。在 `application.properties` 或 `application.yml` 文件中,配置 Nacos 的连接信息,如服务器地址、命名空间等。这样,可以在运行时动态修改配置,而无需重启应用。
4. **日志管理**:使用 SLF4J 和 Logback 进行日志管理,确保日志的统一性和规范性。在 `logback.xml` 文件中,配置日志的输出路径、级别和格式,便于后续的日志分析和问题排查。
#### 组件介绍
1. **SpringBoot 应用**:作为项目的主入口,负责启动应用并初始化各个模块。通过 `@SpringBootApplication` 注解,将应用标记为 SpringBoot 应用,并启用自动配置。
2. **Nacos 客户端**:用于与 Nacos 服务器进行通信,获取和更新配置。在 `pom.xml` 文件中,添加 Nacos 客户端的依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
```
3. **配置管理模块**:负责从 Nacos 获取配置,并在配置发生变化时进行更新。使用 `@Value` 或 `@ConfigurationProperties` 注解绑定配置项,并使用 `@RefreshScope` 注解实现配置的自动刷新。
4. **服务发现模块**:负责注册和发现服务。通过 `@EnableDiscoveryClient` 注解,启用服务发现功能,并在 `bootstrap.properties` 文件中配置 Nacos 作为服务注册中心。
5. **健康检查模块**:负责监控应用的健康状态。通过 `@ConditionalOnBean` 注解,根据应用的状态动态启用或禁用健康检查功能。
### 5.2 集成Nacos的完整步骤
将 SpringBoot 与 Nacos 整合的过程可以分为以下几个步骤:
#### 1. 安装 Nacos 服务器
按照前文所述的安装步骤,安装并启动 Nacos 服务器。确保 Nacos 服务器能够正常运行,并通过浏览器访问 `http://localhost:8848/nacos` 验证安装成功。
#### 2. 配置 Nacos 客户端
在 SpringBoot 项目的 `pom.xml` 文件中,添加 Nacos 客户端的依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
```
在 `bootstrap.properties` 文件中,配置 Nacos 的连接信息:
```properties
spring.application.name=your-application-name
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=your-namespace-id
```
#### 3. 创建配置文件
在 Nacos 控制台中,创建配置文件并保存。例如,创建一个名为 `application.properties` 的配置文件,内容如下:
```properties
example.config=initialConfigValue
```
#### 4. 绑定配置项
在 SpringBoot 应用中,使用 `@Value` 或 `@ConfigurationProperties` 注解绑定配置项,并使用 `@RefreshScope` 注解实现配置的自动刷新。例如:
```java
@RestController
@RefreshScope
public class ConfigController {
@Value("${example.config}")
private String exampleConfig;
@GetMapping("/config")
public String getConfig() {
return exampleConfig;
}
}
```
#### 5. 启动应用
启动 SpringBoot 应用,访问 `http://localhost:8080/config`,验证配置项是否正确加载。修改 Nacos 中的配置项,观察应用是否能够及时接收到变更通知并更新配置。
### 5.3 项目测试与性能评估
在项目开发过程中,进行全面的测试和性能评估是确保应用质量和稳定性的关键。以下是一些测试和性能评估的方法和工具:
#### 单元测试
使用 JUnit 进行单元测试,确保每个模块的功能正确无误。编写测试用例,覆盖各种边界条件和异常情况,提高代码的健壮性。
```java
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetConfig() {
String response = restTemplate.getForObject("/config", String.class);
assertEquals("initialConfigValue", response);
}
}
```
#### 集成测试
使用 MockMvc 进行集成测试,验证各个模块之间的交互是否正常。编写测试用例,模拟真实环境中的请求和响应,确保应用的整体功能符合预期。
```java
@RunWith(SpringRunner.class)
@WebMvcTest(ConfigController.class)
public class ConfigControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetConfig() throws Exception {
mockMvc.perform(get("/config"))
.andExpect(status().isOk())
.andExpect(content().string("initialConfigValue"));
}
}
```
#### 性能测试
使用 JMeter 或 LoadRunner 进行性能测试,评估应用在高并发环境下的表现。编写测试计划,模拟大量用户同时访问应用,记录响应时间和吞吐量,分析性能瓶颈并进行优化。
#### 压力测试
使用 Apache Bench (ab) 进行压力测试,验证应用在极端负载下的稳定性。编写测试脚本,模拟大量并发请求,观察应用的响应时间和错误率,确保应用能够在高负载下正常运行。
### 5.4 开源社区的贡献与反馈
开源社区是推动技术发展的重要力量。将 SpringBoot 与 Nacos 整合的过程中,积极参与开源社区的贡献和反馈,不仅可以获得宝贵的技术支持,还能为社区的发展贡献力量。
#### 报告问题
在使用 Nacos 过程中遇到任何问题,都可以在 Nacos 的 GitHub 仓库中提交 Issue。详细描述问题的现象、复现步骤和环境信息,帮助开发者更快地定位和解决问题。
#### 提交 PR
如果您发现了 Nacos 的 bug 或有改进的建议,可以提交 Pull Request (PR)。在提交 PR 之前,确保代码风格和项目规范一致,并通过所有测试用例。提交 PR 后,积极与社区成员沟通,争取尽快合并。
#### 参与讨论
加入 Nacos 的官方讨论群组或论坛,与其他开发者交流经验和心得。参与技术讨论,分享自己的见解和解决方案,共同推动技术的进步。
#### 文档贡献
帮助完善 Nacos 的官方文档,补充缺失的内容或修正错误。文档的质量直接影响用户的使用体验,您的贡献将使更多人受益。
通过积极参与开源社区的贡献和反馈,您可以不断提升自己的技术水平,同时为社区的发展做出贡献。希望本文的内容对您有所帮助,祝您在 SpringBoot 与 Nacos 的整合过程中取得成功!
## 六、总结
本文详细探讨了如何将SpringBoot与Nacos进行整合,涵盖从配置管理到配置变更监听,再到Java反射机制的应用,以及Nacos的一键安装和项目资源链接。通过Nacos的强大配置管理功能,开发者可以实现在运行时动态修改配置,而无需重启应用程序,极大地提高了系统的灵活性和可维护性。Nacos的配置变更监听机制确保了配置的实时性和动态更新,通过精确识别变更的配置项,减少了不必要的更新范围,提升了系统的响应速度和性能。Java反射机制则为老项目中的静态配置问题提供了解决方案,通过动态更新静态变量,实现了配置的热更新。最后,本文提供了Nacos的一键安装指南和完整的项目资源链接,帮助开发者快速上手并整合Nacos作为配置中心和注册中心。希望本文的内容对读者在SpringBoot与Nacos的整合过程中有所帮助,助力开发出更高效、更稳定的云原生应用。