SpringCloud-Alibaba

SpringCloud-Alibaba

概述

Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

简单来说:就是在以前的微服务搭建中,如果使用SpringCloudAlibaba,来替代以前的某些产品,那么开发SpringCloud应用会变得更加简单

主要功能

  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
  • 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

主要组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

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

RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。

Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

如何使用

只需要在SpringCloud的父项目中引入以下依赖即可

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

在接下来的子项目中根据需求添加依赖即可

Nacos

概述

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

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

简单来说:Nacos就是注册中心+配置中心的组合,就是利用Nacos来代替之前学习的Eureka来做注册中心,代替SpringCloudConfig来做配置中心。

Nacos中文文档:https://nacos.io/zh-cn/docs/what-is-nacos.html

各大注册中心的比较

CAP原则:指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。P原则是必须满足的,即自能又两种原则 CP或者 AP

CP原则:放弃了系统的高可用性,但保证了数据准确唯一

AP原则:维护了系统的高可用,但是得到的数据可能有缺陷,不唯一。

由上图可知Nacos同时支持了CP或者AP原则,对于两个原则,它是可变的,我们只需要启动发送一个命令即可切换(默认是AP)

curl -X PUT 'nacos服务ip或者主机域名:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

CP和AP切换原则:

一般来说:

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

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

Nacos下载

所有版本下载地址:https://github.com/alibaba/nacos/releases

Nacos-server2.0.1-windows版本下载地址:https://github.com/alibaba/nacos/releases/download/2.0.1/nacos-server-2.0.1.zip

Nacos-server2.0.1-linux版本下载地址:https://github.com/alibaba/nacos/releases/download/2.0.1/nacos-server-2.0.1.tar.gz

Nacos-server1.4.2-windows版本下载地址:https://github.com/alibaba/nacos/releases/download/1.4.2/nacos-server-1.4.2.zip

Nacos-server1.4.2-linux版本下载地址:https://github.com/alibaba/nacos/releases/download/1.4.2/nacos-server-1.4.2.tar.gz

安装与启动

安装:将下载的压缩包解压即可

启动:

  1. 修改解压目录的nacos下的config目录下的 application.yaml,将数据库的注释打开,如下

  2. 根据配置文件中的数据库名称建立数据库,默认叫nacos,linux有所不同,字符编码utf8 ,排序规则utf8_general_ci

  3. 将解压目录的nacos下的config目录下的nacos-mysql.sql的数据库脚本放到建立的数据中执行。

  4. 在nacos启动目录下的bin目录下,修改配置文件windows修改startup.cmd,linux修改startup.sh

    # windows 将文件中的 set MODE="cluster" 改为 set MODE="standalone"
    # linux 将文件中的 export MODE="cluster" 改为 export MODE="standalone"
    
  5. 执行启动文件windows 启动startup.cmd linux启动 startup.sh

    然后访问:http://localhost:8848/nacos/,出现如下界面启动成功

注意

默认登录用户名和密码都是 nacos

服务注册与发现

微服务父项目搭建参考:https://www.cnblogs.com/Rampant/p/14770855.html

微服务提供者的注册

  1. 创建新模块 nacos-provider-9001

  2. 导入pom.xml依赖

    <dependencies>
    
        <!--Nacos 服务注册的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    
        <!--spring-boot-web 模块 常用的3个-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    
  3. 配置application.yaml

    server:
      port: 9001  # 端口号
    
    spring:
      application:
        name: cloud-alibaba-provider  # 微服务名称
    
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848 # 连接的注册中心
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'    #暴露端口
    
  4. 主启动类

    package com.wyx.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosProviderMain9001 {
    
        public static void main(String[] args) {
            SpringApplication.run(NacosProviderMain9001.class,args);
        }
    }
    
  5. 业务类

    package com.wyx.cloud.controller;
    
    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;
    
    @RestController
    public class ProviderController {
    
        @Value("${server.port}")
        private String serverPort;
    
        @GetMapping("/provider/{id}")
        public String provider(@PathVariable String id){
            return "使用Nacos服务注册中心,当前服务端口: "+serverPort+"\t"+"查询参数:"+id;
        }
    }
    

    启动测试,访问:http://localhost:9001/provider/1

  6. 为了实现后面的负载均衡,我们在用相同的步骤搭建一个9002端口的服务

