|
b/s结构优点多多,不再赘述。但在绝对性能上来说,不如c/s结构,s端承受压力开销极大,不可避免,但可以通过一个“简“字来优化b/s架构的效率。[以java为例]
1.数据库(你不让我说我也要说,嘻嘻)
表结构设计有很多书籍可以参考,应该不成问题。
讨论一下程序调用数据库的性能。
1.1 DB连接
连接数据库是一个关键,通常问题发生在取连接和释放的机制。
通常无论是vb或者java,我们喜欢在页面包含上下2个数据库操作模块:get和free,头部使用get取得连接,尾部使用free释放,释放是必不可少的,万万不能省略,否则会因为连接数超过上限而异常。
我们讨论的是释放连接的节点。
比方说,返回一个rs集,然后使用rs.XXX()方法来操作,最后rs = null;cn.freeConnection();。原理上来说,这没问题,也是最通常的做法。
但是,这个连接的生存周期,会随着当前模块的运行周期而定,直到程序运行结束,连接才被主动释放。不合理就产生了~~~~
换个角度:把返回的rs用hashtable代替,赋值后马上关掉cn、释放rs,OK,我们可以使用vector做任何事情,而数据库连接可以提供给另一个线程使用,单位时间平均的可提供连接数无形中增大了。这对一个高响应率的b/s系统来说,甚至可以产生扩容的效果,嘻嘻,仅仅是改变了一个集合类的生存周期。
1.2 DB查询次数
讨论这个有点班门弄斧,相信大家都是高手。
数据库的瓶颈在于磁盘I/O,显而易见2万转的scsi阵列也比不上sdram速度。
那么,我们设计的时候,就要充分利用内存来降低磁盘I/O的压力了。
个人习惯的写法是:所有返回量小的查询,使用application bean启更新线程,放在hashtable/vector中,每次访问时激活状态标志检查,相异为0时,从内存中取得,相当于对数据库启动一个2级cache,实测在访问量极大时,可以大幅度提高效率。
2.程序架构
简要讨论一下相关b/s结构性能。
至今我写东西也很乱:(,不敢多说。
1.1 循环
个人认为循环是程序运行中的黑洞,一个考虑不周全的循环,在b/s结构中对系统所造成的压力不可想象,(c/s好些,起码分给每个client承受)。
循环中最隐蔽的##被过滤##是对象初始化和生存周期。
初始化是一个new起来很爽,但释放起来很烦的东东。
很多时候,new一个实例,绝不代表仅仅的一条语句,通常的构造方法中,会执行多个衍生实例的初始化。同样,这对磁盘I/O和CPU运算来说,是一笔不小的开销。
在循环中,这个问题尤为明显!
同样,对象的生存周期,在循环中,可以随你执行次数的增长,成倍的消耗系统资源、降低执行效率。
所以,一个for或者一个while里面,每一个对象都必需保证它的必要性,对于持续存在的实例,最好在上层方法域内定义,保证对可替换的对象尽量覆盖操作。
1.2 调试信息
我测试过一个程序,方法体中有很多System.out.println();,看起来很正常,因为毕竟他在后台打屏,无所谓的。
但是,结果发现,在一台标配Sun 280服务器上,每一个System.out.println();相当于一次Delay(90)左右,是不是很恐怖?100次打屏,耗费了你将近1秒钟的程序执行时间,或许,在这延迟的时候,你有一个数据库连接会延迟释放,或者一个socket连接会延迟释放。
从此,除非调试需要,正式上线的系统我就再也不敢加入print();了。取而代之的是一个log队列,在特定的时间写入log文件中。
1.3 多线程
不可否认的是,只要服务器资源允许(绝大多数系统的硬件闲置率都是很高的),多线程可以给我们节省更多的时间。
最大的受益者应该是网络I/O的情况,避免了队列中其他请求的等候。
3.输出效率
这个和程序没什么关系,就是我们所说得在Browser下载的效率。
合理利用xml/html的标签,把最重要的部分最先表现出来就ok,用户通常最不喜欢看到的就是界面的主体内容出现的最慢。
不要用很大的标签域(例如全屏的表格)。
讨论了几个在开发过程中遇到与性能相关的问题,错漏之处,赶紧告诉我!嘻嘻
|
|