一个角色来充当request的请求入口,处理非业务功能的场所(防刷,协议监控)java
Tyknginx
Spring Cloud Zuulgit
项目改造应该合理利用原有的优点redis
路由+过滤器=Zuulspring
核心是一系列的过滤器apache
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
@EnableZuulProxy
@EnableEurekaClient @EnableZuulProxy
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
查看配置json
全局开启api
zuul: sensitive-headers:
zuul: routes: # /myProduct/product/list -> /product/list # aaa: # path: /myProduct/** # serviceId: PRODUCT #简洁写法 product: /myProduct/** sensitive-headers:
@Component public class ZuulConfig { @Autowired @ConfigurationProperties("zuul") public ZuulProperties zuulProperties() { return new ZuulProperties(); } }
前置跨域
后置缓存
多个节点注册到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; /** * <p>****************************************************************************</p> * <p><b>Copyright © 2010-2018 rollBall team All Rights Reserved<b></p> * <ul style="margin:15px;"> * <li>Description : com.zzjson.apigateway.filter</li> * <li>Version : 1.0.0</li> * <li>Creation : 2018年10月19日</li> * <li>@author : zzy0_0</li> * </ul> * <p>****************************************************************************</p> */ @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; } }
order 的值越小,优先级越高
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; /** * <p>****************************************************************************</p> * <p><b>Copyright © 2010-2018 rollBall team All Rights Reserved<b></p> * <ul style="margin:15px;"> * <li>Description : com.zzjson.apigateway.filter</li> * <li>Version : 1.0.0</li> * <li>Creation : 2018年10月19日</li> * <li>@author : zzy0_0</li> * </ul> * <p>****************************************************************************</p> */ @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; /** * <p>****************************************************************************</p> * <p><b>Copyright © 2010-2018 rollBall team All Rights Reserved<b></p> * <ul style="margin:15px;"> * <li>Description :限流拦截器</li> * <li>Version : 1.0.0</li> * <li>Creation : 2018年10月19日</li> * <li>@author : zzy0_0</li> * </ul> * <p>****************************************************************************</p> */ @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; } }
区分买家和卖家(返回的时候设置)
买家:
卖家:
实现方式
在被调用的类或者方法上加@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