前言:
API网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤。它除了要实现请求路由、 负载均衡、 校验过滤等功能之外,还需要更多能力,比如与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。
Zuul实现如下:
(一)创建项目,大致步骤与之前相同
唯一不同的是需要选择Zuul组件
(二)添加注解
@EnableZuulProxy
(三)修改配置文件,配置eureka的地址
server:
port: 9000
spring:
application:
name: api-gateway
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
启动eureka,product服务
启动api-gateway服务之后通过如下方式可以访问该资源
这是zuul 作为网关最基本的功能。
I.路由/敏感信息过滤等
zuul:
routes:
prd:
path: /prd/**
serviceId: product
或者
zuul:
routes:
product: /prd/**
通过prd也能请求product下的接口
排除某些路由
某些接口不打算对外暴露可以排除掉
zuul:
routes:
product: /prd/**
ignored-patterns:
#- /prd/productMsg
#- /product/productMsg
- /**/productMsg
由于prd和product都可以访问,所以都需要排除
sensitive-headers 敏感头过滤,可以全局配置或者针对某个服务配置
默认过滤
“Cookie”, “Set-Cookie”, “Authorization” 已经被默认过滤
可以设置为空使得这些不被过滤。
配置动态更新
可以通过Spring Cloud Config 配合以下代码实现配置的动态更新
II.高可用
Zuul的高可用可以将多个节点注册到eureka上
然后通过Nginx路由到Zuul,再由Zuul路由到各个微服务上
III.过滤器
zuul最强大的功能之一就是它的各种过滤器了
前置过滤器(Pre):
- 限流
- 鉴权
- 参数调整 等功能
后置过滤器(Post):
- 统计
- 日志记录 等功能
前置过滤器
新建一个TokenFilter
如果请求url里未设置token则返回401 无权限
代码如下
@Component
public class TokenFilter extends com.netflix.zuul.ZuulFilter{
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//可以从url,cookie,header中获取token
String token = request.getParameter("token");
if(StringUtils.isEmpty(token)){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
具体权限校验业务可自己设定
后置过滤器
新建一个AddResponseHeaderFilter
在返回头里面添加一些信息
代码如下
@Component
public class AddResponseHeaderFilter extends ZuulFilter{
@Override
public String filterType() {
return POST_TYPE;
}
@Override
public int filterOrder() {
return SEND_RESPONSE_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletResponse response = requestContext.getResponse();
response.setHeader("X-Foo", UUID.randomUUID().toString());
return null;
}
}
返回头里面有添加的信息。
IIII.跨域
跨域:
浏览器对于javascript的同源策略的限制,例如a.cn下面的js不能调用b.cn中的js,对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了.
同源策略:
请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.
spring cloud 解决跨域常用的方法有两种
1.在被调用的类或者方法上加注解
@CorssOrigin
假设需要调用的商品服务需要支持跨域访问
2.通过Zuul
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter(){
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Arrays.asList("*"));//设置支持跨域的域名 如 http://www.baidu.com
config.setAllowedHeaders(Arrays.asList("*"));//设置支持跨域的头信息
config.setAllowedMethods(Arrays.asList("*"));//设置支持跨域的请求方法 如POST GET
config.setMaxAge(300l);//设置缓存时间,同一个跨域请求300S内通过后不再检查
source.registerCorsConfiguration("/**",config);//设置支持跨域的地址
return new CorsFilter(source);
}
}
以上就是关于zuul的一些常用用法,如果遇到其它用法会继续补充