在B站学习的springcloud的学习记录,第4天(其实离第三天已经过了好多天,一直没有时间整合到csdn上),最难不过坚持。

配置和环境:idea2022   jdk8  mysql8.0 

本文章只用于学习和分享,欢迎大家的建议,讨论和指点。

目录

Hystrix服务

服务降级

Payment8001支付模块端的hystrix降级测试案例

order80消费者服务端的hystrix降级测试案例

Hystrix支付服务8001降级fallback

Hystrix消费者80服务降级fallback

全局服务降级 DefaultProperties

服务熔断 

服务监控仪表盘 

gateway服务网关

案例——入门配置

 Springcloud Config 分布式配置中心

编写一个config-server 配置的服务端

编写一个config-client配置的客户端 

动态刷新(手动)​编辑

消息总线

环境和需要的软件配置和安装

动态刷新全局广播

Bus动态刷新定点通知

Hystrix服务

什么是hystrix服务?

hystrix熔断主要是指在一定的时间窗口内,当请求的次数达到一定的失败比率后,hystrix就会主动拒绝服务,采取将请求直接降级等方式,从而有效的缓解了服务雪崩的问题,通过快速错误的方式,有效的控制服务之间链路调用的响应时间,保证整个微服务的健康。

保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障。

hystrix能干什么:服务降级,服务熔断,接近实时的监控

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延。

分为三种

服务降级

服务降级就是对方的系统不可用了,你需要给我一个兜底的解决方法。

服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback。

有哪些情况惠出现降级:程序运行异常,超时,服务熔断触发服务降级,线程打满也会导致服务降级。

服务熔断

服务熔断就是类似保险丝达到醉倒服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法——就是保险丝

服务限流

服务限流秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒n个,有序的进行。

服务降级

Payment8001支付模块端的hystrix降级测试案例

建model

改pom,添加依赖,增加hystrix的依赖和eureka服务的依赖

<!--        hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--        eureka-client 依赖jar包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

 写yml,与8001端口的yml相似

server:
  port: 8001

spring:
  application:
    name: cloud-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: true   #表示自己注册到eurekaServer中默认是true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版
#      defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka  #eureka集群版

 

主启动类

正常的主启动类

@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class, args);
    }
}

写业务类

在service中写两个方法,一个是正常访问的方法,一个是故意报错的方法

@Service
public class PaymentService {
    /**
     * 正常访问ok的方法
     * @param id
     * @return
     */
    public String paymentInfo_ok(Integer id){
        return "线程池:"+Thread.currentThread().getName() + "paymentInfo_ok,id: " +id+"\t"+"0(n-n)0哈哈";
    }

    /**
     * 异常报错的线程
     * @param id
     * @return
     */
    public String paymentInfo_TimeOut(Integer id){
        //模仿异常,让线程报超时三秒的
        int timeNumber = 3;
        try {
            TimeUnit.SECONDS.sleep(timeNumber);
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:"+Thread.currentThread().getName() + "paymentInfo_TimeOut,id: " +id+"\t"+"0(n-n)0哈哈"+"耗时"+timeNumber+"秒钟";
    }
}

Controller类中调用

@RestController
@Slf4j
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

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

    /**
     * 正常运行的方法
     * @param id
     * @return
     */
    @GetMapping(value = "/payment/hystrix/ok/{id}")
    public String paymentInfo_Ok(@PathVariable("id") Integer id){
        String result = paymentService.paymentInfo_ok(id);
        log.info("*******result"+result);
        return result;
    }

    /**
     * 异常处理的方法
     * @param id
     * @return
     */
    @GetMapping(value = "/payment/hystrix/timeOut/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
        String result = paymentService.paymentInfo_TimeOut(id);
        log.info("*******result"+result);
        return result;
    }
}

实验结果

该服务注册进了eureka中

正常访问的结果

模拟异常超时的结果

 

异常处理三秒钟,前台后台都没有报错。

高并发测试就不测了,我的笔记本电脑有点怕死!!!

order80消费者服务端的hystrix降级测试案例

建model

改pom

写yml

主启动

服务类

使用feign编写一个service接口

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
    //暴露的方法
    @GetMapping(value = "/payment/hystrix/ok/{id}")
    public String paymentInfo_Ok(@PathVariable("id") Integer id);

    @GetMapping(value = "/payment/hystrix/timeOut/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id);

}

调用超时的方法结果显示

 

原因是因为8001同层次的其他服务端口已经被困死,因为tomcat线程池里面的工作线程已经被挤占完毕,81此时去调用8001端口,客户端响应缓慢,转圈圈或者返回错误页面的结果。

