06.微服务globalFilter

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年后跳槽
  1. 限流不会直接问,间接问不超卖商品
 redis单线程(确保线程安全) +mq限流+分布式锁

你可能感兴趣的:(微服务,java,架构)