今天主要是总结的SpringCloud中的网关:由于每一个为服务的地址都有可能发生变化,无法直接对外公布这些服务的地址,基于安全和高内聚低耦合等的设计理念,我们有必要将内部系统和外部系统做一个切割
所谓服务网关:专门处理外部请求的组 件它的主要功能有:
- 权限问题统一处理
- 数据剪裁和聚合
- 简化数据端调用
- 可以针对不同的客户端提供不同的网关支持
在spring cloud中,网关主要有两种实现方式:
- Zuul
- Spring Cluod Geteway
Zuul
是Netfix公司提供的网关服务
功能:
- 权限控制,可以做认证和授权
- 监控
- 动态路由
- 负载均衡
- 静态资源处理
Zuul的基本功能都是基于过滤器实现的,它的过滤器有几种不同的类型 - PRE
- ROUTING
- POST
- ERROR
eg:
1.创建项目,添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
配置:
server:
port: 8006
spring:
application:
name: zuul
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8001/eureka
zuul:
routes:
provider: /fan/**
openFegin: /feginDemo/**
# 忽略某一类地址
ignored-patterns: /**/hello/**
#忽略某一个服务
ignored-services: provider
在启动类上添加开启网关代理
@SpringBootApplication
@EnableZuulProxy //开启网关代理
@EnableEurekaClient
public class ZuuldemoApplication {
public static void main(String[] args) {
SpringApplication.run(ZuuldemoApplication.class, args);
}
}
之后我们就可以通过:
http://localhost:8006/feginDemo/fegin/hello
访问到在feginDemo服务中的hello接口
过滤器的eg:
package com.zuul.zuuldemo.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class PremissFilter extends ZuulFilter {
/**
* 过滤器类型,权限判断一般是pre
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过滤器的优先级
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 是否过滤
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 核心的过滤方法逻辑
* @return 暂时这个返回值无用
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
/**
* 获取当前请求
*/
HttpServletRequest request = ctx.getRequest();
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username+password);
if(!"fan".equals(username) || !"123456".equals(password)){
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(7001);
ctx.setResponseBody("请求不合法");
ctx.addZuulResponseHeader("content-type", "text/html; charset=UTF-8");
}
return null;
}
}
Gateway
Gateway的特点:
- 限流
- 路径重写
- 动态路由
- 集成Spring Cloud DiscoveryClient
- 集成Hystrix断路器
与Zuul之间的比较
- Gateway可以和spring的其他组件更好的融合
- Zuul不支持长链接
- Gateway支持限流
- Gateway是基于Netty来开发的,实现了异步和非阻塞,性能强于Zuul
eg:
1.创建springboot集成Gateway模块
2.配置:
server:
port: 8007
spring:
application:
name: gatewaydemo
cloud:
gateway:
routes:
- id: fan # 路由 ID,唯一
uri: lb://provider # lb:// 根据服务名称从注册中心获取服务请求地址
predicates: # 断言(判断条件)
- Path=/provider/**
discovery:
locator:
enabled: true #开启自动代理
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8001/eureka
注意:
1.predicates的几种用法:
- -Path=/product/** # 匹配对应 URL 的请求,将匹配到的请求追加在目标 URI 之后
- -Query=token, abc. # 匹配请求参数中包含 token 并且其参数值满足正则表达式 abc. 的请求
- -Method=GET # 匹配任意 GET 请求
- -After(Before, Between)=2020-02-02T20:20:20.000+08:00[Asia/Shanghai]
(-和单词之间要加空格)
2.过滤器:
主要有两种:
GatewayFilter:网关过滤器,需要通过 spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过 spring.cloud.default-filters 配置在全局,作用在所有路由上。
GlobalFilter:全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过 GatewayFilterAdapter 包装成 GatewayFilterChain 可识别的过滤器,它为请求业务以及路由的 URI 转换为真实业务服务请求地址的核心过滤器,不需要配置系统初始化时加载,并作用在每个路由上。
过滤器我们之后再细说