那如何解决这个问题呢,解决这个超时调用的宕机,我们可以使用服务降级的方法,

  1. 超时导致服务器变慢(转圈)——超时不再等待,可以返回一个提示信息,告诉客户服务器繁忙,请稍后再试的提示,总比返回一个error page 要好。
  2. 出错(宕机或者程序运行错误)——出错要有兜底

解决方案

  • 对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
  • 对方服务(8001)宕机了,调用者(80)不能一直卡死等待,必须有服务降级
  • 对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者)自己处理降级

Hystrix支付服务8001降级fallback

 

先从8001 自身找问题,继续的加工异常处理,模拟超时服务的处理,业务处理在三秒内的我们正常的将信息打印出来,超过三秒,超时,我们写一个可用兜底的处理方法,作服务降级fallback,向调用方返回一个符合预期的,可处理的备选响应(FallBack)。

首先在8001的service服务类的异常处理方法上加上一个@HystrixCommand的注解

如果该注解不生效,可用在pom文件中引入依赖

<dependency>

    <groupId>com.netflix.hystrix</groupId>

    <artifactId>hystrix-javanica</artifactId>

</dependency>

在主启动类中添加注解@EnableCircuitBreaker,

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentHystrixMain8001.class, args);
    }
}

测试得到的结果,服务超过三秒,然后走兜底的方法。

 

如果系统方法出错也可以调用到兜底的方法,在service的异常方法中改成这样。

Hystrix消费者80服务降级fallback

照葫芦画瓢,

先是在yml文件中开启feign配置

server:
  port: 81
#
#spring:
#  application:
#    name: cloud-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: false   #表示自己注册到eurekaServer中默认是true
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版
#      defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka  #eureka集群版

feign:
  hystrix:
    enabled: true

主启动开启hystrix的注解

 

然后在业务类中写一个兜底的方法

测试的结果

全局服务降级 DefaultProperties

 Hystrix直通配服务降级FeignFallbacke案例

之前我们测试了超时异常,运行异常

现在我们测试服务降级,客户端去调用服务端,碰上服务端宕机或者关闭

降级处理在80端口中完成,与8001端口没有关系

创建一个新的类

@Component
public class PaymentFallbackService implements PaymentHystrixService{
    @Override
    public String paymentInfo_Ok(Integer id) {
        return "----PaymentFallbackService fall back-paymentInfo_Ok,咕咕哒-------";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "----PaymentFallbackService fall back-paymentInfo_TimeOut,哇咔咔-------";
    }
}

 在service中添加注解

@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)

这个paymentFallbackService 相当于总的服务降级。

模拟客户端挂了,吧8001停掉,然后重新访问可用看到的测试是客户端调用的是自己的。

服务熔断 

服务降级和服务熔断是两回事

现在开始学习服务熔断

服务熔断当检测该节点微服务调用响应正常后,恢复调用链路,就是说在坏的过程当中有点自我修复的意思,修复好后帮你恢复调用方法。

实操:修改cloud-provide-hystrix-payment8001

在service类中配置服务熔断的参数

//=====服务熔断的服务
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
        @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), //是否开启断路器
        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //请求次数
        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), //时间窗口
        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"), //失败率达到多少开始跳闸
})
public String paymentCircuitBreaker(@PathVariable("id")Integer id){
    if (id<0){
        throw new RuntimeException("****id 不能是负数");
    }
    String serialNumber = IdUtil.simpleUUID();

    return Thread.currentThread().getName() + "\t"+"调用方法,流水号:"+ serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
    return "id 不能是负数,请稍后再试"+id;
}

 

错误的访问多了就开始跳闸,即使你访问正确的也是会跳转到错误的页面,然后他会半开恢复链路,当正确的访问比率多起来后,重新的可恢复到跳转正确的页面。

在controller中的编写

//======服务熔断
@GetMapping("/payment/circuit/{id}")
public String paymentCircuitBreaker(@PathVariable("id") Integer id) {
    String result = paymentService.paymentCircuitBreaker(id);
    log.info("****result: " + result);
    return result;
}
  • 熔断打开

请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入半熔断状态

  • 熔断关闭

熔断关闭不会对服务进行熔断

  • 熔断半开

部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断

 

 

服务监控仪表盘 

仪表盘9001

建model

改pom

<!--        仪表盘-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
        <!--        hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-javanica</artifactId>
        </dependency>
        <!--        web-->
        <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

 写yml

server:
  port: 9001

主启动

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboardMain9001.class,args);
    }
}

