2007年1月19日
#
初衷是希望有一个简便,不需要配置文件的办法,提高数据层的事务处理能力。以及对连接池的支持。
解决思路是通过修改Spring框架,修改BeanFactory的类搜索机制,默认载入相应的类。
并采用继承的方式,在基类中提供默认方法,允许Spring注入在对象实例中。然后再对象实例中调用。
最近项目组要求使用普元EOS进行项目开发,使用了两个月左右,虽然说有一些心得(这个以后会写出来),但更多是看到了不足的地方,在这里就讨论一下一个成熟的应用框架到底应该有哪些因素。
底层技术:
Application Framework(下称应用框架)是为解决问题而生的,无论是基于JAVA、C++、Ruby等等语言,都必须有基础技术的支持。如JAVA就有经典的Struts+Spring+Hibernate的组合,因此,一个成熟的应用框架,必须拥有完善的MVC框架,以及完整的业务组件管理容器,还有一个成熟的数据访问框架。这个是一切的基础。
权限管理:
拥有一个成熟基础权限架构能够为应用框架增色不少。如果能够和框架本身更好地融合,这样更好。其实目前有很多实现是俄可以借鉴的,如:ACEGI和Spring。
UI:
标签已经非常流行,拥有完善的标签库是必不可少的,Struts是个很好的典范。
Ajax大行其道,如果没有整合一些方便易用的AJAX控件,估计也算不上是一个好框架。
另外还有类似于Freemarker、Velocity之类的简化UI开发的好东东,整合一两个,对于减少开发、提高维护性有很大帮助。
开发工具:
提供敏捷快速的开发工具是一个成熟应用框架所不可或缺的。使用一个成熟的应用框架的开发工具进行开发,可以让开发者最大程度减少对于技术上的瓶颈,让开发者很轻松就可以完成高质量的代码,剩下的精力可以用于专注于业务等其它方面。
另外还有像:单元测试、应用部署等等方面,都是必不可少的一部分。(PS:我是非常痛恨维护几百行ANT的build.xml代码的人)
这里不得不称赞一下普元,普元提供的开发环境和它自身的底层技术融合的非常好,对于开发者而言,是非常方便的,可以不需要很多的培训就可以使用IDE开发出完整的应用。而且测试和部署都很方便。
代码生成器:
其实这个应该和开发工具放在一起,但是因为比较重要,所以单独提出来说。
一个好的代码生成器可以省去开发人员很多不必要的麻烦,能够非常大地提高开发效率。普元的代码生成器是个不错的典范。
我们公司自己也有一个JOP的应用框架,但非常简陋,和普元的设计思想不可同日而语。呵呵~~有点扯远了,但能够看得出,代码生成器对于应用框架是必不可少的。
协同开发:
整合一个好的协同开发和版本管理工具,能够最大程度地降低沟通成本。除了能够支持类似SVN或VSS之类的代码版本管理工具之外,还应该融合进类似Visual Studio Team的任务管理和缺陷管理工具。最好拥有一个可以进行自我积累的知识库的实现。WIKI是个不错的主意。
设计器:
我提出这个是因为看到了IBM的RUP,拥有一个能够从设计到代码实现乃至后面的测试这样一个全流程开发工具,一直是IT人员的一个美好梦想。
一个好的设计器,可以很轻松地在设计图和代码之间相互转换,对于需求变更,设计管理、甚至项目后期的文档都有很重要的意义。
这里又要提到普元,普元在这方面很聪明,走了一条不同的路,它把代码变成一个个图标时,本身就实现了对于设计图和代码之间互转关系。(当然,实现的方式有点土,而且没有办法支持标准的UML)
运行容器:
大家可能觉得奇怪,容器为什么要单独提出来说,很多JAVA开发者都会说,只有遵循JAVA标准就可以啦~。其实不然,一个成熟的应用框架当然要考虑其兼容性,但是有时候,过多考虑兼容性往往会牺牲效率。事实上,很多应用框架被开发出来,都是有一定的局限性的使用场景,针对使用场景的环境进行优化,绝对比使用通用的方法效率要高的多。如我们公司的移动项目使用的是WebSphere,我们的框架就有一个针对WebSphere优化的版本,但同时也存在一个通用版本。
当然还有其它方面也可以引用这种思路,比如使用Oracle自带的一些JDBC类,其效率就比使用JAVA标准的JDBC类要高得多。
其实应用框架被创造出来的目的就是快速、高效、低成本地解决问题,这个大家都知道,但是何谓“成熟”,估计100个人应该有100个答案,这里我的理解就是开发快捷、较低的学习成本、运行稳定,就是一个成熟的应用框架。
PS:上面好像说了一些不少普元的好话,大家千万不要以为我是普元的“托”,晚点我再写遍骂它的文章吧~~呵呵~~。其实我更喜欢SpringSide,但是除了“底层技术”这块之外,在其它方面还有很长的路要走,希望江南白衣兄能够坚持下去。
今年真的是郁闷透顶了。项目组居然叫我去做我从来没有做过的接口方面的编程,搞得我焦头烂额。
因为没有经验,写的代码乱七八糟,出了好多问题,不过,也学了不少东西。
首先就是Socket的编程,我只是在学习JAVA时写了一些socket方面的例子,从来就没有仔细研究过,组长居然叫我设计一个JAVA的接口平台。胡弄了一通之后,系统上线了。但是问题就来了。
首先第一个问题,长连接必须有心跳。因为之前协议中没有定义心跳协议,而我又没有经验,所以等真正上线之后才发现,如果长连接没有心跳,很容易导致在Socket连接中,长时间没有通讯的话,就会导致连接虽然保持,但不能正常通讯的问题。
第二个问题,必须加入流量控制。这个问题出现在业务高峰期时,会接收到大量请求,这时业务系统的处理速度跟不上请求发起方,导致大量请求积压在Socket服务器端,导致JVM崩溃。这个问题我之前是使用了JAVA5中所带的ExecutorService,通过设置固定的线程池数量的方式做流量控制,后来发现不行,线程会不断增加,导致JVM崩溃。不知道是我代码问题还是ExecutorService本身的问题。建议使用BlockingQueue来做队列,我目前用起来还是比较稳定。
第三个问题,是由上面的问题衍生出来的一个问题,就是效率问题。我之前的线程处理方式是每接到一个请求,会在主线程实例化一个线程实例,再把线程放到线程池中运行,这个方式除了导致上面的问题以外,而且效率很慢,我称之为“推”的方式。现在经过改良后,在服务起来之后,先事先运行固定数量的线程,然后所有线程都从同一个BlockingQueue中获取指令,我称之为“拉”的方式。这种方式让程序效率提高了很多,省去了每次生成对象的过程。而且这个设计本身也实现了处理量的控制。
第四个问题,就是指令的返回问题。在处理每个异步指令的过程时,对于返回指令,通常的做法是将返回结果指令放入队列中,然后再逐一返回。这个做法就存在了一个隐患,就是当服务器的进程core掉,或者因其它原因中断,所有的返回指令都会丢失。建议的做法是在得到返回指令之后,将要返回的结果指令持久化,通常是放入数据表或者缓存文件中,然后再操作,这样的话,当重启进程,也可以重新读取返回指令,最大可能保证接口的数据准确性。
第五个问题,其实跟上面有一些接近,就是做接口程序,有一个大原则,就是一切有迹可寻。在受理时要写日志,执行业务时要记录、返回结果时要入库。总之让运维人员可以很方便的定位问题,排除问题。否则,只能麻烦自己啦!
至于其它错误我就不一一罗列了,总之在错误中进步,还是学到不少知识。呵呵~~
非常有幸能调到公司的J2EE基础架构组,负责为公司预研一套完整的架构模型。主要是引入SOA、WorkFlow、AJAX等新技术。
做了开发人员这么久,也做了这么久项目,根本就没有时间好好坐下来研究一下新技术。现在必须先跟一跟潮流,看看那些流行的技术以及概念了,呵呵。。。。。。
研究主要是分三个方向:UI、BPM/SOA、构件化。希望能在这几个方面有所收获吧!努力努力!!!