微服务调用常见问题
常见的现象
-
客户端会多次请求不同的微服务,增加了客户端的复杂性。
-
存在跨域请求,在一定场景下处理相对复杂。
-
认证复杂,每个服务都需要独立认证。
-
难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通讯,那么重构将会很难实施。
-
某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有一定困难。
使用网关优点:
-
易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析。
-
易于认证。可在微服务网关上进行认证。然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
-
减少了客户端与各个微服务之间的交互次数。
Gateway网关创建
1、创建网关工程
启动类打上客户端注解 @EnableDiscoveryClient
@EnableDiscoveryClient //网关相对于客户端,启用
@SpringBootApplication
public class DmwGatewayServerApplication {
public static void main(String[] args) {
SpringApplication.run(DmwGatewayServerApplication.class, args);
}
}
2、配置yml文件
server:
port: 6666
spring:
application:
name: gateway-server #应用程序名称
cloud:
gateway:
routes:
- id: dmw-user-consumer
uri: lb://dmw-user-consumer #要跳转的客户端名称
predicates:
- Path=/user/** #匹配的路径
filters:
- RewritePath=/user(?<segment>/?.*), $\{segment} #匹配的路径要替换成如表达式
#注册中心路径
eureka:
client:
service-url:
defaultZone: http://localhost:7777/eureka/
3、创建过滤器
@Component
public class RedisGlobalFilter implements GlobalFilter, Ordered {
private boolean token = true;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//在此处写代码就是pre过滤器
System.out.println("配置文件的token : "+this.token);
if(this.token) {
List<String> token = exchange.getRequest().getHeaders().get("token");
//此处就到redis数据库中去查询
if (null == token || "".equals(token)) {
ServerHttpResponse response = exchange.getResponse();
//{"msg":"验证不能通过"}
byte[] datas = "{\"msg\":\"验证不能通过\"}".getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(datas);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 1;
}
}
这样你的gateway服务网关基本配置好了!