二、SpringCloud Alibaba之nacos

2.1、环境搭建

SpringCloud Alibaba的帮助文档地址:https://github.com/alibaba/spring-cloud-alibaba 中的wiki

在spring的官网中也有spring cloud alibaba:https://spring.io/projects/spring-cloud-alibaba

2.1.1、分支版本

分支版本地址:https://sca.aliyun.com/zh-cn/docs/next/overview/version-explain

Spring Cloud Alibaba Version Spring Cloud Version Spring Boot Version
2.2.8.RELEASE* Spring Cloud Hoxton.SR12 2.3.12.RELEASE
2.2.7.RELEASE Spring Cloud Hoxton.SR12 2.3.12.RELEASE
2.2.6.RELEASE Spring Cloud Hoxton.SR9 2.3.2.RELEASE
2.1.4.RELEASE Spring Cloud Greenwich.SR6 2.1.13.RELEASE
2.2.1.RELEASE Spring Cloud Hoxton.SR3 2.2.5.RELEASE
2.2.0.RELEASE Spring Cloud Hoxton.RELEASE 2.2.X.RELEASE
2.1.2.RELEASE Spring Cloud Greenwich 2.1.X.RELEASE
2.0.4.RELEASE(停止维护,建议升级) Spring Cloud Finchley 2.0.X.RELEASE
1.5.1.RELEASE(停止维护,建议升级) Spring Cloud Edgware 1.5.X.RELEASE

2.1.2、组件版本关系

其实spring cloud Alibaba依赖也是版本管理器,点击进去会发现这个依赖管理里面管理者nacos、rocketMQ、gateway、seata等组件的版本。

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

每个 Spring Cloud Alibaba 版本及其自身所适配的各组件对应版本如下表所示:

Spring Cloud Alibaba Version Sentinel Version Nacos Version RocketMQ Version Dubbo Version Seata Version
2.2.8.RELEASE 1.8.4 2.1.0 4.9.3 ~ 1.5.1
2021.0.1.0 1.8.3 1.4.2 4.9.2 ~ 1.4.2
2.2.7.RELEASE 1.8.1 2.0.3 4.6.1 2.7.13 1.3.0
2.2.6.RELEASE 1.8.1 1.4.2 4.4.0 2.7.8 1.3.0
2021.1 or 2.2.5.RELEASE or 2.1.4.RELEASE or 2.0.4.RELEASE 1.8.0 1.4.1 4.4.0 2.7.8 1.3.0
2.2.3.RELEASE or 2.1.3.RELEASE or 2.0.3.RELEASE 1.8.0 1.3.3 4.4.0 2.7.8 1.3.0
2.2.1.RELEASE or 2.1.2.RELEASE or 2.0.2.RELEASE 1.7.1 1.2.1 4.4.0 2.7.6 1.2.0
2.2.0.RELEASE 1.7.1 1.1.4 4.4.0 2.7.4.1 1.0.0
2.1.1.RELEASE or 2.0.1.RELEASE or 1.5.1.RELEASE 1.7.0 1.1.4 4.4.0 2.7.3 0.9.0
2.1.0.RELEASE or 2.0.0.RELEASE or 1.5.0.RELEASE 1.6.3 1.1.1 4.4.0 2.7.3 0.7.1

2.1.3、springcloud父类pom文件

在maven中的pom.xml文件中,只允许出现一个<parent>标签,在项目中<parent>是用来引用springboot版本管理中心的。如果需要添加别的父依赖,可以在<dependencyManagement>标签中使用<dependency>标签来实现。

比如添加springcloud的版本管理中心

<dependencyManagement>
    <dependencies>
          <!--springcloud alibaba的版本管理中心,通过dependency完成继承。
            springboot的版本管理中心也可以通过这种方式继承-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

 

2.1.4、完整的父pom文件

搭建环境最重要的一步就是确定好springboot、springcloud、springcloud alibaba三个框架的版本。

这些版本对照可以在springcloud alibaba的官网找到:https://sca.aliyun.com/zh-cn/docs/next/overview/version-explain

在本文中采用的三个框架的版本如下:

<?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>com.java.coder</groupId>
    <artifactId>spring-cloud</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>spring-cloud-order</module>
        <module>spring-cloud-stock</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.boot.version>2.3.2.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR9</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.6.RELEASE</spring.cloud.alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
            <!--springcloud alibaba的版本管理中心,通过dependency完成继承,
            springboot的版本管理中心也可以通过这种方式继承-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version> ${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud的版本管理-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.3</version>
            </plugin>
        </plugins>
    </build>

</project>

 

2.1.5、spring cloud alibaba搭建快速向导

阿里云快速向导地址:https://start.aliyun.com/

2.2、nacos注册中心

官方的帮助文档:https://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html

2.2.1、nacos简介

nacos定义:一个更易于构建云原生应用的动态服务发现、服务配置和服务管理平台。(注册中心+配置中心+服务管理)

服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。

服务心跳:在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。

服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。 leader raft

服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存

服务健康检查:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)

