公共日志服务系统详细设计

上一篇:公共日志服务系统设计

简介:本篇文章将详细介绍公共日志服务系统中的基础信息获取

背景:众所周知,我们现在系统服务类型纷繁复杂,但从大的方面来说,主要分为一下几类。第一,http 服务,主要提供给前端或者其他的公司的同学调用;第二,RPC服务,类似于dubbo ,Spring cloud 等提供的服务。因为笔者的公司主要是使用的dubbo 所以这次文中所提及的RPC服务都指dubbo 服务;第三,就是一些定时的任务系统了;那么针对于这几种服务类型,我们应该用什么样的方式来收集基础的用户和应用信息呢?下面将分别介绍

基础信息获取

   1、http服务类型,这种类型的服务提供给别人调用时,比如我们提供给前端的数据调用接口。对于这种接口笔者的公司会由网关加入SSO验证,所以通过网关能够拿到用户的信息。所以就有必要在具体的数据操作之前,通过拦截器获取到用户的基础信息。见代码:

// 实现Spring 拦截器 HandlerInterceptor 将请求拦截下来进行处理
public class UserInfoCollectInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(UserInfoCollectInterceptor.class);

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            StringBuffer url = request.getRequestURL();
            getAuthUser(url.toString());
        }catch (Exception e){

        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

下面再看看getAuthUser 方法
 

/**
     * 收集应用信息
     * @param
     */
    protected void getAuthUser(String url) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        ThreadLocal<Map<String, String>> threadLocalMap = ThreadLocalCarrier.threadLocalMap;
        Map<String, String> stringMap = new HashMap<>(16);

        //缓存内容传递至下一节点
        stringMap.put(CommonLogConstant.VALUE_ENV, MySpringContextHelper.getProperty(CommonLogConstant.VALUE_ENV));
        stringMap.put(CommonLogConstant.VALUE_APPID, MySpringContextHelper.getProperty(CommonLogConstant.VALUE_COMMONLOG_APPID));
        stringMap.put(CommonLogConstant.VALUE_APPNAME, MySpringContextHelper.getProperty(CommonLogConstant.VALUE_COMMONLOG_APPNAME));
        stringMap.put(CommonLogConstant.VALUE_DESCRIBE, MySpringContextHelper.getProperty(CommonLogConstant.VALUE_COMMONLOG_DESCRIBE));
        stringMap.put(CommonLogConstant.VALUE_SERVICE_URL, url);
            }
        }catch (Exception e){
        }finally {
            threadLocalMap.set(stringMap);
        }

    }

只能贴出部分源码,大概讲一下,定义了一个ThreadLocal,再定义一个Map 然后将能够收集到的基础信息都放到ThreadLocal 里面,然后请求继续往下走,如果这个请求设计到数据更新的操作,那么这个请求会进入到mybatis 拦截器。这个是http 请求获取用户基础信息的方式。
dubbo 请求收集基础信息的方式

 刚开始的时候我们在 Consumer端通过 RpcContext 注入服务调用方的一些基础信息,类似于这样:

RpcContext.getContext().setAttachment("userKey", "userValue");  

不过RpcContext 存在一个问题,RpcContext是一个ThreadLocal的临时状态记录器,当接收到RPC请求,或发起RPC请求,RpcContext的状态都会发生变化。比如,A ---->B, B 能够拿到A的RpcContext里面的信息,B---->C C能够拿到B的RpcContext 的信息。不过 有个问题,加入 A先调B,完了以后,A再调C,那么C就取不到A 调用B之前注入的RpcContext 里面的信息了,因为调用完B以后,这个RpcContext 的信息就被清掉了。由于我们的后端很多的dubbo服务都是存在多重调用的,所以就会造成早在我们真正需要RpcContext 的服务提供方拿不到这个信息。查了些资料,找到了如下的方式解决,通过dubbo 的拦截器来注入所需要的服务信息。

代码如下:

public abstract class DubboProfilerFilterTemplate implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        consumerInvoke(ThreadLocalCarrier.getThreadLocalMap());
        RpcContext rpcContext = RpcContext.getContext();
        providerInvoke(rpcContext);
        return invoker.invoke(invocation);

    }

    /**
     * @title 消费调用端拦截器
     * @description 
     * @param threadLocalMap
     * @return 
     * @throws 
     */
    abstract void consumerInvoke(Map<String, String> threadLocalMap);
    
    /**
     * @title 生产服务端拦截器
     * @description 
     * @param 
     * @return 
     * @throws 
     */
    abstract void providerInvoke(RpcContext rpcContext);
}

这样就能在服务消费端注入应用的基本信息,在服务的提供方拿到信息,为后序的进一步处理做好铺垫。

后序设计

拿到完整的应用信息以后,进一步做拦截处理。解析sql ---> 信息重组----> 发送mq---->服务消费写入ES----->提供个性化查询接口----> 前端展示。

本文旨在提供一个日志服务系统的设计思路,贴出的源码仅供参考,大部分还是需要自己设计的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值