java日志系统简介: 从tomcat大量打印debug日志说起
Java 的日志框架生态可能是所有编程语言中最复杂的——不是因为它功能多复杂,而是历史原因导致了多套体系的并存和交叉。本文从一个真实的线上排查案例出发,理清 Java 日志框架的体系结构。 Java 日志体系架构目前 Java 下最主流的两套日志体系是 Log4j 和 SLF4J + Logback。 日志门面 vs 日志实现理解这个区分是搞懂 Java 日志生态的关键: 类型 角色 例子 日志门面(Facade) 只定义接口,不提供具体实现 SLF4J、Commons Logging(JCL) 日志实现 真正的日志写入逻辑 Logback、Log4j 1.x、Log4j 2、java.util.logging(JUL) SLF4J + Logback 是典型的门面+实现分离架构:SLF4J 只包含接口(LoggerFactory、Logger),Logback 是具体实现。分离的好处是代码只依赖 SLF4J 接口,实现可以随时替换。 Log4j 1.x 则同时包含接口和实现——代码直接用 org.apache.log4j.Logger。 桥接器正是因为有...
Java kryo/protobuf/protostuff序列化 or Json 性能对比
为什么需要序列化方案对比对于一个java object的序列化,想测一下使用json和使用一般序列化工具,在时间性能、空间性能上的区别。 json选择用fastjson. 序列化工具使用了protostuff和kyro. 为什么不用protobuf呢?因为感觉对于一个已有的上百个属性的java class来说,再去新建一个匹配的proto文件有点反人类。protostuff是protobuf的改良版本,可以直接将一个java object进行序列化,使用方法与kyro有点类似,没有protobuf那么多中间过程。其他的,hession, java自带序列化之类的,据说性能比kryo和protobuf差很多,就不测了。 时间性能对比简单测了一下,发现差距还挺明显的,所以感觉也不需要做具体的评测了。把日志截一段发出来,大家感受下。 fastjson serilise cost <span class="hljs-number">555805</span> <span class="hljs-built_in"...
java分布式锁入门实战
这篇文章只讲使用,不讲原理,简单粗暴。 分布式锁,顾名思义,就是分布式的锁,应用于一些分布式系统中。例如,有一个服务部在数太机器上,然后有可能操作数据库中的同一条记录。这时,就需要分布式锁。 分布式锁实现的方式很多,一般来说需要一个实体来代表一个锁,占用锁时就新建这个实体,锁释放时也对应将相应实体删除。同时,一般还需要一个锁超时过期的策略,避免一些异常情况造成锁无法被释放。 zookeeper和redis都是常用的实现分布式锁的方式。接下来就简单介绍一下这两种方式的使用。 基于zookeeper的分布式锁使用zookeeper的话,建议直接使用curator客户端. <span class="hljs-tag"><<span class="hljs-title">dependency</span>></span> <span class="hljs-tag"><<span c...
leetcode第三题: 输出不包含重复字母的最长子串
题目Given a string, find the length of the longest substring without repeating characters. Examples: Given “abcabcbb”, the answer is “abc”, which the length is 3. Given “bbbbb”, the answer is “b”, with the length of 1. Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring. 也就是说给定一个字符串,输出不包含重复字母的最长子串长度。 思路遍历一次字符串,O(n)复杂度下可以...
java多线程实现三个字母顺序输出
问题描述主要还是通过一个例子加深一下对java多线程里wait,notify的理解,因此写了一个例子,三个线程分别输出A,B,C三个字母,控制这三个线程的执行顺序,从而实现ABCABCABC..这样的输出。 方案一:synchronized + wait/notify这个问题主要还是需要设计一下锁的策略,这里只是提供了一种方式: 每个线程占用两把锁,分别代表自己(self)和前一个线程(prev), 三个线程的持有锁情况如下表所示: 线程号prev锁self锁 A c a B a b C b c A 首先启动,持有ac, 运行后先释放a, b可以执行。 线程run方法代码如下: <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>(...
一次kafka空间激增排查:kafka的数据压缩、批量发送等
问题过程我司需要接收很多外部数据,数据源的形式很多,ibmmq, activemq, redis pubsub, 等等都有。为了将这些数据接到内部amq/kafka,之前运行了一大批进程,管理起来十分复杂,因此最近用apache-camel对这些进程作了整合。 上线几个小时之后,kafka磁盘空间开始报警。初步断定是这次上线导致的。 排查流程主要还是对kafka不熟悉,只是能用而已,因此排查过程走了不少弯路。 由于camel本身文档很不完善,一开始配置参数时也主要靠看源码+猜,所以首先怀疑配置的压缩参数compressionCodec=gzip是否无效。 因此进行了一次简单的测试(别问我为什么一开始不测)。建了一个单分区的测试topic, 然后分别使用gzip和none模式发送相同的数据,观察kafka的log file文件大小变化趋势。发现压缩确实是有效的。 因此又跟直接使用kafka api作了对比,发现差别非常大,即使是压缩之后,使用camel-kafka占用的空间也比使用api大数倍。然后去查了两边源码,发现最底层的代码是完全一致的,所以还是怀疑某些参...
java里128有何魔力? 聊聊Integer的缓存
Java 的 Integer 缓存机制是一个高频面试题,也是日常开发中容易踩坑的地方。理解它,首先从一个看起来违反直觉的实验开始。 诡异的 1281234567Integer a = 148;Integer b = 148;System.out.println(a == b); // false —— 符合预期,两个不同对象Integer c = 48;Integer d = 48;System.out.println(c == d); // true —— 等等,为什么? 同一个 == 比较,148 返回 false,48 返回 true。原因就在于 Integer 缓存。 IntegerCache 源码分析当 Java 编译 Integer a = 48 时,实际上执行的是: 1Integer a = Integer.valueOf(48); 来看 Integer.valueOf() 的源码(JDK 8): 12345public static Integer valueOf(int i) { if (i >= IntegerCache.lo...
storm/jstorm生态与周边工具,storm连接activemq,kafka,hdfs等
storm的周边生态非常丰富,与kafka,activemq,hdfs,hbase等的交互都有现成的工具包可以使用。大部分工具,包括今天介绍的这几个,在jstorm中也可以完全正常的使用。 storm-jms实现了与activemq等jms实现的交互。 这里主要介绍JmsSpout。由于storm中发送队列数据与普通java程序没有任何区别,专门封装一个bolt显得有些多此一举。 https://github.com/ptgoetz/storm-jms 包中自带了使用spring方式加载队列配置。 使用示例1234567891011121314JmsProvider jmsQueueProvider = new SpringJmsProvider( "jms-activemq.xml", "jmsConnectionFactory", "TEST_QUEUE");JmsTupleProducer producer = new JsonTupleProducer();// JMS Queue S...
jstorm UI 介绍
UI说明jstorm的UI相对于storm提供了更为丰富的监控项。UI本身是在tomcat中运行的一个war包,进行二次开发也相对容易。 cluster页Cluster Summary, Cluster Stats, Topology Summarycluster的整体信息, conf中是nimbus节点的配置。 Topology Summary当前运行的所有topology列表及概要信息,conf中对应的是topology单独配置的配置项。 Supervisor Summary所有supervisor列表, 可以查看supervisor的配置、日志等。 topology页Topology Summary主要关注Topology Graph 项,这是Component Metrics 页的概要信息,可以较直观的看出运行状况。 其中,节点大小和箭头粗细代表数据量,节点颜色用于区分spout和bolt。箭头颜色对应TupleLifeCycle属性,由绿到红越来越慢。箭头变红色时,可以适当增加下游节点的并行度。 Component Metrics包含每个spout, bolt的统计信息...
五分钟学会写storm代码: jstorm/storm编码原理与普通java程序的区别
Storm(以及阿里巴巴开源的 JStorm)是一个分布式实时计算框架。它的编程模型跟传统 Java 程序有一些关键区别,如果不了解这些区别,很容易写出在本地跑得好好的、部署到集群就出各种诡异 bug 的代码。 本文不深入 Storm 内核原理,而是聚焦开发者最需要知道的几个关键区别,帮你快速上手并避开常见坑。 Storm 运行机制速览一个 Storm Topology 由若干 Spout(数据源)和 Bolt(处理逻辑)组成,它们分散运行在多个 Worker(进程)中。同一个 Worker 可能同时运行多个 Spout/Bolt 的多个线程。 关键要理解的是:你的代码会被序列化后分发到各个 Worker 上执行,而不是在提交 Topology 的那台机器上运行。 与传统 Java 程序的三大关键区别1. main 方法只跑在 Nimbus 上main 方法只在提交 Topology 时运行在 Nimbus(Storm 的 master 节点)上。它的作用仅限于构建 Topology 的结构并提交——实际的 Spout 和 Bolt 代码不在 main 方法所在进程...













