拦截器-工作使用

107 阅读4分钟

背景

工作中经常需要解决拦截的功能,所谓拦截,其实就是对每个请求都要拦截。

今天主要讲一下工作使用的几个应用场景。

监控

监控数据库连接池

不管是阿里连接池druid,还是dbcp,都提供了扩展功能,说白了就是继承了连接池框架的特定类之后,就可以读到连接池的实时数据,然后每次执行sql的时候,就会读实时数据并且判断实时数据是否超过阈值,如果超过,就告警。

这就是监控连接池的目的。

刚才说的连接池数据,其实就是读当前活跃连接数量占最大连接数量的比例,比如超过80%,你就告警。

或者,根据监控结果,调整最小最大连接数量的配置。

监控中间件

elasticjob

elasticjob并没有提供节点是否挂了,或者任务执行超时的功能。所以才需要自己去实现。


为什么要监控这两个指标?

1、节点是否挂了
如果节点挂了,相关的功能就会受影响,比如支付之后,我们基于job任务查询渠道是否支付成功,但是节点挂了,就不知道是否支付成功。线下扫码支付的时候,用户支付之后,商家就听不到喇叭播报的声音。

2、任务超时
主要是监控性能怎么样,如果耗时太久,是否需要优化。


实现思路?

1、节点是否挂了
核心思路是,比较任务上一次执行和下一次执行的时间差,如果超过阈值(比如3min),那么就认为节点挂了。

2、任务是否超时
核心思路是,比较任务开始时间和结束时间,如果超过阈值(比如3s),就告警。

rocketmq

主要是监控mq中间件是否挂了和消息积压,中间件都会提供相应的扩展接口,核心步骤就是:
1、自定义扩展接口
2、读实时数据
3、判断实时数据是否超过阈值
如果超过,就告警

注:rocketmq并没有提供相应的监控告警功能,所以才需要自己去实现。

全链路追踪

全链路追踪的本质是日志戳,所谓日志戳,就是日志id,比如订单号,也可以作为日志id。

日志id的作用,就是把整条链路的日志给串起来,知道这些日志是属于哪个请求的。

那具体怎么解决?两个方面: 1、跨服务 2、服务内部

跨服务

比如dubbo,有提供RpcContext这样的工具类,可以让你透传数据,透传数据是指在服务消费者和服务提供者之间传递数据。

具体的方案是两点:RpcContext + 拦截器。

拦截器是dubbo的Filter,在自定义Filter里设置数据到RpcContext之后,服务消费者就可以把数据透传到服务提供者。

服务内部

1、非异步
基于ThreadLocal传递当前线程的数据。

2、异步
其实就是子线程,基于阿里开源项目Transmittable-Thread-Local,说白了,阿里的这个开源项目,看名字就知道,作用就是为了解决主线程传递数据到子线程。

接口调用先走缓存

背景是这样的,比如交易链接很长,依赖了很多外部服务,特别是很多查询服务,比如查询商户信息等等。

现在呢,要提高性能?怎么提高?加缓存。

加缓存,是一方面,而且一般都是在服务提供者加。

但是呢,如果更变态一点,想要在服务消费者就走缓存,因为如果是服务提供者,其实是需要一次rpc通信,现在的话,说白了,就是需要省掉这一次rpc通信,怎么办?其实还是使用同一个缓存数据,写的时候是在服务提供者,读的时候是在服务消费者,说白了,就是在服务提供者和服务消费者配置同一套redis,然后客户端调用服务器的时候,在客户端侧就会拦截每次接口调用,如果有缓存,就先走缓存,如果没有,降级调用接口。

具体的拦截器,dubbo有提供相应的接口Filter,你可以实现它。