Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,是以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。
Feign被广泛应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。
**封装了Http调用流程,更符合面向接口化的编程习惯。**类似Dubbo服务调用。
使用Feign代替RestTemplate发送Rest请求,使之更符合面向接口化的编程习惯。
先来看看RestTemplate方式调用存在的问题
java代码方式,需要先声明一个bean
由于默认的URLConnection不支持连接池,性能较差,所以需要配置连接池来优化性能。
实际业务中,需要对连接数和最大连接数的数值进行测试和调整,以达到最佳性能。
FeignClient的代码与Provider的controller代码高度相似
原因:
OrderService之所以能访问到UserService,是基于UserClient声明的请求路径请求参数等信息,那么OrderService基于这些信息发送了HTTP请求,而UserService中controller的信息如果与UserClient声明的不一致,那么就无法与OrderService匹配。
UserClient
UserController
存在一定问题
降低了耦合度,调用方便
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
在order-service的pom文件中中引入feign-api的依赖:
<dependency>
<groupId>cn.itcast.demogroupId>
<artifactId>feign-apiartifactId>
<version>1.0version>
dependency>
删除相关import,IDEA会自动完成导包操作
进行测试,发现服务报错
这是因为UserClient现在在 cn.itcast.feign.clients 包下,不在order-service的启动类的SpringBootApplication的扫描范围内,导致UserClient无法创建对象。
推荐方式二,更加精准。
给@EnableFeignClients添加clients = {UserClient.class} 参数
网关的技术实现
引入依赖
<dependencies>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
dependencies>
编写路由配置及nacos地址
server:
port: 10010
spring:
application:
name: gateway #服务实例名称
cloud:
nacos:
server-addr: nacos:8848 # nacos地址
gateway:
routes: #网关路由配置
- id: user-service # 路由标示,必须唯一
uri: lb://userservice # 路由的目标地址
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
网关服务的流程图
总结
断言工厂Route Predicate Factory
成功
PredicateFactory的作用是什么?
读取用户定义的断言条件,对请求做出判断
Path=/user/**是什么含义?
路径是以/user开头的就认为是符合的
对进入网关的请求和微服务返回的响应做处理
Spring提供了31中不同的路由过滤器工厂。
详情可查看spring官方文档-GatewayFilter Factories
对所有路由都生效,可以自定义过滤逻辑,用于处理复杂业务
//@Order(-1)
//@Component注解,将类注入到Spring容器中,作为Bean
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2.获取参数中的 authorization 参数
String auth = params.getFirst("authorization");
// 3.判断参数值是否等于 admin
if ("admin".equals(auth)) {
// 4.是,放行
return chain.filter(exchange);
}
// 5.否,拦截
// 5.1.设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2.拦截请求
return exchange.getResponse().setComplete();
}
//表示过滤器的顺序,return 的值越小,优先级越高
//也可以用@Order(-1)代替
@Override
public int getOrder() {
return -1;
}
}
跨域:域名不一致就是跨域