美文网首页
微服务-springcloud-zuul

微服务-springcloud-zuul

作者: jianshuqiang | 来源:发表于2020-03-10 19:34 被阅读0次

    zuul的作用

    1、进行认证处理:可以对发送过来的请求做认证处理
    2、审查与监控:可以记录各个请求的响应信息,将异常或者错误信息存入到数据库中,然后对数据库的数据进行处理
    3、动态路由:根据配置将请求发送到指定的服务中去
    4、负载均衡:与eureka配合使用,根据注册的多个service-id(Application),实现负载均衡
    5、压力测试:根据动态路由的特点可以对某一个服务进行加大访问量的处理,实现压力测试
    当不进行路由配置的时候直接可以使用zuul服务+service-id+访问路径对服务进行访问

    配置zuul

    配置跨域问题

    @Configuration
    public class CorsFilterConfig {
        @Bean
        public CorsFilter corsConfig() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true);
            config.addAllowedOrigin("*");
            config.addAllowedHeader("*");
            config.addAllowedMethod("*");
            config.setMaxAge(18000L);
            source.registerCorsConfiguration("/**", config);
            return new CorsFilter(source);
        }
    }
    

    配置filter

    权限过滤器

    package com.sgcc.zuul.filter;
    
    import com.google.gson.Gson;
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import com.sgcc.zuul.config.TokenProperties;
    import com.sgcc.zuul.model.ResultVO;
    import com.sgcc.comm.util.CookieUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    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;
    
    @Slf4j
    @Component
    public class AuthFilter extends ZuulFilter {
    
        @Autowired
        StringRedisTemplate stringRedisTemplate;
        @Autowired
        private TokenProperties tokenProperties;
        //无权限时的提示语
        private static final String INVALID_TOKEN = "invalid token";
    
        @Override
        public String filterType() {
            return PRE_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return PRE_DECORATION_FILTER_ORDER - 1;
        }
    
        @Override
        public boolean shouldFilter() {
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
    
            log.info("网关前置过滤器========》》》uri={}", request.getRequestURI());
            if ("false".equals(tokenProperties.getFilterSwitch()) || tokenProperties.getWhiteList().contains(request.getRequestURI())) {
                return false;
            }
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
            checkToken(requestContext, request);
            return null;
        }
    
        /**
         * 校验token
         *
         * @param requestContext
         * @param request
         */
        private void checkToken(RequestContext requestContext, HttpServletRequest request) {
            //先从 cookie 中取 token,cookie 中取失败再从 header 中取,两重校验
            String token = getToken(request);
            //如果获取的token为空,则直接返回401无权限
            if (StringUtils.isEmpty(token)) {
                setUnauthorizedResponse(requestContext, INVALID_TOKEN);
            } else {
                String value = stringRedisTemplate.opsForValue().get(token);
                if (StringUtils.isEmpty(value)) {
                    setUnauthorizedResponse(requestContext, INVALID_TOKEN);
                } else {
                    String[] values = value.split("_");
                    String checkToken = values[0];
                    String userId = values[1];
                    log.info("当前正在操作的用户ID为userId={}", userId);
                }
            }
        }
    
        /**
         * 获取token
         *
         * @return
         */
        private String getToken(HttpServletRequest request) {
            String token = CookieUtil.getValue(request, "X-Token");//先从cookie获取
            if (StringUtils.isEmpty(token)) {//如果cookie获取的token为空
                token = request.getHeader("X-Token");//则从header中获取
            }
            return token;
        }
        /**
         * 设置 401 无权限状态
         */
        private void setUnauthorizedResponse(RequestContext requestContext, String msg) {
            log.info("无权限非法请求~");
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            requestContext.getResponse().setCharacterEncoding("UTF-8");
            requestContext.getResponse().setContentType("application/json; charset=utf-8");
            ResultVO resultVO = new ResultVO();
            resultVO.setStatus(401);
            resultVO.setMessage(msg);
            Gson gson = new Gson();
            String result = gson.toJson(resultVO);
            requestContext.setResponseBody(result);
        }
    }
    
    

    错误拦截器

    package com.sgcc.zuul.filter;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import com.sgcc.zuul.enums.ExceptionTypeEnum;
    import com.sgcc.zuul.service.ZuulExceptionService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * @Author: 杨文培
     * @Desrcription:错误拦截过滤器
     * @Date: Create in 17:43 2018/12/29
     */
    @Component
    @Slf4j
    public class ErrorFilter extends ZuulFilter {
        @Autowired
        private ZuulExceptionService zuulExceptionService;
    
        @Override
        public String filterType() {
            return FilterConstants.ERROR_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return FilterConstants.SEND_ERROR_FILTER_ORDER - 1;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
            String url = request.getRequestURI();
            log.info("拦截错误========》》》url={}", url);
            zuulExceptionService.addException(RequestContext.getCurrentContext(), ExceptionTypeEnum.ERROR);
            return null;
        }
    }
    
    

    后置过滤器

    package com.sgcc.zuul.filter;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import com.sgcc.zuul.enums.ExceptionTypeEnum;
    import com.sgcc.zuul.service.ZuulExceptionService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @Author: 杨文培
     * @Desrcription:后置过滤器
     * @Date: Create in 17:43 2018/12/29
     */
    @Component
    @Slf4j
    public class PostFilter extends ZuulFilter {
        @Autowired
        private ZuulExceptionService zuulExceptionService;
    
        @Override
        public String filterType() {
            return FilterConstants.POST_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
    
            RequestContext requestContext = RequestContext.getCurrentContext();
            HttpServletRequest request = requestContext.getRequest();
            HttpServletResponse response = requestContext.getResponse();
            String url = request.getRequestURI();
            int status = response.getStatus();
            log.info("网关后置过滤器========》》》url={},status={}", url, status);
            if (200 != status) {
                //网页已经被移到别处
                if (status / 100 != 3) {
                    log.info("拦截到一个异常===》url={},status={}", url, status);
                    zuulExceptionService.addException(requestContext, ExceptionTypeEnum.EXCEPTION);
                }
            }
            return null;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:微服务-springcloud-zuul

          本文链接:https://www.haomeiwen.com/subject/ywxtlctx.html