Spring Cloud Alibaba--Nacos服务注册和配置中心

news2024/12/25 9:34:54

文章目录

  • 一、什么是Nacos
    • 1.1、Nacos的由来
    • 1.2、Nacos的特性
    • 1.3、Nacos的下载和启动
  • 二、Nacos服务注册
    • 2.1、代码示例
    • 2.2、各种注册中心的比较
      • CAP定理
      • 多个注册中心比较
  • 三、Nacos配置中心
    • 3.1、Nacos配置管理
    • 3.2、代码示例
    • 3.3、多环境多项目管理
      • 3.3.1、命名空间
      • 3.3.2、Group分组
      • 3.3.3、DataId

一、什么是Nacos

1.1、Nacos的由来

Nacos 是Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

Nacos = Eureka+Config +Bus,替代Eureka做服务注册中心,替代Config做服务配置中心。

1.2、Nacos的特性

Nacos的特性,官网解释如下:

  • 服务发现和服务健康监测

Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&API查找和发现服务。

Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。

  • 动态配置服务

动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

  • 动态 DNS 服务

动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.

  • 服务及其元数据管理

Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

1.3、Nacos的下载和启动

Nacos的官方下载地址为点击跳转至官方下载地址,根据自己需要,可下载linux和windows版本;并且要根据Springboot+Spring Cloud+Spring Cloud Alibaba的版本,合理选择nacos版本。

在这里插入图片描述

我下载linux 2.1.1版本,部署在阿里云服务器,解压到文件夹下,

在这里插入图片描述
使用启动命令:sh bin/startup.sh -m standalone ,开启Nacos;

访问http://182.92.122.196:8848/nacos/index.htm,出现登录页面,nacos服务注册中心启动成功。

在这里插入图片描述

避坑小妙招:

nacos客户端升级到2.1版本后,新增了gRPC的通信方式,新增了两个偏移量端口(9848,9849)在原端口(8848)基础上面偏移量1000和1001。

    端口8848:服务使用。

    偏移量端口--9848: 客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求。

    便宜连端口--9849: 服务端gRPC请求服务端端口,用于服务间同步等。

云服务器上要开通相应的服务端口:8848,9848,9849。

二、Nacos服务注册

2.1、代码示例

注册流程

第一步,建立两个生产者,注册进入Nacos列表,
在父工程pom文件,增加依赖管理

 <!--spring cloud alibaba 2.2.0.RELEASE-->
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>2.2.0.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

新建Model:cloud-alibaba-provider-payment6001,pom文件添加依赖:

        <!--SpringCloud ailibaba nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringBoot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--日常通用jar包配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

增加配置文件,application.yml,要时刻注意缩进,Nacos启动正常,控制台报如下错误的时候,就要去看看配置是不是出了问题,不要犯同样的错误!
在这里插入图片描述

server:
  port: 6001

spring:
  application:
    name: nacos-provider-payment
  cloud:
    nacos:
      discovery:
        server-addr: 182.92.122.196:8848

management:
  endpoints:
    web:
      exposure:
        include: '*'

启动类添加注解@EnableDiscoveryClient,用于服务发现

/**
 * @Auther: songweichao
 * @Date: 2023-05-10 16:52
 * @Description:
 */
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain6001 {

    public static void main(String[] args) {

        SpringApplication.run(PaymentMain6001.class,args);
    }

}

业务类编写,方便调用,

/**
 * @Auther: songweichao
 * @Date: 2023-05-10 16:59
 * @Description:
 */
@RestController
@RequestMapping("/payment")
public class PaymentController {

    @Value("${server.port}")
    private String port;

    @GetMapping(value="/showPort/{id}")
    public String getPayment(@PathVariable("id") String id){

        return "生产者报道,Port:"+port+"\t id:"+id;
    }
}

第二步,再建立一个cloud-alibaba-provider-payment6001,步骤同上。

第三步,新建cloud-alibaba-consumer-nacos-order,作为消费者,pom依赖同生产者,配置application.yml,其中service-url.nacos-payment-service参数表示消费者将要去访问的微服务名称。

server:
  port: 83
spring:
  application:
    name: nacos-consumer-order
  cloud:
    nacos:
      discovery:
        server-addr: 182.92.122.196:8848

service-url:
  nacos-payment-service: http://nacos-provider-payment

启动类添加注解@EnableDiscoveryClient

/**
 * @Auther: songweichao
 * @Date: 2023-05-11 10:22
 * @Description:
 */
