灰度实战(六):SpringCloud灰度(2) - Go语言中文社区

灰度实战(六):SpringCloud灰度(2)


 

【前言】

       在上篇博文中《灰度实战(五):SpringCloud灰度(1)》讲解了SpringCloud项目的灰度实战,其中在zuul中拦截到是灰度请求时采用重定向再次请求网关然后分发至灰度服务,在本篇将zuul针对灰度请求分发策略进行优化,由重定向优化为直接转发提高性能。

【SpringCloud灰度实战】

         一、项目简介

               1、重定向方式的灰度转发策略示意图:

               2、直接转发方式的灰度转发策略示意图:

               3、对比:

                     从示意图中不难发现,zuul网关在进行灰度分发时直接转发比重定向少了一次请求,直接分发到业务系统。

         二、代码调整

               1、增加直接转发拦截器---GrayDirectZuulFilter 

/*
 * Copyright (c) 2019. zhanghan_java@163.com All Rights Reserved.
 * 项目名称:灰度实战
 * 类名称:GrayDirectZuulFilter.java
 * 创建人:张晗
 * 联系方式:zhanghan_java@163.com
 * 开源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://blog.csdn.net/zhanghan18333611647
 */

package com.zhanghan.zuul.filter;


import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zhanghan.zuul.bean.GrayBean;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.util.StreamUtils;
import org.springframework.web.util.UrlPathHelper;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.nio.charset.Charset;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.*;

public class GrayDirectZuulFilter extends ZuulFilter {


    @Autowired
    private GrayBean grayBean;

    @Autowired
    private RouteLocator routeLocator;

    @Autowired
    private UrlPathHelper urlPathHelper;

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return grayBean.isEnabled();
    }

    @Override
    public Object run() {

        Boolean isGray = shouldBeRedirected();

        if (isGray) {

            String grayServiceId = getServiceId() + grayBean.getSuffix();

            String url = RequestContext.getCurrentContext().getRequest().getRequestURI();

            url = replaceUrl(url, grayServiceId);

            try {
                RequestContext.getCurrentContext().put(REQUEST_URI_KEY, url);
                RequestContext.getCurrentContext().put(SERVICE_ID_KEY, grayServiceId);
            } catch (Exception e) {
                return null;
            }


        }

        return null;
    }

    /**
     * 是否为灰度请求  依据条件同时满足1和2为灰度请求: 1.请求在灰度列表中 2.companyNo为配置的灰度companyNo
     *
     * @return true灰度 false不灰度
     */
    private Boolean shouldBeRedirected() {

        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();

        if (grayBean.getGraylist().isEmpty()) {
            return false;
        }

        String serviceId = getServiceId();

        if (!grayBean.getGraylist().contains(serviceId)) {
            return false;
        }

        Object companyNo = getParment(request, "companyNo");

        if (null != companyNo && companyNo.toString().equals(grayBean.getCompanyNo())) {
            return true;
        }

        return false;
    }

    /**
     * 转换为灰度url
     *
     * @param url           原url
     * @param grayServiceId 灰度服务id
     * @return
     */
    private String replaceUrl(String url, String grayServiceId) {
        grayServiceId = grayServiceId.replace(grayBean.getSuffix(), "");
        return url.replace("/" + grayServiceId, "");
    }

    /**
     * 获取本次请求的serviceId
     *
     * @return
     */
    private String getServiceId() {

        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();

        Object object = RequestContext.getCurrentContext().get(SERVICE_ID_KEY);

        String serviceId = object == null ? null : object.toString();

        if (StringUtils.isEmpty(serviceId)) {
            String requestURI = urlPathHelper.getPathWithinApplication(request);
            serviceId = routeLocator.getMatchingRoute(requestURI).getLocation();
        }

        return serviceId;
    }


    /**
     * 获取post请求的body
     *
     * @param request
     * @param parmentKey
     * @return
     */
    private static Object getParment(HttpServletRequest request, String parmentKey) {

        try {

            String charset = request.getCharacterEncoding();

            InputStream inputStream = request.getInputStream();

            String body = StreamUtils.copyToString(inputStream, Charset.forName(charset));

            if (StringUtils.isEmpty(body)) {
                return null;
            }

            JSONObject json = JSONObject.fromObject(body);

            return json.get(parmentKey);

        } catch (Exception e) {
            return null;
        }

    }

}

               2、启动类关闭GrayRedirectZuulFilter的注入,启用GrayDirectZuulFilter注入

/*
 * Copyright (c) 2019. zhanghan_java@163.com All Rights Reserved.
 * 项目名称:灰度实战
 * 类名称:ZhZuulApplication.java
 * 创建人:张晗
 * 联系方式:zhanghan_java@163.com
 * 开源地址: https://github.com/dangnianchuntian/springboot
 * 博客地址: https://blog.csdn.net/zhanghan18333611647
 */

package com.zhanghan.zuul;

import com.zhanghan.zuul.filter.GrayDirectZuulFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZhZuulApplication {

    public static void main(String[] args) {

        SpringApplication.run(ZhZuulApplication.class, args);
    }


    /**
     * 重定向方式的Filter---性能低
     */
//    @Bean
//    public GrayRedirectZuulFilter grayRedirectZuulFilter() {
//        return new GrayRedirectZuulFilter();
//    }

    /**
     * 直接跳转方式的Filter---性能高建议采用
     *
     * @return
     */
    @Bean
    public GrayDirectZuulFilter grayDirectZuulFilter() {
        return new GrayDirectZuulFilter();
    }


}

               3、其他代码

                     灰度实战:https://github.com/dangnianchuntian/gray

                     项目模块:gray-cloud

        三、演示灰度

               效果和上篇博文效果一致,在此不再赘述;

【总结】

         1、本节将SpringCloud中利用zuul灰度重定向优化为直接调用至灰度服务。

         2、在接下来会为大家演示SpringCloud链式调用情况下如何做灰度。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u012829124/article/details/94906100
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 10:43:58
  • 阅读 ( 1096 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