服务网关和zuul
一个角色来充当request的请求入口,处理非业务功能的场所(防刷,协议监控)
要素:
- 稳定性,高可用
- 性能、并发性
- 安全性
- 扩展性
常用的网关方案
- Nginx+Lua(性能极高,事件驱动型,优化设计,扩展性,耦合低)
- Kong
-
Tyk
- 全RestFul Api
- go开发
- 性能高
-
Spring Cloud Zuul
- netflix 开发
- java技术栈
- 一代zuul不能和nginx比性能
项目改造应该合理利用原有的优势
特点:
路由+过滤器=Zuul
核心是一系列的过滤器
四种过滤器
- 前置
- 路由
- 后置
- error
使用
导入依赖
org.springframework.cloud
spring-cloud-starter-netflix-zuul
开启注解@EnableZuulProxy
@EnableEurekaClient
@EnableZuulProxy
yml
spring:
application:
name: zuul
cloud:
config:
discovery:
service-id: CONFIG
enabled: true
profile: dev
server:
port: 8085
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
zuul:
routes:
# /myProduct/product/list -> /product/list
# aaa:
# path: /myProduct/**
# serviceId: PRODUCT
#简洁写法
product: /myProduct/**
# 排除某些路由 set的写法
ignored-patterns:
- /**/myProduct/product/list
#用来查看配置
management:
security:
enabled: false
{{zuul}}/application/routes
查看配置
cookie和动态路由
Cookie
默认是不开启cookie的
全局开启
zuul:
sensitive-headers:
开启方式:
zuul:
routes:
# /myProduct/product/list -> /product/list
# aaa:
# path: /myProduct/**
# serviceId: PRODUCT
#简洁写法
product: /myProduct/**
sensitive-headers:
动态路由(cloud config +cloud bus)
@Component
public class ZuulConfig {
@Autowired
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties() {
return new ZuulProperties();
}
}
特点
- 路由+过滤器=Zuul
- 核心是一系列的过滤器
典型应用场景
-
前置
- 鉴权
- 过滤
-
后置
- 统计
- 日志
Zuul的高可用
多个节点注册到Eureka Server上
Nginx 和Zuul"混搭"
前置和后置过滤器
前置过滤
package com.zzjson.apigateway.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
/**
* ****************************************************************************
* Copyright © 2010-2018 rollBall team All Rights Reserved
*
* - Description : com.zzjson.apigateway.filter
* - Version : 1.0.0
* - Creation : 2018年10月19日
* - @author : zzy0_0
*
* ****************************************************************************
*/
@Component
public class TokenFilter extends 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();
String token = request.getParameter("token");
if (StringUtils.isEmpty(token)) {
//不通过
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
后置过滤
package com.zzjson.apigateway.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.HttpServletResponse;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;
/**
* ****************************************************************************
* Copyright © 2010-2018 rollBall team All Rights Reserved
*
* - Description : com.zzjson.apigateway.filter
* - Version : 1.0.0
* - Creation : 2018年10月19日
* - @author : zzy0_0
*
* ****************************************************************************
*/
@Component
public class AddResponseFilter 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("surprise", "xx");
return null;
}
}
限流
限流保护,防止网络攻击
时机:请求被转发之前调用
令牌桶限流
package com.zzjson.apigateway.filter;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import com.zzjson.apigateway.exception.RateLimiterException;
import org.springframework.stereotype.Component;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;
/**
* ****************************************************************************
* Copyright © 2010-2018 rollBall team All Rights Reserved
*
* - Description :限流拦截器
* - Version : 1.0.0
* - Creation : 2018年10月19日
* - @author : zzy0_0
*
* ****************************************************************************
*/
@Component
public class RateLimiterFilter extends ZuulFilter {
private static final RateLimiter rateLimiter = RateLimiter.create(1);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return SERVLET_DETECTION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
//没有取到令牌
if (!rateLimiter.tryAcquire()) {
throw new RateLimiterException();
}
return null;
}
}
权限校验
- /order/create 只能买家访问
- /order/finish 只能卖家
- /product/list 都可以访问
区分买家和卖家(返回的时候设置)
-
买家:
- cookie设置 openid=abc
-
卖家:
- cookie 设置token=uuid ,redis 设置 key=uuid,value=xyz
实现方式
- Zuul:在前置过滤器中实现相关的逻辑
- 分布式Session Vs OAuth2
跨域解决
-
在被调用的类或者方法上加
@CrossOrigin
注解 -
Zuul里面增加CrosFilter过滤器
@Configuration public class CrosConfig { @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); //是否支持cookie跨域 config.setAllowCredentials(true); //是否支持原始域 http://www.baidu.com config.setAllowedOrigins(Collections.singletonList("*")); config.setAllowedHeaders(Collections.singletonList("*")); config.setAllowedMethods(Collections.singletonList("*")); //设置缓存时间 config.setMaxAge(300L); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
代码地址: https://gitee.com/zzy0_0/api-gateway