调优历程: 我是怎样将一个系统的性能提高20倍的?

调优历程: 我是怎样将一个系统的性能提高20倍的?
最近从米国接收一个新的项目, 项目使用Spring + CXF 处理遵循行业规范的消息,并根据一定的规则将消息转发给其它的一个或者多个产品。
因为刚接手, 先对其进行功能的测试和测试其benchmark。 结果Beanchmark在AWS x3.xlarge机器上10个并发只能达到几十个TPS。
基于我前面的文章的对tomcat和其它框架的性能数据, 可以很自信的说, 这不科学。
经过一番紧张的基于性能考虑的调整,单台服务器终于达到了100个并发每秒能处理3000 多个的请求。

阅读全文

Javacodegeeks网站上关注度最高的几篇文章

Javacodegeeks 网站提供了一系列优秀的关于Java语言的论文。 本文整理罗列了关注度比较高的几篇文章。很多优秀的文章已经被翻译成了中文,读者可以对照着阅读。

  • 115 Java Interview Questions and Answers – The ULTIMATE List 由Sotirios-Efstathios Maneas发表于2014年4月。 文章列出了常见的Java面试题,但是我觉得关于Swing/AWT的问题可以删除了,还有多少现代的公司使用这种技术? 倒是可以将泛型,反射等技术的问题加上。 很遗憾的是这篇文章并没有设计并发编程的问题。

中文翻译请参考: 115个Java面试题和答案(上), 115个Java面试题和答案(下)
importnew还翻译了DZone网站的另外一篇Java面试题相关的文章: Java面试参考指南(一)Java面试参考指南(二)

中文翻译请参考: Java 8新特性终极指南

中文翻译请参考: 关于Spring的69个面试问答——终极列表

Java序列化框架性能比较

jvm-serializers提供了一个很好的比较各种Java序列化的的测试套件。 它罗列了各种序列化框架, 可以自动生成测试报告。
我在AWS c3.xlarge机器上进行了测试,一下是测试报告与解析。

关键的测试数据的统计代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public double runWithTimeMeasurement(int timeMillis, TestCase tc, int iterations) throws Exception
{
long start = System.currentTimeMillis();
double sumTime = 0;
int count = 0;
System.err.println("test-time "+timeMillis+" iteration "+iterations);
while ( System.currentTimeMillis()-start < timeMillis )
{
double time = tc.run(transformer, serializer, value, iterations);
sumTime += time;
measurementVals[count] = time;
count++;
}
double avg = sumTime / count;
Arrays.sort(measurementVals,0,count);
System.err.println("-----------------------------------------------------------------------------");
System.err.println(serializer.getName());
System.err.println("min:" + measurementVals[0]);
System.err.println("1/4:"+measurementVals[count/4]);
System.err.println("1/2:"+measurementVals[count/2]);
System.err.println("3/4:"+measurementVals[count/4*3]);
System.err.println("max:"+measurementVals[count-1]);
System.err.println("average:"+ avg +" deviation:"+(avg-measurementVals[count/2]));
System.err.println("-----------------------------------------------------------------------------");
return avg;
}

测试时序列化和反序列化会迭代多次,默认2000次。 测试会有一个限定时间,一轮测试完成后时间还有的话还会继续新的一轮的测试。 因此, 由于不同的框架花费的时间不同, 测试的轮数也不一样。

阅读全文

一些开源项目的性能基准Benchmark

项目中使用了好些的开源项目。对于它们的性能, 只有官方的一些性能报告和一些第三方的性能分析。 做性能估计的时候只是根据以往的经验做估算。 随着软件的不断升级,以及服务器硬件配置的升级, 这些开源项目的性能也有了变化。以前的性能数据可能不太准确了。
所以这篇文章记录了当前(2014年秋)我在AWS机器上做的一些性能数据,期望在做软件架构的时候有所帮助。
当前测试的软件包括:

  • Tomcat
  • Jetty
  • Vert.x
  • Memcached
  • MongoDB
  • Java serializers
  • CXF
  • Spring MVC

这篇文章会不断更新, 将我最新的测试列出来。

阅读全文

<翻译> 如何利用Bloom Filter在Java中构建大规模基于内存的缓存

原文地址: http://www.javacodegeeks.com/2014/07/how-to-use-bloom-filter-to-build-a-large-in-memory-cache-in-java.html