@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosMain83 {

    public static void main(String[] args) {
        SpringApplication.run(OrderNacosMain83.class,args);
    }
}

添加配置类ApplicationConfig,使用RestTemplate实现远程调用。

@Configuration
public class ApplicationConfig
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

业务类调用

@RestController
public class OrderNacosController {

    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-payment-service}")
    private String serviceURL;


    @GetMapping("/consumer/payment/nacos/{id}")
    public String getSome(@PathVariable("id")String id){

        return restTemplate.getForObject(serviceURL+"/payment/showPort/"+id,String.class);
    }
}

分别启动6001、6002、83项目,查看Nacos服务列表,注册成功。

在这里插入图片描述测试访问http://localhost:83/consumer/payment/nacos/12346,结果成功
在这里插入图片描述
在这里插入图片描述

通过测试,看到Nacos支持负载均衡,这是因为Nacos中集成了ribbon。

在这里插入图片描述

2.2、各种注册中心的比较

常见的注册中心有Zookeeper、Eureka、Nacos、Consul;比较他们之间的不同,需要参考CAP定理。

CAP定理

CAP定理,指的是在分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得。

其中:

  1. 一致性(C):所有节点都可以访问到最新的数据。
  2. 可用性(A):每个请求都是可以得到响应的,不管请求是成功还是失败。
  3. 分区容错性(P):除了全部整体网络故障,其他故障都不能导致整个系统不可用。

在分布式存储系统中,最多只能实现上面的两点。分区容错性由于当前的网络肯定会出现延迟丢包等问题是必须需要实现的。所以只能在一致性和可用性之间进行权衡。

  • CP: 如果不要求A(可用),每个请求都需要在服务器之间保持强一致,而P(分区)会导致同步时间无限延长(也就是等待数据同步完才能正常访问服务),一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。
  • AP:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。

多个注册中心比较

在这里插入图片描述
C是所有节点在同一时间看到的数据是一致的;而A的定义是所有的请求都会收到响应。

Nacos 支持AP和CP模式的切换,何时选择使用何种模式?

一般来说,如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如 Spring cloud 和 Dubbo 服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。

如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

切换方式:

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

三、Nacos配置中心

Nacos除了服务注册的功能,还可以作为配置中心,提供配置给微服务。

3.1、Nacos配置管理

