2011年2月22日星期二

Java Basic Diagnosis Tool

    之前遇到过几次Java占用CPU过多的问题,去定位问题的办法也很简单,主要是就是通过 top -H -p javapid,看一下哪些Java的线程占用CPU多,然后通过jstack,dump java的线程,然后去看下这些线程具体再做什么。
    不过人肉去做这个事情,很麻烦,写了一个简单的工具,放在了google code上,也希望能偶有更多人把一些类似这样比较基础的、但是能够减少人肉的工具也放上来,方便需要去查问题的人。
   具体 google code中project的地址是 http://code.google.com/p/java-basic-diag-tool/

2011年2月4日星期五

Java HashMap的并发问题

    使用Java的同学应该都是知道HashMap是线程不安全的,不能够并发的去put和get,如果有并发操作,会抛出ConcurrentModificationException这个异常。不过可能很多同学没有注意,这个异常并不是一定会抛出的。而并发的去对HashMap对象进行put和get的结果,是可能造成死循环。
     年前在线上,也遇到了这么一次。当时是有同学找过来,说有台机器的load很高,已经启动了流量控制,也没有请求进到容器中。后来dump了thread,也通过top -H看到占用CPU比较高的线程,发现都是在执行HashMap.get,想到可能就是上面的原因,后来看了源码,发现确实是这么一个问题。
具体对于HashMap在并发操作时陷入死循环的分析,可以参看这篇博客 http://pt.alibaba-inc.com/wp/dev_related_969/hashmap-result-in-improper-use-cpu-100-of-the-problem-investigated.html

充实与效率

    先讲一个发生在自己身上的故事。
    最近跟IP地址搞上了, 需要把形如a.b.c.d的ip地址转为数值型表示,然后根据网段的起始和结束地址,确定所在的ISP。
在调试和运行的过程中,会需要把数值型的地址转为形如a.b.c.d,然后需要用whois去查询这个a.b.c.d所属的ISP。
开始的时候,是手工的处理了几个地址,用计算器,把数值型转为a.b.c.d;通过命令行的whois去查询信息,然后人肉看一下whois的结果。
发现这个过程真的烦,写了一个python程序,代替计算器做的事情,爽了一些。
后面,用程序实现了命令行whois的功能。
再后来,自己分析了whois查询后的结果。
到这三步做完,基本上是从原来纯手工的工作,变为了自动化的过程。
其实这三步工作变为程序来做,本身没什么很大的困难,这里想记录的,也是想提醒自己和大家的是,大家要能够了解,让自己每天都很充实是没错的,但是需要注意自己的效率。
这也就是很多人会说的要聪明的读书、聪明的学习,我想就是这个道理了,让自己充实、忙应该是很容易的,重要的是,自己对自己时间的投入产出比。我们单位时间是不是做了足够的事情。我们也需要多思考思考,自己是不是聪明的在忙。

通过编程获取Whois的信息

       近期帮助同事在处理从纯真网络上拿到的IP信息,确定这些IP所在的城市、区县,以及这些IP属于哪些ISP。后来需要用到whois上查询的信息。
       开始的几次,通过whois命令简单的查询了一下。后来同事看到http://blog.chinaunix.net/space.php?uid=9950859&do=blog&cuid=1300091这篇博客介绍的用法,把教育网、电信、铁通、网通(之前是网通,现在算联通)的信息都拿下来了。从这些ISP中提取各自负责的IP段,处理了很多IP信息所对应的ISP,不过还是有些没有能够得到处理。就像写程序去自动处理。
       网上搜索了一下,发现其实whois的协议是非常简单的文本协议。whois服务器的端口,是43,可以直接telnet连接到whois服务器(比如 whois.apnic.net)的43端口,然后输入help,就可以查看支持的协议。
       Trying 202.12.29.222...
Connected to whois.apnic.net (202.12.29.222).
Escape character is '^]'.
% [whois.apnic.net node-2]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html

