庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理


    我们在维护的淘宝开源消息中间件的metaq的github分支,今天发布了1.4.2版本,主要做了如下改进:

    1.添加了大量的使用和原理文档,参见Wiki
    2.合并tools和server-wrapper工程,提供统一的脚本来管理Broker,管理Broker的工作变得非常容易,全部工作都可以通过metaServer.sh的脚本来执行。同时提供了bat启动脚本,用于在windows上启动Broker做测试。
    3.新功能:
   (1)新的客户端API用来获取topic的分区列表
   (2)新的客户端API用来获取Broker的统计信息
   (3)异步复制的Slave可以自动获取Master的配置变更,例如Master在配置文件中新增或者删除了topic并顺利reload热加载成功后,slave可自动复制或者移除变更的topic,无需重启。
   (4)新的统计项目,可以通过'stats config'协议获取Broker的配置文件。
    4.添加meta-python项目,一个python的客户端,暂时仅支持发送消息功能。
    5.其他小改进,如统计信息的优化、构建工具的整合等。

    更详细的发行日志请看RelaseNotes

    下载地址:  https://github.com/killme2008/Metamorphosis/downloads
    入门指南:  《如何开始
    更多文档请看Wiki

posted @ 2012-05-09 22:47 dennis 阅读(4418) | 评论 (1)编辑 收藏


    我发现很多人没办法高效地解决问题的关键原因是不熟悉工具,不熟悉工具也还罢了,甚至还不知道怎么去找工具,这个问题就大条了。我想列下我能想到的一个Java程序员会用到的常用工具。

一、编码工具

1.IDE:Eclipse或者IDEA,熟悉尽可能多的快捷键,《Eclipse常见快捷键列表
2.插件: 
(1) Findbugs,在release之前进行一次静态代码检查是必须的
(2) Clover,关心你的单元测试覆盖率
(3) Checkstyle 代码风格检查

3.构建和部署工具:ant或者maven,现在主流都是maven了吧,使用nexus搭建maven私服,再加上持续集成jenkins。代码质量不用愁。

4.版本管理工具: svn或者git

5.diff和patch

6.设置你的eclipse或者IDEA,如formatter,save actions以及code template等。代码风格,直接用google的也可以啊。《Google style guide

7.掌握一个文本编辑器,Emacs或者VIM,熟悉常用快捷键。这在你需要在线编辑代码,或者编写其他语言代码时候特别有用。《神器圣战

二、JDK相关

1.jstat : 观察GC情况,如:

jstat -gcutil pid 2000

2.jmap,查看heap情况,如查看存活对象列表:
jmap -histo:live pid |grep com.company |less 

或者dump内存用来分析:

jmap -dump:file=test.bin pid

3.分析dump的堆文件,可以用jhat:

jhat test.bin

  分析完成后可以用浏览器查看堆的情况。这个工具的分析结果还比较原始,你还可以用Eclipse MAT插件进行图形化分析,或者IBM的Heap Analyzer.

4.jvisualvm和jconsole: JVM自带的性能分析和监控工具,怎么用?请自己看文档。

5.jstack:分析线程堆栈,如

jstack pid > thread_dump

    查看CPU最高的线程在干什么的方法结合top和jstack:http://www.iteye.com/topic/1114219

6.更多JVM工具,参见官方文档:http://docs.oracle.com/javase/6/docs/technotes/tools/

7.学习使用btrace分析java运行时问题。《Btrace使用简介

8.GC日志分析工具:GC viewerGC-console或者自己挑吧。

9.性能分析工具,除了自带的jvisualvm外,还可以用商业的jprofiler

10.JVM参数大全

11.《JVM调优标准参数陷阱》,iteye神贴。

三、Linux工具

1.熟悉常用的shell命令,


3.使用htop替换top。

4.熟悉下strace,gdb甚至systemtap来分析问题。

5.熟悉vmstat,iostat,sar等性能统计工具。

5.自动化部署脚本,py-fabric或者自荐下我的clojure-control

四、其他

