灰度上线实践之zuul网关流量分配

论坛 期权论坛 脚本     
已经匿名di用户   2022-5-29 19:21   2294   0

最近手头的项目进行了重构,改动比较大,直接上线的话风险较大,于是我采用了灰度上线的方式来将风险最小化。

我们系统包括自己的门户页面,也作为中台来给各个业务方调用,我们灰度上线的话,要兼容各个业务系统。

业务系统调用我们接口是前缀是特殊的,可以和我们的门户调用区分开,且业务系统调用所有接口都是有签名的,每个接口的参数格式都是一样的,会含有每个业务系统的appId

之前流量是经过nginx直接打到我们的服务商,这次在nginx和我们系统之间添加了网关,作为我们灰度的核心--流量分配

关于zuul网关可以参考https://www.cnblogs.com/jing99/p/11696192.html

核心流量控制代码如下:



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;

import java.net.URL;
import java.util.List;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.kuaishou.is.ea.clm.gateway.model.bo.ESignGrayConfigBO;
import com.kuaishou.is.fastjson.replace.JSON;
import com.kuaishou.is.fastjson.replace.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class RouteFilter extends ZuulFilter {

    @Value("${esign.gray}")
    private String esignGray;//流量配置

    @Value("${esign.oldUrl}")
    private String oldUrl;

    @Value("${esign.newUrl}")
    private String newUrl;


    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER + 1;
    }

    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @SneakyThrows
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String url = ctx.getRequest().getRequestURI();
        if (!url.contains("/esignature/api/external")) {
            return null;
        }

        if (url.contains("/esignature/api/external/timing/task")) {
            ctx.setRouteHost(new URL(newUrl));
            return null;
        }
        HttpServletRequest request = ctx.getRequest();
        boolean matched = false;
        if (!ctx.isChunkedRequestBody()) {
            ServletInputStream inp = null;
            try {
                inp = ctx.getRequest().getInputStream();
                String body = null;
                List<ESignGrayConfigBO> eSignGrayConfigBOList = JSON.parseArray(esignGray, ESignGrayConfigBO.class);

                if (inp != null) {
                    body = IOUtils.toString(inp);
                    JSONObject jsonObject = JSON.parseObject(body);
                    Integer appId = -1;
                    try {
                        appId = (Integer) jsonObject.get("appId");
                    } catch (Exception e) {
                        log.error("获取appId error,path:{}", request.getRequestURI());
                    }
                    String path = request.getRequestURI();
                    int random = (int) (Math.random() * 100);
                    for (ESignGrayConfigBO eSignGrayConfigBO : eSignGrayConfigBOList) {
                        if (random < eSignGrayConfigBO.getPersent()
                                && (ObjectUtils.equals(appId, -1) || ObjectUtils.equals(appId, eSignGrayConfigBO.getAppId()))
                                && (path.endsWith(eSignGrayConfigBO.getPath()) || StringUtils.equals(eSignGrayConfigBO.getPath(), ""))) {
                            matched = true;
                            ctx.setRouteHost(new URL(newUrl));
                            log.info("matched :{}", body);
                        }
                    }
                }
            } catch (Exception e) {
                log.error("route error, e:{}", e.getMessage(), e);
                ctx.setRouteHost(new URL(oldUrl));
            }
        }

        if (!matched) {
            ctx.setRouteHost(new URL(oldUrl));

        }

        return null;
    }
}



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP