-
Notifications
You must be signed in to change notification settings - Fork 19
最佳实践
下面简单介绍一下在使用的过程中如何做到最佳实践。
Lofka服务器不做安全校验,所以所有的人都可以向你开放的域名中推送日志数据,或者从WebSocket中读取日志。
日后有增强日志安全性的计划,但是现在还来不及做,所以尽可能保持Lofka只在内网可用。
请勿使用Lofka跨网络传输涉密日志。
对于Java而言,能使用异步就不要使用同步,对于自己开发的日志推送工具也是如此。
- 异步优先于同步
- 异步需要在超时的时候触发保证一定的时效性
- 异步需要在条数超标的时候发送防止积累太多发送中出错
- 不是每一次都需要压缩
- 原则上,超过1k或者超过2k的数据才需要压缩,如果内网带宽无所谓且CPU宝贵可以考虑10k出发压缩
如果你的应用都部署在一个局域网内,那么找一台服务器部署日志系统就可以了。
如果你的应用部署的非常分散(例如两地三中心这种的)推荐的做法是:
- 每一个局域网内都部署一个Lofka服务器;
- 最常用,且方便连接的服务器(称之为X)不要设置转发功能,并且对外开放一个域名(例如logger.example.com)
- 对于服务器X,需要为其配置Kafka+MongoDB持久化
- 对于其他每一个服务器:
- 都向该域名转发自己收集到的所有日志
- 扪心自问一下,该局域网收到的日志是否重要,如果很重要,则在该局域网内配置一套Kafka+MongoDB持久化
- 该域名所属的子系统配置好Lofka服务名称,如果没有特别指定就不需要配置
由于客户的网络环境不一定稳定,推荐单独用作日志服务器,同时具有单独的消息队列和存储层。
如果客户扣的一笔不肯提供单独的存储用于处理日志,至少也配置一台服务器作为转发服务器,转发服务器有如下作用:
- 为所有的日志的app_name加上前缀区别来源(通过配置lofka.application字段,参见:日志服务器配置中参数配置 )
- 在IP链路中增加内网地址防止被运营商混淆
- 在外网不通的时候会自动写入本地文件防止关键日志丢失
目前日志系统还没有支持Https,所以POST的日志都会以明文或压缩过的明文的形式在网上传输。
如果日志涉密,有两种方式进行安全传输:
- 通过安全代理方式直接连接目标机房的局域网的目标机器
- 使用 VPN/Shadowsocks 连接到目标机房内网
- 使用 SSH/GoProxy 做代理来连接
- 其他种种安全代理方式
- 使用Nginx对日志服务器进行代理,并且在Nginx上实现Https。
- 采用类似文件夹层级的命名方式,要能体现系统的层级结构;
- 对于同样功能的单元(例如集群中的节点)应该赋予一样的名称,不一样的单元应该赋予不一样的名称;
- 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大小可以显著提升吞吐量,建议为每个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入库。
为了抗住大规模的数据写入,需要在lofka-kafka.properties
中配置这两项:
# 一次最多写入1M数据
batch.size=1048576
# 最多延迟100ms
linger.ms=100
其目的是通过损失一点实时性,换取批量写入的时候的高性能。
MongoDB建议采用集群的模式,同时,如果业务允许,最好采用 CAPPED COLLECTION
换取更高的写入性能。
Lofka Server 天然支持分片,建议在部署 Kafka 的集群上同时部署 Server,最后使用 Nginx 做负载均衡。
但是有一个例外,即分片以后访问 WebSocket 不能访问到全部的数据,只能访问某个分片的。 但是如果你的数据量已经需要分片了,就不建议通过WebSocket来浏览了,因为这个时候人类也看不过来这么多日志,推荐使用Flink处理你的日志。
批量接口没有直接设置你提交数据的大小,但是不建议一次提交超过10k条日志,过大的 POST BODY 可能导致提交超时,或者直接在入口就被拦下。
Lofka 面向的是 应用程序日志 而非数据处理。 如果你的日志量真的有这么大,可以考虑一下这些东西是否其实是数据而非日志。 包括针对访问的埋点,Nginx的访问记录,这些游走在日志和数据边缘的东西。如果作为数据处理,效率会更高。