SpringCloud-熔断器Hystrix

SpringCloud-熔断器Hystrix

项目结构

在这里插入图片描述
在这里插入图片描述

父工程(每一个服务都是一个子工程)

  1. pom.xml

    <?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.xiaoge.demo</groupId>
        <artifactId>hystrix-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>user-service</module>
            <module>consumer-demo</module>
            <module>eureka-server</module>
        </modules>
        <packaging>pom</packaging>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.SR1</spring-cloud.version>
            <mapper.starter.version>2.0.3</mapper.starter.version>
            <mysql.version>5.1.32</mysql.version>
        </properties>
    
        <dependencyManagement> <!-- 所有子工程, 必须引下面的依赖才会有 -->
            <dependencies>
                <!-- spring cloud 引用了它, 以后cloud依赖版本就不用写了 -->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
    
                <!-- 通用Mapper启动器 -->
                <dependency>
                    <groupId>tk.mybatis</groupId>
                    <artifactId>mapper-spring-boot-starter</artifactId>
                    <version>${mapper.starter.version}</version>
                </dependency>
    
                <!-- mysql驱动 -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
    
            </dependencies>
        </dependencyManagement>
    
        <dependencies> <!-- 因为不会再dependencyManagement标签里, 所以所有的子工程都可以用 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

