SpringCloud中的一些常用的开源框架(一)

版权声明:@Wrial https://blog.csdn.net/qq_42605968/article/details/88431437

在SpringCloud中继承了很多比较好的开源框架,并且可以通过简单的配置更方便的使用它。下面我就来闲聊几个常用的框架。

Hystrix

  • hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制。
  • 在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败。
  • Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
    使用步骤:
    1.导入Hystrix所需的依赖(主要是针对于消费方consumer)
<!--豪猪,防御机制-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

2.导入后再在启动类加上启用Hystrix的注解,可以导入Spring Cloud Application代替前边的所有注解

//@Hystrix 引入熔断就不用引入这个注解
//@EnableCircuitBreaker //熔断hystrix
//@EnableDiscoveryClient//eureka
//@SpringBootApplication
@SpringCloudApplication//里边包含有前面四个注解
public class ConsumerApplication {
    @Bean
    @LoadBalanced//负载均衡,内置拦截器拦截RestTemplate的请求
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

}

3.在控制层配置fallback

  • 方法级别:方法级别的降级必须要保持参数还有返回值的一致!
    先在controller里新建一个FallBack方法
    public String quaryByIdFallBack(@PathVariable("id") Integer id) {//测试的话可以在user-service那加上线程休眠让它强制超时。
        return "你好,服务器忙,请稍后再试!";
    }

然后在特定的方法上绑定FallBack方法,如果出现访问超时,或者异常就会自动执行FallBack方法

    @GetMapping("/{id}")
    @HystrixCommand(fallbackMethod ="quaryByIdFallBack" )//开启失败容错,在回滚方法的返回值必须和此方法一致,参数类型也要一致
    public Order quaryById(@PathVariable("id") Integer id) {
        String url = "http://order-service/order/" + id;//配置main中注解,拦截
        return restTemplate.getForObject(url, Order.class);
    }
  • 类级别:类级别的是在类中通用,如果要使用的话只需要加上HystrixCommand注解。类级别的方法不能写任何参数,因为它根本不知道调用者的参数是什么。
    先写一个FallBack,不能带任何参数
  public String defaultFallBack() {//测试的话可以在user-service那加上线程休眠让它超时。
        return "你好,服务器忙,请稍后再试!";
    }

然后在类上写注解DefaultProperties

@DefaultProperties(defaultFallback = "defaultFallBack")//此处声明此类的容错方法,如果需要在方法中使用的话只需要加上@HystrixCommand注解
//但是不能再容错方法里写任何参数,因为你不能保证容错方法中的参数适合其他方法

然后在特定方法上使用,也可以给特殊的方法如方法级别一样编写特定的降级操作

    @GetMapping("/{id}")
    @HystrixCommand//如果在类上说明了的话就不用配置fallbackMethod
    public String quaryById(@PathVariable("id") Integer id) {
        String url = "http://order-service/order/" + id;//配置main中注解,拦截
        return restTemplate.getForObject(url, String.class);
    }

4.在控制层配置熔断
熔断:就和家里的保险丝一样,到达一定的温度就断了,以防止出现更大的问题。我们的程序出现一定的异常比(说明程序有问题或者是一些不确定因素的抖动),consumer就会出现熔断,在完成修改或者抖动结束后方可访问。
在熔断中得引入几个概念,我们进入HystrixCommandProperties,里面定义了很多的默认常量,
在这里插入图片描述

采取熔断的量:就是我们必须满足20次才能使用熔断,这个我们会在下面示例中用到,因为我手动测试20次有些多,我设置的比较少方便测试。

    private static final Integer default_circuitBreakerRequestVolumeThreshold = 20;// default => statisticalWindowVolumeThreshold: 20 requests in 10 seconds must occur before statistics matter

error阈值百分比:就是如果有百分之50的异常或者超时请求那么就会采取熔断

    private static final Integer default_circuitBreakerErrorThresholdPercentage = 50;// default => errorThresholdPercentage = 50 = if 50%+ of requests in 10 seconds are failures or latent then we will trip the circuit

熔断窗口睡眠时间:就是熔断后5s后才可以再次访问此页面

     private static final Integer default_circuitBreakerSleepWindowInMilliseconds = 5000;// default => sleepWindow: 5000 = 5 seconds that we will sleep before trying again after tripping the circuit

执行超时时间:就是如果一个请求时间超过1s,那就判定它超时了

    private static final Integer default_executionTimeoutInMilliseconds = 1000; // default => executionTimeoutInMilliseconds: 1000 = 1 second

强制打开熔断

    private static final Boolean default_circuitBreakerForceOpen = false;// default => forceCircuitOpen = false (we want to allow traffic)

执行时间可以超时

    private static final Boolean default_executionTimeoutEnabled = true;