在这里插入图片描述在上图配置列表,新增配置文件:
在这里插入图片描述
其中 Data ID的格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值,也可以通过配置,spring.cloud.nacos.config.prefix来配置
  • spring.profiles.active 即为当前环境对应的profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 p r e f i x . {prefix}. prefix.{file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

3.2、代码示例

新建cloud-alibaba-config-nacos-client,调用Nacos 配置中心的配置,pom文件添加依赖

<!--nacos-config-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--nacos-discovery-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--web + actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--一般基础配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

增加bootstrap.yml和application.yml,springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application

bootstrap:

server:
  port: 6088
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 182.92.122.196:8848
      config:
        server-addr: 182.92.122.196:8848
        file-extension: yaml

application:

spring:
  profiles:
    active: dev

配置 应用要到Nacos 找nacos-config-client-dev.yml文件
在这里插入图片描述
启动类

/**
 * @Auther: songweichao
 * @Date: 2023-05-11 13:01
 * @Description:
 */
@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain6088 {

    public static void main(String[] args) {
        SpringApplication.run(NacosConfigClientMain6088.class,args);
    }
}

业务类测试

@RefreshScope:在控制器类加入@RefreshScope注解,使当前类下的配置支持Nacos的动态刷新功能。

@RestController
@RefreshScope
public class ConfigClientController {

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getInfo(){
        return configInfo;
    }
}

访问http://localhost:6088/config/info,成功获取config.info,且在Nacos配置上修改后,客户端能及时刷新,获取最新配置。

在这里插入图片描述
在这里插入图片描述

3.3、多环境多项目管理

项目开发中,同一个微服务面对开发环境、测试环境、生产环境,要在不同的阶段指定不同的配置;不同的服务也有同样的需求,Nacos如何区分,做到井井有条呢?这里用到了三种方案

3.3.1、命名空间

增加命名空间,自动生成空间ID
在这里插入图片描述配置文件中,增加namespace,配置空间ID

server:
  port: 6088
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 182.92.122.196:8848
      config:
        server-addr: 182.92.122.196:8848
        file-extension: yaml
        namespace: f4f26a88-a7c7-4182-a20d-6fce7610d532

这时候,项目启动加载配置,就找空间ID为f4f26a88-a7c7-4182-a20d-6fce7610d532下面的nacos-config-client-dev.yaml文件中的信息,而不是原来的默认空间。

3.3.2、Group分组

同一个命名空间下,也可以设置不同的分组,实现环境区分

在这里插入图片描述在config下增加一条group的配置即可。可配置为DEFAULT_GROUP或SWC_GROUP

server:
  port: 6088
spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 182.92.122.196:8848
      config:
        server-addr: 182.92.122.196:8848
        file-extension: yaml
        group: SWC_GROUP

3.3.3、DataId

同样的命名空间,同样的分组,可以不同的DataId,进行环境的区分配置,进行不同的获取。

在这里插入图片描述
总之,namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/514448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

递归到动态规划:空间压缩技巧-纸币问题的有限张数

这个题是我们纸币问题的第三题 题目大意&#xff1a; arr是货币数组&#xff0c;其中的值都是正数。再给定一个正数aim。 每个值都认为是一张货币&#xff0c; 认为值相同的货币没有任何不同&#xff0c; 返回组成aim的方法数 例如&#xff1a;arr {1,2,1,1,2,1,2}&#xff0…

【C】模拟实现atoi,atof函数

目录 atoi函数 atof函数 模拟实现atoi&#xff0c;atof函数 1、atoi模拟实现 2、atof模拟实现 3、测试案例代码 atoi函数 atoi函数是将字符串转换成整数 函数头文件&#xff1a;#include <stdlib.h> 函数原型&#xff1a;int atoi(const char *str); 参数&…

利用结构相似性做单细胞多模态分析

多模态单细胞测序技术从多层基因组数据中提供了丰富的细胞异质性信息。然而&#xff0c;在没有正确消除模态偏差的情况下去分析联合空间&#xff0c;往往会得到比单模态分析更差的聚类结果。如何有效利用多组学额外信息来描绘细胞状态并识别有意义的信号仍然是一个重大的挑战。…

华为 VOS 移植到 TDA4VM/VH 芯片的 TI RTOS SDK 时的 bug 修复笔记

请从官网下载 TD4VM 技术参考手册&#xff0c;地址如下&#xff1a; TDA4VM 技术参考手册地址 VOS 作为静态库移植到TDA4VM/VH 芯片的 TI RTOS SDK 中 VOS 移植到 mcusw/mcal_drv/mcal/vos&#xff0c;如下&#xff1a; vos 测试应用 在 mcusw/mcuss_demos/vos_test_app …

Shell脚本之正则表达式

目录 一、正则表达式的介绍 1&#xff09;正则表达式的组成 2&#xff09;正则表达式和通配符的区别 二、基础正则表达式 1&#xff09;转义字符的运用 将特殊含义的字符转换为普通字符的含义 将普通字符转换为特殊作用的字符 2&#xff09;基础正则表达式实际应用 查…

C++ | 结构体及大小计算

C结构体及大小计算 文章目录 C结构体及大小计算struct 和 class 区别字节对齐默认对齐方式 位域使用#pragma pack(n)结构体中有结构体Reference struct 和 class 区别 结构体&#xff08;struct&#xff09;和类&#xff08;class&#xff09;有点像&#xff0c;均是定义一个数…

Activi7工作流经典实战(附:常用流程流转代码片段)

一、Activiti7介绍 Activiti正是目前使用最为广泛的开源工作流引擎。Activiti的官网地址是 https:// www.activiti.org 历经6.x和5.x两个大的版本。 1. Activiti工作流引擎 他可以将业务系统中复杂的业务流程抽取出来&#xff0c;使用专门的建模语言BPMN2.0进行定义。业务流…

彻底搞清楚Handler,再也不怕面试官

Handler Handler可以说是Android框架里面很精髓的一部分了&#xff0c;面试必问&#xff0c;用的也最多 Handler是什么&#xff1f; 提到Handler大家一定不陌生&#xff0c;我们经常用它来切换线程&#xff0c;或者是说做一些延时任务等等。最常用的地方可能就是在网络请求中…

Flask全栈解决小问题系列(1)搭建一个bootstrap开发框架

时间不多,闲话少说,实践出真知! 1.目的:为实现FlaskBootStrap开发效果,搞个开发测试项目 2.搭建项目 1)建个test-bootstrap项目,项目目录结构如下: 2)appstart.py内容如下: import json from flask import Flask,redirect,render_templateapp Flask("__main__") …

