Springcloud学习笔记(五)

Springcloud学习笔记(五)

八月 18, 2019

四、Feign负载均衡

1、概述

官网地址:http://cloud.spring.io/spring-cloud-openfeign/single/spring-cloud-openfeign.html

是一个声明式Webservice客户端,,使得编写web服务客户端变得非常容易

==只需要创建一个接口,然后再上面添加注解即可==

面向接口编程,比如webservice接口

  • 微服务名称获得调用地址

  • 通过接口+注解,获得调用服务

    统一面向接口的编程套路—feign

    前面再使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成一套模板化的调用方法,但是在实际的开发中,由于对服务依赖的调用可能不止一处,==往往一个接会被多处调用,所以通常会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用==。所以,Feign在此基础上做了一些封装,由他来帮助我么定义和实现依赖服务接口的定义。在Feign的实现下,==我们只需要创建一个接口并使用注解的方式来配置它==(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对位服务提供方便的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。

2、Feign的使用步骤

参考springcloud-study-consumer-dept-80模块,新建springcloud-study-consumer-dept-feign模块

  • 修改pom文件

    1
    2
    3
    4
    5
    <!--增加Feign的依赖-->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>
  • 修改主启动类

  • 修改springcloud-study-api

    • pom文件修改

      添加Feign支持依赖,与springcloud-study-consumer-dept-feign一致

    • 新建DeptClientService接口类,并增加注解@FeignClient

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      @FeignClient(value = "STUDY-SPRINGCLOUD-DEPT")
      public interface DeptClientService {
      @RequestMapping(value = "/dept/add",method = RequestMethod.GET)
      public boolean add( DeptEntity deptEntity);

      @RequestMapping(value = "/dept/findById/{deptNo}",method = RequestMethod.GET)
      public DeptEntity findById(Long deptNo);

      @RequestMapping(value = "/dept/findAll",method = RequestMethod.GET)
      public List findAll();
      }
  • 在springcloud-study-consumer-dept-feign修改Controller,修改基于上述配置的接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @RestController
    public class DeptConsumerController {
    @Autowired
    private DeptClientService deptClientService;
    @RequestMapping(value = "/consumer/dept/add")
    public boolean add( DeptEntity deptEntity){
    //三个参数:url,requestMap ResponseBean.class
    return deptClientService.add(deptEntity);
    }
    @RequestMapping("/consumer/dept/findById/{deptNo}")
    public DeptEntity findById(Long deptNo){
    //三个参数:url,requestMap ResponseBean.class
    return deptClientService.findById(deptNo);
    }
    @RequestMapping("/consumer/dept/findAll")
    public List findAll(){
    //三个参数:url,requestMap ResponseBean.class
    return deptClientService.findAll();
    }
    }
  • 修改Feign模块主启动类,增加@EnableFeignClients注解

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootApplication
@EnableEurekaClient
/**
* 在启动该微服务式是能去加载我们定义的Feign配置类
*/
@EnableFeignClients(basePackages = "com.gxs.springcloud")
@ComponentScan("com.gxs.springcloud")
public class DeptConsumerFeignApp {
public static void main(String[] args) {
SpringApplication.run(DeptConsumerFeignApp.class,args);
}
}

3、Feign集成了Ribbon

利用Ribbon维护了STUDY-SPRINGCLOUD-DEPT的服务列表,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,==通过Feign只需要定义服务绑定接口且以声明式的方法==,优雅的而简单的实现了服务调用。

4、小结

Feign通过接口的方法调用Rest服务(之前是Ribbon+RestTemplate)

该请求发送给Eureka服务器(http://STUDY-SPRINGCLOUD-DEPT/depe/findAll)通过Feign直接找到服务接口,由于再进行服务调用时候融合了Ribbon技术,所以也支持负载均衡

五、Hystrix 断路器

1、概述

分布式面临的问题

复杂分布式体系结构复杂的依赖关系,不可避免的存在服务宕机,网络中断的问题

  • 服务雪崩

    多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的服务,这就是所谓的==扇出==。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的==雪崩效应==。

    对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源的紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

Hystrix介绍

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,==不会导致整个服务失败,避免级联故障,以提高分布式系统的弹性==。

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

2、服务熔断

应对雪崩效应的一种微服务链路保护机制,快速返回错误的响应信息。

熔断机制的注解:@HystrixCommand

1、参考springcloud-study-provider-dept-8001新建,springcloud-study-provider-dept-hystrix-8001模块

  • pom文件新增
1
2
3
4
5
<!--Hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
  • yml文件修改实例id

    1
    2
    #服务实例名称修改
    instance-id: study-springcloud-dept8001-hystrix
  • 修改DeptController

    用HystrixCommand报异常后如何处理

    一旦服务调用失败并抛出错误信息后,会自动调用@HystrixCommand标注好的fallBackMethod调用类中知道的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @RequestMapping(value = "/dept/findById/{deptNo}",method = RequestMethod.GET)
    public DeptEntity findById(Long deptNo) {
    DeptEntity deptEntity = deptService.findById(deptNo);
    if(null ==deptEntity){
    throw new RuntimeException("该deptNo没有对应的信息"+deptNo);
    }
    return deptEntity;
    }

    public DeptEntity processHystrixGet(Long deptNo){
    return new DeptEntity().setDeptNo(deptNo)
    .setDeptName("该deptNo没有对应的信息")
    .setDbSource("没有这个数据库");
    }
  • 在主启动类上添加==@EnableCircuitBreaker==

3、服务降级

整体资源不够了,忍痛将某些服务先关掉,待度过难关后再开启。

资源的抢占和分配

所谓降级,一般是从整体负荷考虑,当某个服务熔断后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值,这样做,虽然服务水平下降,好歹能用,比直接改掉要强。

==服务降级是在客户端(消费者)处理完成的,与服务端没关系==

1、修改springcloud-study-api模块

  • 根据已有的com.gxs.springcloud.service.DeptClientService接口,新建一个实现FallBackFactory接口的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//@Component 不要忘记添加
//主业务与熔断方法解耦
@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory<DeptClientService> {
@Override
public DeptClientService create(Throwable throwable) {

return new DeptClientService() {

@Override
public boolean add(DeptEntity deptEntity) {
return false;
}

@Override
public DeptEntity findById(Long deptNo) {
return new DeptEntity().setDeptNo(deptNo)
.setDeptName("该deptNo没有对应的信息,Consumer客户端提供的降级信息,此刻服务provider已经关闭")
.setDbSource("没有这个数据库");
}

@Override
public List findAll() {
return null;
}
};
}
}
  • 在DeptClientService中的FeignClient注解中添加FallBackfactory属性值

    1
    2
    @FeignClient(value = "STUDY-SPRINGCLOUD-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)
    public interface DeptClientService {
  • springcloud-study-consumer-dept-feign修改yml

    1
    2
    3
    feign:
    hystrix:
    enable: ture;

4、HystrixDashboard

1、概述

除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续的记录所有通过Hystrix发起的请求的执行信息,并统计报表和图形的形式展示给用户,包括每秒执行多少次清酒,多少成功,多少失败等。Netflix通过Hystrix-metrics-event-stream项目实现了对以上指标的监控。spring cloud 也提供了对Hystrix Dashboard的整合,对监控内容转化成可视化的界面。

2、构建步骤

  • 构建模块项目springcloud-study-consumer-hystrix-dashboard

  • pom文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    <?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>
    <parent>
    <groupId>com.gxs.springcloud</groupId>
    <artifactId>spring-cloud-study</artifactId>
    <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>springcloud-study-consumer-hystrix-dashboard</artifactId>

    <dependencies>
    <dependency>
    <groupId>com.gxs.springcloud</groupId>
    <artifactId>springcloud-study-api</artifactId>
    <version>${project.version}</version>
    </dependency>

    <!--Ribbon相关引用-->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <!--增加Feign的依赖-->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>

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

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    </dependency>

    <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</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-test</artifactId>
    </dependency>
    <!--热部署 修改后立即生效-->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>springloaded</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    </dependency>
    </dependencies>
    </project>
  • yml文件

    1
    2
    server:
    port: 9001
  • 主启动类

    1
    2
    3
    4
    5
    6
    7
    @SpringBootApplication
    @EnableHystrixDashboard
    public class HystrixDashboardApp {
    public static void main(String[] args) {
    SpringApplication.run(HystrixDashboardApp.class,args);
    }
    }
  • 所有provider微服务提供类(8001、8002、8002)都需要监控依赖配置

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  • 启动,访问地址http://localhost:9001/hystrix

填写监控