日志技术选型
Log 门面层选型
《阿里巴巴 Java 开发规范》【强制】应用中不可使用日志系统(Log4J、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API。使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
上面所说的是阿里 Java 开发规范中的规则,应用必须使用门面模式的日志框架,首选我们回顾一下门面设计模式。
门面模式,又叫外观模式,它为子系统中的一组接口提供一个统一的高层接口,使的子系统更容易使用。使用门面模式的优点是:
解耦,通过统一对外的接口,屏蔽了与子系统的依赖和子系统的复杂性。
提高了灵活性,子系统内部的变化,只要不影响到门面对象,任其变化。其结构见下图。
image.png
通过上面的回顾,我们也了解了门面设计模式。应用使用门面模式的日志框架,可以部署时,根据需要切换不同的日志框架。Java 中有哪些门面模式的日志框架呢?常见的有 Apache Common-Logging、SLF4J。
Commons Logging 实现机制:
Apache Common-Logging 使用了 ClassLoader 寻找和载入底层的日志库,存在一定加载问题。
SLF4J 实现机制:
SLF4J 在编译期间,静态绑定本地的 Log 库。它是通过查找类路径下 org.slf4j.impl.StaticLoggerBinder,然后在 StaticLoggerBinder 中进行绑定。使用 SLF4J 时,需要指定具体的日志器实现,常用的 Log4j、Log4j2、Logback、JDK-logging、SLF4J-simple 都可以实现,对于不同的日志实现方案,封装出不同的桥接组件。下图是 SLF4J 与各组件 API 打通的的相关方案。
image.png
门面框架的选择:
考虑到 SLF4J 的广泛通用性及静态编译支持,门面层使用 SLF4J 作为日志 API 层选型。
日志引擎层技术选型
下图是各个日志框架性能测试如下(来自 Log4j2 官方网站):
image.png
下图是 garbage-free async loggers (无垃圾异步模式)在测试的所有配置中都具有最佳响应 time 行为。
image.png
根据以上数据显示,Log4j2 通过异步化支持及队列的使用使性能得到的极大的提升。这是如何工作的,应用线程完成了最少量的工作来捕获 log event 中的所有必需信息,然后将此 log event 放在队列中以供后续线程稍后处理。如果队列的大小足够大,那么应用线程应该能够在 logging 调用上花费很少的 time,并且非常快速地返回到业务逻辑。
事实证明,队列的选择对于峰值吞吐量非常重要。 Log4j2 的 Async Loggers 使用无锁数据结构(Disruptor),而 Logback、Log4j 1.2 和 Log4j2 的异步 Appenders 使用 ArrayBlockingQueue。使用阻塞队列时,对线程应用在尝试将 log event 排入队列时经常会遇到锁争用。所以 Log4j2 的 Async Loggers 在一定程度上提供更好的吞吐量,但是一旦队列已满&#