consumer-demo服务

  1. 配置文件

    1. pom.xml

      <?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">
          <parent>
              <artifactId>hystrix-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>consumer-demo</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
      
              <!-- 引入eureka客户端依赖 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
      
              <!-- 引入负载均衡 ribbon -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
              </dependency>
      
              <!-- 导入hystrix依赖 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
              </dependency>
      
          </dependencies>
      
      </project>
      
    2. application.yml

      server:
        port: 8088
      spring:
        # 在eureka中注册的服务名称
        application:
          name: consumer-service
      
      # 注册方
      # eureka配置 因为它要去注册中心注册, 所以要配置
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka, http://127.0.0.1:10087/eureka # 配置所有的eureka地址, 防止其中一个eureka挂掉
          registry-fetch-interval-seconds: 3 # 设置拉取服务列表的周期 为3秒
          fetch-registry: true # 默认为true 拉取列表, 改为false 不拉取
        instance:
          prefer-ip-address: true # 我希望使用ip地址
          ip-address: 127.0.0.1 # 设置ip地址
      # 对那个服务实现负载均衡
      user-service: # 对user-service服务 (服务名称)
        ribbon: # 固定写法
          NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 使用负载均衡随机算法, 默认是轮询
      
      # 设置hystrix的默认指令
      hystrix:
        command:
          default:
            execution:
              isolation:
                thread:
                  timeoutInMilliseconds: 3000  # 设置全局方法 的 超时 时间 为 3秒  超过  3秒  执行错误方法
          # user-service: # 只针对一个的时候  (这里写服务名称 或者 方法名称)
          #   execution:
          #     isolation:
          #       thread:
          #         timeoutInMilliseconds: 3000  # 设置全局方法 的 超时 时间 为 3秒  超过  3秒  执行错误方法
      
  2. 启动类

    1. ConsumerApplication

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.SpringCloudApplication;
      import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.cloud.client.loadbalancer.LoadBalanced;
      import org.springframework.context.annotation.Bean;
      import org.springframework.web.client.RestTemplate;
      
      /**
       * @program: cloud-demo
       * @description: 服务调用方
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:04
       **/
      // @EnableCircuitBreaker // hystrix注解
      // @EnableDiscoveryClient // 它也是客户端, 它捷能兼容eureka 又能consul、zookeeper等等, 更通用, 更广泛
      // @SpringBootApplication
      
      @SpringCloudApplication // 它的功能就是上面三个注解的功能
      public class ConsumerApplication {
      
          @Bean
          @LoadBalanced // 加上ribbon 负载均衡注解
          public RestTemplate restTemplate() {
              return new RestTemplate();
          }
      
          public static void main(String[] args) {
              SpringApplication.run(ConsumerApplication.class);
          }
      
      }
      
      
  3. 实体类

    1. User

      package com.xiaoge.Consumer.pojo;
      
      import lombok.Data;
      
      import java.io.Serializable;
      import java.util.Date;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:06
       **/
      @Data
      public class User implements Serializable {
          // 主键
          private Long id;
      
          // 用户名
          private String username;
      
          // 密码
          private String password;
      
          // 姓名
          private String name;
      
          // 年龄
          private Integer age;
      
          // 性别,1男性,2女性
          private Integer sex;
      
          // 出生日期
          private Date birthday;
      
          // 创建时间
          private Date created;
      
          // 更新时间
          private Date updated;
      
          // 备注
          private String note;
      
      }
      
  4. 表现层

    1. ConsumerController

      package com.xiaoge.Consumer.controller;
      
      import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
      import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
      import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
      import com.xiaoge.Consumer.pojo.User;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.cloud.client.discovery.DiscoveryClient;
      import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.client.RestTemplate;
      
      import java.util.List;
      
      /**
       * @program: cloud-demo
       * @description: 动态拉取服务列表
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:08
       **/
      @RestController
      @RequestMapping("/consumer")
      @DefaultProperties(defaultFallback = "defaultFallback") // 针对这个类下面的所有方法
      public class ConsumerController {
      
          @Autowired
          private RestTemplate restTemplate;
      
          @Autowired
          private DiscoveryClient discoveryClient; // 专门负责服务发现
      
          //@Autowired
          //private RibbonLoadBalancerClient client; // 专门负责 负载均衡 获取服务的
      
      
          /*
              @GetMapping("/{id}")
              public User queryById(@PathVariable("id") Long id){
                  // 负载均衡算法: 随机, 轮询. hash
      
                  // 1. 在注册restTemplate上加注解@LoadBalanced
      
                  // 2. 直接写路径
                  String url = "http://user-service/user/" + id;
                  User user = restTemplate.getForObject(url, User.class);
                  return user;
              }
          */
      
          @GetMapping("/{id}")
          /*
               @HystrixCommand(fallbackMethod = "queryByIdFallback") // 开启服务的线程隔离 和 降级处理 和指定错误方法 (只是针对这个方法)
      
               @HystrixCommand(commandProperties = {  HystrixCommand 开启线程隔离 和 降级处理
                       @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") // 设置超时时长3秒, 3秒没有响应, 执行错误方法
               })  类上面配置了错误方法, 我这里只需要  开启线程隔离 和 降级处理 和 给这个方法设置超时时长
      
               想要整体配置只能写在 配置文件里
          */
      
          // @HystrixCommand  开启线程隔离 和 降级处理
          @HystrixCommand(
                  commandProperties = {
                          // 设置断路器请求量预值, 每10次统计一次
                          @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
                          // 休眠时间窗 10秒
                          @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
                          // 错误百分比 60%
                          @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
      
                  }
          )
          public String queryById(@PathVariable("id") Long id){
              // 负载均衡算法: 随机, 轮询. hash
      
              // 1. 在注册restTemplate上加注解@LoadBalanced
      
              // 2. 直接写路径
              if (id % 2 == 0) {
                  throw new RuntimeException("");
              }
              String url = "http://user-service/user/" + id;
              String user = restTemplate.getForObject(url, String.class);
              return user;
          }
      
          /**
           * 调用失败时, 启动的方法 (这个方法必须跟成功的方法的  返回值  参数列表  必须完全一样  因为是一对一的)
           * @param id
           * @return
           */
          /*public String queryByIdFallback(@PathVariable("id") Long id){
              return "不好意思, 服务器太拥挤了!";
          }*/
      
          /**
           * 因为类上面写的是通用的错误方法, 所以这里不能写参数, 返回值写String就行了.
           * @return
           */
          public String defaultFallback(){
              return "不好意思, 服务器太拥挤了!";
          }
      
      }
      
      

eureka-server服务

  1. 配置文件

    1. pom.xml

      <?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">
          <parent>
              <artifactId>hystrix-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>eureka-server</artifactId>
      
          <dependencies>
              <!-- springcloud 注册中心 eureka -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
              </dependency>
          </dependencies>
      
      </project>
      
    2. application.yml

      # 这是eureka的默认端口号
      server:
        port: 10086
      
      # 配置eureka服务名称
      spring:
        application:
          name: eureka-server
      
      # 注册方
      # 告诉eureka要注册的地址在哪里 (这样eureka就不会报一个com.sun.jersey.api.client.ClientHandlerException异常)
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka # 配置所有的eureka地址, 防止其中一个eureka挂掉
          register-with-eureka: false  # 默认为true 注册自己, 改为false 不 注册自己
        instance:
          prefer-ip-address: true # 我希望使用ip地址
          ip-address: 127.0.0.1 # 设置ip地址
        server:
          eviction-interval-timer-in-ms: 60000 # 设置eureka失效剔除时长, 每隔60秒失效剔除一次, 失效剔除挂掉的eureka
      
      
  2. 启动类

    1. EurekaServer

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
      
      /**
       * @program: cloud-demo
       * @description: EurekaServer端
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:34
       **/
      @EnableEurekaServer // 启动Eureka服务
      @SpringBootApplication
      public class EurekaServer {
      
          public static void main(String[] args) {
              SpringApplication.run(EurekaServer.class);
          }
      
      }
      
      

