一文弄懂SpringCloud Alibaba服务组件——Nacos

什么是Nacos?

Nacos的核心定位是【一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台】,本文基于Nacos2.0记录相关内容。

什么是服务治理?

服务治理是微服务架构中最核心最基本的模块,用于实现各个微服务的自动化注册与发现。

服务注册:在服务治理框架中,都会构建一个注册中心,每个服务单元像注册中心登记自己提供服务的详细信息。并在注册中心形成一张服务的清单,服务注册中心要去检测服务清单中的服务是否可用,不可用需要剔除。

服务发现:服务调用方向服务注册中心咨询服务,并获取所有服务的实例清单,实现对具体实例服务的访问。

Nacos Discovery 可以帮助我们将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos Discovery 也将服务实例自身的一些元数据信息-例如 host,port, 健康检查URL,主页等内容注册到 Nacos。

Nacos安装

Nacos官网    点击版本  下载压缩包

然后以单机模式启动,这是windows的启动方式,如果在linux中以docker方式启动,则为【 docker run -d -p 8848:8848 -e MODE=standalone --name nacos-server 容器id

启动成功后访问 http://localhost:8848/nacos     默认用户名和密码都是nacos,直接登录即可。

服务注册

我们尝试编写一个服务并注册到nacos中

父工程pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>cloud-alibaba-nacos</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>provider8082</module>
        <module>provider8083</module>
        <module>comsumer9090</module>
    </modules>

    <properties>
        <spring.boot.version>2.2.5.RELEASE</spring.boot.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- SpringBoot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

然后创建子工程 支付服务提供者provider8082,pom中添加依赖如下:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
    </dependencies>

重点是引入nacos的依赖,引入依赖后编写配置文件:

server.port=8082
#nacos服务中心地址
spring.cloud.nacos.discovery.server-addr=Ip
#服务名
spring.cloud.nacos.discovery.service=provider

不需要@EnableDiscoveryClient注解

此时启动该服务,然后查看nacos的后台系统:

然后编写一个控制器用于模拟业务:

@RestController
public class PaymentController {
    @Value("${server.port}")
    private String port;

    @GetMapping("/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id) {
        return "nacos服务注册,端口号:" + port + "\t" + "id:" + id;
    }

}

测试一下

业务正常。接下来创建第二个支付服务 provider-payment8083 ,代码直接拷贝刚才的服务即可,只需修改端口号为8083,其它都一样。

启动payment8083,查看nacos后台:

 服务消费

有了服务提供者之后,我们理应创建服务消费者来消费这些服务,当然,消费者也是要注册到nacos中的,创建服务 consumer9090,pom文件依然是引入nacos依赖,然后编写配置文件:

server.port=9090
#nacos服务中心地址
spring.cloud.nacos.discovery.server-addr=ip
#服务名
spring.cloud.nacos.discovery.service=consumer

既然是服务消费,那就少不了服务调用,但是nacos已经为我们集成了ribbon,当我们引入nacos依赖的时候,ribbon依赖也随之引入进来了,所以我们可以直接使用ribbon实现负载均衡,那么首先就需要将ribbon注册到容器中:

@Configuration
public class ConsumerConfig {

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

最后编写控制器

@RestController
public class OrderController {

    /**
     * 需要调用的服务
     */
    public static final String SERVER_URL = "http://provider";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consumer/nacos/{id}")
    public String paymentInfo(@PathVariable("id") Integer id) {
        // 拼接请求地址
        String reqUrl = SERVER_URL + "/payment/nacos/" + id;
        return restTemplate.getForObject(reqUrl, String.class);
    }
}

启动服务消费者,首先查看nacos后台:

服务注册成功, 测试一下业务代码,访问   localhost:9090/consumer/nacos/1

而且支持负载均衡,默认采用轮询策略。

使用OpenFeign

ribbon虽然能够实现客户端的负载均衡和服务调用,但是稍显麻烦,缺点也很明显,需要在Controller层调用方法请求另外一个服务的Controller方法。为此,我们可以使用OpenFeign来改进这一过程,OpenFeign集成了ribbon,它更侧重服务之间的调用,当然也默认支持负载均衡。

OpenFeign提供了两个重要标注@FeignClient@EnableFeignClients

