1.过滤ip,电话号码,黑名单(业务),白名单(数据库服务特定ip),如上章步骤
1.拿ip
//放在内存中 也可以
public static final List<String> BLACK_LIST = Arrays.asList("127.0.0.1")
request.getHeads().getHost().getHostString();
//网关并发高,不用mysql
if(!BLACK_LIST.contains(ip)){
return chain.filter(exchange);
}
//拦截如上章
map.put("code",438);
map.put("msg","你在黑名单内");
//order返回-5 //先执行
//!!!老手全部用debug启动
2.全局过滤器做token校验(权限校验)
1.把用户名和密码给,网关-->service-->redis(key:uuid,value:user字符串)
--->返回uuid当token-->网关-->前端存储token--->每次带上token
--->直接token查询redis
2.网关需要校验有没有token,是不是正确
3.步骤
1.写个User模拟返回数据库对象,controller
String token=UUID.randaomUUID().toString();
//为什么要token,因为http是无状态的请求
//不能让服务器知道哪一台服务器发的请求,无法拿到指定的数据
//引入redis
//过期时间7200秒,一天8w秒
redisTemplate.opsForValue().set(token,user.toString,Duration.ofSeconds(7200))
2.写过滤器 ,token一般放在请求头里面 Authorization 行业约定俗成 他的value bearer xxx
//指定好放行路径,因为全部都要走,return
exchange.getRequest();
request.getURI().getPath();
if(ALLOW_URL.contains(path)){
return chain.filter(exchange);
}
request.getHeaders();
headers.get("Authorization");
if(CollectionUtils.isEmpty(authorization)){
String token=authorization.get(0);
if(StringUtils.hasText(token)){
String realToken=token.replaceFirst("bearer","");
if(StringUtils.hasText(realToken) && redisTemplate.hasKey(token)){
return chain.filter(exchange);
}
}
}
exchange.getResponse();
response.getHeaders().set("content-type","application/json;charset=utf-8");
new HashMap<String,Object>(4);
map.put("code",HttpStatus.UNAUTHRIZED.value());
map.put("msg","未授权");//401
2.建一个项目eureka和web
3.服务限流(限制一段时间内,用户访问资源的次数,减低服务器压力)(gateway整合redis已经实现)
1.IP限流(5s ip不能访问超过3次)
2.请求流量限流
java限流模型
1.窗口算法
2.漏桶算法
3.令牌桶算法(生成令牌放到令牌桶,请求必须获取令牌才能处理)入不敷出
1.加redis依赖
@Configuration
class
@Bean("ipResolver")
@Primary //主要被候选的, 报容器有两个相同的Bean
public keyResolver ipResolver(){
//lamda表达式,根据ip来限制
return exchange -> Mono.just(exchange.getRequest().getHeaders()
.getHost().getHostString(); //返回ip
}
//新一代网关 api网关,工具接口 /doLogin,根据path路径限制
@Bean
public KeyResolver apiKeyResolver(){
return exchange -> Mono.just(exchange.getRequest().getPath.value())
}
}
4.在配置文件中写gateway的routes的下一层加
filters:
- name: RequestRateLimiter #过滤器的名称
args: #过滤器的参数
key-resolver: '#{@ipResolver}' #spel表达式取ioc容器的值
redis-rate-limiter.replenishRate: 1 #生成令牌的速度
r redis-rate-limiter.burstCapacity: 3 #桶容量
4.跨域配置 ajax同源策略 请求方式 主机名和端口 ,有一种不同,网关统一配置跨域
cross 通过xmlhttprequest 可以克服ajax的跨域
vue通过 vue.config.js配置文件来跨域 proxy代理 changeOrigin: true
后端使用 @CrossOrigin #方法也可以加,本质是过滤器
//配置文件也可以java类
'[/**]': //针对那些连接
allowCredentials: true //cookies可以跨域
#完整的配置
globalcors:
corsConfigurations:
'[/**]':
allowCredentials: true # 可以携带cookie
allowedHeaders: '*'
allowedMethods: '*'
allowedOrigins: '*'
7.gateway面试 总结 zuul性能不好改gateway
1.zuul的使用 写个类继承 ZuulFilter public String filterType(){ return PRE_TYPE; //PRE前置过滤器 Post后置过滤器 } public int filterOrder(){ return true; } public Object run(){ request.getxxx(); }
2.gateway和zuul的区别
1.两个都是web网关,都处理http请求
2.gateway是springcloud官方的,zuul是netflix的
3.gateway适合springcloud框架,spring支持下,内部有限流负载均衡,拓展性强
而zuul可以用在其他微服务框架,内部没有限流,负载均衡
4.gateway是netty nio,支持异步 zuul1.0支持同步使用BIO 2.0后支持异步
8.(拓展)redis是tcp的请求
//redis://localhost:6379 做redis集群 HAproxy做中间件但是性能比redis差,不用
//crc16()hash算法,去中心化的算法,没有核心的主机
9.nginx在微服务的地位(50%的公司使用)大公司会修改
nginx免费,微服务架构不会选择nginx除非做集群,微服务会有许多配套 而且有freemarker,themleaf前后端不分离的项目 //前端后端分离,麻烦,需要打2个包,分别部署,前端在nignx分离 //动静分离 css js可以放在nginx上 斗鱼面试题 不使用后端技术如何实现大规模缓存? 使用nginx做大规模静态资源缓存(不经过后端处理) ssm吃一辈子 稳定赚钱 先入行1年后跳槽
redis单线程(确保线程安全) +mq限流+分布式锁