看完之后有彩蛋欧
网关的作用和使用场景 (画图)
1)什么是网关
唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求、鉴权、监控、缓存、限流等功能
统一接入
智能路由
AB测试、灰度测试
(AB一个界面给不同的用户群体不同的界面,看哪个效果好不好的淘汰)
负载均衡、容灾处理
日志埋点(类似Nignx日志)
流量监控
限流处理
服务降级
安全防护
鉴权处理
监控
机器网络隔离(服务间通过内网访问)
2)主流的网关
zuul:是Netflix开源的微服务网关,和Eureka,Ribbon,Hystrix等组件配合使用,Zuul 2.0比1.0的性能提高很多
kong: 由Mashape公司开源的,基于Nginx的API gateway
nginx+lua:是一个高性能的HTTP和反向代理服务器,lua是脚本语言,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求 (运行快JD开发成本高但很通用)
网关组件zuul基本使用
1、加入依赖
配置
2、启动类加入注解 @EnableZuulProxy(服务的发现不用加)
默认集成断路器 @EnableCircuitBreaker
默认访问规则
http://gateway:port/service-id/**
例子:默认 /order-service/api/v1/order/save?user_id=2&product_id=1
自定义 /xdclass_order/api/v1/order/save?user_id=2&product_id=1
order-service(Eureka中注册的)
自定义路由转发:
zuul:
routes:
order-service: /apigateway/**
环境隔离配置:
服务对外暴露接口
/order-service/api/v1/order/save
/product-service/api/v1/list 不对外通过商品服务
配置: (通过正则)
zuul:
ignored-patterns:
/*-service/api/v1/order/save
http://localhost:9000/apigateway/api/v1/order/save?user_id=1&product_id=3
*26个字母
** 还有特殊符号
?通过
方式访问?
Zuul常用问题分析和网关过滤器原理分析
Zuul网关原理和过滤器生命周期,
1、路由名称定义问题
路由映射重复覆盖问题
2、Http请求头过滤问题
cookie拿不到值(zull网关一些敏感的头信息会默认过滤掉了)所以拿不到
3、过滤器执行顺序问题 ,过滤器的order值越小,越先执行
限流 鉴权在pre filter中实现
4、共享RequestContext,上下文对象
自定义Zuul过滤器实现登录鉴权实战
1、新建一个filter包
ZuulFilter,重写里面的方法
3、在类顶部加注解,@Component,让Spring扫描
com.netflix.zuul.context.RequestContext;
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
JWT 如果查数据库的话效率就太慢了
http://localhost:9000/apigateway/order/api/v1/order/save?user_id=1&product_id=3&token=123
@Component
public class LoginFilter extends ZuulFilter {
//前置过滤器
@Override
public String filterType() {
return PRE_TYPE;
}
//越小越先执行
//可以抽出一个类专门进行顺序管理
@Override
public int filterOrder() {
return 4;
}
//是否生效
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
String uri = request.getRequestURI();///apigateway/order/api/v1/order/save
StringBuffer url = request.getRequestURL();//http://localhost:9000/apigateway/order/api/v1/order/save
// System.out.println("uri"+uri);
// System.out.println("url"+url);
if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(uri)){return true;}
else {
System.out.println("没有拦截");
return false;
}
}
//执行的逻辑
@Override
public Object run() throws ZuulException {
System.out.println("======拦截了========");
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String token = request.getHeader("token");
if (StringUtils.isBlank(token)){
token= request.getParameter("token");
}
if (StringUtils.isBlank(token)){
currentContext.setSendZuulResponse(false);
currentContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
1.获取uri (上下文-->req--->uri) //ACL
2.判断如果是需要的路径进行拦截
拦截中的操作 JWT鉴权
(上下文--->req---header--parameter) JWT
获取token 从Heade中获取
从parameter中获取
高并发情况下接口限流特技
com.google.common.util.concurrent.RateLimiter;
谷歌guava框架介绍,网关限流使用
1、nginx层限流
2、网关层限流
@Component
public class RateLimitFilter extends ZuulFilter {
//每秒产生1000个令牌
private static final RateLimiter RATE_LIMITER=RateLimiter.create(2);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
//最先执行
return -4;
}
@Override
public boolean shouldFilter() {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
String uri = request.getRequestURI();
if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(uri)){
return true;
}
return false;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
//拿不到令牌就限流
if (!RATE_LIMITER.tryAcquire()){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
}
return null;
}
}
Zuul微服务网关集群搭建
微服务网关Zull集群搭建
1、nginx+lvs+keepalive
整理了整套的springcloud全家桶,给大家分享,如有问题请大佬指出。