【SpringCloud】SpringCloud基础教程(5)
前言:
本文内容:Feign:使用接口方式调用服务、Hystrix:服务熔断、服务降级
推荐免费SpringCloud基础教程视频:【狂神说Java】SpringCloud最新教程IDEA版_哔哩哔哩_bilibili
Feign:使用接口方式调用服务
简介
Feign是声明式的web service客户端,它让微服务的调用变得更简单了,类似Controller调用service。SpringCloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。
只需要创建一个接口,然后添加注解即可!
Feign的作用
- Feign意在使编写Java Http客户端变得更容易
- 使用Ribbon+RestTemplate时,利用RestTemplate对Http请求封装处理,形成了一套模板化的调用方法,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它,(类似于以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可)即可完成对服务提供方的接口绑定。
- Feign集成了Ribbon
简单体验
-
复制
springcloud-consumer-dept-80
Module为新的springcloud-consumer-dept-feign
-
在
pom
下添加依赖1
2
3
4
5<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency> -
修改主启动类名字为
FeignDeptConsumer_80
,并修改代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package com.jokerdig.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
/**
* @author Joker大雄
* @data 2022/8/3 - 15:28
**/
public class FeignDeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(FeignDeptConsumer_80.class,args);
}
} -
删除
myrule
包及包下所有类 -
打开
springcloud-api
,新建com.jokerdig.springcloud.service
包 -
在
pom
下添加依赖1
2
3
4
5<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency> -
在
service
包下新建DeptClientService
接口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
26package com.jokerdig.springcloud.service;
import com.jokerdig.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/8 - 11:07
**/
public interface DeptClientService {
public Dept queryById(; Long id)
public List<Dept> queryAll();
public boolean addDept();
} -
修改
springcloud-consumer-dept-feign
下的DeptConsumerController
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
43package com.jokerdig.springcloud.controller;
import com.jokerdig.springcloud.pojo.Dept;
import com.jokerdig.springcloud.service.DeptClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 15:10
**/
public class DeptConsumerController {
// 消费者不会有service
// RestTemplate 供我们调用
// {url,实体:Map,Class<T> responseType}
private DeptClientService deptClientService = null;;
// Feign实现
// 添加
public boolean add(Dept dept){
return this.deptClientService.addDept(dept);
}
// 通过id查询
public Dept get({ Long id)
return this.deptClientService.queryById(id);
}
// 查询
public List<Dept> queryAll(){
return this.deptClientService.queryAll();
}
} -
启动7001,8001,8002,fegin,运行测试
http://localhost/consumer/dept/list
1
[{"deptno":1,"dname":"开发部","db_source":"db01"},{"deptno":2,"dname":"生产部","db_source":"db01"},{"deptno":3,"dname":"研发部","db_source":"db01"},{"deptno":4,"dname":"人事部","db_source":"db01"},{"deptno":5,"dname":"运维部","db_source":"db01"}]
Hystrix:服务熔断
什么是Hystrix
提到Hystrix
就不得不提雪崩效应,什么是“雪崩效应”?
多个微服务之间调用的时候,假设A调用B和C,B和C又在调用其他的微服务,这种情况被称为扇出,这个时候有一个微服务出现问题,或这长时间未响应,对A微服务的占用的越来越多的系统资源,这就是所谓的“雪崩效应“
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,是对雪崩效应的一种微服务链路的保护机制。避免连级故障,提高分布式系统弹性。
断路器本身是一种开关装置,但某个服务单元发生故障,通过断路器的故障监控,向调用方返回一个服务预期且可处理的备选响应(FallBack),而不是长时间等待或抛出异常,避免服务方线程被长时间不必要的占用,避免发生雪崩问题。
Hystrix主要功能
-
服务降级
-
服务熔断
-
服务限流
-
实时监控
服务熔断
服务熔断是应对雪崩效应的一种微服务链路保护机制,注解:@HystrixCommand
当调用链路的某个微服务不可用或者响应时间太长时,会进行服务熔断,不再有该节点微服务的调用,快速返回错误的响应信息。在Spring Cloud框架里,熔断机制通过Hystrix实现。 Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。
简单测试
-
复制项目
springcloud-provider-dept-8001
为springcloud-provider-dept-hystrix-8001
-
修改主启动类名为
HystrixDeptProvider_8001
,并启动Hystrix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package com.jokerdig.springcloud;
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 org.springframework.cloud.netflix.hystrix.EnableHystrix;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:34
**/
// 启动类
//开启eureka
// 服务发现
public class HystrixDeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDeptProvider_8001.class,args);
}
} -
在
pom
文件中引入依赖1
2
3
4<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency> -
修改controller包下的
DeptController
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
39package com.jokerdig.springcloud.controller;
import com.jokerdig.springcloud.pojo.Dept;
import com.jokerdig.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:29
**/
// 提供Restful服务
public class DeptController {
DeptService deptService;
public Dept get({ Long id)
Dept dept = deptService.queryById(id);
if(dept==null){
throw new RuntimeException("id=>"+id+",该用户不存在");
}
return dept;
}
// 备选方案
public Dept hystrixGet({ Long id)
return new Dept()
.setDeptno(id)
.setDname("id=>"+id+",该用户不存在")
.setDb_source("no this database in MySQL");
}
} -
运行7001,hystrix进行测试
http://localhost:8001/dept/get/1
1
{"deptno":1,"dname":"开发部","db_source":"db01"}
http://localhost:8001/dept/get/9
1
{"deptno":9,"dname":"id=>9,该用户不存在","db_source":"no this database in MySQL"}
Hystrix:服务降级
什么是服务降级
服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的备选响应(FallBack)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。
服务熔断和降级
相同点:
- 目标一致 都是从可用性和可靠性出发,为了防止系统崩溃;
- 用户体验类似 最终都让用户体验到的是某些功能暂时不可用;
不同点:
- 触发原因不同 服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
简单测试
-
在
springcloud-api
的service
包下新建DeptClientServiceFallbackFactory
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
40package com.jokerdig.springcloud.service;
import com.jokerdig.springcloud.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/8 - 12:42
**/
// 降级
public class DeptClientServiceFallbackFactory implements FallbackFactory {
public DeptClientService create(Throwable cause) {
return new DeptClientService() {
public Dept queryById(Long id) {
return new Dept()
.setDeptno(id)
.setDname("id=>"+id+",服务端提供了降级信息,该服务暂时无法访问")
.setDb_source("暂时无法获取数据库信息");
}
public List<Dept> queryAll() {
return null;
}
public boolean addDept(Dept dept) {
return false;
}
};
}
} -
修改
service
包下的DeptClientService
1
-
配置
springcloud-consumer-dept-feign
下的application
1
2
3
4
5
6
7
8
9
10
11
12
13server:
port: 80
# Eureka
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002,http://eureka7003.com:7003
# 开启服务降级
feign:
hystrix:
enabled: true -
启动7001,8001,feign,进行测试
http://localhost/consumer/dept/get/1
1
{"deptno":1,"dname":"开发部","db_source":"db01"}
关闭8001,访问:http://localhost/consumer/dept/get/1
1
{"deptno":1,"dname":"id=>1,服务端提供了降级信息,该服务暂时无法访问","db_source":"暂时无法获取数据库信息"}