之前在JavaEye中提出过类似的,很多人都给了我些建议,我用了一周的时间进行了总结,巡查了些资料,总结了下,分享下自己的一些想法。
对于网站流量很大来说,好的架构设计以及从应用程序级别到系统级多了解些是很重要的,我从自己经历的项目以及JavaEye分享的以及资料总结的,和大家分享下:
1. 对于应用程序级方面来说
如果对于高访问量的话,一个重要的实现技术就是界面静态化,例如生成HTML文件,静态界面避免了每次对数据库的访问操作,并且提高了查询性能,目前知道的框架Fremarker,Velocity,举个实现方法例子
1.1 界面静态化
public static void crateHTML
(ServletContext context,
Map<String,Object> data,
String templatePath,
String targetHtmlPath)
{
Configuration freemarkerCfg = new Configuration();
//加载模版
freemarkerCfg.setServletContextForTemplateLoading(context, "/");
freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
//指定模版路径
Template template = freemarkerCfg.getTemplate(templatePath,"UTF-8");
template.setEncoding("UTF-8");
//静态页面路径
String htmlPath = context.getRealPath("/html")+"/"+targetHtmlPath;
File htmlFile = new File(htmlPath);
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
//处理模版
template.process(data, out);
out.flush();
out.close();
}
[color=red]ServletContext:例如Struts2中ServletActionContext.getServletContext()得到
Map<String,Object> data : 模版的数据来源
String templatePath : ftl所在的路径
String targetHtmlPath : 最后生成静态页的路径 [/color]
1.2 缓存的使用
对于缓存的使用,需要根据具体的需求进行具体的配置,那些数据在界面经常被使用到,查询操作相对修改操作更频繁,如Hibernate框架中的一级二级缓存的使用,以及几个开源的基于J2EE缓存框架,如OSCache,JSC,EHCache,JCache等,了解更多的话可以参考http://developer.51cto.com/art/200807/83164.htm。缓存说简单点的话就是缓存对象,放在内存或硬盘中,即取即拿,提高了性能,但也带来内存的消耗。以OSCache缓存为例,OSCache的特性:
1.2.1 缓存任意对象:可以不受限制的缓存JSP的一部分或是Http请求,任何的Java对象都可以被缓存。
1.2.2 通过API可以完完全全的控制OSCache的任何特性。
1.2.3 持久缓存:我们可以把认为重要的数据缓存到硬盘上。
1.2.4 支持集群:集群缓存数据能被单个的进行参数配置,不需要修改代码。
1.2.5 缓存记录的过期:你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。
OSCache可以有JSP应用,API应用以及CacheFilter的应用,分别的例子
1.2.5.1 JSP应用:
<os:cache key="<%=myKey%>" cron="0 2 * * *" refresh="<%=needRefresh%>">
<!--这里是要缓存的内容-->
</os:cache>
将myKey标识的缓存内容在每天的凌晨2时自动刷新.如果needRefresh为true也会刷新(适合于更新内容的即时刷新).
1.2.5.2 API应用:
主要用到的GeneralCacheAdministrator的方法有
public Object getFromCache(String key) throws NeedsRefreshException; -- 从缓存中获取一个key标识的对象.
public Object getFromCache(String key, int refreshPeriod) throws NeedsRefreshException ; -- 从缓存中获取一个key标识的对象. refreshPeriod刷新周期,标识此对象在缓存中保存的时间(单位:秒)
public void putInCache(String key, Object content) -- 存储一个由Key标识的缓存对象.
public void putInCache(String key, Object content, String[] groups) -- 存储一个由Key标识的属于groups中所有成员的缓存对象.
public void flushEntry(String key) -- 更新一个Key标识的缓存对象.
public void flushGroup(String group) --更新一组属于groupr标识的所有缓存对象.
public void flushAll() -- 更新所有缓存.
public void cancelUpdate(String key) --- 取消更新 只用于在处理捕获的NeedsRefreshException异常并尝试生成新缓存内容失效的时候.
public void removeEntry(String key) ---从缓中移除一个key标识的对象
public void clear() --- 清除所有缓存
1.5.2.3 CacheFilter的应用:
配置CacheFilter,在Web.xml中加入如下:
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>600</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>session</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
这个例子将在session范围缓存所有JSp10分钟.默认情况scope为application,时间为1小时. 可以参考http://code-chris.iteye.com/blog/294731
对于项目瓶颈问题,在优化方面可以使用例如AOP计算具体用时较长的时间,研究具体实际情况,找到哪些URL比较常使用比较耗时,分析SQL 监控日志 查看用的最多的20条,最慢的10条。 目前在应用程序级想到的就这几方面,目前在总结系统级例如集群,负载均衡等等,应用程序级方面的还需要集体的智慧
对于网站流量很大来说,好的架构设计以及从应用程序级别到系统级多了解些是很重要的,我从自己经历的项目以及JavaEye分享的以及资料总结的,和大家分享下:
1. 对于应用程序级方面来说
如果对于高访问量的话,一个重要的实现技术就是界面静态化,例如生成HTML文件,静态界面避免了每次对数据库的访问操作,并且提高了查询性能,目前知道的框架Fremarker,Velocity,举个实现方法例子
1.1 界面静态化
public static void crateHTML
(ServletContext context,
Map<String,Object> data,
String templatePath,
String targetHtmlPath)
{
Configuration freemarkerCfg = new Configuration();
//加载模版
freemarkerCfg.setServletContextForTemplateLoading(context, "/");
freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
//指定模版路径
Template template = freemarkerCfg.getTemplate(templatePath,"UTF-8");
template.setEncoding("UTF-8");
//静态页面路径
String htmlPath = context.getRealPath("/html")+"/"+targetHtmlPath;
File htmlFile = new File(htmlPath);
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
//处理模版
template.process(data, out);
out.flush();
out.close();
}
[color=red]ServletContext:例如Struts2中ServletActionContext.getServletContext()得到
Map<String,Object> data : 模版的数据来源
String templatePath : ftl所在的路径
String targetHtmlPath : 最后生成静态页的路径 [/color]
1.2 缓存的使用
对于缓存的使用,需要根据具体的需求进行具体的配置,那些数据在界面经常被使用到,查询操作相对修改操作更频繁,如Hibernate框架中的一级二级缓存的使用,以及几个开源的基于J2EE缓存框架,如OSCache,JSC,EHCache,JCache等,了解更多的话可以参考http://developer.51cto.com/art/200807/83164.htm。缓存说简单点的话就是缓存对象,放在内存或硬盘中,即取即拿,提高了性能,但也带来内存的消耗。以OSCache缓存为例,OSCache的特性:
1.2.1 缓存任意对象:可以不受限制的缓存JSP的一部分或是Http请求,任何的Java对象都可以被缓存。
1.2.2 通过API可以完完全全的控制OSCache的任何特性。
1.2.3 持久缓存:我们可以把认为重要的数据缓存到硬盘上。
1.2.4 支持集群:集群缓存数据能被单个的进行参数配置,不需要修改代码。
1.2.5 缓存记录的过期:你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。
OSCache可以有JSP应用,API应用以及CacheFilter的应用,分别的例子
1.2.5.1 JSP应用:
<os:cache key="<%=myKey%>" cron="0 2 * * *" refresh="<%=needRefresh%>">
<!--这里是要缓存的内容-->
</os:cache>
将myKey标识的缓存内容在每天的凌晨2时自动刷新.如果needRefresh为true也会刷新(适合于更新内容的即时刷新).
1.2.5.2 API应用:
主要用到的GeneralCacheAdministrator的方法有
public Object getFromCache(String key) throws NeedsRefreshException; -- 从缓存中获取一个key标识的对象.
public Object getFromCache(String key, int refreshPeriod) throws NeedsRefreshException ; -- 从缓存中获取一个key标识的对象. refreshPeriod刷新周期,标识此对象在缓存中保存的时间(单位:秒)
public void putInCache(String key, Object content) -- 存储一个由Key标识的缓存对象.
public void putInCache(String key, Object content, String[] groups) -- 存储一个由Key标识的属于groups中所有成员的缓存对象.
public void flushEntry(String key) -- 更新一个Key标识的缓存对象.
public void flushGroup(String group) --更新一组属于groupr标识的所有缓存对象.
public void flushAll() -- 更新所有缓存.
public void cancelUpdate(String key) --- 取消更新 只用于在处理捕获的NeedsRefreshException异常并尝试生成新缓存内容失效的时候.
public void removeEntry(String key) ---从缓中移除一个key标识的对象
public void clear() --- 清除所有缓存
1.5.2.3 CacheFilter的应用:
配置CacheFilter,在Web.xml中加入如下:
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>600</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>session</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
这个例子将在session范围缓存所有JSp10分钟.默认情况scope为application,时间为1小时. 可以参考http://code-chris.iteye.com/blog/294731
对于项目瓶颈问题,在优化方面可以使用例如AOP计算具体用时较长的时间,研究具体实际情况,找到哪些URL比较常使用比较耗时,分析SQL 监控日志 查看用的最多的20条,最慢的10条。 目前在应用程序级想到的就这几方面,目前在总结系统级例如集群,负载均衡等等,应用程序级方面的还需要集体的智慧