一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术经过这些年的发展,已经细分到很细的方方面面,尤其对于大型网站来说,所采用的技术更是涉及面非常广,从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求,已经不是原来简单的html静态网站所能比拟的。大型网站,比如门户网站。在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面,还没法根本解决大型网站面临的高负载和高并发问题。上面提供的几个解决思路在一定程度上也意味着更大的投入,并且这样的解决思路具备瓶颈,没有很好的扩展性,下面我从低成本、高性能和高扩张性的角度来说说我的一些经验。1、HTML静态化其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。一下是一个SSH下的html静态化例子用Article表来演示下页面静态化,在此做记录,便于今后参考。这里是基于SSH2架构来演示的。1.演示工程整体结构概览这里我引入了htdz_lib这么个UserLibraliry,包含了SSH2整合所需的jar以及urlrewrite.jar。同时urlrewrite.xml也已创建于WEB-INF下。2.Article表预览我们给Article表增加个HadStatic字段,用以标识此文章是否已静态化。我们不建议添加一篇文章就直接生成对应的静态页面,如果都没有用户来阅读,服务器就徒增了大量html文件,浪费资源。所以我们一般采用访问生成策略:用户访问某文章,判断服务器是否存在此文章对应的静态页,存在则直接重定向到此静态页面,不存在则执行静态化,然后再重定向到生成的静态页。然而每次通过IO去查找文件是否存在,耗费性能,所以像Article这类表加个HadStatic字段,直接判断字段的值来决定是否静态化显得合理多了。3.配置web.xml1.!--定义Spring的装载器--2.context-param3.param-namecontextConfigLocation/param-name4.param-value5.classpath:conf/spring/applicationContext.xml6./param-value7./context-param8.!--监听Spring装载器--9.listener10.listener-class11.org.springframework.web.context.ContextLoaderListener12./listener-class13./listener14.15.!--定义Struts2核心过滤器--16.filter17.filter-namestruts2/filter-name18.filter-class19.org.apache.struts2.dispatcher.FilterDispatcher20./filter-class21./filter22.filter-mapping23.filter-namestruts2/filter-name24.url-pattern/*/url-pattern25.dispatcherREQUEST/dispatcher26.dispatcherFORWARD/dispatcher27.dispatcherINCLUDE/dispatcher28./filter-mapping29.30.filter31.filter-nameUrlRewriteFilter/filter-name32.filter-classorg.tuckey.web.filters.urlrewrite.UrlRewriteFilter/filter-class33.init-param34.param-namelogLevel/param-name35.param-valueWARN/param-value36./init-param37./filter38.filter-mapping39.filter-nameUrlRewriteFilter/filter-name40.url-pattern/*/url-pattern41./filter-mapping其它你懂的,就是修改了struts2的过滤器的filter-mapping/,增加了几个dispatcher/,WHY?后面会讲到。另外再加了个urlrewrite的过滤器。4.配置applicationContext.xml1.beanid=articleActionclass=com.htdz.test.action.ArticleAction/bean2.beanid=articleServiceclass=com.htdz.test.service.impl.ArticleServiceImpl/bean3.beanid=articleDaoclass=com.htdz.test.dao.ArticleDao/bean其他dataSource、sessionFactory、事务等配置,不是本帖的重点,略去了。这里我在beans/中用了default-autowire=byName让spring自动装配依赖的bean了。5.下面贴上各层的代码以下是ArticleDao.java1.publicclassArticleDaoextendsHibernateDaoSupport{2.3.@SuppressWarnings(unchecked)4.publicListArticlelistArticles(){5.return(ListArticle)this.getHibernateTemplate().find(fromArticleaorderbya.articleID);6.}7.8.publicArticlegetArticleByID(LongarticleID){9.return(Article)this.getHibernateTemplate().get(Article.class,articleID);10.}11.12.publicvoidstaticArticle(LongarticleID){13.Articlearticle=getArticleByID(articleID);14.article.setHadStatic(1);15.this.getHibernateTemplate().update(article);16.}17.}再是ArticleService.java及ArticleServiceImpl.java1.publicinterfaceArticleService{2.3./**4.*查询所有文章5.*@returnArticle实例集合6.*/7.publicListArticlelistArticles();8.9./**10.*获取某篇文章11.*@paramarticleID12.*@returnArticle实例13.*/14.publicArticlegetArticleByID(LongarticleID);15.16./**17.*静态化某篇文章18.*@paramarticleID19.*/20.publicvoidstaticArticle(LongarticleID);21.22.}1.publicclassArticleServiceImplimplementsArticleService{2.3.privateArticleDaoarticleDao;4.5.publicListArticlelistArticles(){6.returnarticleDao.listArticles();7.}8.9.publicArticlegetArticleByID(LongarticleID){10.returnarticleDao.getArticleByID(articleID);11.}12.13.publicvoidstaticArticle(LongarticleID){14.articleDao.staticArticle(articleID);15.}16.17.publicArticleDaogetArticleDao(){18.returnarticleDao;19.}20.21.publicvoidsetArticleDao(ArticleDaoarticleDao){22.this.articleDao=articleDao;23.}24.25.}然后是ArticleAction.java1.publicclassArticleActionextendsActionSupport{2.3.privateArticleServicearticleService;4.privateListArticlearticleList;5.privateArticlearticle;6.privateLongarticleID;7.privateStringhadStatic;8.privateStringhtmlName;9.10.publicStringlistArticles()throwsException{11.articleList=articleService.listArticles();12.returnSUCCESS;13.}14.15.publicStringshowArticle()throwsException{16.//静态化文件名称,我们以article_作为前缀,后面连接上articleID,让其独一无二;17.this.htmlName=article_+articleID;18.//如果已经静态化,则直接访问静态化页面这里的hadStatic是作为参数从request中获取到的19.if(1.equals(hadStatic)){20.returnSUCCESS;21.}22.//原本此次操作应该访问的article.jsp页面23.Stringjsp_url=/article.jsp;24.//要生成的静态化文件路径(我