目录
一、Feign整合Sentinel
第1步: 引入sentinel的依赖
第2步: 在配置文件中开启Feign对Sentinel的支持
第3步: 创建容错类(假设关掉所有的product他就会去找容错类,而不是直接报错)
第4步: 为feign的接口指定容错类
第5步: 修改controller
测试:关闭所有的product让rpc远程调用失效。
二、springcloud整合Spring Cloud Gateway
微服务被访问分为内部访问和外部访问:
使用网关的好处:
第一步:还原版本
第二步:(注意要将此模块注册到nacos上,配置文件中也要配置)
那么我们的路径是怎么从localhost:7000/product-serv/product/1
变成的localhost:8081/product/1的呢?
实验:去除nacos的注册
?增强版 (避免把url写死)
第1步:加入nacos依赖
第2步:在主类上添加注解
第三步:修改配置文件
接下来帮order模块也加上网关。
sentinel启动命令:
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.0.jar
一、Feign整合Sentinel
第1步: 引入sentinel的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
第2步: 在配置文件中开启Feign对Sentinel的支持
feign:
sentinel:
enabled: true
第3步: 创建容错类(假设关掉所有的product他就会去找容错类,而不是直接报错)
//容错类要求必须实现被容错的接口,并为每个方法实现容错方案
@Component
@Slf4j
public class ProductServiceFallBack implements ProductService {
@Override
public Product findByPid(Integer pid) {
Product product = new Product();
product.setPid(-1);
return product;
}
}
第4步: 为feign的接口指定容错类
/**
* @author Dragon code!
* @create 2022-05-04 15:42
*/
//fallback用于指定容错类
@FeignClient(value = "service-product",fallback = ProductServiceFallBack.class)//声明调用的提供者的name
public interface ProductService {
@GetMapping(value = "/product/{pid}")
Product findByPid(@PathVariable("pid") Integer pid);
}
第5步: 修改controller
/**
* @author Dragon code!
* @create 2022-05-04 16:46
*/
@RestController
@Slf4j
public class OrderController {
@Resource
private OrderService orderService;
@Resource
private ProductService productService;
@RequestMapping("/order/prod/{pid}")
public Order save(@PathVariable Integer pid){
log.info("准备调用商品服务查询商品信息");
//直接使用微服务名字, 从nacos中获取服务地址
String url = "service-product";
//通过fegin调用商品微服务
Product product = productService.findByPid(pid);
//当前微服务不能被访问
if (product.getPid() == -1){
Order order = new Order();
order.setPname("请求失败");
return order;
}
log.info("商品微服务返回的商品"+ JSON.toJSONString(product));
log.info("创建订单对象");
Order order = new Order();
order.setPname(product.getPname());
order.setPprice(product.getPprice());
order.setNumber(1);
order.setPid(product.getPid());
order.setUsername("测试用户");
orderService.save(order);
return order;
}
}
测试:关闭所有的product让rpc远程调用失效。
访问端口发现没有报错误,还是有结果。此时就是容错类起作用了!
二、springcloud整合Spring Cloud Gateway
Spring Cloud Gateway是Spring公司基于Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代Netflex Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。
优点:
性能强劲:是第一代网关Zuul的1.6倍
功能强大:内置了很多实用的功能,例如转发、监控、限流等
设计优雅,容易扩展
缺点:
其实现依赖Netty(当今最好的底层通讯框架)与WebFlux,不是传统的Servlet编程模型,学习成本高
不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行
需要Spring Boot 2.0及以上的版本,才支持
局域网开放对外部的访问。
微服务被访问分为内部访问和外部访问:
对于网关来讲,主要强调微服务被外部访问的时候是存在一些问题的。
- 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
- 认证复杂,每个服务都需要独立认证。
- 存在跨域请求,在一定场景下处理相对复杂。
使用网关的好处:
提供统一(有标准规则)的访问路径。
可以把一些公共的代码由网关去实现,这些代码与我们的核心业务代码没有关系。
第一步:还原版本
第二步:(注意要将此模块注册到nacos上,配置文件中也要配置)
创建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>com.lay</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shop-gateway</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
</dependencies>
</project>
配置文件: application.yml
server:
port: 7000
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
- id: product_route # 当前路由的标识, 要求唯一
uri: http://localhost:8081 # 请求要转发到的地址
order: 1 # 路由的优先级,数字越小级别越高
predicates: # 断言(就是路由转发要满足的条件)
- Path=/product-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发
filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
- StripPrefix=1 # 转发之前去掉1层路径
启动项目, 并通过网关去访问微服务:访问成功!
那么我们的路径是怎么从localhost:7000/product-serv/product/1
变成的localhost:8081/product/1的呢?
?首先断言匹配自定义访问路径(product-serv),那么通过StripPrefix直接将product-serv这层路径去掉!然后转发到我们自定义的路径。结果就是端口号修改为8081且product-serv这层路径被去掉。
实验:去除nacos的注册
?
?
结果是虽然后台报错,但是还是能正常使用
?
?增强版 (避免把url写死)
现在在配置文件中写死了转发路径的地址, 前面我们已经分析过地址写死带来的问题, 接下来我们从注册中心获取此地址。
第1步:加入nacos依赖
spring-cloud-starter-alibaba-nacos-discovery
第2步:在主类上添加注解
@EnableDiscoveryClient
第三步:修改配置文件
server:
port: 7000
spring:
application:
name: service-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# gateway:
# routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
# - id: product_route # 当前路由的标识, 要求唯一
# uri: http://localhost:8081 # 请求要转发到的地址
# order: 1 # 路由的优先级,数字越小级别越高
# predicates: # 断言(就是路由转发要满足的条件)
# - Path=/product-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发
# filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
# - StripPrefix=1 # 转发之前去掉1层路径
#增强版配置写法
gateway:
discovery:
locator:
enabled: true # 让gateway可以发现nacos中的微服务
routes:
- id: product_route
uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates:
- Path=/product-serv/**
filters:
- StripPrefix=1
?同样是访问成功!
?
接下来帮order模块也加上网关。
做法是在配置文件中加上多个id来实现多个网关。
server:
port: 7000
spring:
application:
name: service-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# gateway:
# routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
# - id: product_route # 当前路由的标识, 要求唯一
# uri: http://localhost:8081 # 请求要转发到的地址
# order: 1 # 路由的优先级,数字越小级别越高
# predicates: # 断言(就是路由转发要满足的条件)
# - Path=/product-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发
# filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
# - StripPrefix=1 # 转发之前去掉1层路径
#增强版配置写法
gateway:
discovery:
locator:
enabled: true # 让gateway可以发现nacos中的微服务
routes:
- id: product_route
uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates:
- Path=/product-serv/**
filters:
- StripPrefix=1
- id: order_route
uri: lb://service-order # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates:
- Path=/order-serv/**
filters:
- StripPrefix=1
可以看到同样是成功了。
?
|