Skip to content

最佳实践

Yuan Yifan edited this page Dec 11, 2018 · 4 revisions

最佳实践

下面简单介绍一下在使用的过程中如何做到最佳实践。

日志安全

Lofka服务器不做安全校验,所以所有的人都可以向你开放的域名中推送日志数据,或者从WebSocket中读取日志。

日后有增强日志安全性的计划,但是现在还来不及做,所以尽可能保持Lofka只在内网可用。

请勿使用Lofka跨网络传输涉密日志。

日志接入最佳实践

对于Java而言,能使用异步就不要使用同步,对于自己开发的日志推送工具也是如此。

  • 异步优先于同步
    • 异步需要在超时的时候触发保证一定的时效性
    • 异步需要在条数超标的时候发送防止积累太多发送中出错
  • 不是每一次都需要压缩
    • 原则上,超过1k或者超过2k的数据才需要压缩,如果内网带宽无所谓且CPU宝贵可以考虑10k出发压缩

多机房日志统一收集最佳实践

如果你的应用都部署在一个局域网内,那么找一台服务器部署日志系统就可以了。

如果你的应用部署的非常分散(例如两地三中心这种的)推荐的做法是:

  1. 每一个局域网内都部署一个Lofka服务器;
  2. 最常用,且方便连接的服务器(称之为X)不要设置转发功能,并且对外开放一个域名(例如logger.example.com)
  3. 对于服务器X,需要为其配置Kafka+MongoDB持久化
  4. 对于其他每一个服务器:
    1. 都向该域名转发自己收集到的所有日志
    2. 扪心自问一下,该局域网收到的日志是否重要,如果很重要,则在该局域网内配置一套Kafka+MongoDB持久化
    3. 该域名所属的子系统配置好Lofka服务名称,如果没有特别指定就不需要配置

由于客户的网络环境不一定稳定,推荐单独用作日志服务器,同时具有单独的消息队列和存储层。

如果客户扣的一笔不肯提供单独的存储用于处理日志,至少也配置一台服务器作为转发服务器,转发服务器有如下作用:

  • 为所有的日志的app_name加上前缀区别来源(通过配置lofka.application字段,参见:日志服务器配置中参数配置 )
  • 在IP链路中增加内网地址防止被运营商混淆
  • 在外网不通的时候会自动写入本地文件防止关键日志丢失

关于日志安全的小Tips

目前日志系统还没有支持Https,所以POST的日志都会以明文或压缩过的明文的形式在网上传输。

如果日志涉密,有两种方式进行安全传输:

  1. 通过安全代理方式直接连接目标机房的局域网的目标机器
    • 使用 VPN/Shadowsocks 连接到目标机房内网
    • 使用 SSH/GoProxy 做代理来连接
    • 其他种种安全代理方式
  2. 使用Nginx对日志服务器进行代理,并且在Nginx上实现Https。

应用名称命名最佳实践

  1. 采用类似文件夹层级的命名方式,要能体现系统的层级结构;
  2. 对于同样功能的单元(例如集群中的节点)应该赋予一样的名称,不一样的单元应该赋予不一样的名称;
  3. app_name中应该尽可能的少出现特殊符号和中文。

这样做的目的是为了使日志的结构更加的清晰,以后可能会支持前缀语法的app_name过滤器。

命名示例:

  • google/online/database/mycat/node
  • google/online/bigdata/spark/driver
  • h5app/server/web
  • h5app/server/dubbo
  • h5app/database/mycat

同时需要注意,如果一套系统有自己的日志服务器,而且服务器的系统名称已经设置(参见高级应用/日志服务器配置例如h5app),那么应该省略开头,例如h5app内的应用名称如下所示即可:

  • server/web
  • server/dubbo
  • database/mycat

在转发的时候会被日志服务器自动变更为:

  • h5app/server/web
  • h5app/server/dubbo
  • h5app/database/mycat

性能调优最佳实践

目前的日志系统没有考虑日志蜂蛹而入的情况,所以,我在生产系统上一般都使用-Xmx1G -Xms1G的配置,绰绰有余了。

如果你的日志特别多,特别变态的话,你需要考虑几个方面的因素来承受较大的压力。

增加Heap内存的大小,使用 Java 11

增加Heap大小可以显著提升吞吐量,建议为每个Server分配4G内存,可以打满 100MBps 的网卡。