这些都是一些关于熔断的默认配置,在项目中可能不会用到,但是在测试中可能会用到一些。

这些属性可以在yml文件中如此配置

#配置默认hystrix的超时时间,IDEA没有提示
hystrix:
  command:
    default:
      isolation:
          thread:
            timeoutInMilliseconds: 3000

也可以在类上或方法上配置

    @GetMapping("/{id}")
   //    @HystrixCommand(commandProperties = {
   //            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")//因为每个服务需要的时间不同,根据默认属性设置采取容错的最大时间(系统默认1s)
   //    })                                                                                    //也可以在yaml中配置默认,但是没有提示
       @HystrixCommand//在yaml配置了3秒,运行后成功!,如果要配置个性的时间,可参考上边配置
       public String quaryByIdTest(@PathVariable("id") Integer id) {
           String url = "http://order-service/order/" + id;//配置main中注解,拦截
           return restTemplate.getForObject(url, String.class);
       }

因此我为了方便测试熔断效果,我更改为了以下配置,并且我用if语句来触发异常(异常可以造成熔断),发生熔断后,再访问奇数id,发现还是提示的FallBack内容,过滤5s就又可以访问了!

@GetMapping("/{id}")
@HystrixCommand(commandProperties = {
        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "6"),//设置阈值为6默认20,如果超过三次出错就说明有问题,开发基本不用调
        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//沉睡时间窗,默认5s
        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")//错误百分比
})
public String quaryById(@PathVariable("id") Integer id) {
        if(id%2==0){
            throw new RuntimeException("触发!");
        }
    String url = "http://order-service/order/" + id;
    return restTemplate.getForObject(url, String.class);
}

在这里插入图片描述
这个我就用到这里,它里面还包含线程池什么的后边用的时候再说!

OpenFeign

在微服务设计里,服务之间的调用是很正常的,通常我们使用httpClient来实现对远程资源的调用,而这种方法需要知识服务的地址,业务接口地址等,而且需要等他开发完成后你才可以去调用它,这对于集成开发来说是一件很不好的事,产生了A业务与B业务的强依赖性,openfeign就可以对它进行很好的解耦。
1.引入依赖

<!--伪装,用于伪装自己的url路径,可以通过SpringMVC注解自动识别url,先引入依赖,在给核心类加注解,编写接口并用注解声明url参数,在controller注入接口,使用已经注入的接口进行调用或者返回-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.在核心加载类中加上它的注解,当然这里也就不需要restTemplate了,因为用不到HTTP Client了。

@SpringCloudApplication
@EnableFeignClients      //注解Feign
public class ConsumerApplication {
//    @Bean
//    @LoadBalanced//负载均衡,内置拦截器拦截RestTemplate的请求
//    public RestTemplate restTemplate() {
//        return new RestTemplate();
//    }

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

}

3.编写伪装接口,当然它只能支持restful风格(个人理解是如果传进去两个参数的话他就不能知道下一步的动作是什么了),它可以把请求根据SpringMVC注解配置来生成Restful风格,并且也减少了控制层代码。

//feign内部有实现Fallback的策略,必须继承OrderClient才能使用
@FeignClient(value = "order-service",fallback =FallBack.class )//表名服务名称然后在eureka上找,在下面声明url的所有信息
@Component
public interface OrderClient {
    @GetMapping("/order/{id}")
    String quaryById(@PathVariable("id") Integer id);
}

4.如果需要实现伪装接口里的方法的FallBack时,在feign内部有fallback策略,实现这个接口就ok

@Component//加入容器
public class FallBack implements OrderClient {
    @Override
    public String quaryById(Integer id) {
        return "quaryById失败!";
    }
}

5.在controller中使用

  @Autowired
    OrderClient orderClient;//注入接口后就不需要再使用rest Template进行远程调用,也支持负载均衡

    @GetMapping("/{id}")
    @HystrixCommand//如果在类上说明了的话就不用配置fallbackMethod
    public String quaryById(@PathVariable("id") Integer id) {
        return orderClient.quaryById(id);
    }


一些疑问:
如果我同时在Hystrix和feign中同时写了fallback方法,那到底是采用谁的呢?
时间发现先采用Hystrix,如果Hystrix没有才能使用feign的fallback。

在feign中也有ribbon(负载均衡)和hystrix(保护机制)的支持,因此也可以不用引入ribbon和hystrix的依赖,下边是一些设置

#使用feign要设置ribbon的配置和spring有一些区别
#配置ribbon的连接超时时长和获取超时时长的配置
ribbon:
  ConnectionTimeOut: 5000
  ReadTimeOut: 2000
feign:
  hystrix:
    enabled: true     #开启feign的熔断功能

这次就主要聊一聊这两个。

猜你喜欢

转载自blog.csdn.net/qq_42605968/article/details/88431437
今日推荐