help
% -l <ip-lookup>   Returns first level less specific inetnum,
%                  inet6num or route objects, excluding exact matches.
% -L <ip-lookup>   Returns all level less specific inetnum,
%                  inet6num or route objects, including exact matches.
% -m <ip-lookup>   Returns first level more specific inetnum,
%                  inet6num or route objects, excluding exact matches.
% -M <ip-lookup>   Returns all level more specific inetnum,
%                  inet6num or route objects, excluding exact matches.
% -x <ip-lookup>   Requests that only an exact match on a prefix be
%                  performed.  If no exact match is found no objects are
%                  returned.
% -c <ip-lookup>   Requests first level less specific inetnum or inet6num
%                  objects with the "mnt-irt:" attribute.
% -b <ip-lookup>   Requests first level less specific inetnum or inet6num
%                  objects with the "mnt-irt:" attribute. Only object keys
%                  and "abuse-mailbox:" attributes are visible.
% -d <ip-lookup>   Enables use of the -m, -M, -l and -L flags for lookups on
%                  reverse delegation domains.
%
% -i <attribute-name> <inverse-key> Perform an inverse query.
%
% -F               Produce output using short hand notation for attribute
%                  names.
% -K               Requests that only the primary keys of an object to be
%                  returned.  The exceptions are set objects, where the
%                  members attributes will also be returned. This flag does
%                  not apply to person and role objects.
% -k (optional normal query) Requests a persistent connection. After
%                  returning the result the connection will not be closed by
%                  the server and a client may issue multiple queries on the
%                  same connection.
%                  Note, that server implements 'stop-and-wait' protocol,
%                  when no next query can be sent before receiving a reply
%                  for the previous one.  Use RIPE whois3 client to be able
%                  to send queries in batch mode.
%                  Except the first -k query, -k without an argument closes
%                  the persistent connection.
% -g (mirroring request) Request a NRTM stream from the server.
%                  See [REF], section 4. "Mirroring the RIPE Database" for
%                  more information".
% -G               Disables the grouping of objects by relevance.
% -B               Disables the filtering of "notify:", "changed:" and "e-mail:"
%                  attributes.
%
% -R               Switches off use referral mechanism for domain lookups,
%                  so that the database returns an object in the RIPE
%                  database with the exact match with the lookup argument,
%                  rather than doing a referral lookup.
% -r               Switches off recursion for contact information after
%                  retrieving the objects that match the lookup key.
% -T (comma separated list of object types, no white space is allowed)
%                  Restricts the types of objects to lookup in the query.
% -a               Specifies that the server should perform lookups in all
%                  available sources.  See also -q sources" query.
% -s (comma separated list of sources, no white space is allowed) Specifies
%                  which sources and in which order are to be looked up when
%                  performing a query.
%
% -q sources       Returns the current set of sources along with the
%                  information required for mirroring. See [REF], section
%                  2.9 "Other server features" for more information.
% -q version       Displays the current version of the server.
% -t <object-type> Requests a template for the specified object type.
% -V<client-tag>   Sends information about the client to the server.
% -v <object-type> Requests a verbose template for the specified object
%                  type.
%
% [REF] RIPE Database Reference Manual.
%       http://www.ripe.net/ripe/docs/databaseref-manual.html
   whois的每次请求结束后,服务器会自动断开连接。
   有了上述的信息,我们就可以很简单去实现一个自己的whois查询功能了。比如,我这边针对单个ip的查询,就可以使用-l这个参数。
    具体就是,先创建和服务端连接的socket,
    然后通过socket发送"-l ip\r\n"给服务端
    读取响应,直到socket被关闭。
    具体代码就不贴了,非常简单,需要的同学,分分钟就写好了。

2010年12月17日星期五

JavaOne 2010 北京 Session的评价

在基于Java技术的Web服务中处理异步 
    这个session,概括的说,讲了三个方面的东西
  1. 可以方便的在客户端进行一个异步调用的模拟,实际上是有一个后台线程,仍然进行阻塞的访问。
  2. 采用WS-Addressing来进行异步调用,实质是A调用了B,这个时候,B处理完了,结果给谁,是要配置的。可能是返回给A,但是是一个新的调用,也可以给到其他地方去。这个其实是对Request和Response的分解。而这里有一个问题是,如果B处理完了以后,结果主动给A,有防火墙的问题。so,第三种
  3. 叫做是WS-makeConnection,其实是对2的一种修改,A调用了B以后,会进行轮询。解决防火墙的问题。
    另外,提到了JavaEE 6的一些新的特点,完全基于Annotation等。
    总体来说,是长见识了,但是还用不上。

