使用Flume Log4j Appender正确的姿势

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: <br><div style="orphans:2; widows:2; font-size:13px; margin:0px; font-family:Monaco,Menlo,'Ubuntu Mono',Consolas,source-code-pro,SimSun,Song,宋体,幼圆,Heiti,黑体,文泉驿等宽正黑,文泉驿正黑,monospace"> <h2 style="fo

使用Flume Log4j Appender正确的姿势

我们使用Flume-ng的LoadBalancingLog4jAppender,将线上服务的日志实时传输到日志服务器,转交给告警系统和HDFS做存储。
FLume的Log4j Appender必须使用Log4j的异步加载器,否则一旦日志服务器挂掉,将会导致应用服务器宕机。

使用过程中的坑

问题1: Flume Log4j使用异步加载器,日志服务器宕机情况导致业务系统阻塞

在阅读了Flume的RPC源码以及LoadBalancingLog4jAppender的实现之后,发现问题原来在Log4j的异步加载器AsyncAppender。异步加载器的原理见这里
根本原因是、日志服务器宕机导致消费者消费能力不足,缓冲区满的情况下,AsyncAppender会阻塞程序。设置Blocking=false之后就可以了。

问题2:Flume Log4j失败重连策略异常

当其中一台日志服务器宕机,其他的日志服务器就会不停的接收到链接异常的日志。明显是重连的时间间隔太短。在LoadBalancingRpcClient中,

    while (it.hasNext()) {
      HostInfo host = it.next();
      try {
        RpcClient client = getClient(host);
        client.append(event); 
        eventSent = true;
        break;
      } catch (Exception ex) {
        selector.informFailure(host); //宕机情况标志该主机异常
        LOGGER.warn("Failed to send event to host " + host, ex);
      }
    }

Flume默认不启用back off,也就是说selector.informFailure(host)这行代码完全没用。简直坑爹。OrderSelector.java:

  public void informFailure(T failedObject) {
    //If there is no backoff this method is a no-op.
    if (!shouldBackOff) {
      return;
    }
    //将该主机暂时移除可用主机列表
    ...

所以解决办法:配置max back off

问题3:Flume Log4j失败重连策略异常

问题体现在,设置了max back off,重连时间居然一直是2000ms,看了一下它的算法,指数退避算法。在OrderSelector.java的informFailure函数中。

  public void informFailure(T failedObject) {
    //If there is no backoff this method is a no-op.
    if (!shouldBackOff) {
      return;
    }
    FailureState state = stateMap.get(failedObject);
    long now = System.currentTimeMillis();
    long delta = now - state.lastFail;
    long lastBackoffLength = Math.min(maxTimeout, 1000 * (1 << state.sequentialFails));
    long allowableDiff = lastBackoffLength + CONSIDER_SEQUENTIAL_RANGE;
    if (allowableDiff > delta) {
      if (state.sequentialFails < EXP_BACKOFF_COUNTER_LIMIT) {
        state.sequentialFails++;
      }
    } else {
      state.sequentialFails = 1;
    }
    state.lastFail = now;
    //Depending on the number of sequential failures this component had, delay
    //its restore time. Each time it fails, delay the restore by 1000 ms,
    //until the maxTimeOut is reached.
    state.restoreTime = now + Math.min(maxTimeout, 1000 * (1 << state.sequentialFails));
  }

最后生成的restoreTime即下一次进行重试的时间。我没有去设置avro connect time out 和request time out,默认都是20s,应该算是偏长了。根据他的算法,delta永远是大于40s,但是allowableDiff却一直是3s,4s.所以我直接改了判定条件,allowableDiff < delta,之后就正常。但是还存在一个问题,sequentialFails并不会在一段时间后reset.

问题4:Log4j异步加载器丢失日志数据

AsyncAppender默认缓冲区大小128,满了之后会丢失数据。调大缓冲区,avro connect time out 和request time out也得适当调一下

另外,由于我们的告警系统接收的告警日志必须是时间顺序的,所以我写了个FlumeFailoverAppender了

https://github.com/EdwardsBean/FlumeFailoverLog4jAppender

本博客已迁移至:http://edwardsbean.github.io

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
Java
flume的log4j.properties配置说明
flume的log4j.properties配置说明
|
分布式计算 Hadoop 分布式数据库
SLF4J: Hbase和Flume的slf4j-log4j12-x.x.xx.jar与hadoop的slf4j-log4j12-x.x.xx.jar冲突
SLF4J: Hbase和Flume的slf4j-log4j12-x.x.xx.jar与hadoop的slf4j-log4j12-x.x.xx.jar冲突
181 0
SLF4J: Hbase和Flume的slf4j-log4j12-x.x.xx.jar与hadoop的slf4j-log4j12-x.x.xx.jar冲突
|
监控 Java
通过Alibaba Cloud Log Log4j Appender采集日志到阿里云日志服务
Log4j是Apache的一个开放源代码项目,通过使用Log4j,您可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;您也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,您能够更加细致地控制日志的生成过程。
5659 0
|
Arthas Java 测试技术
Java技术周刊第9期:自定义log4j的appender写es日志
Java的开发者们:云栖社区已有5000位Java开发者,发布了30000+Java文章(文章列表),沉淀了7000+的Java精品问答(问答列表)。 Java技术周刊将会为大家介绍最新的Java技术与动态、预告活动、最热问答、直播教程等,欢迎大家订阅Java技术周刊。
7628 0
|
监控 Java Docker
自定义log4j的appender写es日志
本篇和大家分享的是自定义log4j的appender,用es来记录日志并且通过kibana浏览es记录;就目前互联网或者一些中大型公司通常会用到第三方组合elk,其主要用写数据到es中,然后通过可视化工具kibana来做直观数据查看和统计;本篇内容节点如下: docker快速搭建es,es he...
4062 0
|
Web App开发 存储 监控
Flume + Solr + log4j搭建web日志采集系统
首先我们有多个web 应用,每个web应用每天都有不断的日志产生,这些日志文件现在以文件的形式存储在服务器当中,我们需要收集这些日志,并对日志进行查询。 所以整个流程就是,Flume agent 收集日志 -> Morphline 进行过滤 -> 对结果进行索引然后在Solr中进行搜索。
2350 0
|
分布式计算 Hadoop Java
log4j2+flume+hadoop
数据采集框架
3732 0