你好旧时光百度云,请问你有David Allen的《How to get things done》这本书吗?

flume机器在一次重启后,一直报下面的错
java.io.IOException: Not a data file.
at org.apache.avro.file.DataFileStream.initialize(DataFileStream.java:103)
at org.apache.avro.file.DataFileReader.(DataFileReader.java:97)
at org.apache.avro.file.DataFileWriter.appendTo(DataFileWriter.java:160)
at org.apache.avro.file.DataFileWriter.appendTo(DataFileWriter.java:149)
at org.apache.flume.serialization.DurablePositionTracker.(DurablePositionTracker.java:141)
at org.apache.flume.serialization.DurablePositionTracker.getInstance(DurablePositionTracker.java:76)
at org.apache.flume.client.avro.ReliableSpoolingFileEventReader.getNextFile(ReliableSpoolingFileEventReader.java:417)
at org.apache.flume.client.avro.ReliableSpoolingFileEventReader.readEvents(ReliableSpoolingFileEventReader.java:212)
at org.apache.flume.source.SpoolDirectorySource$SpoolDirectoryRunnable.run(SpoolDirectorySource.java:154)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
flume 配置如下
agent.sources.pcap_source.type=spooldir
agent.sources.pcap_source.spoolDir=/services/logs/dfp_sniffer_sigmad/spool/
agent.sources.pcap_source.channels=pcap_channel
agent.sources.pcap_source.deletePolicy =
agent.sources.pcap_source.interceptors = ti hi
agent.sources.pcap_source.interceptors.ti.type = timestamp
agent.sources.pcap_source.interceptors.hi.type = host
agent.sources.pcap_source.interceptors.hi.hostHeader = host
agent.sources.pcap_source.ignorePattern = (.+).tmp$
原因是下面这个bug
https://issues.apache.org/jira/browse/FLUME-2525
但是奇怪的是,之前从来没有遇到类似的问题,暂时猜测是由于机器重启时,flume在写这个文件的时候失败了,导致只生成了文件,但是内容没写进去。
费了不少波折才发现,最终通过删除spool目录下的.flumespool目录解决
本文翻译至Aaron Swartz在2005年所写的一篇网志《》,那时候他还不过是一个18,9岁的毛头小子,但他对个人生产力的理解已经相当成熟。我想这篇网志也是他短暂的一生给这个世界留下的最好的礼物之一。想了解关于Aaron Swartz,可以看看关于他的纪录片《》(其实Aaron小时候也是很可爱的)。文章后面有几个补记,为的是补充在正文里被数字标记的地方。下面是译文正文。
“如果把那些看电视的时间都拿来写作,你可能已经写完一本小说了。” 无可否认,把时间花在写小说上要比花在看电视上更有意义,但这里有个前提,时间必须是可被调换的,比如本来用来看电视的时间可以很随易地被拿来写小说,但事实并不是那么一回事。
时间的效能在不同情况下是不一样的。比如在地铁里,如果忘记带笔记本,我就很难在手头没有工具的情况下写出什么东西来。又或者当你一而再再而三地被打断,就很难集中注意力。我们的大脑在不同情况下会表现出不同的状态,有时候会感觉很开心,充满活力,充满干劲,有时候又会感觉很糟糕,累到只想看电视。
如果你想提升个人生产力,必须要认清这个事实,然后采取相应的措施。首先要把各个时间段都充分利用起来,然后尝试更好的办法,提升各个时间段的效能。
做重要的事
人生是短暂的,我们没理由把时间花在无谓的事情上。开头做一件事情总是很容易的,但你要问问自己,这些事情是否值得去做,是不是还有其它更重要的事情可以做?如果有,你为什么不去做那些更重要的事情! 能总是做到这样扪心自问不容易,但你做的每一点努力,到最后都会让你变得更有效率。如果你一直问自己这样的问题,到最后你一定会去做世界上最重要的事情。
当然,并不是说你所有的时间都必须花在最重要的事情上。我自己就不是这样的,但至少我把它作为生活的一个衡量标准。
让事情多起来
大多数人认为,越是一次只专注做一件事情,到最后就会完成得越多。但在我看来,这种观点几乎是大错特错的。比如就这当口,我一会儿调整一下坐姿,一会儿练练肌肉,一会儿喝喝饮料,一会儿整理整理书桌,一会儿跟我兄弟在线上聊聊天,一会儿又回来继续写这篇文章。这一天里面,除了写这篇文章,我还读了一本书,吃了一些好吃的,回了几封电子邮件,跟朋友们聊天,去买了一些东西,还写了其它几篇文章,备份了我的硬盘,整理了我的阅读清单。在过去的一个礼拜,我花了一些时间在几个软件项目上,读了几本不同类型的书,学了几种不同的编程语言,整理了自己的杂物,等等。
如果你有不同的事情可以做,就可以把它们安排在不同的时间段。这样做的好处是,当你在做一件事情感觉厌烦或者没有思路的时候,可以去做另外一件事情,从而把自己从混沌中解放出来。
不仅如此,这种方式还会激发你的创意能力。创意有时候是来自你把从一个领域学到的东西应用在其它领域上。你在不同领域有越多的事情可以做,就越会有更多的想法可以相互应用。
列一个清单
让事情多起来并不难,事实上大部分人都有很多他们想去完成的事情。但如果你把所有事情都装在脑子里,你很快会崩溃的,试图只通过大脑记住所有的事情会让人抓狂。解决办法其实很简单:把它们写下来。
等你有了这样的一个清单,就可以对它们进行分门别类。比如我的清单是这样分类的:编程,写作,思考,差事,阅读,聆听,观看娱乐节目。
大多数时候,一件大的事情可以被分成很多不同的小任务。就拿写这篇文章来说,我需要去了解人类的拖延症行为,想想怎么给文章增加新的内容,润色句子,发邮件向其他人求助,等等。这里的每一个任务,都是为了最终能写成这篇文章。不同的任务是为了促成文章的不同部分,所以你可以把它们安排在最合适的时间段去做。
把清单融入你的生活
光是有了清单还不够,关键是如何使用它。最好的做法是当你想做什么事情的时候就把它拿出来看看。我会在书桌上放一叠想看的书,最上面那本是最近正在看的那本。当我想看书的时候,直接拿最上面那本。
看电影或者电视节目也是这样的。每当有人推荐刚好是我想看的电影,我就把它放在电脑的某个文件夹里。当我想看电影的时候,直接打开那个文件夹。
除此之外,还有其它一些方式,尽管它们看起来有些“粗鲁”。比如,当我在查阅网志的时候,网页会把我阅读清单里的文章列表弹出来。或者当我没事可做的时候,有一个窗口时不时地弹出来告诉我还有哪些事可以做。
提升你的时间效能
只是做到充分利用你的各个时间段还远远不够,更要紧的是如何提升你的各个时间段的效能。很多人的时间都被学校和工作上的琐事给占用掉了,如果你也是其中一员,你应该考虑是否要退出。当然,除了这个以外,还有什么可以用来提升时间效能呢?
减少外界不利因素的限制和影响
带上纸和笔
据我所知,很多人都喜欢随身携带口袋笔记本。纸笔在各种情况下都能够派上用场,比如在你需要把东西写下来给别人看的时候,或者在你需要记录看到的东西或者想法的时候,等等。我甚至曾经用它们在地铁里写完一整篇文章。[1]
(不过现在不怎么带纸笔了,代替它们的是电脑手机。不过这样我就没办法把信息写下来给别人了,但它们让我随时都有东西可以读,比如邮件,而且可以立即把笔记发到邮箱里,特别是那些需要紧急处理的邮件。)
避免被打扰
在做那些需要高度集中注意力的事情时,你最好避免被打扰。最简单的办法是躲到一个不会被人打扰的地方,也可以事先跟周围的人说好,“在我门关着的时候不要来打扰我”,或者“如果看到我戴着耳机,有什么事情可以直接在线上给我发消息”(这样你就可以在不忙的时候再来处理这些消息)。
当然,你也不要老是这样做。有时当你真的无事可做,也会觉得心烦意乱。这个时候如果你去帮助别人解决他们的问题,要比傻坐着看新闻强。这个就是跟别人事先约定的好处,在你需要的时候可以免受打扰,在你闲下来的时候就可以去帮助别人。
减少身理和精神方面的条件限制
吃饭,睡觉,锻炼
当你处在饥饿,疲劳或者焦躁不安的状态的时,时间效能是很低的。应对的办法自然是:吃饭,睡觉和锻炼。但说起来容易,有时候我自己也做不到。我不喜欢出去买食物,所以经常忙过了头,结果饿到连出去买食物的力气都没有了。[2]
人们总是倾向于劝自己:”我知道自己很累了,但我不能休息,我必须先把手头的事情做完。”但实际上,如果你停下来休息一会儿再继续手头的事情,这样效率会更高,因为等你恢复饱满的精力,后面的时间效能会更高。而且不管怎么说,累了本来就应该休息。
至于锻炼,因为我自己也不怎么做,所以我并不适合在这方面给出什么建议,不过只要有可能,我还是会尽量多做一些。比如在我躺在床上看书的时候,我会同时做一些起坐动作,又或者如果要去什么地方需要走路的,我就用跑步代替。
跟正能量的人聊天
排除精神方面的不利因素会更难一些。如果你拥有一帮正能量的朋友,对你会有帮助。比如,我发现当每次跟Paul Graham或者Dan Connolly聊完天以后,我就干劲十足——他们都是散发正能量的人。人们自然而然地认为远离人群,把自己锁在房间里干活会更好,但这样其实是很低效的。
找人分担你的问题
如果暂时找不到可以散发正能量的人,找人帮忙一起解决手头的难题也会让你变得轻松。首先,你的压力会因为别人的分担而减少。其次,因为有人在跟你一起干活,你就不会随意开小差了。
拖延症和脑力场
不过上面所说的其实都算是迂回的做法,人们在效率方面面临的真正问题其实是拖延症。不单单是你,严格地说,每个人都有这个毛病。这算是个不能说的小秘密,但这并不意味着你就可以让它牵着鼻子走。
什么是拖延症?在外人看来,它就好比说放着正事不做,却跑去干那些看起来更”有趣“的勾当(比如玩游戏或看新闻)。(在外人眼里,这样做就是懒惰,不务正业)。但问题的实质是,当我们拖延的时候,我们的头脑里发生了什么?
我花了很多时间去探究这个问题,我想可以用这样的方式来解释这个问题:我们的大脑会在任务周围产生某种可以称之为脑力场的东西。玩过磁铁吗?当我们把两块磁铁的同一极相对,并试着把它们靠在一起,它们会相互排斥。当你随意移动它们,你会感觉到它们周围存在的磁场。如果你再试着把它们放到一起,相斥的磁场会把你往另一个方向弹开。
脑力场差不多也是这样的,当然不是说真有这样的实体存在,自然也看不见,但你可以感觉得到它的存在。你越是试着靠近它,它越是会把你弹开。所以毫无疑问地,事情会朝着你所期望的相反方向发展。[3]
既然我们无法通过蛮力把两块相斥的磁铁放到一起(我们一放手它们就立即弹开),自然也没办法只是使用意志力来克服脑力场。但我们可以绕个弯——把磁铁转个方向。
产生脑力场主要有两个因素:任务的难易程度以及它是否由别人指派給你的。
棘手的难题
难题的特点之一是它的规模比较大。比如说你要做一个管理菜谱的程序,没人可以干坐着就能做出这样的一个程序来。菜谱管理程序只是一个目标,并不是一个具体可执行的任务。一个可执行的任务应该是一个清晰的可操作步骤,每完成一个,都是向你的目标迈近了一步。做这个程序的第一步最好是先画一个可以展示菜谱的界面原型,这就是一个可操作的步骤。[4]
当你做完第一步,就知道下一步该做什么了。比如你要决定一个菜谱有哪些部分组成,需要什么样的搜索功能,怎样给数据库建模,等等。你像有了加速度一样,一个任务接一个地完成。当你在一个任务上遇到了问题,解决起来也容易些。
每一个比较大的项目,我都会事先想好怎么把它划分为很多小的任务,然后添加到我的任务清单里。当我完成一个任务,就把下一步可能需要做的事情加到清单里。
难题的另一个特点是复杂或者令人手足无措。写一本书看起来足以让人望而生畏,那么不如先从写一篇文章开始。如果仍然觉得写文章棘手,那就先写一个段落。最重要的是要有一个好的开头。
一旦事情开了头,你的思路就会变得清晰起来,也能更确切地知道你所面对的问题。要知道,改进一个已有的事物要比从头创造个东西出来容易得多。你的段落写好了,就可以把它们组成文章,然后再汇成一本书。渐渐地,一本书就这样写出来了。
很多时候,解决难题的关键是如何获得灵感。如果你对某个领域不太熟悉,就要着手去研究,看看其他人是怎么做的,心里好有个底。然后集中火力,对该领域进行全方位的了解。紧接着,尝试从解决小问题入手,看看你是否已经入了门。
指派的任务
所谓指派的任务就是指那些你被告知要去完成的事情。无数的心理学实验证明,当你试图使用物质激励的方式去让别人做事情,他们往往都不太乐意,就算做了也只会把事情做得更糟。外部的刺激,比如奖赏或者惩罚,会抹杀我们对事物原有的兴趣,也就是心理学家们所说的“内在动机”。这个是社会心理学上最有说服力的发现之一,已经超过70多项的研究表明,奖惩会破坏人们对事物原有的兴趣。[5]人们的大脑似乎对被告知该做什么有极大的排斥反应。[6]
有意思的是,这种现象并不仅仅局限于对其他人的反应,如果你试着告诉你自己该做什么,也会有类似的反应。“我应该去做事情X,因为它是目前最重要的事情”,一旦你这样告诉自己,事情X马上就会变成这个世界上最棘手的难题。而当有另外一个更重要的事情Y出现,原先的X又会变成原来的样子。
虚拟的任务
给自己创建虚拟任务是为了达到这样的目的:当你想做事情X的时候,告诉你自己应该去做更重要的事情Y。不过通过故意“欺骗”自己达到目的会有些困难,因为你心里清楚自己想做什么,所以要想办法绕个弯子。[7]
一种办法是让其他人来给你指派任务。举个非常著名的例子,毕业生通常被要求写一篇毕业论文才能毕业,而这个任务对他们来说非常困难。为了避免写论文,他们会以完成其它也很棘手的难题来代替。
虚拟任务必须足够重要(不完成就无法毕业),并且规模足够大(数百页纸的工作量),但不至于重要到完成不了天就会塌下来。
不要给自己指派任务
人们倾向于这样劝自己,“好吧,我要把其它事情先放到一边,专心把这篇文章写完”。比这更糟糕的是你想通过贿赂自己去完成一些事情,比如说,“好吧,如果我把文章写完,就可以出去吃点甜品”。当然最糟糕的是你让其他人来逼你做事情。
我们很容易掉入上面所说的陷阱,以上的情况我都经历过,它们都是非常低效的。这三种情况有一个共同点,就是你给自己指派了任务。一旦任务是被指派的,你的大脑就会想尽各种办法来逃避。
让事情变得有趣
人们通常不会把棘手的难题跟舒适惬意联系在一起,但我却很喜欢做这样的事情。解决难题不单单会令你全神贯注,而且会在事后让你因为解决了这么困难的问题而感觉良好。
所以,能驱动你自己做事情的秘诀,不是跟自己说别无选择必须去做,而是告诉自己事情很有趣。如果事情看起来不是那么有趣,那就让它变得有趣。
第一次践行这个秘诀,是在我被校方要求写一篇小论文的时候。虽说被要求写小论文并不是难事,但毕竟是被指派的。谁会主动写文章去描述原本分马牛不相及的两本书之间的关联的呢?于是我开始在这上面开起了小玩笑。我决定给每个段落使用不同的风格,并尽力模仿各种各样的语言表达方式(这样做的同时也让我的论文内容丰富了起来)。[8]
另一种可以让事情变得有趣的做法,是去解决可以解决问题的问题。如果原先想做一个应用程序,不如试着做一个应用框架,并把程序作为其中的一个示例。这样做不单单使任务看起来更有意思,你最终的成果也许也会更有用。
关于个人生产力,存在着很多迷思。认为不同时间段是可以互相替换的,一味的专注是有益的,贿赂自己是有效的,解决难题是令人不快的,拖延是违背自然的。它们都有一个共同的前提,认为做事情跟我们对事物原有的兴趣是两码事。
对大多数人来说,在大多数工作领域,情况也许是这样的:不是每个人都要去写无聊的论文,或者记录言毫无意义的生活琐事,但一旦我们所处的环境需要我们这么去做,我们就得试着妥协。
但如果你想做一些有价值有创造性的事情,妥协是一种错误的方式。个人生产力的真正秘密不是妥协,而是听从你的身体和内心。饿了就应该吃东西,累了就应该睡觉,感到无聊了就应该停下来休息,做项目的时候就应该选择那些有趣的项目。
事情就是这么简单,不需要用什么构思奇特的缩略语来表示,也不涉及什么深奥的自我控制力,或者来自某些成功人士的个人手记,它几乎就是一个大家所共知的常识。不过我们所处的社会总是跟我们唱反调,如果我们想提升个人生产力,就要想办法绕个弯子。
如果你想继续了解动机心理学,就不要错过Alfie Kohn。他写了很多关于这方面的文章,还有一本书,由Rewards出版,我极力推荐。
我会在以后写一篇以退学为主题的文章,不过你如果真要这么做,最好还是去读读相关的手册。如果你是一个电脑极客,又想自立门户,那么你可以从Y Combinator公司申请创业资金。另外,Mickey Z所写的《Murdering of My Years》里列举了一些艺术家和活动家,讲述了他们是如何做到在坚持他们梦想的同时又能保证生计。
不管你信不信,我真的有在地铁里写文章。给自己不做事情找借口是很容易的,比如你挤不出时间,楼下很吵,等等。但我发现,当灵感出现的时候,我会毫不犹豫地在地铁车厢里把想法写下来,不管周围有多吵,甚至离地铁到站只有几分钟时间。
对睡觉来说也是一样的,没有什么事情比累了不睡觉更糟糕的了,你会感觉自己像个僵尸。
现在我发现在其它方面我也面临同样的问题:害羞。我一般不太会给陌生人打电话,或者在派对上跟别人交谈,上面所说的脑力场会把我推开。也许是因为害羞这个性格特征也是从小遭遇某些事情而形成的吧,不过这个也只是推测。
这里使用的术语”下一个具体步骤”是借用自David Allen所写的《Getting Things Done》,这本书里有很多原则(可能是无意识地)被应用于极限编程。极限编程把这套系统作为管理编程活动的工具,不过我发现实际上它恰好有效地克服了拖延症。
举个例子,结对编程会自然而然地让两个人共同分担来自任务的压力,而且让人们在原本低效率的时间段也有有用的事情可以做。把一个项目划分为很多具体步骤是极限编程的另一个关键部分,这样可以让事情很快得到解决,并加以改进。而所有这些并不是编程活动独有的。
如果想对这方面文献有更全面的了解,可以看看Alfie Kohn的书,由Rewards出版。这个主张是来自他所写的文章《挑战行为圣经——关于金钱和动机的迷思》。
我原先简单地认为这是人类的天性,但Paul Graham认为这是后天形成的。在你还是个孩子的时候,你的父母总是想方设法地控制你。他们要你乖乖地写作业,而你的头脑却开小差,想其它事情去了。久而久之,开小差就变成了习惯。不管它是怎么形成的,想改正它都是很难的。反正我已经放弃这么做了,现在我都是试着怎么绕开这个陷阱。
Richard Reynman告诉我们一个关于他试图探究自己梦境的故事,这个有点像我试图探究如何克服自己的拖延症。每天晚上,他都试着观察当他睡着的时候在他身上发生了什么事:
一天晚上,我跟往常一样做梦,同时观察在我身上发生的变化。我发现我的后脑勺靠在了一根铜棒上,我伸手去摸我的后脑勺,感觉我的后脑勺是软的。我想,我知道为什么我可以在梦里观察自己了,是因为那根铜棒干扰了视觉皮层。我只要在我的后脑勺底下放一根铜棒,那么在任何时候我都可以随心所欲地观察自己了。于是当晚我就没有继续观察,而是进入了梦乡。
当我醒过来的时候,发现脑袋下面根本就没有什么铜棒,我的后脑勺也不是软的。也许,是我的大脑编造了这么一个虚假的理由,让我不要再观察自己的梦境。
你的大脑远比你想象的强大。
举个例子,本来应该写“根据协议,Riis没有引述太多人的话”,我就把它写成“。。。(这里省略N句废话)。。。”
教授认为这是非常糟糕的写法,并没有意识到这只是我的恶作剧,即使我跟他把整篇论文都过了一遍。
linode上的ubuntu主机重启了一下,结果造成VPN客户可以连接,但是却不可以上网,原来重启后iptable需要重新设置
iptables -t nat -A POSTROUTING -s 192.168.3.0/24 -o eth0 -j MASQUERADE
其中192.163.3为客户端子网网段(在/etc/pptpd.conf中配置),问题解决!
对于下面一段代码,执行结果会是什么呢?
var a = [{
for (var i = 0; i & a. i++) {
var item = a[i];
setTimeout(function () {
console.log(&a[& + i + &].x = & + item.x);
猛一看,觉得结果应该是:
a[0].x = 1
a[1].x = 2
ExtJS 的表格功能非常强大,可参见其,但是这些表格只是负责数据的简单展示,当表格的单元格需要显示比较复杂的form元素时,却并没有提供很好的支持。下面的例子提供了一个可行的办法,虽然有一些缺陷,并不完美,但却可以比较好的工作。
其主要原理在于:ExtJS grid可以为每个列指定一个, 该renderer可以返回表格单元格的文本,也可以是一段html,不支持直接返回ExtJS 组件,因此,先返回一段html:
renderer: function (view, meta, record) {
var id = Ext.id();
(function () {
new Ext.Component_XXX({
renderTo: id
}).defer(100);
return String.format(‘&div id={0}&&/div&’, id);
在生成单元格时,ExtJS组件并没有生成,而是在100ms后才添加到单元格的一个指定id的div中,从而达到在单元格中添加任意组件的效果。
这样做的缺点在于:在表格排序时,每一行会重新渲染,而每一行的组件都会通过defer的方式渲染Ext组件,当数据比较多时,会有一个比较明显的延时
最早接触到文件上传功能大概是在九年前了,当时用的struts 1.2, 有一个UploadForm, 具体名字已经记不大清了,印象里觉得把一个文件上传到服务器其实也不复杂,这么多年过去了,再次接触到这个功能的开发,却发现,要做好文件的上传下载,其实并不简单
那做好一个文件上传下载需要考虑哪些问题呢?
一次从文件系统选择多个文件
显示每个文件的上传进度
中途取消文件上传
如果某个文件中途上传失败如何处理
选择多个文件一次性下载
选择后立即下载还是先显示列表,在确认开始后再开始下载
可以通过从操作系统中将需要上传文件拖拽到页面中指定区域进行下载
对文件名的多语言支持,如西班牙语,阿拉伯语,中文等
在文件上传过程中如何不影响进行其他操作,其他操作也不影响文件的上传下载,在一个页面中有多个iframe时,在iframe中的上传下载如何控制
上传时根据文件扩展名进行过滤
对上传文件进行二进制检查 ()
文件大小控制,对系统全局,不同的用户,不同的功能模块可分别设置
文件名中特殊字符的处理,如:& :
(Windows 平台和 Linux平台对文件名中特殊字符的要求会不同)
显示时对文件名进行编码,以防止XSS
大文件上传时,如何高效网络间传输
在服务器端如何高效将上传文件进行存储
大文件上传时浏览器不能出现”页面无响应”
两个不错的文件上传下载框架
plupload ()
功能比较齐全,支持多种不同的实现方式(flash, gear, html5, silverlight, browserplus etc),根据浏览器动态选择不同的实现,不过商用需要另外买license
Uploadify ()
提供flash和HTML5两种实现,flash版免费,HTML5的要付费
两个框架都基于jquery实现,可以根据自己的需要进行一些定制。可惜如果需要在现有系统里使用这两个框架,都需要引入jquery,对于没有使用jquery的系统,则不能保证能够正常使用,如果能够提供对其他主流JS库(如Ext JS)的支持就好了
公司产品的Webservice调用是基于SAAJ实现,对于消息的处理需要涉及SOAP的很多细节,包括设置mimeheader, 手动构建message body, 添加attachment。这应该算是比较古老的实现方式了,现在开发新应用,估计很少有人再用这种方式,新的jax-ws通过定义相应的接口,添加annotation,基本不需要了解soap的低层细节,可以很方便的开发webservice功能。但是这次调优无法从saaj迁移到jax-ws,所以还是要深入了解一下SAAJ的实现细节。
当前使用的saaj版本如下:
&dependency&
&groupId&javax.xml.soap&/groupId&
&artifactId&saaj-api&/artifactId&
&version&1.3.4&/version&
&/dependency&
&dependency&
&groupId&com.sun.xml.messaging.saaj&/groupId&
&artifactId&saaj-impl&/artifactId&
&version&1.3.21&/version&
&/dependency&
当上传的附件尺寸比较大时,出现了Out of Memory,这个主要是由多方面原因造成的。
问题1:提交请求时tomcat进程占内存持续增长,但java堆大小却变化不大
原因:由于在发送SOAPMessage时,使用了如下代码:
URL url = new URL(“endpiont”);
URLConnection conn = url.openConnection();
OutputStream out = httpConnection.getOutputStream();
out = new BufferedOutputStream(out, 2048);
message.writeTo(out);
在运行时可以相看到实际使用的URLConnection为sun.net.www.protocol.http.HttpURLConnection,查看其getOutputStream()方法
public synchronized OutputStream getOutputStream()
throws IOException
if (!this.doOutput) {
throw new ProtocolException(“cannot write to a URLConnection if doOutput=false – call setDoOutput(true)”);
if (this.method.equals(“GET”)) {
this.method = “POST”;
if ((!”POST”.equals(this.method)) && (!”PUT”.equals(this.method)) && (“http”.equals(this.url.getProtocol())))
throw new ProtocolException(“HTTP method ” + this.method + ” doesn’t support output”);
if (this.inputStream != null) {
throw new ProtocolException(“Cannot write output after reading input.”);
if (!checkReuseConnection()) {
connect();
if ((streaming()) && (this.strOutputStream == null)) {
writeRequests();
this.ps = ((PrintStream)this.http.getOutputStream());
if (streaming()) {
if (this.fixedContentLength != -1)
this.strOutputStream = new StreamingOutputStream(this.ps, this.fixedContentLength);
else if (this.chunkLength != -1) {
this.strOutputStream = new StreamingOutputStream(new ChunkedOutputStream(this.ps, this.chunkLength), -1);
return this.strOutputS
if (this.poster == null) {
this.poster = new PosterOutputStream();
return this.
默认情况下以非流的方式处理,仍然会全部写到内存中去(PosterOutputStream继承自ByteArrayOutputStream,至于为什么堆大小变化不大,但tomcat进程内存持续增长却未被释放,还有待求证)
解决方案:采用流方式处理
private boolean streaming() {return (this.fixedContentLength != -1) || (this.chunkLength != -1);}
从代码看,用流方式有两种方式,一种是设置content length,一种是用chunked encoding
由于我们对附件进行了gzip压缩,所以对大小不可预测,因此采用chunk 方式
httpConnection.setChunkedStreamingMode(0);
问题2:取附件大小时出现OOM
threw exception
with root cause
java.lang.OutOfMemoryError: Java heap space
at com.sun.xml.messaging.saaj.util.ByteOutputStream.ensureCapacity(ByteOutputStream.java:102)
at com.sun.xml.messaging.saaj.util.ByteOutputStream.write(ByteOutputStream.java:109)
at javax.activation.DataHandler.writeTo(DataHandler.java:294)
at com.sun.xml.messaging.saaj.soap.AttachmentPartImpl.getSize(AttachmentPartImpl.java:156)
查看AttachmentPartImpl.getSize()的实现:
ByteOutputStream bout = new ByteOutputStream();
dataHandler.writeTo(bout);
} catch (IOException ex) {
log.log(Level.SEVERE,”SAAJ0501.soap.data.handler.err”,new String[] { ex.getLocalizedMessage()});
throw new SOAPExceptionImpl(“Data handler error: ” + ex);
return bout.size();
可以看出,在取附件大小时,先把附件写入到了bout,然后从bout取大小,当文件很大时,自然出现内在不足了。
解决办法:引入第三方包mimepull(http://mimepull.dev.java.net/)
在com.sun.xml.messaging.saaj.saajImpl 1.3.21版本里已经带了对mimepull的依赖,mimepull支持对附件的读取采用流方式,当附件比较大,超过指定的域值时,会被缓存到磁盘,从而避免了内存的过度分配。默认mimpull是没有enable的,需要加上系统参数saaj.use.mimepull=true来启动。
该方案也解决了soapMessage.getAttachments()时引起的OOM问题
参见:https://java.net/jira/browse/SAAJ-31
经常在网上下载一些web框架或一些web应用,第一件事,自然是跑一跑example,做个部署,把相关内容拷贝到web容器。其实如果安装了python的话,在当前目录下,运行以下命令,就可以把当前目录部署成web应用。省去了拷贝的麻烦,节省了磁盘空间,减少硬盘垃圾,好处多多…
$ python -m SimpleHTTPServer [port]
在控制台看到
Serving HTTP on 0.0.0.0 port 8000 …
然后就可以通过http://localhost:8000直接访问
继续了解了一下python的SimpleHTTPServer模块,发现用这个可以写自己的web server,通过简单的几行代码就可以实现一个web proxy,第一次接触python,这种简洁,还是挺印象深刻的。
Ruby 版本:
ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port =& 9090, :DocumentRoot =& Dir.pwd); trap('INT') { s.shutdown }; s.star"
继续找,发现下面两个用scala实现的http server
Twitter 的finagle也可以实现http server,当然更多的是提供其他一些功能
对于用惯了apache, tomcat, nginx的人,豁然觉得,世界很精彩
经过几天的折腾,终于在网络世界有了自己的一片自留地,顿时有了家的感觉。作为一个开发人员,都应该要有自己的网站,就像我们总希望要买自己的房子,而不愿意长期租房子,租的即使再好,也还是别人的,不如自己的好。所以,以前也先后在MSN,新浪,wordpress建了自己的博客,但总是没能够坚持长期写下来,这次在自己的地头上,得好好的种地啊!!
下面说一下整个建站的心路历程:
1. 购买域名
首先想到的是用自己的名字做域名,但是却被别人给抢注了,难道是跟我同名的?小郁闷了一下,后来想想,其实用名字做域名太长了,别人也不好记,绞尽脑汁想了几天突发灵感想到了现在这个域名,其实也没啥特别的意思,感觉应该蛮好记,就一下买了5年期的。正好赶上促销,只要295¥,还是蛮划算的,现在续费同样时间要将近500¥了。后来在购买VPS的时候发现,在我购买域名后一个月左右,万网被划到阿里巴巴旗下了,变化真是快啊。
2.购买VPS(virtual private server)
经过多方比较最终选定了linode的,主要基于如下考虑
稳定(Xen虚拟化),相对其他供应商,不存在超卖现象
速度佳(日本机房)
由于是Xen,可以用于自建VPN来翻墙
只提供linux系统,可以强迫自己好好学习linux
用户量大,口碑不错
缺点就是相对其他VPS 供应商,稍有点贵。如果感兴趣可以用我的推荐码,通过来购买,谢了!!!

我要回帖

更多关于 你好 的文章

 

随机推荐