我的应用程序怎么了:Java虚拟机监控工具 
    这个就是工具介绍,介绍了Palantir的功能,并且提到这个是基于Dtrace做的。并且,目前不确定什么时候Palantir能够Ready给公众。
    也没有别的更多的东西了。
    不过,这个session可能给我的一个感受是,工具是非常非常的关键和重要的,不管是集群的管理,还是单机的监控等。下面的Action是跟进我们自己的工具的开发。

实现从云端到终端的均衡发展 
   这个主要是是讲Intel的产品的。CPU的高性能、低功耗、虚拟化技术等。

分步说明:HotSpot Java虚拟机中的GC调优 
    这个Session,跟美国JavaOne的貌似一样的,PPT我看起来就非常的眼熟。
    主要是之前看过这个PPT了,内容大概都知道。而Speaker好像也没有很大的激情,整体比较平铺直叙
    主要就是讲了Throughput、Latencies和FootPrint以及一些调优的基本做法。内容还是很不错的。

数据库复制 
    这个Session是我抱着很大希望去的,结果真的是希望越大失望越大。
    基本是将用Oracle的产品怎么做到容灾的。我承认,我睡着了。
    最后是讲到GoldenGate,这个我在iDataForum上第一次听说,据说很强大,然后很贵。     

技术概述:Sun Fire x86集群系统 
    这个Session,我天真的以为会将技术,其实就是完全介绍产品,不过这产品看的让人流口水。
    8路8核超线程,128条8G内存。。。。。。
    然后是介绍了Oracle的一套系统的Stack。App,DB,Virtualization,OS,Server,Storage啥都有。。。强的

JavaOne技术主题演讲 
    这个应该是和JavaOne美国的那个差不多的,从JavaSE的发展到JavaEE的发展到JavaME的 发展。
   这里面也明确提到,Java7会在2011年7月28日Ready,好吧,在等上7个多月看吧。
   另外,JavaEE7里面,JMS的API会升级到2.0,不知道有什么新东西,到时候看。
   JavaSE8,要到2012年底,希望玛雅的语言不准的,否则也许用不上Java8了。
   JavaME里面提到,ME会朝着水平和垂直的方向发展,水平是提供给开发者统一一致的API,垂直是指针对不同的设备,比如智能电视、或者别的智能设备,有不同的API

如何在Java虚拟机上调优和编写低延迟应用程序 
    这个Session,包含的东西还是比较多的,也比较碎,还是看PPT比较好。是很好的主题

面向轻量级服务器的Java方法 
    这个Session,应该说讲了4件事情
  1.  BIO是阻塞的通信方式,连接数跟线程数是1:1,这种方式有他应用的场景。
  2.  NIO是非阻塞的方式,采用reactor模式,不需要一个线程处理一个连接。
  3.  NIO2是通知的方式(貌似Winsocket是早就有这种方式了),比NIO会更高效,跟容易使用。
  4.  SSLEngine
   我对这个Session,总体评价不高

在JDK中使用文件系统API 
   这个主要介绍了新的File API。比如对目录的遍历、比如文件变化通知等。
   并且给了一个性能比较,新的API提升了很多。那我想,这个提升也不是基于OS的变化的提升,那么。。。。。。,就是说,之前的实现很不好了。

多种语言,一个虚拟机 
    这个Session,比较好玩儿,演示了使用jrunscript(1.6中默认就带的)。
    在jrunscript的交互的shell里面,来创建Swing窗口,控制Swing窗口等。
    讲到了JavaSE7的invokeDynamic。讲到了如何在Java中使用脚本的引擎等。
    长见识了。

开发和使用面向互联网服务的企业服务总线的经验 
    这个Session,觉得内容比较少,主要是在讲一件事情,就是ESB在互联网环境下,作为Caller和Callee中的ServiceGate,完成的工作。 但是没有讲到具体的一些细节、经验教训等。 最后的图,是在传统的方式上,加入了Cloud Connector。
    
JDK 7和Java SE 7 
    讲了四个方面
  1. Modularity(Project Jigsaw)
  2. Small Language Changes(Project coin)
  3. Closures(Project Lambda)
  4. Dynamic Method Calls(invokeDynamic)
