6.gateway
gateway简介
网关是微服务最边缘的服务,直接暴露给用户,用来做用户和微服务的桥梁
gateway zuul
SpringCloud Gateway作为Spring Cloud生态的网关,目标是替代Zuul,在SpringCloud2.0 以上的版本中,没有对新版本的 zuul2.0 以上的最新高性能版本进行集成,仍然还是使用的 zuul1.x[可以看项目依赖找到]非 Reactor 模式的老版本。而为了提升网关的性能
SpringCloud Gateway 是基于 webFlux 框架实现的,而 webFlux 框架底层则使用了高性能 的 Reactor 模式通信框架的 Netty
快速使用
新建一个项目,添加gateway能力
1)更改配置文件
server:
port: 80 #网关的端口一般为80
spring:
application:
name: gatewaycus-service
cloud:
gateway:
enabled: true #只要加了依赖默认开启
routes:
- id: gatewaypro-service # 路由的id 保持唯一性即可
uri: http://localhost:8096 #uri统一资源定位符
predicates:
- Path=/order #匹配规则 只要匹配上了就网uri上转发 并且在路径上附带
@Configuration
public class RouteConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
return builder.routes()
.route("guochuang-id",r->r.path("/guochuang").uri("https://www.bilibili.com"))
.build();
}
}
开启动态路由
-
网关加入eureka
-
启动类上注解启动eureka
-
配置文件
server: port: 80 #网关的端口一般为80 spring: application: name: gatewaycus-service cloud: gateway: enabled: true #只要加了依赖默认开启 discovery: locator: enabled: true lower-case-service-id: true #开启服务名称小写 eureka: client: service-url: #指定注册的地址 defaultZone: http://120.79.169.237:8761/eureka registry-fetch-interval-seconds: 3 #降低拉取服务列表的时间间隔 instance: hostname: localhost #应用的主机名称 (写主机IP) instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} #主机名称:应用名称:端口号
-
调用即可(默认为80端口,ip/服务名/api)
Spring Cloud Gateway 三大核心概念
-
路由(route)
路由信息组成:由一个ID,一个目的URL,一组断言工厂,一组Filter组成
如果断言为真,说明URL和配置路由匹配
-
断言(predicate)(就是返回一个bool的表达式)
java8中的断言函数。lambda 四大接口 供给型,消费型,函数型,断言型
Spring Cloud Gateway 中 的 断 言 函 数 输 入 类 型 是 Spring 5.0 框 架 中 的 ServerWebExchange。
Spring Cloud Gateway 的断言函数允许开发者去定义匹配来自于 Http Request 中的任何信息比如请求头和参数。
-
过滤(filter)
pring Cloud Gateway 中的 Filter 分为两种类型的 Filter,分别是 Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理。
@Component
public class MyGlobalFilter implements GlobalFilter{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().set("content-type","application/json;characterset='utf-8'");
HashMap<String,Object> map = new HashMap<>(4);
map.put("code",401);
map.put("msg","拦截器未通过");
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//不通过过滤器
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
//通过过滤
//return chain.filter(exchange);
}
}
过滤器Tocken登录检验
- 登录赋权Tocken
@GetMapping("/login")
public String login(String name,String password){
System.out.println(name);
System.out.println(password);
UserInfo userInfo = new UserInfo(name,password);
String tocken = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(tocken, userInfo.toString(), Duration.ofSeconds(7200));
return tocken;
}
- 过滤器检验Tocken
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if(ALLOW_URI.contains(path)){
return chain.filter(exchange);
}
List<String> tockens = exchange.getRequest().getHeaders().get("Authorization");
if(!CollectionUtils.isEmpty(tockens)){
String tocken = tockens.get(0);
if(StringUtils.hasText(tocken)){
String realTocken = tocken.replaceFirst("bearer ","");
if(StringUtils.hasText(realTocken) && redisTemplate.hasKey(realTocken)){
chain.filter((exchange));
}
}
}
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().set("content-type","application/json;characterset='utf-8'");
HashMap<String,Object> map = new HashMap<>(4);
map.put("code",401);
map.put("msg","拦截器未通过");
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//不通过过滤器
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
}
限流操作
- 写配置类
@Configuration
public class RequestLimitConfig {
//针对某个ip地址来做限流
@Bean
@Primary
public KeyResolver ipKeyResolver(){
return exchange -> Mono.just(exchange.getRequest().getHeaders().getHost().getHostString());
}
//针对某个api接口来实现限流
@Bean
public KeyResolver apiKeyResolver(){
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
}
- 更改配置文件
spring:
application:
name: gatewaycus-service
cloud:
gateway:
enabled: true #只要加了依赖默认开启
discovery:
locator:
enabled: true
lower-case-service-id: true #开启服务名称小写
routes:
- id: gatewaypro-service-route
uri: lb://gatewaypro-service
predicates:
- Path=/order
filters:
- name: RequestRateLimiter #这个是过滤器的名字
args: #过滤器的参数
key-resolver: '#{@ipKeyResolver}' #通过spel表达式取ioc容器中bean的值
redis-rate-limiter.replenishRate: 1 #生成令牌的速度
redis-rate-limiter.burstCapacity: 3 #桶容量
本文链接:
/archives/6gateway
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
郭远的博客空间!
喜欢就支持一下吧
打赏
微信
支付宝