2.2.2、注册中心演变及其原理

刚开始时服务之间通过ip:port的方式直接调用

2.2.3、nacos的下载

下载地址:https://github.com/alibaba/nacos/tags

windows环境下nacos server

2.2.4、启动模式修改成单例

在windows环境下执行startup.cmd,默认情况下是集群模式,需要修改startup.cmd,改成单机模式

2.2.5、nacos与springcloud alibaba的版本关系

根据spring cloud alibaba的版本,选择响应的nacos版本

Spring Cloud Alibaba Version Sentinel Version Nacos Version RocketMQ Version Dubbo Version Seata Version
2.2.8.RELEASE 1.8.4 2.1.0 4.9.3 ~ 1.5.1
2021.0.1.0 1.8.3 1.4.2 4.9.2 ~ 1.4.2
2.2.7.RELEASE 1.8.1 2.0.3 4.6.1 2.7.13 1.3.0
2.2.6.RELEASE 1.8.1 1.4.2 4.4.0 2.7.8 1.3.0
2021.1 or 2.2.5.RELEASE or 2.1.4.RELEASE or 2.0.4.RELEASE 1.8.0 1.4.1 4.4.0 2.7.8 1.3.0
2.2.3.RELEASE or 2.1.3.RELEASE or 2.0.3.RELEASE 1.8.0 1.3.3 4.4.0 2.7.8 1.3.0
2.2.1.RELEASE or 2.1.2.RELEASE or 2.0.2.RELEASE 1.7.1 1.2.1 4.4.0 2.7.6 1.2.0
2.2.0.RELEASE 1.7.1 1.1.4 4.4.0 2.7.4.1 1.0.0
2.1.1.RELEASE or 2.0.1.RELEASE or 1.5.1.RELEASE 1.7.0 1.1.4 4.4.0 2.7.3 0.9.0
2.1.0.RELEASE or 2.0.0.RELEASE or 1.5.0.RELEASE 1.6.3 1.1.1 4.4.0 2.7.3 0.7.1

2.2.6、nacos server 依赖

在父类的pom文件中引入spring cloud alibaba的依赖以及spring cloud的依赖

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.boot.version>2.3.2.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR9</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.6.RELEASE</spring.cloud.alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
            <!--springcloud alibaba的版本管理中心,通过dependency完成继承,
            springboot的版本管理中心也可以通过这种方式继承-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version> ${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud的版本管理-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.3</version>
            </plugin>
        </plugins>
    </build>

 

在子模块的pom文件中引入nacos作为【注册中心】的依赖,

<!--必须加入web应用才能注册到nacos中-->  
	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--nacos的注册与发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

 

nacos作为【配置中心】的依赖是另外一个

  		<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

2.2.7、注册服务到nacos服务器

在子模块的.properties文件中配置nacos的配置信息

order-service

server.port=8081
# 应用名称(nacos会把应用名称作为服务名称)
spring.application.name=order-service
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=123456
#命名空间id
spring.cloud.nacos.discovery.namespace=495e2ede-c37a-4258-8e11-72f21b0cf1cd
#分组信息
spring.cloud.nacos.discovery.group=java-coder

 

stock-service

server.port=8083
# 应用名称(nacos会把应用名称作为服务名称)
spring.application.name=stock-service
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=123456
#命名空间id
spring.cloud.nacos.discovery.namespace=495e2ede-c37a-4258-8e11-72f21b0cf1cd
#分组信息
spring.cloud.nacos.discovery.group=java-coder

 

启动程序

如果springcloud版本比较低,在启动程序那里需要添加一个@EnableDiscoveryClient注解

stock-service的启动类

package com.java.coder.stock;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class StockApplication {

    public static void main(String[] args) {
        SpringApplication springApplication=new SpringApplication();
        springApplication.run(StockApplication.class,args);
    }

    /**
     * 注入 RestTemplate
     * @param builder
     * @return
     */
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        RestTemplate restTemplate=builder.build();
        return restTemplate;
    }
}

 

order-service的启动类

package com.java.coder.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication springApplication=new SpringApplication();
        springApplication.run(OrderApplication.class,args);
    }

    /**
     * 注入 RestTemplate
     * @param builder
     * @return
     */
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        RestTemplate restTemplate=builder.build();
        return restTemplate;
    }
}

服务之间调用

在之前的分布式应用中,服务之间的调用时通过ip:port方式调用的

