1、监控

通过继承 AbstractCacheMonitorConsumer 对监控数据进行消费处理(客户端内部异步线程)

监控源数据

  1. MonitorData {
  2. /**
  3. * 连接资源唯一标识
  4. */
  5. private String cacheType;
  6. /**
  7. * 操作的命令
  8. */
  9. private String commands;
  10. /**
  11. * 缓存的key
  12. */
  13. private String key;
  14. /**
  15. * 如果是批量命令,则通过List传递
  16. */
  17. private List<String> keys;
  18. /**
  19. * 命令执行时间
  20. */
  21. private int executeTime;
  22. /**
  23. * 执行结果,true 成功,false 失败
  24. */
  25. private boolean result;
  26. }

在extend.handle.monitor中,已支持3个监控统计实现

  • CacheCounterMonitorConsumer:count类监控统计,需使用者修改doMonitor实现
  • CacheTimerMonitorConsumer:timer类监控统计,需使用者修改doMonitor实现
  • CacheHotKeyMonitorConsumer:热key监控统计,默认每5秒通过debug方式输出数据

    热key统计监控数据接入方式

    log4j.xml文件中增加配置:允许热keydebug日志输出到hotekey.log

    1. <appender name="redis-hotkey" class="org.apache.log4j.DailyRollingFileAppender">
    2. <param name="File" value="/opt/log/lcache/${log4j.log.dir}/hotekey.log"/>
    3. <param name="DatePattern" value="'.'yyyy-MM-dd"></param>
    4. <layout class="org.apache.log4j.PatternLayout">
    5. <param name="ConversionPattern" value="%m%n"/>
    6. </layout>
    7. </appender>
    8. <logger name="com.lcache.extend.handle.monitor.hotkey" additivity="false">
    9. <level value="debug" />
    10. <appender-ref ref="redis-hotkey" />
    11. </logger>

    使用者可考虑通过Grafana等开源工具输出监控报表

    2、后置处理

    Lcache中的每次操作(CONNECT/COMMANDS)都通过统一的执行调度器进行执行,并在内部集成了多级缓存与各种后置处理;
    通过实现 AbstractHandlePostProcessor 抽象类扩展

    1. public abstract class AbstractHandlePostProcessor implements InterfaceHandlePostProcessor {
    2. /**
    3. * 获取优先级Id,ID高先执行前置,后执行后置、成功、失败,可以理解为洋葱,外层包内层,核心是handle
    4. *
    5. * @return
    6. */
    7. public abstract int getOrder();
    8. /**
    9. * 获取处理器Id,后置处理工厂通过此ID进行唯一校验
    10. *
    11. * @return
    12. */
    13. public abstract int getHandlePostId();
    14. /**
    15. * 获取处理器类型,支持 CONNECT 与 HANDLE
    16. *
    17. * @return
    18. */
    19. public abstract HandlePostProcessorTypeEnum getHandleType();
    20. /**
    21. * 获取客户端类型,支持 RedisClientConstants.JEDIS 与 RedisClientConstants.LETTUCE
    22. *
    23. * @return
    24. */
    25. public abstract int getClientType();
    26. @Override
    27. //如果指定了命令,则使用限定命令
    28. public Set<String> specifiedCommands() {
    29. return null;
    30. }
    31. /**
    32. * 注册实现类到工厂
    33. */
    34. @PostConstruct
    35. public void registerIntoPostFactory(){
    36. HandlePostFactory.addBeanPostProcessor(this);
    37. }
    38. @Override
    39. public void handleBefore(CacheHandleProcessorModel cacheHandleProcessorModel) {
    40. }
    41. @Override
    42. public void handleAfter(CacheHandleProcessorModel cacheHandleProcessorModel) {
    43. }
    44. @Override
    45. public void onSuccess(CacheHandleProcessorModel cacheHandleProcessorModel) {
    46. }
    47. @Override
    48. public void onFail(CacheHandleProcessorModel cacheHandleProcessorModel) {
    49. }
    50. }

    后置处理支持灵活扩展,Lcache中默认实现3个后置处理:

  • JedisHandlesPostProcessor:onFail中捕获Lua脚本异常,并进行重新缓存,保证Lua脚本缓存自动化执行高可用;

  • JedisPubSubPostProcessor:subscribe 命令进入,onFail增加重试保证Jedis的消费闪断重连;
  • LettuceHandlesPostProcessor:onFail中增加Lua脚本异常处理与Lettuce单连接自动重连功能;

    后置处理执行流程

    image.png
  1. 后置处理工厂将后置处理器根据orderId进行倒排,调用前置处理;
  2. 前置执行处理完毕后执行命令;
  3. 将后置处理器根据orderId再进行一次倒排,调用后置、成功、失败处理;

    后置处理上下文数据

    1. public class CacheHandleProcessorModel {
    2. /**
    3. * 命令
    4. */
    5. private String commands;
    6. /**
    7. * key
    8. */
    9. private String key;
    10. /**
    11. * keys
    12. */
    13. private List<String> keys;
    14. /**
    15. * 方法
    16. */
    17. private CacheFunction function;
    18. /**
    19. * 执行结果
    20. */
    21. private Object result;
    22. /**
    23. * 命令执行时间
    24. */
    25. private Long executeTime;
    26. /**
    27. * 配置
    28. */
    29. private CacheConfigModel cacheConfigModel;
    30. /**
    31. * 异常信息
    32. */
    33. private Exception e;
    34. }