《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
- 接近实时的监控
四、服务熔断
=======
4.1 介绍
熔断机制是赌赢雪崩效应的一种微服务链路保护机制。
当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阀值缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是:@HystrixCommand。
4.2 搭建服务熔断
4.2.1 建立一个父工程Maven
编写pom.xml:
org.springframework.cloud
spring-cloud-alibaba-dependencies
0.2.0.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR12
pom
import
org.springframework.boot
spring-boot-dependencies
2.3.12.RELEASE
pom
import
4.2.2 建立子工程
注:同样是Maven。
职责:
springcloud-api:存放实体类和需要调用的接口(service)
springcloud-eureka-7001:服务注册中心
springcloud-consumer-blog-feign-80:服务消费方
springcloud-provider-hystrix-8001:服务生产方
4.2.3 配置springcloud-eureka-7001
(1)建立以下目录
(2)导入依赖
org.springframework.cloud
spring-cloud-starter-eureka-server
1.4.6.RELEASE
org.springframework.boot
spring-boot-devtools
(3)编写配置文件
application.yml:
server:
port: 7001
Eureka配置
eureka:
instance:
Eureka服务端的实例名字
hostname: localhost
client:
表示是否向 Eureka 注册中心注册自己(这个模块本身是服务器,所以不需要)
register-with-eureka: false
fetch-registry如果为false,则表示自己为注册中心,客户端的化为 ture
fetch-registry: false
Eureka监控页面~
service-url:
defaultZone: http:// e u r e k a . i n s t a n c e . h o s t n a m e : {eureka.instance.hostname}: eureka.instance.hostname:{server.port}/eureka/
(4)编写启动类EurekaServer_7001
package com.yixin.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class,args);
}
}
4.2.4 配置springcloud-provider-hystrix-8001
注意:我们就是在该项目即服务的生产方使用熔断服务。
(1)建立以下目录
(2)导入依赖 导入Hystrix依赖。
org.springframework.cloud
spring-cloud-starter-hystrix
1.4.6.RELEASE
org.springframework.cloud
spring-cloud-starter-eureka
1.4.6.RELEASE
org.springframework.boot
spring-boot-test
2.4.5
org.springframework.boot
spring-boot-starter-web
2.4.5
org.springframework.boot
spring-boot-devtools
(3)编写配置文件
application.yml:
server:
port: 8001
spring:
application:
name: springcloud-provider-blog
Eureka配置:配置服务注册中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-8001 #修改Eureka上的默认描述信息
(4)编写BlogController
package com.yixin.springcloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BlogController {
//表示db这个数据库
@Value(“dbsource”)
private String dbsource;
//如果根据id查询出现异常,则走hystrixGet这段备选代码
@HystrixCommand(fallbackMethod = “hystrixGet”)
@GetMapping(“/blog/info/{id}”)
public String getInfo(@PathVariable(“id”) Integer id){
if(id==0){//id为0就会抛出异常
throw new RuntimeException(“这个id=>”+id+“,不可以为0”);
}
return dbsource+id;
}
public String hystrixGet(@PathVariable(“id”) Integer id){
return dbsource+“的id不可以为”+id;
}
}
(5)编写启动类BlogProvider_8001
注意:为主启动类添加对熔断的支持注解@EnableCircuitBreaker。
package com.yixin.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker // 添加对熔断的支持注解
public class BlogProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(BlogProvider_8001.class,args);
}
}
4.2.5 配置springcloud-api
(1)建立以下目录
(2)导入依赖
org.springframework.cloud
spring-cloud-starter-feign
1.4.6.RELEASE
org.projectlombok
lombok
(3)编写BlogClientService
package com.yixin.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
//value就是我们服务生产方在注册中心的服务名
@FeignClient(value = “SPRINGCLOUD-PROVIDER-BLOG”)
public interface BlogClientService {
@GetMapping(“/blog/info/{id}”)
public String getInfo(@PathVariable(“id”) Integer id);
}
4.2.6 配置springcloud-consumer-blog-feign-80
(1)建立以下目录
(2)导入依赖
org.springframework.cloud
spring-cloud-starter-feign
1.4.6.RELEASE
com.yixin
springcloud-api
1.0-SNAPSHOT
org.springframework.cloud
spring-cloud-starter-eureka
1.4.6.RELEASE
org.springframework.boot
spring-boot-test
2.4.5
org.springframework.boot
spring-boot-starter-web
2.4.5
org.springframework.boot
spring-boot-devtools
(3)编写配置文件
server:
port: 8000
spring:
application:
name: springcloud-consumer-blog
Eureka配置:配置服务注册中心地址
eureka:
client:
register-with-eureka: false # 不向 Eureka注册自己
service-url:
defaultZone: http://localhost:7001/eureka/
(4)编写BlogConsumerController
package com.yixin.springcloud.controller;
import com.yixin.service.BlogClientService;
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.RestController;
@RestController
public class BlogConsumerController {
//这个就是我们springcloud-api下的接口
@Autowired
private BlogClientService blogClientService;
@GetMapping(“/consumer/blog/{id}”)
public String get(@PathVariable(“id”) Integer id){
return “消费端:”+blogClientService.getInfo(id);
}
}
(5)编写启动类BlogConsumer_feign_80
package com.yixin.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;
@SpringBootApplication
@EnableEurekaClient
// feign客户端注解,并指定要扫描的包以及配置接口BlogClientService
@EnableFeignClients(basePackages = {“com.yixin.service”})
public class BlogConsumer_feign_80 {
public static void main(String[] args) {
SpringApplication.run(BlogConsumer_feign_80.class,args);
}
}
至此,我们的熔断服务就搭建好了。
4.2.7 测试
依次启动:
a、springcloud-eureka-7001:服务注册中心
b、springcloud-provider-hystrix-8001:服务生产方
c、springcloud-consumer-blog-feign-80:服务消费方
访问:http://localhost:7001/
(1)如果出现以下界面,则说明成功绑定我们的服务生产方了。
(2)接下来我们来进行服务消费方的测试。
规则:不可输入id=0的请求。
我们先正常访问:http://localhost:8000/consumer/blog/1
(3)如果我们进行不正常访问,看下效果。
非正常访问:http://localhost:8000/consumer/blog/0
可以发现,它给予了我们友好的提示,而这个提示就是我们用熔断机制写的! 如果不写熔断机制,那么其输出会变成如下图,非常不友好!
因此,为了避免因某个微服务后台出现异常或错误而导致整个应用或网页报错,使用熔断是必要的!
五、服务降级
======
5.1 介绍
服务降级就是当服务器压力剧增的情况下,整体资源快不够了,忍痛将某些服务单元先关掉,关闭后还要返回一些可处理的备选方法,待渡过难关,再开启回来,就是尽可能的把系统资源让给优先级高的服务。
5.2 为什么要服务降级?
资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证核心功能服务的可用性,都要对某些服务降级处理。比如当双11活动时,把交易无关的服务统统降级,如查看蚂蚁深林,查看历史订单等等。
如下图可知,当某一时间内服务A的访问量暴增,而B和C的访问量较少,为了缓解A服务的压力,这时候需要B和C暂时关闭一些服务功能,去承担A的部分服务,从而为A分担压力,叫做服务降级。
5.3 服务降级需要考虑的问题
- 那些服务是核心服务,哪些服务是非核心服务
- 那些服务可以支持降级,那些服务不能支持降级,降级策略是什么
- 除服务降级之外是否存在更复杂的业务放通场景,策略是什么?
5.4 自动降级分类
(1)超时降级:主要配置好超时时间和超时重试次数和机制,并使用异步机制探测回复情况。
(2)失败次数降级:主要是一些不稳定的api,当失败调用次数达到一定阀值自动降级,同样要使用异步机制探测回复情况。
(3)故障降级:比如要调用的远程服务挂掉了(网络故障、DNS故障、http服务返回错误的状态码、rpc服务抛出异常),则可以直接降级。降级后的处理方案有:默认值(比如库存服务挂了,返回默认现货)、兜底数据(比如广告挂了,返回提前准备好的一些静态页面)、缓存(之前暂存的一些缓存数据)。
(4)限流降级:秒杀或者抢购一些限购商品时,此时可能会因为访问量太大而导致系统崩溃,此时会使用限流来进行限制访问量,当达到限流阀值,后续请求会被降级;降级后的处理方案可以是:排队页面(将用户导流到排队页面等一会重试)、无货(直接告知用户没货了)、错误页(如活动太火爆了,稍后重试)。
5.5 搭建服务降级
我们只需修改我们的以上的项目即可实现。
步骤一:增加一个没有熔断机制的springcloud-provider-blog-8001
(1)导入依赖
org.springframework.cloud
spring-cloud-starter-eureka
1.4.6.RELEASE
org.springframework.boot
spring-boot-test
2.4.5
org.springframework.boot
spring-boot-starter-web
2.4.5
org.springframework.boot
spring-boot-devtools
(2)编写配置类
server:
port: 8001
spring:
application:
name: springcloud-provider-blog
Eureka配置:配置服务注册中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-8001 #修改Eureka上的默认描述信息
(3)编写BlogController
package com.yixin.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BlogController {
//表示dbsource这个数据库
@Value(“dbsource”)
private String dbsource;
//注册进来的微服务,获取一些消息
@GetMapping(“/blog/info/{id}”)
public String getInfo(@PathVariable(“id”) Integer id){
//id不可以为0
if(id==0){
throw new RuntimeException(“这个id=>”+id+“,不可以为0”);
}
return dbsource+id;
架构学习资料
由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
instance:
instance-id: springcloud-provider-dept-8001 #修改Eureka上的默认描述信息
(3)编写BlogController
package com.yixin.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BlogController {
//表示dbsource这个数据库
@Value(“dbsource”)
private String dbsource;
//注册进来的微服务,获取一些消息
@GetMapping(“/blog/info/{id}”)
public String getInfo(@PathVariable(“id”) Integer id){
//id不可以为0
if(id==0){
throw new RuntimeException(“这个id=>”+id+“,不可以为0”);
}
return dbsource+id;
架构学习资料
[外链图片转存中…(img-aeivv0To-1714749517008)]
[外链图片转存中…(img-MM1saXfR-1714749517009)]
[外链图片转存中…(img-mB2ga0gF-1714749517009)]
[外链图片转存中…(img-Jk6hlHSS-1714749517009)]
[外链图片转存中…(img-3IMd1w11-1714749517009)]
由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!