微服务消费者的注册

  1. 创建模块nacos-consumer-80

  2. 添加依赖

    <dependencies>
    
        <!--Nacos 服务注册的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    
        <!--spring-boot-web 模块 常用的3个-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    
  3. 修改yaml

    server:
      port: 80  # 端口号
    
    spring:
      application:
        name: cloud-alibaba-consumer  # 微服务名称
    
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848 # 连接的注册中心
    
    
    service-url:
      nacos-service: http://cloud-alibaba-provider #将微服务提供者的名字放入配置文件,后面读取即可
    
  4. 主启动类

    package com.wyx.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class NacosConsumerMain80 {
        public static void main(String[] args) {
            SpringApplication.run(NacosConsumerMain80.class,args);
        }
    }
    
  5. 业务类

    RestTemplate注入

    package com.wyx.cloud.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 RestTemplateConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    服务调用

    package com.wyx.cloud.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    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;
    
    @RestController
    public class ConsumerController {
    
        @Value("${service-url.nacos-service}")
        private String serviceUrl;
    
        @Resource
        RestTemplate restTemplate;
    
        @GetMapping("/consumer/{id}")
        public String getConsumer(@PathVariable String id){
            return restTemplate.getForObject(serviceUrl+"/provider/"+id,String.class);
        }
    }
    

负载均衡

概述

对于Nacos服务注册中心,天生集成了 ribbon做负载均衡,

使用Ribbon做负载均衡,就是它默认给我们写了很多负载均衡类

1、随机策略——RandomRule

2、轮询策略——RoundRobinRule
注:Ribbon默认策略

3、重试策略——RetryRule

4、最低并发策略——BestAvailableRule

5、可用过滤策略——AvailabilityFilteringRule
过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)

性能仅次于最低并发策略。

6、响应时间加权策略——WeightedResponseTimeRule
每隔30秒计算一次服务器响应时间,以响应时间作为权重,响应时间越短的服务器被选中的概率越大。

7、区域权衡策略——ZoneAvoidanceRule

Ribbon的负载均衡策略使用建议
一般情况下,推荐使用最低并发策略,这个性能比默认的轮询策略高很多。

负载均衡替换

  1. 编写配置类

    // 编写一个类注入负载均衡算法类,该类必须不能让springboot扫描到,不能放在同级,或者子包下面,必须放在其它地方
    @Configuration
    public class RibbonConfiguration {
      @Bean
      public IRule ribbonRule() {
        // 负载均衡规则,改为随机,可以new的类,参考上面提供的类名,官方写好的的类,也可以自定义负载均衡类
        return new RandomRule();
      }
    }
    
  2. 在RestTemplate注入配置类添加注解

    package com.wyx.cloud.config;
    
    import com.wyx.loadbalance.RibbonConfiguration;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.ribbon.RibbonClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    // name 是微服务的应用名
    @Configuration
    @RibbonClient(name = "cloud-alibaba-provider", configuration = RibbonConfiguration.class)
    public class RestTemplateConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
  3. 其他配置不修改,启动即可。

  4. 当然如果对提供的负载均衡算法,不满意,也可以自定义负载均衡算法,只需要编写一个类,实现IRule接口即可。

配置中心的使用

项目创建

  1. 创建新模块nacos-config-3344

  2. 导入 pom.xml

    <dependencies>
    
        <!--Nacos 配置中心依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    
        <!--这个依赖,看版本来修改版本是20版之后的最好导入,因为在版后默认剔除了,不导入启动项目会出错-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    
        <!--Nacos 服务注册的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    
        <!--spring-boot-web 模块 常用的3个-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    
  3. 添加application.yamlbootstrap.yml

    # application.yml
    server:
      port: 3344
    
    spring:
      profiles:
        active: dev
    
    # bootstrap.yml
    spring:
      application:
        name: nacos-config-client
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 #服务注册中心地址
          config:
            server-addr: localhost:8848 #配置中心地址
            file-extension: yaml #指定文件后缀名,切记配置中心的后缀,必须一样,不能一个是yml 一个是yaml
    
  4. 主启动类

    package com.wyx.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class NacosConfigMain3344 {
        public static void main(String[] args) {
            SpringApplication.run(NacosConfigMain3344.class,args);
        }
    }
    
    
  5. 业务类

    package com.wyx.cloud.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;
    
    @RestController
    @RefreshScope	//动态刷新功能,nacos修改后,不需要在发送什么命令,直接会自动刷新
    public class ConfigClientController {
    
        @Value("${config.info}")
        private String configInfo;
    
        @GetMapping("/config/info")
        public String getConfigInfo() {
            return configInfo;
        }
    }
    