使用Java Servlet 3.0和Java EE 6的安全、异步的Web应用程序 
    这个Session主要是讲Servlet 3.0中,应该怎么使用异步。 以及在Server端,Servlet的安全性控制。

Java移动支付中间件支持支付宝安全支付服务 
    这个很强,好像和其他的Session都不冲突,爆满。
    支付宝也很强,要和Oracle一起去搞JSR 229,这个是很早之前西门子提出的支付API。如果支付宝能够把JSR 229真的继续搞下去,那真牛啊。
Oracle的ME的VM,就内置支付宝的支付中间件了,支付宝也在跟其他的VM厂商谈。太牛了。
    纯技术的内容,好像没什么

Sun SPOT项目:支持Java的普适计算平台 
     这个本来以为是跟云计算有关系的东西,去了才知道是介绍SPOT的,SPOT就是Small Programmable Object Technology 是一个有温度、光线、3D位置感应的可编程的一个设备。 这个东东比较好玩儿,并且貌似不好买到。 Sun的技术上的想法和动作,其实都还是很强的,可惜。。。

    总体来说,特别好的Session很少很少,介绍性质的居多,也有很水的。相对于之前12号的iDataForum,虽然方向不同,但是还是iDataForum更加实战些。
    明年应该不会参加国内的Javaone了。我想如果是Sun自己办,应该会好很多。不过。。。,明年如果有机会,还是希望参加些比较实战的,能够有技术上交流的会议,比如QCon等。
     最后额外的收获,作为Speaker,参加了Oracle的答谢活动,吃了顿不错的自助餐,然后Oracle送了一块儿手表,看起来好像还不错的样子,据一个在Oracle中国待了十多年的朋友说,他从来没见过Oracle送这么好的礼物。呵呵。

JavaOne 2010 北京 我的Session选择


北京参加 iDataForum总结

      感谢淘宝DBA的邀请,参加了12月12号在北京的iDataForum的技术论坛,并且也分享了一个主题《淘宝网的前世今生》。
      虽然这个论坛,只有一天的时间,但是应该说还是效果很好的。相关的PPT都可以从http://www.idata-forum.org/下载。
      这次,主要听了三个主题。
      一个是赵林(新浪微博 @丹臣)的《淘宝数据库架构演进历程》,一个是邵宗文的《数据库托管平台介绍》,一个是孙立的《NOSQL研发之路》。
      赵林分享的内容相当丰富,用时间顺序串起来了淘宝数据库的变化。内容相当的丰富。没有去现场的同学,一定要去看一下这个PPT。
      邵宗文的分享,我是一直站着听完的。他介绍的数据库托管平台,给了我不少启发:
       一个是对托管平台的数据库的管理、信息统计、监控这个部分,我们这边的管理工具还不够强;
       另外一个是单机多实例,这个对应的是单物理机多虚拟机的做法,这块儿,跟我们的DBA讨论了,貌似还是倾向于多虚拟机的方式,不过这块儿,也要跟进下,在Java应用上,也有类似的选择;
       然后是对于复制延时的探测和下掉延时大的slave。这个部分,我之前不知道Mysql是可以方便的知道复制延时有多大的,这个我土了。另外,腾讯的方案是通过DNS来管理slave的,通过从DNS上摘除地址,下掉慢的读库的。
      下面的Action就是,管理工具这个部分的加强,下周约DBA碰一下。希望能够在明面Q1结束的时候,我们能够搞好一个好用强大的数据库管理平台。
      孙立(新浪微博 @sunli1223_孙立)的NoSQL开发之路,我没有完全听下来,当时刚好有同学找我交流,总体来说,他是遇到了TTServer的问题后,有点不得不去开发一个NoSQL的,貌似是数据量在五六十G的时候TT出问题的。然后他这边基于BDB的自己的存储,性能测试曲线相当的平稳和稳定。具体大家可以看看他的PPT。存储这块儿,我这边现在不涉及,没有Action。只是丰富见识了。
      最后,我自己的分享,我感觉应该还是把目前我们做的数据层,跟大家讲清楚了。如果有问题,欢迎大家一起交流。感谢iDataForum,希望今后越办越好。