现在引入了注册中心之后,服务的调用可以通过服务名进行调用

注意:在springcloud中,服务之间的调用是客户端通过负载均衡器进行调用的,因此需要把RestTemplate的Bean示例托管给负载均衡器管理。需要在注册RestTemplate时,在注册方法上加上@LoadBalanced注解

  /**
     * 注入 RestTemplate
     * @param builder
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        RestTemplate restTemplate=builder.build();
        return restTemplate;
    }

 

默认的负载均衡器

通过上面学习,可以看到消费者服务通过生产者服务名称可以访问到生产者。那么默认的负载均衡策略时什么呢?

首先修改生产者代码,同一个服务不同示例端口不一样。

@RestController
@RequestMapping("/stock")
public class StockServiceController {


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

    @RequestMapping("/getStock")
    public String addOrder(){

        return "getStock:"+port;
    }
}

 

其次把生产者这个实例再复制一份

把生产者的第二个实例再idea中的名称改成StockApplication_8083, 占用的端口改成8083

启动服务后,nacos注册中心情况如下:

日志分析

调用消费者时,消费者后台日志如下,打印出了服务配置信息

2023-06-03 09:51:03.481  INFO 9676 --- [nio-8081-exec-1] c.n.l.DynamicServerListLoadBalancer: 
#客户端stock-service的DynamicServerListLoadBalancer已初始化
DynamicServerListLoadBalancer for client stock-service initialized: 

DynamicServerListLoadBalancer:
{
#NFLoadBalancer的配置情况
NFLoadBalancer:name=stock-service,current list of Servers=[169.254.206.80:8082,169.254.206.80:8083],Load balancer stats=Zone 
# 状态情况
stats: {unknown=[Zone:unknown;	Instance count:2;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
},

#服务情况
Server stats: 
#第一个实例的情况
[[Server:169.254.206.80:8082;	Zone:UNKNOWN;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0], 

#第二个实例的情况
[Server:169.254.206.80:8083;	Zone:UNKNOWN;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
]

}ServerList:com.alibaba.cloud.nacos.ribbon.NacosServerList@16cc3180

 

2.2.8、Nacos 配置信息列表

更多关于 spring-cloud-starter-alibaba-nacos-discovery 的 starter 配置项如下所示:

配置项 key 默认值 说明
服务端地址 spring.cloud.nacos.discovery.server-addr Nacos Server 启动监听的ip地址和端口
服务名 spring.cloud.nacos.discovery.service ${spring.application.name} 给当前的服务命名
服务分组 spring.cloud.nacos.discovery.group DEFAULT_GROUP 设置服务所处的分组
权重 spring.cloud.nacos.discovery.weight 1 取值范围 1 到 100,数值越大,权重越大
网卡名 spring.cloud.nacos.discovery.network-interface 当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址
注册的IP地址 spring.cloud.nacos.discovery.ip 优先级最高
注册的端口 spring.cloud.nacos.discovery.port -1 默认情况下不用配置,会自动探测
命名空间 spring.cloud.nacos.discovery.namespace 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
AccessKey spring.cloud.nacos.discovery.access-key 当要上阿里云时,阿里云上面的一个云账号名
SecretKey spring.cloud.nacos.discovery.secret-key 当要上阿里云时,阿里云上面的一个云账号密码
Metadata spring.cloud.nacos.discovery.metadata 使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息
日志文件名 spring.cloud.nacos.discovery.log-name  
集群 spring.cloud.nacos.discovery.cluster-name DEFAULT 配置成Nacos集群名称
接入点 spring.cloud.nacos.discovery.enpoint UTF-8 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址
是否集成Ribbon ribbon.nacos.enabled true 一般都设置成true即可
是否开启Nacos Watch spring.cloud.nacos.discovery.watch.enabled true 可以设置成false来关闭 watch

 

2.2.9、nacos管理页面

windows环境下,运行nacos服务器bin目录下的startup.cmd。

通过浏览器访问: http://169.254.206.80:8848/nacos/index.html

默认的密码用户名和密码都是nacos

服务列表

在服务列表中可以查询注册到nacos服务器的服务。

一般建议 用命名空间来区分工作生产、测试、开发等环境。 用分组来区分项目

 

 

命名空间

nacos默认注册到public命名空间,public命名空间是保留命名空间,有时候命名空间需要进行区分,可以新建命名空间,如果服务中要注册到相应的命名空间。

首先在命名空间这里创建一个新的命名空间prod

然后在application.properties配置文件中配置spring.cloud.nacos.discovery.namespace,把这个值配置成命名空间的id

2.2.10、注册中心工作原理

 

posted @ 2024-01-23 22:24  阿瞒123  阅读(66)  评论(0编辑  收藏  举报