缓存(Cache)是用来解决当下软件性能问题时需要考虑的一个很重要的手段。 你的程序可能有密集的CPU操作,而你却不想一遍又一遍的折磨CPU。 相反, 你会将结果抽取出来并缓存到内存中。 有时候系统的瓶颈也可能是IO操作, 比如你不想重复执行数据库的查询,而是把查询结果缓存起来, 只是在数据库的数据改变的时候才去更新缓存。

类似地还有一些其它需要cache的情况如处理收到的request时我们需要执行一个快速的查询。例如, 你需要判断一个URL是否指向了一个恶意网站。 可能有非常多的(恶意网站的)URL, 如果我们将所有的恶意网址都缓存起来, 需要很大的空间。 又比如我们需要识别用户输入的字符串中是否包含美国的一个地方。 比如用户输入华盛顿的博物馆, 这个字符串中华盛顿是美国的一个地名。 我们要把美国所有的地名缓存起来以供查找? 缓存会变得多大?没有数据库支持的这样做是否有效?
这就是我们淘汰map数据结构而去宣召一个更先进数据结构-boomfilter。 你可以把blommfilter看作类似java collection中的类。 可以把数据项放到它里面,可以检查某个数据项是否已经存在。 如果Bloomfilter说数据项不存在, 那数据项的确不存在, 不必怀疑。 但是如果它说数据项存在, 可能是误报, 有可能数据项真的不存在。 如果我们考虑周全, 就能减少误报的可能。

阅读全文

java bean对象之间复制属性

在现在的企业级Java应用程序中, Java Bean被广泛的应用。 一堆的相关的划分也应运而生, 如DTO, DAO, BO, POJO, VO等。这里不去管这些概念的细节, 如果你感兴趣,可以google之, 比如这篇文章。 这里要讨论的问题是如何在不同的Java Bean对象之间复制它们的属性?
这有几种情况需要考虑:

  • 源对象和目标对象的类型可能不同
  • 只想复制部分的对象
  • 要复制的对象的属性名字不同
  • 如何实现深复制 (deep copy)?

阅读全文

使用MongoDB作为Quartz JobStore

Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。你可以到 http://www.quartz-scheduler.org/站点下载 Quartz 的发布版本及其源代码。目前最新的版本是2.2.1。

作为一个优秀的开源调度框架,Quartz 具有以下特点:

  • 强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求;
  • 灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;
  • 分布式和集群能力,Terracotta 收购后在原来功能基础上作了进一步提升。本文暂不讨论该部分内容

另外,作为 Spring 默认的调度框架,Quartz 很容易与 Spring 集成。

下面是Quartz中的一些术语:

  • scheduler: 任务调度器
  • trigger: 触发器,用于定义任务调度时间规则
  • job: 任务,即被调度的任务
  • misfire: 错过的,指本来应该被执行但实际没有被执行的任务调度

阅读全文

Java bean validation 规范与参考实现

JSR 303 – Bean Validation 是一个数据验证的规范。 2009年11月正式发布最终版本。
在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。在通常的情况下,应用程序是分层的,比如表现层,业务层,持久化层等,很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定,为各个层提供统一的数据校验。

Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations,通过使用 XML 可以对Java注解信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以确保数据模型(JavaBean)的正确性。在JSR303规范中,constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。

Hibernate Validator 4.0是 JSR 303 的参考实现。

IBM developerWorks网站有一篇很好的文章介绍它。

JSR 349是Bean Validation 1.1规范,根据社区的反馈对JSR 303进行了优化和加强。 可以点击这里查看细节。
主要围绕一下方面进行工作。

  • 集成其它最新发布的JSR
  • JAX-RS: 对HTTP method进行参数和返回值的校验
  • JAXB: 集成JAXB.
  • JPA: 提升JPA的集成
  • CDI: 允许CDI风格的注入
  • CDI: 集成方法级别的校验
  • EJB: 集成方法级别的校验
  • JSF: 集成JSF

Hibernate Validator 5.x 是Bean Validation 1.1参考实现。

阅读全文

Metrics介绍和Spring的集成

Metrics可以为你的代码的运行提供无与伦比的洞察力。作为一款监控指标的度量类库,它提供了很多模块可以为第三方库或者应用提供辅助统计信息, 比如Jetty, Logback, Log4j, Apache HttpClient, Ehcache, JDBI, Jersey, 它还可以将度量数据发送给Ganglia和Graphite以提供图形化的监控。

Metrics提供了Gauge、Counter、Meter、Histogram、Timer等度量工具类以及Health Check功能。

Metrics Graphite dashboard

阅读全文