• SpringCloud 学习笔记总结 (七)


    1. Spring Cloud Alibaba 简介


    Spring Cloud Alibaba 基本上替代了 Spring Cloud netflix。
    在这里插入图片描述

    2. Spring Cloud Alibaba 之 Nacos 介绍 和 安装


    Nacos:全称Dynamic Naming and Configuration ServiceNaming Configuration service(前两个字符na和co,s就是service) 就拼成了nacos得简写。

    Nacos官方解释:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。


    官方地址:https://nacos.io/zh-cn/index.html

    下载地址:https://github.com/alibaba/nacos/releases?page=1

    本次使用的Nacos是1.1.4版本。

    注意:Beta版本是用户公开测试版本。


    Nacos的使用:

    • 解压安装包,直接运行bin目录下的startup.cmd。
    • 访问localhost:8848/nacos网站,默认的账号密码都是nacos。
      在这里插入图片描述
      出现以下页面nacos登录成功:
      在这里插入图片描述

    3. Nacos 服务注册与发现 之 服务提供者注册


    对于项目要引入spring cloud alibaba:

    • 只有父项目引入了该jar包,子项目直接就可以导入nacos的相关内容,不用担心版本环境冲突的问题。
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-alibaba-dependenciesartifactId>
        <version>2.1.0.RELEASEversion>
        <type>pomtype>
        <scope>importscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    第一步:创建项目,导依赖。

    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第二步:配置application.yml文件。

    server:
      port: 9001
    spring:
      application:
        name: nacos-payment-provider
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 # 配置Nacos地址
    
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db2019?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
        username: "root"
        password: "0818"
        
    management:
      endpoint:
        web:
          exposure:
            include: '*'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    第三步:创建启动类。不要忘记添加@EnableDiscoveryClient注解。

    package com.itholmes.springcloud.alibaba;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    /**
     * @description: TODO
     * @date: 2022/8/5 13:40
     */
    @EnableDiscoveryClient
    @SpringBootApplication
    public class PaymentMain9001 {
        public static void main(String[] args) {
            SpringApplication.run(PaymentMain9001.class,args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    第四步:查看nacos网站是否有注册。

    • nacos的默认端口8848。
      在这里插入图片描述
      注意启动的时候,如果提示是集群启动,就加上参数./startup.sh -m standalone。

    小技巧:

    • 拷贝虚拟端口映射,见下:

    在这里插入图片描述

    4. Nacos 服务注册与发现 之 服务消费者注册 和 负载


    服务消费者创建流程:

    第一步:创建项目,导入依赖。

    • nacos也能负载均衡,因为有了ribbon。
      在这里插入图片描述
     
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    <dependency>
        <groupId>com.itholmes.springcloudgroupId>
        <artifactId>cloud-api-commonsartifactId>
        <version>${project.version}version>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-actuatorartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-devtoolsartifactId>
        <scope>runtimescope>
        <optional>trueoptional>
    dependency>
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <optional>trueoptional>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    第二步:创建application.yml文件,配置如下:

    server:
      port: 83
    
    spring:
      application:
        name: nacos-order-consumer
      cloud:
        nacos:
          discovery:
            server-addr: 150.158.199.52:8848 # 配置Nacos地址
    
    # 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
    service-url:
      nacos-user-service: http://nacos-payment-provider
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    第三步:创建启动类。

    package com.itholmes.springcloud.alibaba;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    /**
     * @description: TODO
     * @date: 2022/8/5 22:04
     */
    @EnableDiscoveryClient
    @SpringBootApplication
    public class OrderNacosMain83 {
        public static void main(String[] args) {
            SpringApplication.run(OrderNacosMain83.class,args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第四步:编写配置类。

    • @LoadBalanced负载均衡注解很重要,不要忘记配置,,没有它启动不起来项目
    package com.itholmes.springcloud.alibaba.config;
    
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class ApplicationContextConfig {
    
        @Bean
        @LoadBalanced // 不要忘记配置负载均衡,没有它启动不起来项目
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第五步:写个controller,测试测试。

    package com.itholmes.springcloud.alibaba.controlller;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import javax.annotation.Resource;
    
    /**
     * @description: TODO
     * @date: 2022/8/5 22:08
     */
    @RestController
    @Slf4j
    public class OrderNacosController {
    
        @Resource
        private RestTemplate restTemplate;
    
        @Value("${service-url.nacos-user-service}")
        private String serverURL;
    
        @GetMapping(value = "/consumer/payment/nacos/{id}")
        public String paymentInfo(@PathVariable("id") Long id) {
            return restTemplate.getForObject(serverURL + "/payment/nacos/" + id ,String.class);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    5. Nacos 服务注册与发现 之 服务注册中心对比提升


    在这里插入图片描述


    什么是CAP?


    在这里插入图片描述


    Nacos 支持AP 和 CP模式的切换:
    在这里插入图片描述
    可以通过curl发送一个put请求,来切换CP。

    URL指令:$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP 。

    6. Nacos作为 服务配置中心


    将nacos作为服务配置中心搭建项目:

    第一步:创建项目,导入依赖。

    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    第二步:配置bootstrap.yml,application.yml文件。

    • bootstrap优先级高于application。
    • Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。

    bootstrap.yml配置:

    server:
      port: 3377
    
    spring:
      application:
        name: nacos-config-client
      cloud:
        nacos:
          # 将Nacos作为服务注册中心地址
          discovery:
            server-addr: localhost:8848
          # 将Nacos作为配置中心地址
          config:
            server-addr: localhost:8848
            file-extension: yaml # 指定yaml格式的配置
    
    # ${prefix}-${spring.profiles.active}.${file-extension} 根据公式就如下信息:
    # nacos-config-client-dev.yaml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    application.yml配置:

    spring:
      profiles:
        active: dev # dev表示开发环境、test表示测试环境、prod表示生产环境,这是标准一点。
    
    • 1
    • 2
    • 3

    第三步:创建主启动类,不要忘记添加注解@EnableDiscoveryClient。

    package com.itholmes.springcloud.alibaba;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    /**
     * @description: TODO
     * @date: 2022/8/6 11:00
     */
    @EnableDiscoveryClient
    @SpringBootApplication
    public class NacosConfigClientMain3377 {
        public static void main(String[] args) {
            SpringApplication.run(NacosConfigClientMain3377.class,args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第四步:创建业务类,通过Spring Cloud原生注解,@RefreshScope实现配置的自动更新。

    package com.itholmes.springcloud.alibaba.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author: xuyanbo
     * @description: TODO
     * @date: 2022/8/6 11:14
     */
    @RestController
    @RefreshScope // 通过Spring Cloud原生注解,@RefreshScope实现配置的自动更新。
    public class ConfigClientController {
    
        @Value("${config.info}")
        private String configInfo;
    
        @GetMapping(value = "/config/info")
        public String getConfigInfo(){
            return configInfo;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    第五步:按照规则来,在nacos配置Data ID。

    官方给出的Nacos Spring Cloud的Data ID配置格式:

    ${prefix}-${spring.profiles.active}.${file-extension}
    # 读下面图片的介绍,很重要!
    
    • 1
    • 2

    在这里插入图片描述
    nacos新建配置如下:
    在这里插入图片描述
    (注意这里要配置成yaml,不能配置为yml)

    详细图:
    在这里插入图片描述

    第六步:编写业务类,测试,并且能够达到动态刷新的效果。

    package com.itholmes.springcloud.alibaba.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @description: TODO
     * @date: 2022/8/6 11:14
     */
    @RestController
    @RefreshScope // 通过Spring Cloud原生注解,@RefreshScope实现配置的自动更新。
    public class ConfigClientController {
    
        @Value("${config.info}")
        private String configInfo;
    
        @GetMapping(value = "/config/info")
        public String getConfigInfo(){
            return configInfo;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    7. Nacos 服务配置中心 之 namespace、group、DataID 三者关系


    其实就是下图这样的关系:
    在这里插入图片描述
    默认情况:

    • Namespace 默认为 public。
    • Group 默认为 DEFAULT_GROUP。
    • 默认Cluster是DEFAULT。

    场景如下:
    在这里插入图片描述

    7. Nacos 服务配置中心 之 Data Id方案


    默认空间 + 默认分组 + 新建dev和test的两个DataID实现:
    在这里插入图片描述

    通过spring.profile.active属性就能进行多环境下配置文件的读取。
    在这里插入图片描述

    通过这种方式就可以显示一个开发,测试,生产环境的一个替换。

    8. Nacos 服务配置中心 之 Group分组方案


    依靠group分组来实现:
    在这里插入图片描述
    在这里插入图片描述

    9. Nacos 服务配置中心 之 Namespace空间方案


    新建命名空间:
    在这里插入图片描述
    创建后,在配置列表,会多出创建好的命名空间来:
    在这里插入图片描述

    配置bootstrap和application配置文件:
    在这里插入图片描述

    10. Nacos 集群 和 持久化


    Nacos要集群化,首先的问题是数据一致性问题,因为nacos存储是嵌入式数据库。

    默认Nacos使用嵌入式数据库实现数据derby的存储。
    在这里插入图片描述

    因此,Nacos采用了集中式存储的方式来支持集群化部署,目前支持MySQL的存储。

    在这里插入图片描述

    10. Nacos 集群 之 持久化切换配置


    切换derby到mysql,通过是用mysql来进行持久化存储。

    第一步:在nacos目录下面,有一个conf目录,找到对应的sql脚本。直接按照要求创建一个数据库,执行这些sql脚本。注意:mysql数据库要求5.6.5 + 以上的。
    在这里插入图片描述
    第二步:同样,在nacos服务目录的conf目录下有一个application.properties文件,修改application.properties文件。

    • 有一个example的文件案例,按照该逻辑来配置application.properties文件。
      在这里插入图片描述

    第三步:重启Nacos,这样就切换到了mysql数据库存储。


    踩坑-注意事项:

    • linux系统下,nacos切换mysql的启动的时候,报错,查看日志如下(注意查看的是nacos/logs,并不是bin/logs):
    org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Could not create connection to database server. Attempted reconnect 3 times. Giving up.)
            at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81)
            at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)
            at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:523)
            at com.alibaba.nacos.config.server.service.BasicDataSourceServiceImpl$SelectMasterTask.run(BasicDataSourceServiceImpl.java:317)
            at com.alibaba.nacos.config.server.service.BasicDataSourceServiceImpl.reload(BasicDataSourceServiceImpl.java:213)
            at com.alibaba.nacos.config.server.service.BasicDataSourceServiceImpl.init(BasicDataSourceServiceImpl.java:131)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    解决方案:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    完成上图,切换到nacos/bin目录,执行./startup.sh -m standalone命令,启动服务,就切换成功了。

    如果报错是下面错误,是属于连接mysql数据库配置错误,连接mysql8.x需要加上时区)

    Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '???ú±ê×??±??' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
            at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
            at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85)
            at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132)
            at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2234)
            at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2258)
            at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1319)
            at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:868)
            ... 95 more
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    11. Nacos 集群 之 搭建集群


    搭建Nacos集群,需要3个或3个以上Nacos节点才能构成集群。

    按照上面的配置,切换好mysql持久化。

    第一步:复制conf目录下的cluster.conf.example文件,文件名为cluster.conf文件。
    在这里插入图片描述

    第二步:编辑cluster.conf文件。

    • 注意:IP不能写127.0.0.1,必须是Linux命令hostname -i 命令能够识别的IP。

    第三步:编辑startup.sh脚本,添加上能识别-p port端口。
    在这里插入图片描述

    1.先cp startup.sh startup.sh.bk做备份。
    在这里插入图片描述

    2.修改startup.sh脚本,如下信息。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3.接下来就可以通过./startup.sh -p xxxx 来启动定义端口号的nacos。

    • 通过使用ps -ef | grep nacos | grep -v grep | wc -l命令来查看是否启动了nacos节点。

    命令解释:

    # 该命令可以查看我们启动了几台nacos节点
    ps -ef | grep nacos | grep -v grep | wc -l
    
    ######	以下对上面命令的解释:
    
    # 查看进程
    ps -ef 
    # 表示只查看包含nacos这个关键字的行内容
    grep nacos 
    # 表示查看除了含有grep内容之外的行内容
    grep -v grep 
    # wc 命令用于计算字数。
    wc -l
    # wc -c, --bytes:统计字节数。
    # wc -m, --chars:统计字符数。
    # wc -w, --words:统计字数。
    # wc -l, --lines:统计行数。
    # wc -L, --max-line-length:统计最长行的长度。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    第四步:配置nginx对应nacos的几个端口。
    在这里插入图片描述

    第五步:启动服务,测试效果。
    在这里插入图片描述

  • 相关阅读:
    Eureka 和 Consul两个注册中心的差异。
    微前端是模块化后的最终选择
    上周热点回顾(11.14-11.20)
    MongoDB 的集群架构与设计
    【JavaWeb】之JSP
    css的三种引入方式
    Git commit规范
    BS系统的登录鉴权流程演变
    比较两个文本文件是否相等(C语言)
    设计模式之编程方法论
  • 原文地址:https://blog.csdn.net/IT_Holmes/article/details/126175530