使用wireshark抓包,验证feign http请求的数据透传结果

一、背景

在灰度部署、A/B测试、单元化部署等场景下,微服务服务之间的调用,要求我们对上游服务给过来的数据进行透传至下游服务。

如果是灰度部署,需要对http请求进行染色,http header头部增加灰度标识,然后传递给下游服务。这个传递就跟击鼓传花一样,谁都不能丢弃掉这个灰度标识。
可现实是,我们的服务在执行的过程中,极容易把这个灰度标识丢掉了。(当然不是故意的)

如果程序的执行顺序都是串行的,那当然不会丢了上下文中的数据。现实中的程序执行,为了高性能和解耦,我们就会使用线程池、本地异步事件、mq异步、redis数据订阅与发布等技术,使得上下文的数据丢掉了,无法继续透传下去了。

为了做到数据透传,我们一般有两种做法,一是java agent技术,另外就是在服务中,在拦截器中增加数据的赋值。

验证数据透传的结果,一般的做法是输入日志,通过唯一标识去跟踪数据透传到哪一步。比如http feign调用框架,你就可以使用wireshark抓包来验证。(本文就使用后者来验证feign框架的数据透传)

二、目标

  • 支持feign调用的数据透传
  • 支持父子线程和线程池等的数据透传
  • 能够验证数据透传的结果

三、边界

服务之间的数据透传,不包括rabbitmq、redis等第三方中间件的透传。

四、关键思路

  • 父子线程的上下文传递,包括线程池等并发工具类,可以使用阿里云的开源框架transmittable-thread-local

  • 抓http协议的包,你可以使用charles,也可以使用强大的抓包工具:wireshark(说后者强大,是因为它还可以抓websocket等协议的包)

  • feign调用的参数传递,使用RequestInterceptor拦截器,在头部增加你的参数进行调用

五、feign拦截器


import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
 
public class CustomFeignInterceptor implements RequestInterceptor {

    private static final Logger log = LoggerFactory.getLogger(CustomFeignInterceptor.class);
    /**
     * FeignClient调用时传递的用户id
     */
    public static String XX_USER_ID = "XX_USER_ID";
    /**
     * FeignClient调用时传递的学校id
     */
    public static String XX_SCHOOL_ID = "XX_SCHOOL_ID";
    
    @Autowired
    @Qualifier(ITransmittableThreadLocal.TransmittableThreadLocal_BEAN_NAME)
    ITransmittableThreadLocal<TransmittedUserInfo> transmittableThreadLocal;

    @Override
    public void apply(RequestTemplate template) {
        TransmittedUserInfo userInfo = transmittableThreadLocal.get();
        if (userInfo != null) {
            if (StringUtils.isNotEmpty(userInfo.getUserId())){
                template.header(CustomFeignInterceptor.XX_USER_ID, userInfo.getUserId());
            }
            if (StringUtils.isNotEmpty(userInfo.getSchoolId())){
                template.header(CustomFeignInterceptor.XX_SCHOOL_ID, userInfo.getSchoolId());
            }
        }
    }
}

六、把要透传的数据传递至上下文

        String authUserId = request.getHeader(JwtAuthHeaders.AUTH_USER_ID);
        String authSchoolId = request.getHeader(JwtAuthHeaders.AUTH_SCHOOL_ID);
        
        if (StringUtils.isNotBlank(authUserId)) {
        
            TransmittedUserInfo userInfo = new TransmittedUserInfo(authUserId, authSchoolId);
           
            ITransmittableThreadLocal<TransmittedUserInfo> transmittableThreadLocal = (ITransmittableThreadLocal<TransmittedUserInfo>) ApplicationContextProvider
                    .getApplicationContext()
                    .getBean(ITransmittableThreadLocal.TransmittableThreadLocal_BEAN_NAME);
            transmittableThreadLocal.set(userInfo);
       }

七、wireshark抓包

开启抓包

# 这里输入过滤条件
ip.addr == 192.168.5.70 and tcp.port == 7584

使用wireshark抓包,验证feign http请求的数据透传结果_第1张图片

使用Postman调用接口,开始测试

使用wireshark抓包,验证feign http请求的数据透传结果_第2张图片
找到http协议的报文,见"Hypertext Transfer Protocol"部分:

如果你想要去看那些tcp协议的报文,可以进一步帅选:

ip.addr == 192.168.5.70 and tcp.port == 7584 and http

使用wireshark抓包,验证feign http请求的数据透传结果_第3张图片

你可能感兴趣的:(wireshark,http,测试工具)