美文网首页
微服务集成hystrix

微服务集成hystrix

作者: 刘小刀tina | 来源:发表于2020-03-10 20:05 被阅读0次

1. spring cloud集成hystrix

定义


1 服务降级

image.png image.png

2 服务熔断

image.png

3 hystrix dashboard 仪表盘

a) hystrix dashboard 端
第一步  pom.xml

        <!--hystrix 仪表盘的依赖包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

==========================================================
第二步 启动类

@EnableHystrixDashboard
@SpringBootApplication
public class HystrixdashboardOrder9001 {

    public static void main(String[] args) {
        SpringApplication.run(HystrixdashboardOrder9001.class,args);
    }
}

==========================================================
b) 被检测的服务端
第一步 pom.xml引入相关的依赖
<!--actuator信息完善 后,方可以被hystrix dashboard监控 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-actuator</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

==========================================================
第二步 启动类(加注解 + 额外添加一个新的方法)
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient //表明是eureka客户端
@EnableCircuitBreaker //开启hystrix功能
public class HystrixPaymentApplication8001 {

   public static void main(String[] args) {
       SpringApplication.run(HystrixPaymentApplication8001.class,args);
   }

   /**
    *配置 hystris  dashbaord 须添加的额外方法
    */
   @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;
   }
}
==========================================================

4. Spring boot 整合hystrix 实现服务降级 服务熔断 代码

服务提供者

pom.xml
    <dependencies>
        <!--actuator信息完善 后,方可以被hystrix dashboard监控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--添加hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>


        <!--添加common 通用包-->
        <dependency>
            <artifactId>springcloud-api-common</artifactId>
            <groupId>com.tina.springcloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--添加swagger2依赖的jar包-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.6.1</version>
        </dependency>


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

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

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--添加热部署的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--   引入eureka客户端     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
==========================================================
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient //表明是eureka客户端
@EnableCircuitBreaker //开启hystrix功能
public class HystrixPaymentApplication8001 {

    public static void main(String[] args) {
        SpringApplication.run(HystrixPaymentApplication8001.class,args);
    }

    /**
     *配置 hystris  dashbaord 须添加的额外方法
     */
    @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;
    }

}
==========================================================
配置文件
#设置端口号
server:
  port: 8001

##设置name
spring:
  #配置mysql数据源
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://152.136.27.48:3306/d_xiaokai?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
  #配置热部署
  devtools:
    restart:
      enabled: true
  application:
    name: springcloud-payment-hystrix-service

#注册到eureka
eureka:
  client:
    register-with-eureka: true   #是否将自己注册到注册中心,集群必须设置为true配合ribbon
    fetch-registry: true    #是否从服务端抓取已有的注册信息
    service-url:
      defaultZone: http://springcloud-eureka-server7001:7001/eureka,http://springcloud-eureka-server7002:7002/eureka
  instance:
    instance-id:  springcloud-payment-hystrix-service
    prefer-ip-address: true  #访问路径可以显示IP地址
    lease-renewal-interval-in-seconds: 1  #向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
    lease-expiration-duration-in-seconds: 2 #收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除


#开启eureka负载均衡策略
ribbon:
  eureka:
    enabled: true
==========================================================
service   层

/**
 * @program: springcloud2020
 * @description
 * @author: tina.liu
 * @create: 2020-03-10 10:56
 **/
@Service
public class PaymentService {

    /**
     * 服务熔断
     * commandKey = "findUserById", groupKey = "UserGroup", threadPoolKey = "findUserByIdThread"
     */
    @HystrixCommand(fallbackMethod = "payment_circuit_breaker_fallback"//指定专属的回调函数
//            commandProperties = {
//                    @HystrixProperty(name ="circuitBreaker.enable",value = "true"),//是否开启熔断器
//                    @HystrixProperty(name ="circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数
//                    @HystrixProperty(name ="circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间窗口
//                    @HystrixProperty(name ="circuitBreaker.errorThresholdPercentage",value = "60")//失败率达到多少后跳闸
//            }
            )
    public  String paymentCircuitBreaker(@PathVariable(value = "id") Integer id){
        if(id<0){
            throw new RuntimeException("****id不能为负数***");
        }else {
            String serialNumber  = IdUtil.simpleUUID();//利用糊涂工具生成一个随机的ID不含"-"
            return Thread.currentThread().getName()+"调用成功的流水号为:"+serialNumber;
        }
    }

    //专属的回调方法(不能带参数)
    public String payment_circuit_breaker_fallback(){
        return "id的值不能为负数,请稍后再重试";
    }

    //专属的回调方法(不能带参数)
    public String payment_circuit_breaker_fallback(@PathVariable(value = "id") Integer id){
        return "id的值不能为负数,请稍后再重试";
    }


    public  String paymentInfo_ok(Integer id){
        return "线程池"+Thread.currentThread().getName()+"方法 PaymentService ,id的值为"+id;
    }

    /**
     * 服务降级
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
    })
    public  String paymentInfo_TimeOut(Integer id){
        if(id<0){
            throw new RuntimeException("****id不能为负数***");
        }else {
            String serialNumber  = IdUtil.simpleUUID();//利用糊涂工具生成一个随机的ID不含"-"
            return Thread.currentThread().getName()+"调用成功的流水号为:"+serialNumber;
        }
//        int timeNumber = 5 ;
////        try {
////            TimeUnit.SECONDS.sleep(timeNumber);
////        } catch (InterruptedException e) {
////            e.printStackTrace();
////        }
//        int i =10/0 ;
//        return "线程池"+Thread.currentThread().getName()+"方法 paymentInfo_TimeOut ,id的值为"+id;
    }

    public String paymentInfo_TimeOutHandler(Integer id){
        return "线程池"+Thread.currentThread().getName()+"方法 paymentInfo_TimeOutHandler ,id的值为"+id+"服务降级";
    }

}

==========================================================
controller 
@RestController
@Slf4j
public class PaymentController {

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

        @Resource
        private PaymentService paymentService ;

        //服务熔断测试
        @GetMapping(value = "/payment/circuit/{id}")
        public  String paymentCircuitBreaker(@PathVariable(value = "id") Integer id){
          return  paymentService.paymentCircuitBreaker(id);
        }

        @GetMapping(value = "/payment/paymentInfo_TimeOut/{id}")
        public  String paymentInfo_TimeOut(@PathVariable(value = "id") Integer id){
            return paymentService.paymentInfo_TimeOut(id);
        }

        @GetMapping(value = "/payment/paymentInfo_ok/{id}")
        public  String paymentInfo_ok(@PathVariable(value = "id") Integer id){
           return paymentService.paymentInfo_ok(id);
        }

}
==========================================================

服务消费者

pom.xml
    <dependencies>

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


        <!--添加common 通用包-->
        <dependency>
            <artifactId>springcloud-api-common</artifactId>
            <groupId>com.tina.springcloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--添加swagger2依赖的jar包-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.6.1</version>
        </dependency>

        <!--添加openFeign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>

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


        <!-- boot web actuator -->
        <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>
        </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-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>
==========================================================
启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient //表明是eureka的客户端
@EnableFeignClients //开启openFeign
@EnableCircuitBreaker //开启hystrix
public class HystrixOrderApplication8002 {

    public static void main(String[] args) {
        SpringApplication.run(HystrixOrderApplication8002.class,args);
    }
}

==========================================================
配置文件
server:
  port: 8002

eureka:
  client:
    register-with-eureka: true   #是否将自己注册到注册中心
    fetch-registry: true    #是否从服务端抓取已有的注册信息
    service-url:
      defaultZone: http://springcloud-eureka-server7001:7001/eureka,http://springcloud-eureka-server7002:7002/eureka
  instance:
    instance-id: springcloud-consumer-feign-hystrix-order
    prefer-ip-address: true   #访问路径可以显示IP地址

spring:
  application:
    name: springcloud-consumer-feign-hystrix-order


# 配置feign的日志级别,以什么级别监视哪个接口
logging:
  level:
    com.tina.consumer.openfeign.service.PaymentFeignService: debug

#用户服务降级,设置为true,可以在注解@FeignClient中添加fallbackFactory
feign:
  hystrix:
    enabled: true
==========================================================
service
接口
@Component
@org.springframework.cloud.openfeign.FeignClient(value = "SPRINGCLOUD-PAYMENT-HYSTRIX-SERVICE",fallback = PaymentFeignClientFallBack.class )
public interface PaymentFeignClient {

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

    @GetMapping(value = "/payment/paymentInfo_ok/{id}")
    public  String paymentInfo_ok(@PathVariable(value = "id") Integer id);
   
}
==========================================================
回调函数
@Component
public class PaymentFeignClientFallBack implements PaymentFeignClient {
    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "服务消费者8002,PaymentFeignClientFallBack类,paymentInfo_TimeOut方法的服务降级";
    }

    @Override
    public String paymentInfo_ok(Integer id) {
        return "服务消费者8002,PaymentFeignClientFallBack类,paymentInfo_ok方法的服务降级";
    }
}
==========================================================
controller
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallBackMethod")
public class ConsumerController {

    @Resource
    private PaymentFeignClient paymentFeignClient ;


    /**
     * 服务降级
     * @param id
     * @return
     */

    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000")
    })//有指定的专属方法 就执行专属方法,没的话就是执行默认的方法
   @GetMapping(value = "/consumer/payment/paymentInfo_TimeOut/{id}")
    //@HystrixCommand
    public  String paymentInfo_TimeOut(@PathVariable(value = "id") Integer id){
        int i = 10/0;
        return paymentFeignClient.paymentInfo_TimeOut(id);
    };


    //定义一个全局的降级方法  ps 一定要写两个方法 (无参数方法和有参数方法)
    public String payment_Global_FallBackMethod(@PathVariable(value = "id") Integer id){
        return "Global服务消费者8001对方系统繁忙或者一次";
    }
    public String payment_Global_FallBackMethod(){
        return "Global服务消费者8001对方系统繁忙或者一次";
    }

    //定义一个专属对象的回调方法
    public  String paymentInfo_TimeOutHandler(@PathVariable(value = "id") Integer id){
        return "我是服务消费者8001,执行服务降级";
    }

    @GetMapping(value = "/consumer/payment/paymentInfo_ok/{id}")
    public  String paymentInfo_ok(@PathVariable(value = "id") Integer id){
        return paymentFeignClient.paymentInfo_ok(id);
    };

}

==========================================================

相关文章

网友评论

      本文标题:微服务集成hystrix

      本文链接:https://www.haomeiwen.com/subject/cuwidhtx.html