在配置中心准备配置的文件

文件名要求规则如下(dataId)即为文件名

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${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 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

由文件命名规则可知,我们该项目的配置文件命令为:nacos-config-client-dev.yml

添加配置文件如下图

启动项目测试即可:访问,http://localhost:3344/config/info

在修改配置文件后继续访问,发现是动态刷新的,不在像 springcloud-config 一样需要实时的刷新配置。

多环境多项目管理

对于SpringCloud-config一般情况下都是通过修改文件名字来实现生产环境,测试环境的使用,但是在Nacos中,利用了Java的包名类名管理思想。

它存在三级管理配置文件的功能,具体来说就是命名空间 + GROUP + Data ID,三者之间的关系命名空间 > GROUP > Data ID

命名空间的使用

下面我们来看一下如何创建命令空间

我们可以通过修改application.yaml来获取我们的命名空间,如下

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址
      config:
        server-addr: localhost:8848 #配置中心地址
        file-extension: yaml #指定文件后缀名,切记配置中心的后缀,必须一样,不能一个是yml 一个是yaml
        namespace: f50332a2-9b31-479c-9111-102c125d97d7 # 这个数字是刚刚创建时自动生成的命名空间ID
组的使用

在新建配置的时候可以自定义组名

我们在配置中如何配置组

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址
      config:
        server-addr: localhost:8848 #配置中心地址
        file-extension: yaml #指定文件后缀名,切记配置中心的后缀,必须一样,不能一个是yml 一个是yaml
        namespace: f50332a2-9b31-479c-9111-102c125d97d7 # 这个数字是刚刚创建时自动生成的命名空间ID
        group: DEV_GROUP	# 指定组名
Data ID的使用

Data ID就是一个对应文件名的配置,上面已经解释过了。

Nacos集群配置

架构部署

官方集群架构部署图

可能开起来不是很理解,下面是根据官网修改后的集群部署图:

简单来说:

  1. 就是我们访问一个域名,给我们解析成为一个虚拟IP。
  2. 虚拟IP映射到对应的Nginx服务器。
  3. 在由Nginx服务器反向代理到我们的需要正规访问的Nacos。
  4. Nacos的一些操作(比如保持配置文件)在将其持久化到我们的高可用的MySQL数据库。

持久化配置

默认Nacos使用的是内嵌式数据库实现数据存储(derby)。如果采用集群配置,每个Nacos节点都有自己的配置,就会存在数据一致性的问题。为了解决这个问题,Nacos采用了集中式存储方式来支持集群化部署(目前只支持MySQL)。

切换默认的数据源

  1. 创建数据库nacos_devtest,字符编码utf8 ,排序规则utf8_general_ci

  2. 将在安装nacos的目录下的conf下的nacos-mysql.sql文件复制到自己刚刚创建的数据库中执行SQL命令

  3. 修改在安装nacos的目录下的conf下的application.properties文件,添加如下配置

    #使用的数据源
    spring.datasource.platform=mysql	
    # 数据库的数量
    db.num=1	
    
    #连接的URL注意数据库名称
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    #用户名
    db.user.0=root	
    #密码
    db.password.0=970699
    

重新启动即可。

特别注意,数据库的名字不能改变,必须使用 nacos_devtest否则不能用

MySQL 8.0,需要加上时区配置。

开始配置

环境准备

  1. 环境准备(3台虚拟机+阿里云服务器一台)

    环境说明,由于服务器不够所以这里数据库就不集群了。其他的都集群配置

    master	192.168.137.129
    slave1	192.168.137.130
    slave2	192.168.137.131
    阿里云服务器	47.97.218.81
    
  2. 三台虚拟机上都先安装JDK,教程很多不在说明

    准备Nginx安装包,Nacos安装包

    下载地址:

    Nginx(1.20.0版本):http://nginx.org/download/nginx-1.20.0.tar.gz

    Nacos(nacos-server2.0.1版本):https://github.com/alibaba/nacos/releases/download/2.0.1/nacos-server-2.0.1.tar.gz

    并将 Nginx和Nacos放到三台虚拟机上

Nacos集群安装

说明以下,这里三台服务器的Nacos安装教程都一样,只对一台讲解

  1. 解压配置上传的压缩包

    # 我是安装在 /opt目录下
    [root@localhost opt]# pwd
    /opt
    [root@localhost opt]# tar -xzvf nacos-server-2.0.1.tar.gz 
    
    
  2. 配置MySQL数据源(我选用的是阿里云的服务器来配置数据源,如果条件不允许,可以自己用虚拟机来装MySQL也可以)

    首先:查看数据库配置文件在解压目录下的nacos 下的 conf目录下的数据库名称

    [root@localhost opt]# vim /opt/nacos/conf/nacos-mysql.sql
    

    使用navicat连接我的阿里云服务器的数据库建立数据库名为nacos_config,字符集为 utf8,排序规则为utf8_general_ci

    将刚刚我们查看的nacos-mysql.sql脚本,拿到navicat中运行数据库脚本。具体简单,不在操作。

  3. 配置nacos目录下的conf目录下的application.properties文件

    # 首先将文件备份,防止修改错
    [root@localhost conf]# cp application.properties application.properties.bk
    # 修改文件
    [root@localhost conf]# vim application.properties
    

    在文件最后配置数据源的位置,就是在文件最后添加如下内容

    #使用的数据源
    spring.datasource.platform=mysql	
    # 数据库的数量
    db.num=1	
    
    #连接的URL注意数据库名称,及其数据源的位置IP
    db.url.0=jdbc:mysql://xxx.xxx.xxx.xxx:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    #用户名
    db.user.0=root	
    #密码
    db.password.0=970699
    
  4. 配置集群文件

    # j将集群文件先复制一份,并改名为 cluster.conf
    [root@localhost conf]# cp cluster.conf.example cluster.conf
    # 编辑 cluster.conf
    [root@localhost conf]# vim cluster.conf
    

    上面修改的这个文件 3个服务器上都需要配置

    在三台服务器上都启动nacos

    # 启动命令,三台都要启动
    [root@localhost conf]# sh /opt/nacos/bin/startup.sh 
    # 关闭防火墙,如果是阿里云服务器建议开启端口,并配置安全组规则不要关闭防火墙
    systemctl stop firewalld.service
    # 查看防火墙状态
    firewall-cmd --state
    

    访问:http://192.168.100.129:8848/nacos/

    注意:启动实在太慢了,需要多等一会。我3G的运行内存启动差不多花了3分钟,这里可能是网络原因。所以记得等,如果等不了,使用如下命令查看启动日志

    1G内存启动花了6分钟左右

    # 默认就是安装目录下的logs下的start.out
    [root@localhost bin]# vim /opt/nacos/logs/start.out
    

    看到出现如下信息才算启动成功,看服务器配置启动时间。

全部启动成功后可以查看节点状态

Nginx集群接入

  1. 两台服务器安装Nginx

    安装教程参考:Nginx安装教程

  2. 这里使用192.168.100.129和192.168.100.130来搭建Nginx

    安装完成后测试访问没有问题后开始搭建

    搭建过程如果看不到可以参考这里:https://www.cnblogs.com/Rampant/p/14785179.html反向代理模式中的负载均衡,和Nginx高可用两个部分

  3. 修改Nginx启动配置文件

    # 编辑配置文件 
    [root@localhost conf]# vim /usr/local/nginx/conf/nginx.conf
    

    编辑后如下

        upstream nacoscluster{
             server 192.168.100.129:8848;
             server 192.168.100.130:8848;
             server 192.168.100.131:8848;
            }
        server {
            listen     5000;
            server_name  192.168.137.129;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            location / {
               # root   html;
               # index  index.html index.htm;
               proxy_pass http://nacoscluster
            }
    

    另外一台也做配置

        upstream nacoscluster{
             server 192.168.100.129:8848;
             server 192.168.100.130:8848;
             server 192.168.100.131:8848;
            }
        server {
            listen     5000;
            # 只需要这里的IP是本机IP,其他不变
            server_name  192.168.137.130;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            location / {
               # root   html;
               # index  index.html index.htm;
               proxy_pass http://nacoscluster
            }
    

Nginx高可用接入

参考:Nginx高可用搭建

安装 keeplived

# 安装命令
yum install keepalived

编辑配置文件

# 进入配置文件目录
cd /etc/keepalived/
# 编辑配置文件
vim keepalived.conf 
! Configuration File for keepalived
## 两台服务器都要配置
global_defs {

   notification_email { # keepalived服务宕机异常出现的时候,发送通知邮件 可以是多个

     acassen@firewall.loc  #  收件人邮箱1

     failover@firewall.loc #  收件人邮箱2

     sysadmin@firewall.loc #  收件人邮箱3

   }

   notification_email_from Alexandre.Cassen@firewall.loc  #邮件发件人

   smtp_server 192.168.200.1  # 邮件服务器地址

   smtp_connect_timeout 30   # 超时时间

   router_id LVS_DEVEL   # 机器标识 局域网内唯一即可

   vrrp_skip_check_adv_addr # 默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)。

   #vrrp_strict   # 严格遵守VRRP协议。下列情况将会阻止启动Keepalived:1. 没有VIP地址。2. 单播邻居。3. 在VRRP版本2中有IPv6地址。

   vrrp_garp_interval 0  # 小数类型,单位秒,在一个网卡上每组gratuitous arp消息之间的延迟时间,默认为0,一个发送的消息=n组 arp报文

   vrrp_gna_interval 0 # 小数类型,单位秒, 在一个网卡上每组na消息之间的延迟时间,默认为0

}

# 检测 nginx 的活动状态
vrrp_script chk_http_port{
	# 检测脚本路径
        script "/etc/keepalived/nginx_chech.sh"  

        interval 2

        weight 2
}

 

# vrrp实例  我们集群设置 多机配置,除了state和priority不一样,其他都一样
vrrp_instance VI_1 {

    state MASTER  # 服务器状态 MASTER是主服务器  BACKUP是备份服务器 主服务器的priority要比备份服务器大

    interface ens33 # 通信端口 通过ip addr可以看到 根据自己的机器配置

    virtual_router_id 51  # vrrp实例id  keepalived集群,实例id必须一致

    priority 100  # 权重比 主服务器的priority要比备份服务器大

    advert_int 1  # 心跳间隔  单位秒  keepalived多机器集群 通过心跳检测,如果发送心跳没反应 就立刻接管;

    authentication { # 服务器之间通信密码

        auth_type PASS

        auth_pass 1111

    }

    virtual_ipaddress { # 自定义虚拟IP 
		# 虚拟IP池,要求必须在一个网段内,必须192.168.100开头
        192.168.100.80

    }
}

配置检测脚本

#!/bin/bash
A=`ps -C nginx -no-header | wc -l`
if [$A -eq 0 ];then
        /usr/local/neginx/sbin/nginx
        sleep 2
        if [`PS -C nginx --no-header |wc -1` -eq 0 ]; then
                killall keepalived
        fi  
fi

访问:192.168.100.80:5000/nacos/测试,当主服务器192.168.100.129宕机后,测试访问依然成功,搭建完成。

Sentinel

概述

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

简单来说:它是一个轻量级的流量控制、熔断降级的Java库,就是以前学习的Hystrix的加强版

中文官方文档SpringCloudalibaba Sentinel中文官方文档

Sentinel 分为两个部分:

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

特点

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

主要功能

安装启动

  1. 下载Setinel

    下载地址(全部版本):https://github.com/alibaba/Sentinel/releases

    1.8.2版本:https://github.com/alibaba/Sentinel/releases/download/1.8.2/sentinel-dashboard-1.8.2.jar

  2. 启动,运行下载出来的jar包就可以了

    # 运行jar包
    java -jar Sentinel-dashboard-1.8.2.jar
    
  3. 访问:http://localhost:8080/ 如下启动成功

    登录用户和密码都是 sentinel

服务搭建

  1. 创建新模块nacos-sentinel-service-9003

  2. pom.xml

    <dependencies>
        <!--Sentinel 服务监控的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    
        <!--Nacos 服务注册的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    
        <!--spring-boot-web 模块 常用的3个-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    
  3. application.yaml

    server:
      port: 9003
    
    spring:
      application:
        name: nacos-sentinel-service
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 #注册到nacos注册中心
        sentinel:
          transport:
            dashboard: localhost:8080	#在8080d
            port: 8719  #默认8719,假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口
    
    management:   #凡是涉及监控的都需要暴露端口
      endpoints:
        web:
          exposure:
            include: '*'
    
    
  4. 主启动类

    package com.wyx.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class SentinelServiceMain9003 {
        public static void main(String[] args) {
            SpringApplication.run(SentinelServiceMain9003.class,args);
        }
    }
    
  5. 业务类

    package com.wyx.cloud.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class SentinelController {
    
        private Integer contA=0;
    
        private Integer contB=0;
    
        @GetMapping("/getInfoA")
        public String getInfoA(){
            contA++;
            return "提供A服务次数"+contA;
        }
    
        @GetMapping("/getInfoB")
        public String getInfoB(){
            contB++;
            return "提供B服务次数"+contB;
        }
    }
    

    访问 http://localhost:8080/ 查看监控信息,发现没有上面,是因为Sentinel使用懒加载模式

    只有访问服务后才会进入监控列表。

    我们访问 http://localhost:9003/getInfoA

    再次查看监控信息

仪表盘介绍

实时监控

显示在一段时间内对服务的每个请求的访问量,并以秒吉显示出来

簇点链路

触电链路主要有两种显示方式 树状视图和列表视图,主要功能就是显示某个服务的请求路径,并可用为其添加 流控、熔断、热点、授权等规则

流控规则

通过一定的规则来配置限流规则,来对服务提供一种保护作用,具体如何实现请看后面

热点规则

也是一种限流规则,具体参考后面。

系统规则

授权规则

集群流控

机器列表

查看当前服务名下有多少台实例的服务。

流控规则设置

在学习流控规则前,我们先来了解几个基本概念

阈值类型

QPS单位时间类的请求如果超过设定的规则就返回失败

默认返回错误的页面,后期可用自定义

并发线程数给定固定线程数,如果请求大于线程数的处理范围就快速失败

流控模式

直接针对自己的流控规则,满足规则就对自己限流。这个很简单不在解释

关联:将两个资源名进行关联,当关联资源达到限流规则时,来限流与之关联的资源。

简单理解:如下图,当/getInfoB在单位时间内的访问次数超过2次以上,那么/getInfoA将会被限流

,如果是并发线程数也是一样。当两个线程数处理不过来时,那么/getInfoA限流。(适用于当支付模块处理不过来时,可以对下单模块限流)

链路:在微服务调用过程中,如果入口资源调用资源名的服务,满足限流规则,则开始限流。

简单来说:假设微服务之间互相调用,那么当/getIfoB服务调用/getInfoA满足单位时间内超过2次以上触发限流

流控效果

流控效果只能针对QPS模式,并发线程模式,只能时快速失败

快速失败:就是快速放回默认的错误信息如下图(可以自定义)。

Warm UP(缓慢唤醒):即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

简单理解如下:起始单机阈值是3(在源码WarmUpController类中)当请求量突然增大时,系统会自动的在5秒钟内将我们的单机阈值调到我们设定的最大值10。(使用场景:抢购东西时,避免一开始就出现系统死机的情况)

等待排队:等待排队利用的原理是漏桶算法,就是对所有请求都不返回错误(在不超时的情况下,超时也会返回错误),而是将请求拿过来后,经行排队,以此处理。什么是漏桶算法

熔断规则设置

熔断规则又称服务熔断:但是这里的服务熔断和Hystrix有区别,它并没有半开状态,就只有两种状态可用,不可用。

慢比例调用模式

慢比例调用:在设置的统计时间内,如果满足最小请求数,且响应时间(最大RT)大于设定值的比例高于阈值就熔断设定的时长,当过了熔断时长,若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

下图的例子/getInfoA请求,如果在统计时长(1秒内)内,请求次数大于4次(最小请求数),并且响应时间大于50毫秒(最大RT)的比例大于0.4(比例阈值),就会进入熔断 10秒(熔断时长)。过了熔断时长就恢复访问。熔断界面为默认的出错界面,可用修改。

异常比例模式

异常比例模式:当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

例如,表示在一秒钟内,请求次数大于5次,并且出现异常的的次数大于请求次数的百分之四十,就会开启熔断,熔断时间过了后,如果请求还是异常继续熔断,等待下一次可用。

异常数模式

异常数模式:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

热点规则设置

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。

热点设置

  1. 环境准备,在业务类新加一个请求

    // 新增一个请求参数为非必须,这里只能用 SentinelResource,单独使用/hotKey是没效果的
    @GetMapping("/hotKey")
    @SentinelResource(value = "hotKey", blockHandler = "del_hotKet")    //定义访问的资源名,和失败后走的处理方法
    public String hotKet(@RequestParam(value = "p1", required = false) String p1,
                         @RequestParam(value = "p2", required = false) String p2){
        return "热点访问成功";
    }
    
    // 失败后的处理方法
    public String del_hotKet(String p1, String p2 , BlockException exception){
        return "热点新闻访问失败!😢😢😢😢";
    }
    
  2. 重启,添加热点规则

    上面的规则代表当访问/hotKey时,如果添加第一个参数(参数索引0开始),对应代码中的第一个参数为 p1,即当带有p1参数的访问在统计时间内,访问超过2次,就进行熔断。

    效果如下

参数例外项配置

简单来说:对于上述的请求,当p1等于任何值是,只要单机访问超过2个QPS,那么他就会熔断,对于参数例外项配置,就是可用当p1等于特殊的某个值,进行重新的定义限流规则。

如下,即当我们请求的参数为第一个(对于代码中的p1)本来限流是每秒钟超过2次进行限流,但是现在如果请求参数 p1 = 5并且请求类型为String类型,那么他的限流就为200

系统规则设置

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

简单来说:就是对我们之前定义的限流规则在外面包裹一层,来做新的限流规则,必须满足系统的限流规则,才能走到里面的限流规则

参考:系统自适应限流

系统规则支持以下的模式:(一般不是很常用,因为会如果配置不好,可能会导致下一层的一些规则失效不可用。导致系统瘫痪)

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

@SentinelResource

参考官网:@SentinelResource注解详解

控制台资源限流配置

用来配置访问资源名和达到限流规则后应该怎么处理

@GetMapping("/hotKey")
@SentinelResource(value = "hotKey", blockHandler = "del_hotKet")    //定义访问的资源名,和失败后走的处理方法
public String hotKet(@RequestParam(value = "p1", required = false) String p1,
                     @RequestParam(value = "p2", required = false) String p2){
    return "热点访问成功";
}

// 失败后的处理方法
public String del_hotKet(String p1, String p2 , BlockException exception){
    return "热点新闻访问失败!😢😢😢😢";
}

当然也可用只用定义的访问资源名称,就算定义了资源名称,配置流控规则时依然可以使用URL来做资源名,就是请求地址,但是热点规则除外,不能使用URL

// 达到限流规则时默认走,系统默认的
@SentinelResource(value = "hotKey") 

问题存在:

  1. 当我们不想使用系统默认时,自定义替换。
  2. 但是每个方法一个替换,会显得代码膨胀,不直观
  3. 没有体现全局统一管理等问题

问题解决:

  1. 自定义一个类,用来写异常的方法

    package com.wyx.cloud.myHandler;
    
    import com.alibaba.csp.sentinel.slots.block.BlockException;
    
    public class ConsumerHandler {
    
        // 因为JVM 的加载机制只能使用 static 返回值和要处理的方法的返回值相同
        public static String handlerEx(BlockException exception){
            return "自定义异常处理方法";
        }
        
    }
    
  2. 在方法中调用自定义的异常处理

    @GetMapping("/handlerEx")
    // blockHandlerClass 指定处理异常的类, blockHandler 指定处理异常类中的那个方法,如果没有异常类就是在自己的类中找方法
    @SentinelResource(value = "hotKey", blockHandlerClass = ConsumerHandler.class ,blockHandler = "handlerEx")
    public String handlerEx(){
        return "访问成功";
    }
    

运行时Java异常处理

fallback:

// 参数中还有defaultFallback,代表默认的处理,当与fallback同时标注时,fallback优先级高于defaultFallback
@GetMapping("/fallBack")
@SentinelResource(value = "fallBack",fallback = "fallbackMethod")
public String fallBack(){
    return "访问成功";
}
// 失败后的处理方法
public String fallbackMethod(Throwable exception){
    return "运行时异常处理方法";
}

上面的配置方式还是存在代码膨胀的问题

我们这里也可以用控制台资源处理的方法来处理。即创建一个fallbackMethod的类,然后通过fallbackClass来处理

  1. 创建类ConsumerFallbackMethod

    package com.wyx.cloud.myHandler;
    
    public class ConsumerFallbackMethod {
    
        // 因为JVM 的加载机制只能使用 static 返回值和要处理的方法的返回值相同
        public static String fallback(Throwable exception){
            return "自定义运行时异常处理方法";
        }
    }
    
  2. 在方法中调用

    @GetMapping("/fallBack")
    @SentinelResource(value = "fallBack", fallbackClass = ConsumerFallbackMethod.class, fallback = "fallback")
    public String fallBack(){
        int a=10/0;
        return "访问成功";
    }
    

特别说明:当Java运行时异常和控制台限流规则同时配置,且同时生效时,优先使用控制台的限流或熔断处理方法

Sentinel中使用openfeign做服务降级

使用方法和在Hystrix中使用类似,有一点点微小差异(开启的yaml支持不一样),可以参考

OpenFeign的使用:OpenFeign使用流程

Hystrix中使用OpenFeign做服务降级:Hystrix配合OpenFeign使用服务降级

具体步骤如下

微服务提供者搭建:(2个微服务提供者)

  1. 新建模块Nacos-Sentinel-OpenFeign-Provider-8001Nacos-Sentinel-OpenFeign-Provider-8002,两个搭建的东西都一样改端口即可

  2. pom.xml

    <dependencies>
    
        <!--Nacos 服务注册的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    
        <!--spring-boot-web 模块 常用的3个-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    
  3. yaml

    server:
      port: 8001  # 端口号
    
    spring:
      application:
        name: nacos-sentinel-openfeign  # 微服务名称
    
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848 # 连接的注册中心
    
    management:
      endpoints:
        web:
          exposure:
            include: '*'    #暴露端口
    
  4. 主启动类

    package com.wyx.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class NacosSentinelOpenFeignProviderMain8001 {
        public static void main(String[] args) {
            SpringApplication.run(NacosSentinelOpenFeignProviderMain8001.class,args);
        }
    }
    
  5. 业务类

    OpenFeign调用服务

    package com.wyx.cloud.service;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    @Service
    public class Provider {
    
        @Value("${server.port}")
        private String serverPort;
    
        public String getService(){
            return "提供服务成功,当前服务端口:"+serverPort;
        }
    }
    

    控制层

    package com.wyx.cloud.controller;
    
    import com.wyx.cloud.service.Provider;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    @RestController
    public class ProviderController {
    
        @Resource
        Provider provider;
    
        @GetMapping("/getServer")
        public String getService(){
            return provider.getService();
        }
    }
    

微服务消费者搭建:

  1. 创建新模块Nacos-Sentinel-OpenFeign-Consumer-80

  2. pom.xml

    <dependencies>
        <!--添加 openfeign 的启动依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    
        <!--Sentinel 服务监控的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    
        <!--Nacos 服务注册的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <!--spring-boot-web 模块 常用的3个-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    
  3. yaml

    server:
      port: 80
    
    
    spring:
      application:
        name: nacos-order-consumer
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848
        sentinel:
          transport:
            dashboard: localhost:8080
            port: 8719
    
    service-url:
      nacos-user-service: http://nacos-sentinel-openfeign
    
    #对Feign的支持
    feign:
      sentinel:
        enabled: true
    
  4. 主启动类

    package com.wyx.cloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class NacosSentinelOpenFeignConsumerMain80 {
        public static void main(String[] args) {
            SpringApplication.run(NacosSentinelOpenFeignConsumerMain80.class,args);
        }
    }
    
  5. 业务类

    OpenFeign调用接口

    package com.wyx.cloud.service;
    
    import com.wyx.cloud.fallback.ProviderFallBackImpl;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @FeignClient(value = "nacos-sentinel-openfeign",fallback = ProviderFallBackImpl.class)
    public interface ProviderService {
    
        @GetMapping("/getServer")
        public String getService();
    }
    

    出错处理类

    package com.wyx.cloud.fallback;
    
    
    import com.wyx.cloud.service.ProviderService;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ProviderFallBackImpl implements ProviderService {
    
        @Override
        public String getService() {
            return "Nacos下Sentinel的程序运行出错方法调用";
        }
    
    }
    

    控制层

    package com.wyx.cloud.controller;
    
    import com.wyx.cloud.service.ProviderService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    @RestController
    public class ConsumerController {
    
        @Resource
        private ProviderService provider;
    
        @GetMapping("/getServer")
        public String getServer(){
            int a = 10/0;
            return provider.getService();
        }
    }
    

    启动测试即可

配置规则持久化

一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化。那么如何持久化呢?

  1. 导入依赖

    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    
  2. 添加yaml配置

    spring:
      cloud:
        sentinel:
          datasource:
            ds1:
              nacos:
                server-addr: localhost:8848
                dataid: ${spring.application.name}
                groupid: DEFAULT_GROUP
                data-type: json
                rule-type: flow
    
  3. 在Nacos中添加配置Data Id配置文件名:是spring.application.name,服务名称,类型为json

    [
        {
             "resource": "/getInfoB",
             "limitApp": "default",
             "grade":   1,
             "count":   1,
             "strategy": 0,
             "controlBehavior": 0,
             "clusterMode": false    
        }
    ]
    

重启即可

posted @ 2021-07-26 21:11  橘子有点甜  阅读(237)  评论(0编辑  收藏  举报