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

什么是Nacos?

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

什么是服务治理?

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

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

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

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

Nacos安装

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

然后以单机模式启动,这是windows的启动方式

startup.cmd -m standalone

如果在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-addrNacos Server 启动监听的ip地址和端口
配置对应的 DataIdspring.cloud.nacos.config.name先取 prefix,再取 name,最后取 spring.application.name
配置对应的 DataIdspring.cloud.nacos.config.prefix先取 prefix,再取 name,最后取 spring.application.name
配置内容编码spring.cloud.nacos.config.encode读取的配置内容对应的编码
GROUPspring.cloud.nacos.config.groupDEFAULT_GROUP配置对应的组
文件扩展名spring.cloud.nacos.config.fileExtensionproperties配置项对应的文件扩展名,目前支持 properties 和 yaml(yml)
获取配置超时时间spring.cloud.nacos.config.timeout3000客户端获取配置的超时时间(毫秒)
接入点spring.cloud.nacos.config.endpoint地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
命名空间spring.cloud.nacos.config.namespace常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
AccessKeyspring.cloud.nacos.config.accessKey当要上阿里云时,阿里云上面的一个云账号名
SecretKeyspring.cloud.nacos.config.secretKey当要上阿里云时,阿里云上面的一个云账号密码
Nacos Server 对应的 context pathspring.cloud.nacos.config.contextPathNacos 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】文件中的端口号修改

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoneWalker、

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值