1.掌握一门脚本语言,Python或者Ruby,高效解决一些需要quick and dirty的任务:比如读写文件、导入导出数据库、网页爬虫等。注意不是python.com,咔咔。

2.使用Linux或者Mac os系统作为你的开发环境。

3.升级你的“硬件工具”,双屏大屏显示器、SSD、8G内存甚至更多。

4.你懂的:https://code.google.com/p/goagent/

五、如何查找工具?

1.搜索引擎,google或者baidu,《搜索技巧

2.万能的stack overflow:http://stackoverflow.com/

3.虚心问牛人。

六、最重要的是⋯⋯

一颗永不停止学习的心。

posted @ 2012-04-17 17:05 dennis 阅读(18132) | 评论 (17)编辑 收藏


    最近陆陆续续补充了不少metaq的文档,部分是直接从官方文档里摘抄出来,放在了github工程的wiki页,有兴趣了解甚至使用meta的可以仔细阅读下,一份目录:     
    后续还会继续补充。

posted @ 2012-04-13 22:43 dennis 阅读(45486) | 评论 (13)编辑 收藏

    Java世界里有findbugs这样的神器,可以让你避免很多“简单愚蠢”的bug。同样,Clojure世界里也有相应的替代品,这就是今天要介绍的kibit。不过kibit现在还比较年轻,判断的规则较少,但是已经可以使用起来做clojure代码的静态检查。

项目主页:https://github.com/jonase/kibit
使用:
1.安装lein插件:
lein plugin install jonase/kibit 0.0.2

2.在项目的根目录运行
lein kibit

kibit会分析项目里所有clojure源码,每个namespace分别分析,例如我分析clojure-control的输出:

== control.commands ==
== control.core ==
[186] Consider (zero? (:status (ssh host user cluster (str "test -e " file)))) instead of (= (:status (ssh host user cluster (str "test -e " file))) 0)
== control.main ==
== leiningen.control ==
[null] Consider Integer/parseInt instead of (fn* [p1__61444#] (Integer/parseInt p1__61444#))
[null] Consider Integer/parseInt instead of (fn* [p1__65254#] (Integer/parseInt p1__65254#))

    显然,kibit一个一个namespace分析过去,并且按照规则对它认为有问题的地方打印出来,并提出建议。例如这里它建议我用
(zero? (:status (ssh host user cluster (str "test -e " file))))
    替换control.core里186行的:
 (= (:status (ssh host user cluster (str "test -e " file))) 0)

    目前kibit大多数是这类代码风格上的检查,还没有做到类似findbugs那样更丰富的检查,例如NPE异常检查等。此外kibit还提供反射检查,任何有反射调用的地方都给出警告。
    kibit是基于core.logic实现的,它的规则都放在了这里,通过defrules宏来定义检查规则,源码中对算术运算的规则定义:
(defrules rules
  [(+ ?x 1) (inc ?x)]
  [(+ 1 ?x) (inc ?x)]
  [(- ?x 1) (dec ?x)]

  [(* ?x (* . ?xs)) (* ?x . ?xs)]
  [(+ ?x (+ . ?xs)) (+ ?x . ?xs)])
   
    第一个规则,任何对类似(+ 1 x)的代码,都建议替换成(inc x),后面的与此类似。理论上你也可以自定义规则,并提交给官方。总体上说kibit仍然是比不上findbugs的,期待未来发展的更好。

posted @ 2012-03-23 21:28 dennis 阅读(4329) | 评论 (0)编辑 收藏


    我们经常需要在程序中测量某段代码的性能,或者某个函数的性能,在Java中,我们可能简单地循环调用某个方法多少次,然后利用System.currentTimeMillis()方法测量下时间。在Ruby中,一般都是用Benchmark module做测试,提供了更详细的报告信息。

    同样,在Clojure里你可以做这些事情,你仍然可以使用System.currentTimeMillis()来测量运行时间,例如:

user=> (defn sum1 [& args] (reduce + 0 args))
#'user/sum1

user=> (defn sum2 [& args]
             (loop [rt 0
                    args args]
                 (if args
                   (recur (+ rt (first args)) (next args))
                   rt)))
#'user/sum2

user=> (defn bench [sum n]
         (let [start (System/currentTimeMillis)
               nums (range 0 (+ n 1))]
           (dotimes [_ n] (apply sum nums))
           (println (- (System/currentTimeMillis) start))))

user=> (bench sum1 10000)
1818
nil
user=> (bench sum2 10000)
4220
nil
   
    定义两个求和函数sum1和sum2,一个是利用reduce,一个是自己写loop,然后写了个bench函数循环一定次数执行sum函数并给出执行时间,利用System.currentTimeMillis()方法。显然sum1比sum2快了一倍多。为什么更快?这不是我们的话题,有兴趣可以自己看reduce函数的实现。

    除了用System.currentTimeMillis()这样的java方式测量运行时间外,clojure还提供了time宏来包装这一切:
user=> (doc time)
-------------------------
clojure.core/time
([expr])
Macro
  Evaluates expr and prints the time it took.  Returns the value of
 expr.
nil

    time宏用的不是currentTimeMillis方法,而是JDK5引入的nanoTime方法更精确。重写bench函数:
user=> (defn bench [sum n]
             (time (dotimes [_ n] (apply sum (range 0 (+ n 1))))))
#'user/bench

user=> (bench sum1 10000)
"Elapsed time: 5425.074 msecs"
nil
user=> (bench sum2 10000)
"Elapsed time: 7893.412 msecs"
nil
     尽管精度不一致,仍然可以看出来sum1比sum2快。
    
     这样的测试仍然是比较粗糙的,真正的性能测试需要考虑到JVM JIT、warm up以及gc带来的影响,例如我们可能需要预先执行函数多少次来让JVM“预热”这些代码。庆幸的是clojure世界里有一个开源库Criterium帮你自动搞定这一切,它的项目主页也在github上:https://github.com/hugoduncan/criterium

     首先在你的项目里添加criterium依赖:
:dependencies [[org.clojure/clojure "1.3.0"]
                        [criterium "0.2.0"]])
   
     接下来引用criterium.core这个ns,因为criterium主要宏也叫bench,因此我们原来的bench函数不能用了,换个名字叫bench-sum:
user=> (use 'criterium.core)
nil
user=> (defn bench-sum [sum n]
              (with-progress-reporting (bench (apply sum (range 0 (+ 1 n))) :verbose)))
#'user/bench-sum

     调用criterium的bench宏执行测试,使用with-progress-reporting宏包装测试代码并汇报测试进展,测试进展会打印在标准输出上。请注意,我这里并没有利用dotimes做循环测试,因为criterium会自己计算应该运行的循环次数,我们并不需要明确指定,测试下结果:
user=> (bench-sum sum1 10000)
Cleaning JVM allocations 
Warming up for JIT optimisations 
Estimating execution count 
Running with sample-count 60 exec-count 1417 
Checking GC
Cleaning JVM allocations 
Finding outliers 
Bootstrapping 
Checking outlier significance
x86_64 Mac OS X 10.7.3 4 cpu(s)
Java HotSpot(TM) 64-Bit Server VM 20.4-b02-402
Runtime arguments: -Dclojure.compile.path=/Users/apple/programming/avos/logdashboard/test/classes -Dtest.version=1.0.0-SNAPSHOT -Dclojure.debug=false
Evaluation count             : 85020
             Execution time mean : 722.730169 us  95.0% CI: (722.552670 us, 722.957586 us)
    Execution time std-deviation : 1.042966 ms  95.0% CI: (1.034972 ms, 1.054015 ms)
         Execution time lower ci : 692.122089 us  95.0% CI: (692.122089 us, 692.260198 us)
         Execution time upper ci : 768.239944 us  95.0% CI: (768.239944 us, 768.305222 us)

Found 2 outliers in 60 samples (3.3333 %)
    low-severe     2 (3.3333 %)
 Variance from outliers : 25.4066 % Variance is moderately inflated by outliers
nil


user=> (bench-sum sum2 10000)
Cleaning JVM allocations 
Warming up for JIT optimisations 
Estimating execution count 
Running with sample-count 60 exec-count 917 
Checking GC
Cleaning JVM allocations 
Finding outliers 
Bootstrapping 
Checking outlier significance
x86_64 Mac OS X 10.7.3 4 cpu(s)
Java HotSpot(TM) 64-Bit Server VM 20.4-b02-402
Runtime arguments: -Dclojure.compile.path=/Users/apple/programming/avos/logdashboard/test/classes -Dtest.version=1.0.0-SNAPSHOT -Dclojure.debug=false
Evaluation count             : 55020
             Execution time mean : 1.070884 ms  95.0% CI: (1.070587 ms, 1.071136 ms)
    Execution time std-deviation : 1.057659 ms  95.0% CI: (1.050688 ms, 1.062877 ms)
         Execution time lower ci : 1.024195 ms  95.0% CI: (1.024164 ms, 1.024195 ms)
         Execution time upper ci : 1.145664 ms  95.0% CI: (1.145664 ms, 1.145741 ms)

Found 1 outliers in 60 samples (1.6667 %)
    low-severe     1 (1.6667 %)
 Variance from outliers : 19.0208 % Variance is moderately inflated by outliers
nil


    这个报告是不是相当专业?不是搞统计还不一定读的懂。大概解读下,sample-count是取样次数,默认是60次,exec-count是测试的执行次数(不包括前期warm up和JIT在内),CI是可信区间,这里取95%,Execution time mean是平均执行时间,而lower和upper是测试过程中执行时间的最小和最大值。而outliers是这一组测试中的异常值,比如执行sum1测试发现了2组异常结果。从结果来看,sum1的平均执行时间是722微秒,而sum2的平均执行时间是1.07毫秒,因此还是sum1更快一些。

    总结下,如果只是在开发过程中做一些小块代码的简单测试,可以直接利用内置的time宏,如果你希望做一次比较标准的性能测试,那么就应该利用criterium这个优秀的开源库。

posted @ 2012-03-22 21:14 dennis 阅读(3784) | 评论 (0)编辑 收藏


    继续Clojure世界之旅,介绍下我今天的探索成果,使用clojure生成clojure项目的API文档。在java里,我们是利用javadoc生成API文档,各种build工具都提供了集成,例如maven和ant都提供了javadoc插件或者task。在Clojure世界里,同样有一系列工具帮助你从源码中自动化生成API文档。今天主要介绍三个工具。不过我不会介绍怎么在clojure里写doc,具体怎么做请看一些开源项目,或者直接看clojure.core的源码。

    首先是codox,使用相当简单,我们这里都假设你使用Leiningen作为构建工具,在project.clj里添加codox依赖:
  :dev-dependencies    [[codox "0.5.0"]]

    解下执行lein doc命令即可生成文档,生成的文档放在doc目录,在浏览器里打开index.html即可观察生成的文档。我给clojure-control生成的codox文档可以看这个链接,效果还是不错的。

    第二个要介绍的工具是marginalia,使用方法类似codox,首先还是添加依赖:
:dev-dependencies [lein-marginalia "0.7.0"]
   
    执行lein deps处理依赖关系,然后执行lein marg命令即可在docs目录生成文档,与codox不同的是marginalia只生成一个html文件,没有带js和css,但是效果也不错,可以看我给clojure-control生成的marg文档链接marginalia生成的文档说明和源码左右对照,很利于阅读源码。

   最后要介绍的就是Clojure.org自己在使用的autodoc,如果你喜欢clojure.org上的API文档格式可以采用这个工具。并且autodoc可以跟github pages结合起来,生成完整的项目文档并展示在github上。例如以clojure-control为例来介绍整个过程。首先你需要配置你的github pages,参照这个链接
http://pages.github.com/

    第一步,仍然是在project.clj添加依赖:
:dev-dependencies [[lein-autodoc "0.9.0"]]
       第二步,在你的.gitignore里忽略autodoc目录:
autodoc/**
       将这些更改提交到github上,接下来在你的项目目录clone一份项目源码到<project>/autodoc目录:
 git clone git@github.com:<user name>/<project name>.git autodoc
       进入autodoc目录,执行下列命令创建一个gh-pages分支:
 $ cd autodoc
 $ git symbolic-ref HEAD refs/heads/gh-pages
 $ rm .git/index
 $ git clean -fdx
 $ cd ..
     回到项目根目录后,执行lein autodoc命令在autodoc目录生成文档:
lein autodoc
     接下来将生成的文档推送到github分支上:
 $cd autodoc 
 $ git add -A
 $ git commit -m"Documentation update"
 $ git push origin gh-pages
    等上几分钟,让github渲染你的文档,最终的效果看这个链接 http://killme2008.github.com/clojure-control     
    autodoc和marginalia都支持maven,具体使用请看他们的文档。

posted @ 2012-03-21 22:24 dennis 阅读(3951) | 评论 (0)编辑 收藏

    前面一篇博客介绍了我在github上的一个metaq分支,今天下午写了个metaq的python客户端,目前仅支持发送消息功能,不过麻雀虽小,五脏俱全,客户端和zookeeper的交互和连接管理之类都还具备,不出意外,我们会首先用上。第一次正儿八经地写python代码,写的不好的地方请尽管拍砖,多谢。
    项目叫meta-python,仍然放在github上:https://github.com/killme2008/meta-python

    使用需要先安装zkpython这个库,具体安装这篇博客,使用很简单,发送消息:
    from metamorphosis import Message,MessageProducer,SendResult
    p=MessageProducer("topic")
    message=Message("topic","message body")
    print p.send(message)
    p.close()

    
MessageProducer就是消息发送者,它的构造函数接受至少一个topic,默认的zk_servers为localhost:2181,可以通过zk_servers参数指定你的zookeeper集群:

p=MessageProducer("topic",zk_servers="192.168.1.100:2191,192.168.1.101:2181")

更多参数请直接看源码吧。一个本机的性能测试(meta和客户端都跑在我的机器上,机器是Mac MC700,osx 10.7,磁盘没有升级过):
from metamorphosis import Message,MessageProducer
from time import time
p=MessageProducer("avos-fetch-tasks")
message=Message("avos-fetch-tasks","http://www.taobao.com")
start=time()
for i in range(0,10000):
    sent=p.send(message)
    if not sent.success:
        print "send failed"
finish=time()
secs=finish-start
print "duration:%s seconds" % (secs)
print "tps:%s msgs/second" % (10000/secs)
p.close()

 结果:


duration:1.85962295532 seconds
tps:5377.43415749 msgs/second

posted @ 2012-03-21 19:08 dennis 阅读(5166) | 评论 (1)编辑 收藏

    开源的memcached Java客户端——xmemcached发布1.3.6版本。

    主要改进如下: 

1.  为MemcachedClientBuilder添加两个新方法用于配置:

public void setConnectTimeout(long connectTimeout);  
public void setSanitizeKeys(boolean sanitizeKeys);

 

2.  用于hibernate的XmemcachedClientFactoryd添加了connectTimeout属性,感谢网友 Boli.Jiang的贡献。

3.  添加新的枚举类型 net.rubyeye.xmemcached.transcoders.CompressionMode,用于指定Transcoder的压缩类型,默认是ZIP压缩,可选择GZIP压缩。Transcoder接口添加setCompressionMode方法。

4.  修改心跳规则,原来是在连接空闲的时候发起心跳,现在变成固定每隔5秒发起一次心跳检测连接。

5.  修改默认参数,默认禁用nagle算法,默认将批量get的合并因子下降到50。

6.  修复bug和改进,包括:161163165169172、173176179180

 

项目主页:http://code.google.com/p/xmemcached/

项目文档:http://code.google.com/p/xmemcached/w/list

下载:http://code.google.com/p/xmemcached/downloads/list

源码:https://github.com/killme2008/xmemcached

 

Maven依赖:

 <dependency>  

    <groupId>com.googlecode.xmemcached</groupId>  
    <artifactId>xmemcached</artifactId>  
    <version>1.3.6</version>  
</dependency> 

    最后感谢所有提出issue和改进意见的朋友们。

posted @ 2012-03-19 10:51 dennis 阅读(4596) | 评论 (3)编辑 收藏

    加入avos.com已经一个月多一点,很荣幸加入这个充满活力的跨国团队。去了趟北京,跟我的同事们终于当面认识了下,并且顺利举办了cn-clojure的第二次聚会。不过很悲剧的是在北京一周都在生病,哪也没去成,要见的人也没见到,要凑的饭局也没吃到,非常遗憾,希望以后再弥补。不过我暂时因为家庭的因素还在杭州远程办公,沟通都是通过gtalk和google+ hangout,很多东西对我来说都是全新的经历。远程办公有利有弊,其实我还是更喜欢能在一个办公室里工作,交流方便,只要转个椅子就好。

    正式介绍下我们公司,大boss是youtube创始人查德•赫利(Chad Hurley)和陈士骏(Steve Chen),我们在中国的boss是前google员工/耶鲁的博士江宏帅哥,更多关于团队成员的介绍请看这里,我的同事们真的很强大,我要学习的地方很多。我们做的产品是从雅虎手上买下来的delicious.com,不过中国团队运作的是美味书签——mei.fm。我们刚在3月1号开始做public beta,预计会在4月份的时候正式对外开放注册。我们的团队博客在这里

    我在团队里做的事情还是偏向后端,这一个月来做的事情更偏向运维之类,搞搞solr复制、mysql复制、程序监控之类,将原来只是简单了解过的东西动手做了一遍,能亲手实践的感觉不错。在此过程中要感谢锋爷和刘帅哥的帮助,再次感谢。淘宝的同事们开源了metaq和gecko,我也做了点工作,都在这里。几个维护的开源项目都没有太大进展,很惭愧,还被人催发新版本,能承诺的是周末发xmemcached的新版本,主要还是修bug。本来要写个clojure世界的系列文章,因为响应寥寥,也不是很有动力写下去。杂七杂八读了几本书,都没读完,这一个月杭州太冷了,雨下个不停,不过终于这一周开始晴天了,希望老天爷别再掉眼泪。

    收拾收拾心情,整装待发,希望新的一年里能做出点不同的东西。
    

posted @ 2012-03-16 22:59 dennis 阅读(2725) | 评论 (7)编辑 收藏


    上周我在淘宝的同事开源了一个消息中间件metamorphosis,放在了淘蝌蚪上。我从淘蝌蚪的svn上fork了一个github的分支,放在了这里:
 1.主体工程:https://github.com/killme2008/Metamorphosis
    
    主要做了一些pom文件的简化,发布1.4.0.2版本到maven central仓库,并且写了几个简单的入门文档,提供了一个完整打包可运行的下载,有兴趣的自己看github页面吧。 Wiki文档放在:
    https://github.com/killme2008/Metamorphosis/wiki
   
     客户端Maven依赖包括,可自行选择添加:
<dependency>
    <groupId>com.taobao.metamorphosis</groupId>
    <artifactId>metamorphosis-client</artifactId>
    <version>1.4.0.2</version>
</dependency>

<dependency>
    <groupId>com.taobao.metamorphosis</groupId>
    <artifactId>metamorphosis-client-extension</artifactId>
    <version>1.4.0.2</version>
</dependency>

<dependency>
    <groupId>com.taobao.metamorphosis</groupId>
    <artifactId>storm-metamorphosis-spout</artifactId>
    <version>1.0.0</version>
</dependency>

     ps.我开通了新浪微博,有兴趣相互关注下:http://weibo.com/fnil,你看,偏见是可以改变的。

posted @ 2012-03-16 10:39 dennis 阅读(8019) | 评论 (12)编辑 收藏

仅列出标题
共56页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last