00后太卷了上班还没3年,跳到我们公司起薪18k....

都说00后已经躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。前段时间我们部门就来了个00后&#xff0c;工作都还没三年&#xff0c;跳到我们公司起薪18K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。最近和他…

Yolov5/Yolov7改进:小目标到大目标一网打尽,轻骨干重Neck的轻量级目标检测器GiraffeDet

1.GiraffeDet介绍 论文:https://arxiv.org/abs/2202.04256 🏆🏆🏆🏆🏆🏆Yolov5/Yolov7魔术师🏆🏆🏆🏆🏆🏆 ✨✨✨魔改网络、复现前沿论文,组合优化创新 🚀🚀🚀小目标、遮挡物、难样本性能提升 🍉🍉🍉定期更新不同数据集涨点情况 本文是…

gitlab上传大文件限制问题解决

gitlab上传大文件限制问题解决 前景提要&#xff1a; 今天收到同事反馈遇到gitlab 上传大文件时候报如下错误 error: RPC failed; result22, HTTP code 413 fatal: The remote end hung up unexpectedly fatal: The remote end hung up unexpectedly从报错来看是因为文件大…

什么样的冷链保温箱,既环保又实用?

冷链物流运输已经应用在了很多行业中&#xff0c;作为冷链物流运输中的重要设备——冷链保温箱&#xff0c;起到了举足轻重的作用。如果选择不当&#xff0c;选到了劣质产品&#xff0c;尤其是化学行业或者食品行业&#xff0c;就有可能造成试剂失效或者是影响粮食食品安全问题…

2023英码科技激发团队活力,提升集体凝聚力团建拓展之旅圆满结束!

5月6日&#xff0c;时至立夏&#xff0c;风暖昼长&#xff0c;万物繁茂。 在这个生机盎然、活力四射的时节&#xff0c; 尤其适合出游&#xff0c;开展有益身心健康的活动。 这一天&#xff0c;英码科技全体家人们齐聚广州白云区钟落潭&#xff0c;开展一天好玩有趣又意义深…

SVN基本操作 使用教程

01-SVN概述 1、为什么需要SVN版本控制软件 2、解决之道 SCM&#xff1a;软件配置管理 所谓的软件配置管理实际就是对软件源代码进行控制与管理 CVS&#xff1a;元老级产品 VSS&#xff1a;入门级产品 ClearCase&#xff1a;IBM公司提供技术支持&#xff0c;中坚级产品 SVN&…

C++类与对象(三)

文章目录 一.初始化列表1.初始化列表的概念2.初始化列表的注意事项 二.explicit关键字1.单参数构造函数2.多参数构造函数 三.static成员1.static成员的概念2.static成员的特性 四.友元1.概念2.友元函数3.友元类 五.内部类1.概念2.内部类的性质 六.匿名对象七.拷贝对象时编译器的…

Docker安装MySQL主从配置

今天学习Docker安装MySQL主从配置 一、Master 1.1、拉取镜像 $docker pull mysql:8.0.25 1. 2、新建MySQL主服务器的容器实例&#xff0c;端口为3306 docker run -p 3306:3306 --name mysql-master \ -v /data/mysql/mysql-master/log:/var/log/mysql \ -v /data/mysql/mys…

WebSocket聊天功能小Demo

一、WebSocket简介 1.1 什么是WebSocket&#xff1f; WebSocket协议是基于TCP的一种网络协议&#xff0c;它实现了浏览器与服务器全双工&#xff08;Full-duplex&#xff09;通信。它允许服务端主动向客户端推送数据&#xff0c;这使得客户端和服务器之间的数据交换变得更加简…

模型微调的预处理

一.简历文本标注数据的准备 目标&#xff1a;把原始数据集转换为PaddleNLP支持的文本/文档抽取标注格式&#xff0c;为后续的模型微调做好准备。 工具&#xff1a;Label Studio 使用手册&#xff1a; applications/information_extraction/label_studio_text.md PaddlePad…

ai原创文章生成器-原创文章生成的软件

AI原创文章生成器——让你轻松批量生成高质量文章 随着内容创作的需求不断增加&#xff0c;人工撰写也难以满足快速高效的产出需求。在这种情况下&#xff0c;AI原创文章生成器应运而生&#xff0c;为人们创造了一种全新的自动化创作方式。下面我们就来了解一下这个神奇的工具…