可以访问这个说明平台搭建成功:localhost:端口号/hystrix

监控8001是否健康的准备工作,必须在8001的主启动类中添加这个代码

    /**
     * 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
     * ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
     * 只要在自己的项目里配置上下面的servlet就可以了
     */
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }

 

开始监控服务

刷新或者进入要监控的微服务

 

 

 

 

 

 

gateway服务网关

Gateway是网飞zuul网关的替代,是springcloud自主开发的服务网关

属于响应式编程组件

对比zuul的区别

Gateway是基于异步非阻塞模型上进行开发的;

支持路由指定Predicate(断言)和filter(过滤);

集成了hystrix的断路器功能;

 

案例——入门配置

建model

 

改pom

写yml

我们先是到8001端口中,功能:我们目前不想暴露8001端口,希望在8001外面套一层9527,新增一个网关的配置进去

<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/maven-v4_0_0.xsd">
    <parent>
        <artifactId>cloud2023</artifactId>
        <groupId>com.liangliang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloud-gateway-9527</artifactId>
    <packaging>war</packaging>
    <name>cloud-gateway-9527 Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>

        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!--        eureka-client 依赖jar包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--        引入自定义的api通用包,可以使用payment支付entity-->
        <!--        这个依赖是实体类引用公共model中的实体类,可以达到只修改一个地方的实体类就能让其他的服务一同修改实体类的效果-->
        <dependency>
            <groupId>com.liangliang</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

        <!--        一些通用配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>cloud-gateway-9527</finalName>
    </build>
</project>

写yml

我们先是到8001端口中,功能:我们目前不想暴露8001端口,希望在8001外面套一层9527,新增一个网关的配置进去

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh  #路由的id,没有固定规则但是要求唯一,建议配合服务名
          uri: http://localhost:8001  #匹配提供的服务的路由地址
          predicates:
            - Path=/payment/get/**   #断言,路径相匹配的进行路由

        - id: payment_routh2  #路由的id,没有固定规则但是要求唯一,建议配合服务名
          uri: http://localhost:8001  #匹配提供的服务的路由地址
          predicates:
            - Path=/payment/lb/**   #断言,路径相匹配的进行路由

eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

这样就可以通过访问9527端口来访问

Gateway网关配置有两种,可以通过yml文件配置,也可以通过硬编码的形式,这种我没有认真的看,所以没有笔记。

 Springcloud Config 分布式配置中心

Config service是什么,提供了集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。

怎么用,springcloud config 分为两部分服务端和客户端

服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口

客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。

读取一份公用的配置,减少配置文件。

编写一个config-server 配置的服务端

建model

 

改pomx

<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/maven-v4_0_0.xsd">
    <parent>
        <artifactId>cloud2023</artifactId>
        <groupId>com.liangliang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-cloud-config-config3344</artifactId>
    <packaging>war</packaging>
    <name>spring-cloud-config-config3344 Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <!--添加消息总线RabbitMQ支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

        <!--        配置中心的服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

        <!--        eureka-client 依赖jar包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>spring-cloud-config-config3344</finalName>
    </build>
</project>

写yml

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      label: master      #搜索目录
      server:
        git:
          uri: https://gitee.com/the-first-chord-of-the-moon_0/springcloud-config.git
          search-paths:
            - springcloud-config # 搜索的文件夹

#将服务注册到eureka中
eureka:
  client:
    register-with-eureka: true   #表示自己注册到eurekaServer中默认是true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版

主启动类

认真的观察yml文件,可以看到我们使用到了gitee中的文件,所以我们需要在gitee中创建一个仓库名为springcloud-config,然后添加文件config-dev.yml,添加内容。

 

运行项目,连接 端口。

成功的打通了,可以从gitee中获取信息。

编写一个config-client配置的客户端 

Config客户端配置和测试——Cloud-config-Client3355

首先先创建一个bootstrap.yml,这是系统级的,优先级比application.yml要高

Application.yml是用户级的资源配置项

加载时bootstrap.yml先加载,所以这次我们不创建application.yml文件,创建bootstrap.yml文件

server:
  port: 3355
spring:
  application:
    name: config-client
  cloud:
    #config客户端的配置
    config:
      label: master      #分支名称
      name: config  #配置文件名称
      profile: dev  #读取后缀名称
      uri: https://localhost:3344  #配置中心地址

eureka:
  client:
    register-with-eureka: true   #表示自己注册到eurekaServer中默认是true
    fetch-registry: true
    service-url:

通过两个的对比可以知道

他不会主动的去找gitee,而是去3344端口找能够匹配到的

 

 创建主启动类,加载到eureka服务中

@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientMain3355.class,args);
    }
}

 业务——控制类

@RestController
@Slf4j
@RefreshScope
public class ConfigClientController {
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo() {
        return configInfo;
    }
}

这是3344端口读到的

 

这是3355端口读到的

动态刷新(手动)

所以我们开始配置config的动态刷新

改pom,添加一个actuator监控

除了网关不加这个依赖其他的项目都会加这个依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

在yml中添加一个配置

#rabbitmq相关配置,暴露bus刷新配置的端点
management:
  endpoints: #暴露bus刷新配置的端点
    web:
      exposure:
        include: 'bus-refresh'

在控制类中添加一个@RefreshScope 刷新的功能

重新的启动33555端口,

然后在gitee中修改config-dev.yml文件

 

访问3344端口发现3344端口的信息变了,

但是访问3355端口,信息没有改变

 为什么呢,是因为需要运维人员使用post发送一个刷新的请求,这样3355端口才能改变。

重新刷新3355端口可以发现信息更新了。

 

这是动态刷新手动版。

 

但是这样的有问题的。

为了解决这个问题,引出一个新的概念,消息总线!!!

消息总线

Springcloud bus配合 Spring Cloud Config 使用可以实现配置的动态刷新。

Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。

环境和需要的软件配置和安装

安装Erlang,下载地址:http://erlang.org/download/otp_win64_21.3.exe 

安装RabbitMQ,下载地址:

https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe

这两个软件安装的时候一直next就行了,安装的地方可以自定义

安装完成后打开rabbitMQ的sbin目录,运行环境。

输入cmd打开窗口输入rabbitmq-plugins enable rabbitmq_management执行

安装完成后就可以在windows系统可以看到可视化图形

  

启动后,访问地址http://localhost:15672查看是否成功

账号和密码都是guest

动态刷新全局广播

模仿3355端口复制出一个3366端口,然后使用总线来控制他们实现动态刷新,

3366端口除了名字和端口号有区别外其他一样。

总线的设计思想

 

 

通知总控,然后由总控通知其他的实例,由总控来承担刷新的功能。

继续,在3344端口服务端增加总线的支持,改pom加依赖

<!--添加消息总线RabbitMQ支持-->

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-bus-amqp</artifactId>

</dependency>

然后改3344端口的yml,增加rabbitMQ的配置和增加暴露bus刷新配置的端点。

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      label: master      #搜索目录
      server:
        git:
          uri: https://gitee.com/the-first-chord-of-the-moon_0/springcloud-config.git
          search-paths:
            - springcloud-config # 搜索的文件夹
#rabbitmq相关配置
rabbitmq:
  host: localhost
  port: 5672
  username: guest
  password: guest

#rabbitmq相关配置,暴露bus刷新配置的端点
management:
  endpoints: #暴露bus刷新配置的端点
    web:
      exposure:
        include: 'bus-refresh'

#将服务注册到eureka中
eureka:
  client:
    register-with-eureka: true   #表示自己注册到eurekaServer中默认是true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版

 接下来修改3355和3366端口的pom和yml

也是添加依赖

<!--添加消息总线RabbitMQ支持-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

 yml添加rabbit相关的配置

server:
  port: 3355
spring:
  application:
    name: config-client2
  cloud:
    #config客户端的配置
    config:
      label: master      #分支名称
      name: config-dev  #配置文件名称
      profile: yml  #读取后缀名称
      uri: http://localhost:3344  #配置中心地址

eureka:
  client:
    register-with-eureka: true   #表示自己注册到eurekaServer中默认是true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版
#rabbitmq相关配置
rabbitmq:
  host: localhost
  port: 5672
  username: guest
  password: guest
#暴露监控的端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

3366端口的修改和3355的一致

修改完成后

运行项目,然后修改gitee中config-dev.yml文件的内容

启动项目,访问 3344

访问3355和3366

 

打开cmd发送post请求,刷新,一次发送处处生效。

curl -X POST "http://localhost:3344/actuator/bus-refresh"

 刷新3355和3366可以发现内容已经修改了

 

 这样就达到了广播通知的效果,一处修改处处生效的功能。

Bus动态刷新定点通知

就是不想全部通知,只想定点通知,指定某个实例生效而不是全部,比如只通知3355,不通知3366。

修改gitee文件内容,在post中做事情,定点通知。

在cmd中使用命令

curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"

刷新,3355修改了被通知到了

3366没有修改,没被通知到

这样子就完成了精确的通知。

这次有点长因为是学了好几天的但是没有将其总结到csdn中。

Logo

更多推荐