  • @FeignClient标注用于声明Feign客户端可访问的Web服务。
  • @EnableFeignClients标注用于修饰Spring Boot应用的入口类,以通知Spring Boot启动应用时,扫描应用中声明的Feign客户端可访问的Web服务。

首先修改子项目consumer9090中的pom文件,添加依赖:

<!-- org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

在启动类上添加注解

然后编写一个接口,在该接口上标注 @FeignClient("provider") 注解,其中值为需要远程调用的服务名,在接口中定义方法,一般来说,方法的声明与需要调用的方法声明一致。

@FeignClient("provider")
public interface PaymentService {

    @GetMapping("/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id);
}

然后改写order控制层    把接口注入进来,直接调用接口中的方法即可。

@RestController
public class OrderController {

    /**
     * 需要调用的服务
     */
//    public static final String SERVER_URL = "http://provider";
//
//    @Autowired
//    private RestTemplate restTemplate;
//
//    @GetMapping("/consumer/nacos/{id}")
//    public String paymentInfo(@PathVariable("id") Integer id) {
//        // 拼接请求地址
//        String reqUrl = SERVER_URL + "/payment/nacos/" + id;
//        return restTemplate.getForObject(reqUrl, String.class);
//    }

    @Autowired
    private PaymentService paymentService;

    @GetMapping("/consumer/nacos/{id}")
    public String paymentInfo(@PathVariable("id") Integer id){
        return paymentService.getPayment(id);
    }
}

启动项目,测试业务

使用Nacos作为服务配置中心

Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。

在特殊的 bootstrap 阶段,配置被加载到 Spring 环境中。当应用程序通过部署管道从开发到测试再到生产时,我们可以管理这些环境之间的配置,并确保应用程序具有迁移时需要运行的所有内容。

项目一般都会有多个Profile配置,用于区分开发环境,测试环境,准生产环境,生成环境等,每个环境对应一个properties文件(或是yml/yaml文件),然后通过设置 spring.profiles.active 的值来决定使用哪个配置文件

Nacos Config的作用就把这些文件的内容都移到一个统一的配置中心,即方便维护又支持实时修改后动态刷新应用

Data ID的拼接格式:${prefix} - ${spring.profiles.active} . ${file-extension}

  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置

  • spring.profiles.active 取 spring.profiles.active 的值,即为当前环境对应的 profile

  • file-extension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置

这里我们新建一个子项目 nacos-config2001

pom中的依赖为

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

这里的配置文件有讲究,我们需要创建一个名为 bootstrap.properties[或者bootstrap.yml]的配置文件,这是因为我们需要优先去配置中心获取所需的配置,当配置中心没有配置时,才使用本地的配置,而bootstrap.properties配置文件的优先级高于其它命名的配置文件,故需将配置写在bootstrap.properties中。

server.port=2001
#nacos服务中心地址
spring.cloud.nacos.discovery.server-addr=192.168.XXX
#nacos配置中心地址
spring.cloud.nacos.config.server-addr=192.168.XXX
#指定配置文件格式
#spring.cloud.nacos.config.file-extension=yaml
#DataId前缀
spring.cloud.nacos.config.prefix=nacosconfig

#服务名
spring.cloud.nacos.discovery.service=nacos-config2001

这里有一行指定配置文件格式的,因为默认是properties,所以如果用yml就需要配置一下。

编写一个接口测试一下

@RestController
public class ConfigController {

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

    @GetMapping("/config/msg")
    public String getMsg() {
        return msg;
    }

}

在nacos控制台的配置列表中新增配置

然后点击发布

启动项目,开始测试

然后我们修改配置,看是否可以生效 

 发现并未达到我们想要的效果。

Nacos Confg 支持标准 Spring Cloud @RefreshScope特性,即应用订阅某个 Nacos 配置后,当配置内容变化时,Refresh Scope Beans 中的绑定配置的属性将有条件的更新。

所谓的条件是指 Bean 必须:

  • 必须条件:Bean 的声明类必须标注 @RefreshScope
  • 二选一条件:
    • 属性(非 static 字段)标注 @Value
    • @ConfigurationPropertiesBean

在类上添加@RefreshScope  注解 就可以实现在nacos配置中心里修改配置后,就能够立马在项目中生效,无需重新启动项目。

这里需要注意的是当 Nacos Config 接收到服务端配置变更时,对应的 @RefreshScopeBean 生命周期回调方法会被调用,并且是先销毁,然后又重新初始化。

配置管理

nacos作为配置中心,除了能够提供配置外,它还具有非常强大的功能,比如命名空间、配置分组等等,首先说说命名空间。命名空间是用来区分部署环境的,一个项目往往需要经历开发、测试、维护三个阶段,每个阶段的配置内容可能不尽相同,为此,可以创建三个命名空间来分别接管这三个阶段的配置;默认情况下会有一个 public 命名空间。然后是Data ID,前面我们已经了解过Data ID的组成结构,所以我们可以直接通过Data ID的不同来区分不同环境的配置

此时我们就能通过修改:

spring.profiles.active=dev

来分别获取三个配置文件的配置。

接下来我们再来看看分组,默认情况下我们会有一个 DEFAULT_GROUP 分组,新建的配置文件都会被存放在该分组下,通过分组我们也能够区分部署环境的配置信息:

这三个配置文件名相同,但是分组分别属于开发、测试和生产环境,然后通过 group 属性指定即可:

spring.cloud.nacos.config.group=DEV_GROUP

最后是命名空间,通过命名空间,我们仍然能够实现同样的效果:

创建好命名空间后,nacos会为每个命名空间分配id

此时服务会去寻找该命名空间下的指定分组的配置文件,若有环境指定,也需要加上,然后在nacos中新建配置文件: 

spring.cloud.nacos.config.group=DEV_GROUP
spring.cloud.nacos.config.namespace=531bd39b-92b0-4bd9-b1f1-f32333c62ba5

在指定命名空间下创建配置文件即可。

更多关于 Nacos Config Starter 的配置项如下所示:

配置项 Key 默认值 说明
服务端地址 spring.cloud.nacos.config.server-addr   Nacos Server 启动监听的ip地址和端口
配置对应的 DataId spring.cloud.nacos.config.name   先取 prefix,再取 name,最后取 spring.application.name
配置对应的 DataId spring.cloud.nacos.config.prefix   先取 prefix,再取 name,最后取 spring.application.name
配置内容编码 spring.cloud.nacos.config.encode   读取的配置内容对应的编码
GROUP spring.cloud.nacos.config.group DEFAULT_GROUP 配置对应的组
文件扩展名 spring.cloud.nacos.config.fileExtension properties 配置项对应的文件扩展名,目前支持 properties 和 yaml(yml)
获取配置超时时间 spring.cloud.nacos.config.timeout 3000 客户端获取配置的超时时间(毫秒)
接入点 spring.cloud.nacos.config.endpoint   地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
命名空间 spring.cloud.nacos.config.namespace   常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
AccessKey spring.cloud.nacos.config.accessKey   当要上阿里云时,阿里云上面的一个云账号名
SecretKey spring.cloud.nacos.config.secretKey   当要上阿里云时,阿里云上面的一个云账号密码
Nacos Server 对应的 context path spring.cloud.nacos.config.contextPath   Nacos Server 对外暴露的 context path
集群 spring.cloud.nacos.config.clusterName   配置成Nacos集群名称
共享配置 spring.cloud.nacos.config.sharedDataids   共享配置的 DataId, "," 分割
共享配置动态刷新 spring.cloud.nacos.config.refreshableDataids   共享配置中需要动态刷新的 DataId, "," 分割
自定义 Data Id 配置 spring.cloud.nacos.config.extConfig   属性是个集合,内部由 ConfigPOJO 组成。Config有 3 个属性,分别是 dataIdgroup以及 refresh

集群模式

3个或3个以上Nacos节点才能构成集群。在本地搭建的伪集群

配置集群配置文件

nacos的解压目录nacos/的conf目录下,有配置文件cluster.conf,请每行配置成ip:port。(请配置3个或3个以上节点)

把【conf】目录下的sql文件导入数据库

【conf】目录下集群配置文件,把该文件后缀名【.example】去掉之后,修改该文件中的内容

请每行配置成ip:port。(请配置3个或3个以上节点)

接着修改【application.properties】文件中的db信息

把nacos目录复制两份,目录名添加对应的端口号,把每个服务中【conf】目录下的【application.properties】文件中的端口号修改

把这三个服务依次启动即可

猜你喜欢

转载自blog.csdn.net/QingXu1234/article/details/116094694