Author: Gorit
Date:2021年1月
Refer:阿里云大学
2021年发表博文: 10/30
SpringCloud Gateway 2.2.6 版本 doc
微服务网关是整个微服务 api 接口的入口,可以实现很多功能。 作用:可以实现用户的验证登录、解决跨域,日志拦截,权限控制,限流、熔断、负载均衡、黑名单和白名单机制
前后端分离,前端调用地址都能够被抓包分析到
传统方式我们可以使用 过滤器拦截用户会话信息,这个过程所有的服务都必须写入该验证会话登录的代码。
过滤器:适合单个服务实现过滤请求
网关拦截:整个微服务实现过滤请求 能够解决整个微服务中冗余代码。
主要:
网关的服务端口号一般为:80 或者 443
开启 nacos,开启 8080 的 memeber 服务进行测试
<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">
<modelVersion>4.0.0modelVersion>
<groupId>cn.goritgroupId>
<artifactId>GatewayartifactId>
<version>1.0-SNAPSHOTversion>
<parent>
<artifactId>spring-boot-starter-parentartifactId>
<groupId>org.springframework.bootgroupId>
<version>2.3.4.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
<version>2.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
<version>2.2.4.RELEASEversion>
dependency>
dependencies>
project>
编写 application.yml
这里是作为测试用,后期会编写配置类,来实现路由的跳转
server:
port: 80
# 服务网关名称
spring:
application:
name: gorit-gateway
cloud:
gateway:
discovery:
locator:
# 开启服务 id 去注册中心上获取转发地址
enabled: true
routes:
# 路由 id,就是前面的服务 name
- id: gorit-member
## 基于 lb 负载均衡形式转发
uri: lb://gorit-member/
filters:
- StripPrefix=1
# 匹配规则 127.0.0.1/memeber/xxxx
predicates:
- Path=/member/**
nacos:
discovery:
server-addr: 127.0.0.1:8848
编写 app 运行
PS:确保 nacos 和 8080 端口的 member 启动了
然后我们访问 127.0.0.1/member/user 就能访问到 127.0.0.1:8080/user 的服务
微服务网关能做的事情,Nginx 也可以实现
相同点:
不同点
官方文档:链接
实现案例:
没有传递 token 参数的话,就不会转发
package cn.gorit.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @Classname GlobalTokenFilter
* @Description 全局过滤使用
* @Date 2021/1/20 20:14
* @Created by CodingGorit
* @Version 1.0
*/
@Component
public class GlobalTokenFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取参数
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (StringUtils.isEmpty(token)) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
String msg = "token null is not allowed";
DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
return response.writeWith(Mono.just(buffer));
}
return chain.filter(exchange);
}
}
token null is not allowed
user+ 8080
网关一旦宕机,整个微服务无法通信
如何解决? 网关实现集群 基于 Nginx 实现即可
网关实现了集群如何访问?
环境配置
Nginx 服务器 127.0.0.1:80, 使用 Nginx 对 网关进行负载均衡的配置
动态网关:任何配置都实现不用重启网关服务器都可以及时刷新网关配置
实现思路:
{
"路由的id": '',
"路由的名称": '',
"路由的规则": ''
}
id route_id route_name route_pattern route_type route_url
1 member gorit-member /member/** 0 gorit-member
网关已经提供了 api 接口
思路:
默认加载的时候
SpringBoot 项目源码入口
微服务跨域问题解决,在后端解决
使用 jsonp 只能用 GET 请求
解决:
跨域解决方案 1,配置文件方式
server:
port: 80
# 服务网关名称
spring:
application:
name: gorit-gateway
cloud:
gateway:
discovery:
locator:
# 开启服务 id 去注册中心上获取转发地址
enabled: true
# 跨域配置
globalcors:
corsConfigurations:
'[/**]':
allowCredentials: true
allowedOrigins: "*"
allowedHeaders: "*"
allowedMethods: "*"
maxAge: 3628800
routes:
# 路由 id
- id: member
## 基于 lb 负载均衡形式转发
uri: lb://gorit-member/
filters:
- StripPrefix=1
# 匹配规则
predicates:
- Path=/member/**
nacos:
discovery:
server-addr: 127.0.0.1:8848
跨域解决方案2:Java 配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;
/**
* @Classname CrossConfig
* @Description 配置类解决跨域
* @Date 2021/1/22 18:14
* @Created by CodingGorit
* @Version 1.0
*/
@Configuration
public class CrossConfig {
@Bean
public CorsWebFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", buildConfig());
return new CorsWebFilter(source);
}
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*"); // 请求头
corsConfiguration.addAllowedMethod("*"); // 所有方法
corsConfiguration.setMaxAge(3628800L);
return corsConfiguration;
}
}
Sentinel 服务保护框架