@SentinelResource
自定义异常返回是对所有的情况进行统一处理,但针对一些特定的情况我们要单独处理
代码示例:
@RestController @Slf4j public class AnnoController { //设置流控规则 qp=3 //访问/anno1达到阈值,调用annolBlockHandler方法,并返回内容 // @RequestMapping("/anno1") @SentinelResource(value = "anno1", blockHandler = "annoBlockHandles",//当前方法如果被限流或者被降级会调用这个字符串对应的方法 fallback = "annoFallback")//当方法出现异常之后,会调用这个字符串对应的方法 public String anno1(String name){ if("wolfcode".equals(name)){ throw new RuntimeException(); } return "anno1"; } public String annoBlockHandles(String name, BlockException ex){ log.error("{}",ex); return "接口被限流或者降级了"; } //Throwable时进入的方法 public String annoFallback(String name,Throwable throwable){ log.error("{}",throwable); return "接口发生异常了"; } }
blockHandler:当方法如果被限流或者被降级会调用这个字符串对应的方法
falback:当方法出现异常之后,会调用这个字符串对应方法
设置的流控规则 qps=3
访问/anno1 ==>达到阈值,调用anno1BlockHandler方法,并返回内容
访问/anno1?name="wolfback"
Feign整合Sentinel
什么场景下需要Feign集合Sentinel呢?
比如我们在购物的时候,查看商品详情页面的时候,里面包含库存信息,商品详情信息,评论信息,这个需求包含的微服务如下:
假设现在评论服务宕机了,那是不是意味用户发出查看商品请求也无法正常显示了,商品都看不到了,那用户也无法进行下单的操作了.但是对于用户来说,评论看不到并不影响他购物,所以这时候我们应该对评论服务进行及·降级处理,返回一个兜底数据(空数据),这样用户的查看商品请求能正常显示,只是评论数据看不到而已,这样的话,用户的下单请求也不会受到影响.
正常情况下:
若商品服务挂了:
解决方案:
创建容错类:
@Component public class ProductFeignFallback implements ProductFeignApi { @Override public Product findByPid(Long pid) { System.out.println("返回兜底数据"); return new Product(); } }
创建feign接口定义容错类
//远程调用服务名称 @FeignClient(name = "product-service",fallback = ProductFeignFallback.class) public interface ProductFeignApi { @RequestMapping("/product/{pid}") Product findByPid(@PathVariable("pid") Long pid); }
在shop-order-server项目的配置文件中开启feign对Sentinel的支持
feign: sentinel: enabled: true
运行结果:
服务网关
为什么需要网关
1.记录很多的服务地址
2.在后端微服务做集群的情况下,前端需要进行负载均衡
3.微服务的统一处理逻辑,需要在每个微服务中都实现一次
网关组件
统一请求入口,进行统一逻辑的处理,对后端微服务集群进行负载均衡,网络的隔离
实现步骤
1.网关获取到请求地址,默认截取域名后面的部分请求路径 product-serve
2.拿到路径信息和路由规则进行匹配,可以获取到对应的服务名product-service
3.拿到服务名在本地的缓存列表中找到对应的ip地址
4.进行URL地址拼接 http://192.168.10.110/product/1进行网络的调用
Gateway快速入门
什么是Gateway
Spring Cloud Gateway是Spring公司基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。它的目标是替代Netflflx Zuul,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控和限流。
操作示例
1.创建一个api-gateway的模块,导入相关依赖
<?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"> <parent> <artifactId>shop-parent</artifactId> <groupId>cn.wolfcode</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>api-gateway</artifactId> <dependencies> <!--gateway网关--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--nacos客户端--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
2.编写启动类
@SpringBootApplication @EnableDiscoveryClient public class ApiGatewayServer { public static void main(String[] args) { SpringApplication.run(ApiGatewayServer.class,args); } }
3.编写配置文件
server: port: 9000 spring: application: name: api-gateway cloud: nacos: discovery: server-addr: localhost:8848 gateway: discovery: locator: enabled: true #让gateway可以发现nacos中的微服务
测试:
自定义路由规则
spring: application: name: api-gateway cloud: nacos: discovery: server-addr: 192.168.80.131:8848 gateway: discovery: locator: enabled: true #让gateway可以发现nacos中的微服务 routes: - id: product_route uri: lb://product-service predicates: - Path=/product-serv/** filters: - StripPrefix=1 - id: order_route uri: lb://order-service predicates: - Path=/order-serv/** filters: - StripPrefix=1
id:路由名称,保证唯一
uri: 将符合条件的请求转发到哪个微服务,1b表示对服务进行负载均衡
predicates:拦截那些请求
filters:在转发请求之前,将拦截到的路径的第一层路径删除掉