OSChina.net,目前每天的访问 IP 在 50 万左右,每天的动态请求在 2000 万左右,高峰期并发请求达到 8000。
这是一个纯 Java 技术开发的网站,没有使用任何框架。整个网站的底层只需要一台低端服务器:
- DELL SC 1435 (1 台)
- CPU:双 AMD 2G
- 内存:4 * 2G + 4 * 1G
- 硬盘:250G * 2
这样一个技术选型是如何决策的?InfoQ 编辑与 OSChina 最初的代码撰写者刘柄成(红薯)进行了沟通。
InfoQ:OSChina 网站仅采用了 Servlet+Velocity 这一在今天看起来颇为“简陋”的技术架构,与当今 SSH 打天下的做法“背道而驰”,请问是如何做出这个决定的,在网站的发展过程中,是否有过转型到框架上的想法?
红薯:当初开发网站的时候是为了短平快,因为网站一开始功能非常的简单,只是一些开源软件的分类展示,因此整个系统最麻烦的地方其实是页面的展示。而且对于 Java 开发网站一个最麻烦的地方便是一旦修改了 Java 的代码就需要重启应用服务器。对一个互联网网站来说,不能因为这些技术的问题导致用户的访问频繁中断。因此刚开始架构选型的思路便是后端代码只提供一些数据的基本封装,由前端的模版自由组合数据。
在网站这五年的发展过程中,我们深刻体会这种设计带来的便利性。由于产品不断的在完善和更新中,经常要对页面做各种调整,包括版面、显示的数据等。由于是模版根据自身需要调用 Velocity Toolbox 的方法去获取数据,相当于每次的调整只需要修改模版页面即可,随时更新到服务器随时生效,无需重启应用服务器,非常的便利。而常规的 SSH 做法,当我需要在页面上增加某些额外的数据显示时,往往需要在 Controller (Java 类) 中读取数据,然后需要重新编译,重新发布……
目前尚未有转型到框架上的想法。
InfoQ:你提到目前 SSH 框架结构流行,而且很多应用都采用了过于模式化的设计。能举几个例子说明一下这种过于模式化的设计吗?
红薯:我接触过很多用 Spring 框架开发的项目,过份的接口化设计是普遍存在的问题。
好比说访问用户资料的方法,首先会做一个 UserDAO 的接口,然后再做一个 UserDAO_Impl 的接口实现类。理由是可以方便扩展其他读取资料的实现,或者部署为支持远程调用的接口方法等等
但你会发现,至始至终不曾要求过其他第二种用户资料的读取方式,换成是我比较极端,一个静态的 UserTool 类搞定即可。
InfoQ:底层与数据库交互之处仅仅使用了 JDBC 么?有没有做过哪些具体的优化措施?
红薯:OSChina 访问数据库使用了 dbutils 这个工具包以及阿里的 druid 连接池实现。
我曾是 Hibernate 的深度用户,深感 Hibernate 在实现跨数据库支持的便利性,我以前的一个 DLOG4J 开源博客产品,因为需要支持各种数据库,因此用 Hibernate 来开发非常之方便,你不需要关心数据库之间的差异性。
但对 OSChina 来说,从第一天上线就以前确定了它是运行在 MySQL 数据库上,不会改变。既然这样,我们就不认为 Hibernate 能给这个项目带来多少好处,而且又是这么庞大的一个 jar 包。相比之下 dbutils 简单得多得多。
优化方面主要是大量的缓存处理以及索引优化。
InfoQ:OSChina 网站的读写并发量如何,读与写的比例大概是多少?针对这个比例采取了怎样的缓存手段?
红薯:我们还真没统计过读写的比例,目前会根据具体的功能需求来处理缓存。
例如:
a)发布新闻、新帖,无需即时更新列表,通过缓存中配置的失效时间自动更新列表
b)回帖、评论、动弹等,用户发布完回帖必须马上看到新的内容显示,因此会在代码上手工去清除对应的缓存
整个 OSChina 的代码中有大量的代码是用来处理缓存的更新问题。
InfoQ:之前是否做过评估,如果这个请求量按照流行的 SSH 框架结构来实现,预计会需要怎样的硬件配置进行支撑?
红薯:这个真没做过评估,我觉得两种开发架构对硬件的要求不会差别太多,关键是不断的开发更新上会更加便利,此外使用 SSH 开发的应用在启动上也需花费更多的时间。
InfoQ:服务端仅使用了 Servlet,请问是如何实现 MVC 的,是通过制度强制开发人员遵循,还是采取了哪些具体的分层手段来实现 MVC?
红薯:OSChina 自己实现了一个简单的 MVC ,代码请看这里。
无需任何配置文件,依照“惯例重于配置”的思路。
评论