-
2006-02-18
有状态的程序
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://dreamhead.blogbus.com/logs/1949612.html
我现在工作的一个程序是读入Video(或连续帧图像),然后逐帧进行处理。当前帧处理的结果需要依赖于之前的处理结果,所以,这个程序的状态逐步累加的。记得刚开始开发这个程序的时候,由于程序不稳定,经常出现崩溃的现象,为了找到原因所在,我们只有选择从头开始运行,虽然可以从中间开始运行,但由于状态累加的不同,bug很可能无法重现。那是一段相当逍遥的日子,因为当时的程序是Matlab版本,处理一帧图像就要好几秒的时间,而且崩溃通常发生在数百之后,出现一个错误,通常要花几个小时来重新运行,所以,我们会在相当长一段时间内无所事事,就这样,大家有了很多时间聊天,增进了彼此的感情,而且领导绝对没有理由说我们不工作。为此,领导特意给我增加了一台机器,美其名曰提高工作效率。
后来,我良心发现,认为这种工作方式着实不怎么样,于是,我决定开发程序的持久化功能。简而言之,就是把程序运行过程中的数据存起来。这样的话,一旦程序崩溃,我们就可以利用保存起来的数据,重建原有的状态。我知道,熟悉J2EE开发的人对持久化这个词有着特别的感情,实际上,本质上是完全一样的,存储而已。
在《管窥OS——进程透明化》中,我曾经讨论过持久化的问题,持久化的目的就是为了恢复。实际上,对于那些问题的思考主要源自我在这个程序所写的持久化部分。持久化的关键在于数据的持久化,但并不是所有的数据都需要持久化,在应用这个层次上,我们需要保留的数据是那些需要积累的状态,因为其它的数据或者可以通过它们恢复出来,或者只是一些临时数据。在我们的应用中,用来积累状态的主要是一些全局变量。再有就是保存的时机,每当一帧处理完毕的时候,都会把相应的信息持久化,这也符合我讨论过的原子操作之后,只不过,这个原子操作的规模大了一些。在我们的应用中,有一个有趣的细节,因为涉及到图像操作,持久化的过程中要存储一些图像,如果存储为JPG图像,恢复过来就会有些问题,这是因为JGP属于有损压缩,也就是存进去的矩阵和读出来的矩阵会有所差异,虽然在视觉上几乎看不出来,不得已,存放格式选择了BMP。
我不喜欢编写有状态的程序,因为它会带来很多的问题。记得从前编写服务端应用的时候,我们的应用希望能够做集群,从而带来更好的水平扩展性。分析的结果,发现大部分请求几乎可以在不做任何改动的情况下进行扩展,因为它不会对服务端状态有任何改变,只是一来一回。所有的问题都来自我们转发异步请求,因为我们必须在服务端记录请求的信息,这样的话,对于其它服务器处理之后的应答,我们才能进行正确的匹配,进行后续处理。就是因为保存了这些信息,扩展的复杂度一下就上来了,因为一旦做了集群,一种可能的结果是,一台机器发起的请求,应答回到了另外的机器上,这种情况下,我们仍需要进行正确的匹配。这种情况与单机处理截然不同,所以,需要进行额外的设计,而这一切的罪魁祸首就是程序中的状态。
在宏观层面上,应用的性质决定了它是否有状态,这是程序员无法决定的,但是我们可以通过设计,将状态降至一个可以接受的程度。在微观层面上,我们可以通过自己的代码,将状态限制在一个很小的范围之内,让我们编写的大部分函数都属于无状态的。我已经见识过太多本来可以无状态的有状态函数,结果是牵一发而动全身,由于状态带来的副作用。之所以这样的代码经常存在,仅仅因为这种代码编写起来很方便,直接访问全局变量,省去了声明参数之苦。程序员是应该懒惰,但不是这么个懒法,因为这只是一时之快,后面则是无尽的痛苦在等待。本来应用的折磨已经够受了,程序员们何苦为难自己呢!
当然,有状态的程序并不那么可怕,毕竟,身经百战的我们有着兵来将挡的本领。
引用地址:
桧蜩
Blog:桧蜩2009-07-02 06:31:59桧蜩
Blog:桧蜩2009-07-02 05:25:21镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-07-02 03:15:59铕咫 珥嚓铎耱忄 皴犟
Blog:铕咫 珥嚓铎耱忄 皴犟2009-07-01 20:37:56爨
Blog:爨2009-07-01 19:31:33铍
Blog:铍2009-06-24 13:46:08皴犟 珥嚓铎耱忄 徨
Blog:皴犟 珥嚓铎耱忄 徨2009-06-24 10:41:42赅眚屐桊钼耜
Blog:赅眚屐桊钼耜2009-06-24 09:38:54忸耱铟睇
Blog:忸耱铟睇2009-06-24 07:24:07镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-06-24 06:20:11镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-06-19 13:25:26徨耧豚蝽
Blog:徨耧豚蝽2009-06-19 11:43:44镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-06-19 05:52:07镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-06-19 05:23:43赅塍骜觐-痂骜赅
Blog:赅塍骜觐-痂骜赅2009-06-19 04:53:33皴犟 珥嚓铎耱忄 扈眈赅 漕耜
Blog:皴犟 珥嚓铎耱忄 扈眈赅 漕耜2009-06-19 01:48:20dosug 忤溴
Blog:dosug 忤溴2009-06-19 01:24:06镱赍
Blog:镱赍2009-06-10 16:49:00忤溴
Blog:忤溴2009-06-10 10:51:28痼耨觇
Blog:痼耨觇2009-06-10 07:17:11玎
Blog:玎2009-06-09 22:36:56箅桷
Blog:箅桷2009-06-09 21:31:12桧蜩
Blog:桧蜩2009-06-09 12:13:46桧蜩
Blog:桧蜩2009-06-09 07:56:50忤痼
Blog:忤痼2009-05-26 19:23:16镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-05-26 14:25:07镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-05-26 10:00:53镳囫蜩蝮蜿
Blog:镳囫蜩蝮蜿2009-05-26 08:03:44镥蝈疳箴
Blog:镥蝈疳箴2009-05-14 13:44:54镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-05-14 07:13:32襦轵 桊牦蝰觇
Blog:襦轵 桊牦蝰觇2009-05-14 00:46:07镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-05-13 23:20:48漕耋
Blog:漕耋2009-05-13 14:54:48觐眈镥牝 漕耋汔
Blog:觐眈镥牝 漕耋汔2009-05-11 15:42:08皴犟 珥嚓铎耱忄 狃羼
Blog:皴犟 珥嚓铎耱忄 狃羼2009-05-11 10:30:01镳铘耦
Blog:镳铘耦2009-05-08 17:02:59镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-05-08 10:31:48桧蜩
Blog:桧蜩2009-05-08 09:18:19赅躅怦赅
Blog:赅躅怦赅2009-05-08 07:55:10- Blog:2009-05-08 04:15:52
玎赅
Blog:玎赅2009-05-04 05:41:37皴犟 篑塍汨 蜞灬钼
Blog:皴犟 篑塍汨 蜞灬钼2009-04-29 11:36:02犭
Blog:犭2009-04-28 13:28:24耥桁
Blog:耥桁2009-04-28 08:09:40皴犟 珥嚓铎耱忄 24
Blog:皴犟 珥嚓铎耱忄 242009-04-28 06:01:51溴
Blog:溴2009-04-28 04:58:29漕耋
Blog:漕耋2009-04-28 03:05:36牮囫眍皴朦耜
Blog:牮囫眍皴朦耜2009-04-28 01:48:32镨蝈
Blog:镨蝈2009-04-22 21:19:54镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-22 14:55:01忸痤狳糕
Blog:忸痤狳糕2009-04-21 15:26:31蝠囗耨尻耋嚯
Blog:蝠囗耨尻耋嚯2009-04-21 13:19:21桧蜩
Blog:桧蜩2009-04-21 12:16:28桧蜩祉
Blog:桧蜩祉2009-04-20 18:45:04驽磬 镳铖蜩蝮蜿
Blog:驽磬 镳铖蜩蝮蜿2009-04-20 17:54:32镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-20 05:59:56镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-19 19:00:28- Blog:2009-04-19 12:53:55
镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-19 09:50:28- Blog:2009-04-18 21:40:54
镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-18 16:52:01镱痱嚯 溴
Blog:镱痱嚯 溴2009-04-18 15:41:39忤
Blog:忤2009-04-18 12:37:21镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-18 06:21:35- Blog:2009-04-18 04:41:13
蝠囗疋羼蜩螓 镳铖蜩蝮蜿
Blog:蝠囗疋羼蜩螓 镳铖蜩蝮蜿2009-04-18 03:07:40桧蜩
Blog:桧蜩2009-04-15 12:32:12耱囵桕囔 蝮
Blog:耱囵桕囔 蝮2009-04-12 22:38:21镳羼蝮镯桕
Blog:镳羼蝮镯桕2009-04-12 18:54:43襦禧
Blog:襦禧2009-04-11 04:06:19狍朦忄
Blog:狍朦忄2009-04-10 17:15:14桧蜩
Blog:桧蜩2009-04-10 14:42:31dosug 痤耱钼
Blog:dosug 痤耱钼2009-04-10 10:47:34镱骅臌
Blog:镱骅臌2009-04-10 09:49:22皴牮弪 爨沅嚯屙
Blog:皴牮弪 爨沅嚯屙2009-04-10 07:28:29镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-07 02:51:48镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-04-07 01:36:11磬泐痦
Blog:磬泐痦2009-04-07 00:31:46麇麇眈觇
Blog:麇麇眈觇2009-04-04 11:39:37踵疣牝屦桉蜩觇 漕耋汔
Blog:踵疣牝屦桉蜩觇 漕耋汔2009-04-04 04:28:50徨耧豚蝽
Blog:徨耧豚蝽2009-04-04 02:22:19蝈脲纛睇 溴
Blog:蝈脲纛睇 溴2009-04-04 01:15:56- Blog:2009-04-04 00:11:35
忤
Blog:忤2009-04-03 18:50:10- Blog:2009-04-03 17:26:57
耱噔痤镱朦耜桢
Blog:耱噔痤镱朦耜桢2009-04-01 23:56:10躅痤
Blog:躅痤2009-04-01 22:43:55- Blog:2009-03-31 16:45:27
桉蝾痂
Blog:桉蝾痂2009-03-31 08:33:04桧蜩
Blog:桧蜩2009-03-31 04:52:48- Blog:2009-03-30 14:14:41
皴犟 蝠囗覃 珥嚓铎耱忄
Blog:皴犟 蝠囗覃 珥嚓铎耱忄2009-03-30 08:47:30耔祠屦铒铍
Blog:耔祠屦铒铍2009-03-30 05:10:59皴犟 珥嚓铎耱忄
Blog:皴犟 珥嚓铎耱忄2009-03-30 01:40:52犭
Blog:犭2009-03-30 00:36:43镱潢膻麇龛
Blog:镱潢膻麇龛2009-03-29 03:57:30篑蜞眍怅
Blog:篑蜞眍怅2009-03-29 00:50:19蝠筢铒痤忸
Blog:蝠筢铒痤忸2009-03-28 17:01:08镱蝾腙
Blog:镱蝾腙2009-03-28 15:27:35漕耋
Blog:漕耋2009-03-28 10:30:12镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-28 05:02:17钺龛眈
Blog:钺龛眈2009-03-28 03:25:05镱脲驵邂耜
Blog:镱脲驵邂耜2009-03-28 00:21:48潇栩痤怦赅
Blog:潇栩痤怦赅2009-03-27 21:09:13镳钼邃屙桢 漕耋汔
Blog:镳钼邃屙桢 漕耋汔2009-03-26 13:32:19纛蝾 镳铖蜩蝮蜿
Blog:纛蝾 镳铖蜩蝮蜿2009-03-26 08:19:40漕耋
Blog:漕耋2009-03-26 06:18:44襦疣眈
Blog:襦疣眈2009-03-25 02:56:54蜮屦耜桢
Blog:蜮屦耜桢2009-03-24 21:58:05磬汔蜩眈赅
Blog:磬汔蜩眈赅2009-03-24 16:36:47箨疣桧
Blog:箨疣桧2009-03-24 06:01:17皴犟 篑塍汨 镟痦
Blog:皴犟 篑塍汨 镟痦2009-03-24 03:40:36蝮朦耜
Blog:蝮朦耜2009-03-24 01:14:47镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-24 00:37:06皴犟 篑塍汨 蝠囗耨尻耋嚯
Blog:皴犟 篑塍汨 蝠囗耨尻耋嚯2009-03-23 23:43:13铗铍铕桧泐腩
Blog:铗铍铕桧泐腩2009-03-14 07:17:02礤 祛泱 觐眵栩
Blog:礤 祛泱 觐眵栩2009-03-14 02:22:18镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-12 04:50:45镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-11 17:03:39磬
Blog:磬2009-03-11 08:38:12篑蝠铋耱忸 镱蝾腙钼
Blog:篑蝠铋耱忸 镱蝾腙钼2009-03-11 03:40:52祉钽铙痤忭邂
Blog:祉钽铙痤忭邂2009-03-10 23:24:31磬
Blog:磬2009-03-10 22:37:38桧蜩
Blog:桧蜩2009-03-06 17:47:07- Blog:2009-03-06 14:33:08
- Blog:2009-03-06 13:41:45
桧蜩
Blog:桧蜩2009-03-06 12:59:15镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-06 08:03:44镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-06 06:26:42镳铖蜩蝮蜿
Blog:镳铖蜩蝮蜿2009-03-05 18:13:40漕耋
Blog:漕耋2009-03-05 17:21:55桧蜩
Blog:桧蜩2009-03-05 15:03:31- Blog:2009-03-05 08:28:09
漕耋
Blog:漕耋2009-03-05 07:33:41- Blog:2009-03-04 06:47:18
矬蜞睇 礤漕痤泐
Blog:矬蜞睇 礤漕痤泐2009-03-03 15:04:41蝠弪
Blog:蝠弪2009-03-03 14:11:52皴忄耱铒铍
Blog:皴忄耱铒铍2009-03-03 07:55:00镳铖蜩蝮鲨
Blog:镳铖蜩蝮鲨2009-03-03 03:52:34镱蝾腙
Blog:镱蝾腙2009-02-26 00:03:08磬
Blog:磬2009-02-22 21:07:58囵屙溧 扈龛 镱沭箸麒赅 玎疱汨耱痂痤忄
Blog:囵屙溧 扈龛 镱沭箸麒赅 玎疱汨耱痂痤忄2009-02-21 09:24:19耧弼 蝈蹴桕
Blog:耧弼 蝈蹴桕2009-02-21 07:42:34耱嚯
Blog:耱嚯2009-02-21 05:11:27镱痱嚯 镱沭箸麒
Blog:镱痱嚯 镱沭箸麒2009-02-21 04:26:51脲襦 耱痤栩咫
Blog:脲襦 耱痤栩咫2009-02-20 22:30:52忸耨蜞龛
Blog:忸耨蜞龛2009-02-19 07:23:22蝠遽箦蝰
Blog:蝠遽箦蝰2009-02-18 19:11:12磬
Blog:磬2009-02-18 08:22:16滂玎轫 镳铄牝
Blog:滂玎轫 镳铄牝2009-02-18 07:33:40镳铊玮钿耱忸 镱蝾腩
Blog:镳铊玮钿耱忸 镱蝾腩2009-02-18 03:01:11眍蜞痂篑 镥疱忸
Blog:眍蜞痂篑 镥疱忸2009-02-18 00:03:16- Blog:2009-02-17 16:05:54
耜圜囹
Blog:耜圜囹2009-02-17 02:42:32驵驿
Blog:驵驿2009-02-15 23:50:09http://spaces.msn.com/joyfire/Blog/cns!502060A314B1A145!728.entry
Blog:joyfire2006-02-25 23:35:00










评论
如何知道程序什么时候Crush呢? 如果不知道,那只能是实时的记录LOG日志,不太可能实时序列化?
我在这篇blog里谈到的不仅仅是日志,而是程序的状态,通过它,可以重建系统当时的运行情景。
<bean id="securityInterceptor" class="com.SecurityInterceptor"/>
<bean id="secAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref local="securityInterceptor"/>
</property>
<property name="mappedNames">
<list>
<value>*</value>
</list>
</property>
</bean>
<bean id="serviceWithSecurityProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>secAdvisor</value>
</list>
</property>
<property name="beanNames">
<list>
<value>remoteService</value>
</list>
</property>
</bean>
<bean id="remoteService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://${rmi.host}:${rmi.port}/BKService"/>
<property name="serviceInterface" value="com.service.IService"/>
</bean>
这个 remoteService 怎么没有自动织入安全拦截呢?