微服务之间的调用openfeign 请求头信息丢失处理

433 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

首先说一下出现这个问题的场景

在我自己的项目中操作数据库的服务都在服务A上 服务A上有一个操作记录的记录,在往DB更新数据是发现从B服务请求过来的请求头中的信息是null。通过断点我们发现B服务调用A服务的时候并不会带着请求头的信息。所以我们只能手动配置。

添加请求头信息

添加配置类设置请求头信息

@Configuration
public class FeignConfig {
    @Bean
    public RequestInterceptor requestInterceptor(){
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
                //1.RequestContextHolder拿到当前请求的数据,相当与拿到controller入参的HttpServletRequest
                ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if(!ObjectUtils.isEmpty(requestAttributes)){
                    //本服务进来的请求信息
                    HttpServletRequest request = requestAttributes.getRequest();
                    //2. 获取本次请求的信息
                    String ua = request.getHeader("User-Agent");
                   // 3.将请求信息设置进 requestTemplate->ua
                    requestTemplate.header("User-Agent",ua);
                    //当然这里也可以设置其他的属性,因为在我的场景中只需要拿到请求头的信息。。。
                }
            }
        };
    }
}

A服务进行日志记录时使用

public void recordLog(JoinPoint joinpoint ) throws Throwable{
    SysLog sysLog  =new SysLog();
    //将当前实体保存到threadLoacl
    sysLogThreadLocal.set(sysLog);
    //开始时间
    long beginTime = Instant.now().toEpochMilli();
    //获取请求信息
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    sysLog.setActionUrl(URLUtil.getPath(request.getRequestURI()));
    sysLog.setStartTime(LocalDateTime.now().toString());
    //todo 设置操作人
    // sysLog.setUserName();
    //设置ip
    String ip = ServletUtil.getClientIP(request);
    sysLog.setIp(ip);
    //设置地址
    IpData ipData = IpGetAdders.doPostOrGet();
    sysLog.setLocation(ipData.getCname());
    sysLog.setRequestMethod(request.getMethod());
    //设置浏览器
        String header = request.getHeader("User-Agent");
    sysLog.setBrowser(UserAgentUtil.parse(header).getBrowser().toString());
    //设置操作系统
    sysLog.setOs(UserAgentUtil.parse(header).getOs().toString());
    //访问目标方法的参数  可动态改变参数值
    Object[] args=joinpoint.getArgs();
    //获取执行的方法名
    sysLog.setActionMethod(joinpoint.getSignature().getName());
    //类名
    sysLog.setClassPath(joinpoint.getTarget().getClass().getName());
    sysLog.setActionMethod(joinpoint.getSignature().getName());
    sysLog.setParams(Arrays.toString(args));
    String controllerMethodDescription = LogUtil.getControllerMethodDescription(joinpoint);
    sysLog.setDescription(controllerMethodDescription);
    long endTime = Instant.now().toEpochMilli();
    sysLog.setConsumingTime(endTime-beginTime);
}

运行结果:

image.png 数据库日志信息正常记录:

image.png 还有如果是跨服务传递文件也是需要在这里设置不然在另一个服务会丢文件对象,导致文件对象获取不到。
实践是检验真理的唯一方法! 明天见🥰🥰🥰