user-service服务

  1. 配置文件

    1. pom.xml

      <?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">
          <parent>
              <artifactId>hystrix-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>user-service</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
      
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
              </dependency>
      
              <dependency>
                  <groupId>tk.mybatis</groupId>
                  <artifactId>mapper-spring-boot-starter</artifactId>
              </dependency>
      
              <!-- 引入eureka(注册中心)-客户端 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
          </dependencies>
      
      </project>
      
    2. application.yml

      server:
        port: 9090
      spring:
        # 在eureka中注册的服务名称
        application:
          name: user-service
        # 数据库连接信息配置
        datasource:
          url: jdbc:mysql://localhost:3306/yun6
          username: root
          password: root
          hikari:
            maximum-pool-size: 20
            minimum-idle: 10
      # 别名包
      mybatis:
        type-aliases-package: com.xiaoge.user.pojo
      
      # 注册方
      # eureka配置 因为它要去注册中心注册, 所以要配置
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka, http://127.0.0.1:10087/eureka # 配置所有的eureka地址, 防止其中一个eureka挂掉
        instance:
          prefer-ip-address: true # 我希望使用ip地址
          ip-address: 127.0.0.1 # 设置ip地址
          lease-renewal-interval-in-seconds: 30 # 每隔30秒发一次心跳
          lease-expiration-duration-in-seconds: 90 # 每隔30秒发一次心跳, 如果隔了90秒都没发, 那就证明挂了
      
  2. 启动类

    1. UserApplication

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
      import tk.mybatis.spring.annotation.MapperScan;
      
      /**
       * @program: cloud-demo
       * @description: 服务的提供方
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:43
       **/
      @EnableDiscoveryClient // 它也是客户端, 它捷能兼容eureka 又能consul、zookeeper等等, 更通用, 更广泛
      @SpringBootApplication
      @MapperScan("com.xiaoge.user.mapper")
      public class UserApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(UserApplication.class);
          }
      
      }
      
  3. 实体类

    1. User

      package com.xiaoge.user.pojo;
      
      import lombok.Data;
      import tk.mybatis.mapper.annotation.KeySql;
      
      import javax.persistence.Id;
      import javax.persistence.Table;
      import java.io.Serializable;
      import java.util.Date;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:46
       **/
      @Table(name = "tb_user")
      @Data
      public class User implements Serializable {
      
          @Id
          @KeySql(useGeneratedKeys = true) // id自动增长
          private Long id;
      
          // 用户名
          private String username;
      
          // 密码
          private String password;
      
          // 姓名
          private String name;
      
          // 年龄
          private Integer age;
      
          // 性别,1男性,2女性
          private Integer sex;
      
          // 出生日期
          private Date birthday;
      
          // 创建时间
          private Date created;
      
          // 更新时间
          private Date updated;
      
          // 备注
          private String note;
      
      }
      
  4. 表现层

    1. UserController

      package com.xiaoge.user.controller;
      
      import com.xiaoge.user.pojo.User;
      import com.xiaoge.user.service.UserService;
      import org.apache.tomcat.jni.Time;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:51
       **/
      @RestController
      @RequestMapping("/user")
      public class UserController {
      
          @Autowired
          private UserService userService;
      
          @GetMapping("/{id}")
          public User queryById(@PathVariable("id") Long id) {
              User user = userService.queryById(id);
              return user;
          }
      
      }
      
  5. 业务层

    1. UserService接口

      package com.xiaoge.user.service;
      
      import com.xiaoge.user.pojo.User;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:50
       **/
      public interface UserService {
      
          public User queryById(Long id);
      
      }
      
    2. UserServiceImpl实体类

      package com.xiaoge.user.service.impl;
      
      import com.xiaoge.user.mapper.UserMapper;
      import com.xiaoge.user.pojo.User;
      import com.xiaoge.user.service.UserService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:51
       **/
      @Service
      public class UserServiceImpl implements UserService {
      
          @Autowired
          private UserMapper userMapper;
      
          @Override
          public User queryById(Long id) {
              return userMapper.selectByPrimaryKey(id);
          }
      }
      
  6. Mapper

    1. UserMapper

      package com.xiaoge.user.mapper;
      
      
      import com.xiaoge.user.pojo.User;
      import tk.mybatis.mapper.common.Mapper;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:49
       **/
      
      public interface UserMapper extends Mapper<User> {
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

只因为你温柔

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值