而使用 Java 11 可以显著减少GC带来的性能损耗和Pause。

异步入库

例如如下的配置

[
  {
    "sourceType": "local",
    "config": {
      "register.name":"shard-local"
    },
    "processors": {
      "mongodb-saver-0": {
        "processorType": "mongodb",
        "config": {
          "mongodb.collection": "lofka",
          "mongodb.database": "logger",
          "mongodb.deprecate.time": "3600000",
          "mongodb.expired.setting.DEBUG": "600000",
          "mongodb.expired.setting.DEFAULT": "2678400000",
          "mongodb.expired.setting.ERROR": "31622400000",
          "mongodb.expired.setting.FATAL": "63244800000",
          "mongodb.expired.setting.INFO": "86400000",
          "mongodb.expired.setting.NGINX": "16416000000",
          "mongodb.expired.setting.TRACE": "300000",
          "mongodb.expired.setting.WARN": "2678400000",
          "mongodb.servers": "127.0.0.1:27017"
        }
      }
    }
  }
]

会将服务器收集到的所有的数据以同步的方式写入 MongoDB,在峰值的时候可能造成积压,甚至造成服务器失去响应。

推荐采用异步入库,即,不要在Server端配置lofka-persistence.json,而是单独打包lofka-persistence模块,然后使用如下配置:

[
  {
    "sourceType": "kafka",
    "config": {
      "auto.commit.interval.ms": "99999999",
      "auto.offset.reset": "latest",
      "bootstrap.servers": "data1:9092,data2:9092,data3:9092",
      "enable.auto.commit": "true",
      "group.id": "logger-json-persistence-consumer",
      "kafka.topic": "logger-json",
      "key.deserializer": "org.apache.kafka.common.serialization.IntegerDeserializer",
      "value.deserializer": "org.apache.kafka.common.serialization.StringDeserializer"
    },
    "processors": {
      "mongodb-saver-0": {
        "processorType": "mongodb",
        "config": {
          "mongodb.auth": "logger_write:logger_write@logger",
          "mongodb.collection": "lofka",
          "mongodb.database": "logger",
          "mongodb.deprecate.time": "3600000",
          "mongodb.expired.setting.DEBUG": "600000",
          "mongodb.expired.setting.DEFAULT": "2678400000",
          "mongodb.expired.setting.ERROR": "31622400000",
          "mongodb.expired.setting.FATAL": "63244800000",
          "mongodb.expired.setting.INFO": "86400000",
          "mongodb.expired.setting.NGINX": "16416000000",
          "mongodb.expired.setting.TRACE": "300000",
          "mongodb.expired.setting.WARN": "2678400000",
          "mongodb.servers": "127.0.0.1:27017"
        }
      }
    }
  }
]

从Kafka接受数据以后再入库,让Kafka承受峰值的压力。

注意:如果单节点入库有困难,可以利用night-watcher入库。

Kafka 参数调整

为了抗住大规模的数据写入,需要在lofka-kafka.properties中配置这两项:

# 一次最多写入1M数据
batch.size=1048576
# 最多延迟100ms
linger.ms=100

其目的是通过损失一点实时性,换取批量写入的时候的高性能。

MongoDB 调整

MongoDB建议采用集群的模式,同时,如果业务允许,最好采用 CAPPED COLLECTION 换取更高的写入性能。

Server 集群

Lofka Server 天然支持分片,建议在部署 Kafka 的集群上同时部署 Server,最后使用 Nginx 做负载均衡。

但是有一个例外,即分片以后访问 WebSocket 不能访问到全部的数据,只能访问某个分片的。 但是如果你的数据量已经需要分片了,就不建议通过WebSocket来浏览了,因为这个时候人类也看不过来这么多日志,推荐使用Flink处理你的日志。

接口调用参数设置

批量接口没有直接设置你提交数据的大小,但是不建议一次提交超过10k条日志,过大的 POST BODY 可能导致提交超时,或者直接在入口就被拦下。

最后

Lofka 面向的是 应用程序日志 而非数据处理。 如果你的日志量真的有这么大,可以考虑一下这些东西是否其实是数据而非日志。 包括针对访问的埋点,Nginx的访问记录,这些游走在日志和数据边缘的东西。如果作为数据处理,效率会更高。

Clone this wiki locally