java处理高并发高负载类网站的优化方法.docx

上传人:b****6 文档编号:8013583 上传时间:2023-01-27 格式:DOCX 页数:13 大小:26.25KB
下载 相关 举报
java处理高并发高负载类网站的优化方法.docx_第1页
第1页 / 共13页
java处理高并发高负载类网站的优化方法.docx_第2页
第2页 / 共13页
java处理高并发高负载类网站的优化方法.docx_第3页
第3页 / 共13页
java处理高并发高负载类网站的优化方法.docx_第4页
第4页 / 共13页
java处理高并发高负载类网站的优化方法.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

java处理高并发高负载类网站的优化方法.docx

《java处理高并发高负载类网站的优化方法.docx》由会员分享,可在线阅读,更多相关《java处理高并发高负载类网站的优化方法.docx(13页珍藏版)》请在冰豆网上搜索。

java处理高并发高负载类网站的优化方法.docx

java处理高并发高负载类网站的优化方法

java处理高并发高负载类网站的优化方法

一:

高并发高负载类网站关注点之数据库

没错,首先是数据库,这是大多数应用所面临的首个SPOF。

尤其是Web2.0的应用,数据库的响应是首先要解决的。

一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降。

常用的优化措施是M-S(主-从)方式进行同步复制,将查询和操作和分别在不同的服务器上进行操作。

我推荐的是M-M-Slaves方式,2个主Mysql,多个Slaves,需要注意的是,虽然有2个Master,但是同时只有1个是Active,我们可以在一定时候切换。

之所以用2个M,是保证M不会又成为系统的SPOF。

Slaves可以进一步负载均衡,可以结合LVS,从而将select操作适当的平衡到不同的slaves上。

以上架构可以抗衡到一定量的负载,但是随着用户进一步增加,你的用户表数据超过1千万,这时那个M变成了SPOF。

你不能任意扩充Slaves,否则复制同步的开销将直线上升,怎么办?

我的方法是表分区,从业务层面上进行分区。

最简单的,以用户数据为例。

根据一定的切分方式,比如id,切分到不同的数据库集群去。

全局数据库用于meta数据的查询。

缺点是每次查询,会增加一次,比如你要查一个用户nightsailer,你首先要到全局数据库群找到nightsailer对应的clusterid,然后再到指定的cluster找到nightsailer的实际数据。

每个cluster可以用m-m方式,或者m-m-slaves方式。

这是一个可以扩展的结构,随着负载的增加,你可以简单的增加新的mysqlcluster进去。

需要注意的是:

1、禁用全部auto_increment的字段

2、id需要采用通用的算法集中分配

3、要具有比较好的方法来监控mysql主机的负载和服务的运行状态。

如果你有30台以上的mysql数据库在跑就明白我的意思了。

4、不要使用持久性链接(不要用pconnect),相反,使用sqlrelay这种第三方的数据库链接池,或者干脆自己做,因为php4中mysql的链接池经常出问题。

二:

高并发高负载网站的系统架构之HTML静态化

其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。

但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。

  除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。

同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求高并发。

网站HTML静态化解决方案

当一个Servlet资源请求到达WEB服务器之后我们会填充指定的JSP页面来响应请求:

HTTP请求---Web服务器---Servlet--业务逻辑处理--访问数据--填充JSP--响应请求

HTML静态化之后:

HTTP请求---Web服务器---Servlet--HTML--响应请求

静态访求如下

Servlet:

[java]viewplaincopyprint?

1.publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

2.throwsServletException,IOException{

3.if(request.getParameter("chapterId")!

=null){

4.StringchapterFileName="bookChapterRead_"+request.getParameter("chapterId")+".html";

5.StringchapterFilePath=getServletContext().getRealPath("/")+chapterFileName;

6.FilechapterFile=newFile(chapterFilePath);

7.if(chapterFile.exists()){response.sendRedirect(chapterFileName);return;}//如果有这个文件就告诉浏览器转向

8.INovelChapterBiznovelChapterBiz=newNovelChapterBizImpl();

9.NovelChapternovelChapter=novelChapterBiz.searchNovelChapterById(Integer.parseInt(request.getParameter("chapterId")));//章节信息

10.intlastPageId=novelChapterBiz.searchLastCHapterId(novelChapter.getNovelId().getId(),novelChapter.getId());

11.intnextPageId=novelChapterBiz.searchNextChapterId(novelChapter.getNovelId().getId(),novelChapter.getId());

12.request.setAttribute("novelChapter",novelChapter);

13.request.setAttribute("lastPageId",lastPageId);

14.request.setAttribute("nextPageId",nextPageId);

15.newCreateStaticHTMLPage().createStaticHTMLPage(request,response,getServletContext(),

16.chapterFileName,chapterFilePath,"/bookRead.jsp");

17.}

18.}

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

throwsServletException,IOException{

if(request.getParameter("chapterId")!

=null){

StringchapterFileName="bookChapterRead_"+request.getParameter("chapterId")+".html";

StringchapterFilePath=getServletContext().getRealPath("/")+chapterFileName;

FilechapterFile=newFile(chapterFilePath);

if(chapterFile.exists()){response.sendRedirect(chapterFileName);return;}//如果有这个文件就告诉浏览器转向

INovelChapterBiznovelChapterBiz=newNovelChapterBizImpl();

NovelChapternovelChapter=novelChapterBiz.searchNovelChapterById(Integer.parseInt(request.getParameter("chapterId")));//章节信息

intlastPageId=novelChapterBiz.searchLastCHapterId(novelChapter.getNovelId().getId(),novelChapter.getId());

intnextPageId=novelChapterBiz.searchNextChapterId(novelChapter.getNovelId().getId(),novelChapter.getId());

request.setAttribute("novelChapter",novelChapter);

request.setAttribute("lastPageId",lastPageId);

request.setAttribute("nextPageId",nextPageId);

newCreateStaticHTMLPage().createStaticHTMLPage(request,response,getServletContext(),

chapterFileName,chapterFilePath,"/bookRead.jsp");

}

}

生成HTML静态页面的类:

[java]viewplaincopyprint?

1.packagecom.jb.y2t034.thefifth.web.servlet;

2.importjava.io.ByteArrayOutputStream;

3.importjava.io.FileOutputStream;

4.importjava.io.IOException;

5.importjava.io.OutputStreamWriter;

6.importjava.io.PrintWriter;

7.importjavax.servlet.RequestDispatcher;

8.importjavax.servlet.ServletContext;

9.importjavax.servlet.ServletException;

10.importjavax.servlet.ServletOutputStream;

11.importjavax.servlet.http.HttpServletRequest;

12.importjavax.servlet.http.HttpServletResponse;

13.importjavax.servlet.http.HttpServletResponseWrapper;

14./**

15.*创建HTML静态页面

16.*功能:

创建HTML静态页面

17.*时间:

2009年1011日

18.*地点:

home

19.*@authormavk

20.*

21.*/

22.publicclassCreateStaticHTMLPage{

23./**

24.*生成静态HTML页面的方法

25.*@paramrequest请求对象

26.*@paramresponse响应对象

27.*@paramservletContextServlet上下文

28.*@paramfileName文件名称

29.*@paramfileFullPath文件完整路径

30.*@paramjspPath需要生成静态文件的JSP路径(相对即可)

31.*@throwsIOException

32.*@throwsServletException

33.*/

34.publicvoidcreateStaticHTMLPage(HttpServletRequestrequest,HttpServletResponseresponse,ServletContextservletContext,StringfileName,StringfileFullPath,StringjspPath)throwsServletException,IOException{

35.response.setContentType("text/html;charset=gb2312");//设置HTML结果流编码(即HTML文件编码)

36.RequestDispatcherrd=servletContext.getRequestDispatcher(jspPath);//得到JSP资源

37.finalByteArrayOutputStreambyteArrayOutputStream=newByteArrayOutputStream();//用于从ServletOutputStream中接收资源

38.finalServletOutputStreamservletOuputStream=newServletOutputStream(){//用于从HttpServletResponse中接收资源

39.publicvoidwrite(byte[]b,intoff,intlen){

40.byteArrayOutputStream.write(b,off,len);

41.}

42.publicvoidwrite(intb){

43.byteArrayOutputStream.write(b);

44.}

45.};

46.finalPrintWriterprintWriter=newPrintWriter(newOutputStreamWriter(byteArrayOutputStream));//把转换字节流转换成字符流

47.HttpServletResponsehttpServletResponse=newHttpServletResponseWrapper(response){//用于从response获取结果流资源(重写了两个方法)

48.publicServletOutputStreamgetOutputStream(){

49.returnservletOuputStream;

50.}

51.publicPrintWritergetWriter(){

52.returnprintWriter;

53.}

54.};

55.rd.include(request,httpServletResponse);//发送结果流

56.printWriter.flush();//刷新缓冲区,把缓冲区的数据输出

57.FileOutputStreamfileOutputStream=newFileOutputStream(fileFullPath);

58.byteArrayOutputStream.writeTo(fileOutputStream);//把byteArrayOuputStream中的资源全部写入到fileOuputStream中

59.fileOutputStream.close();//关闭输出流,并释放相关资源

60.response.sendRedirect(fileName);//发送指定文件流到客户端

61.}

62.}

packagecom.jb.y2t034.thefifth.web.servlet;

importjava.io.ByteArrayOutputStream;

importjava.io.FileOutputStream;

importjava.io.IOException;

importjava.io.OutputStreamWriter;

importjava.io.PrintWriter;

importjavax.servlet.RequestDispatcher;

importjavax.servlet.ServletContext;

importjavax.servlet.ServletException;

importjavax.servlet.ServletOutputStream;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjavax.servlet.http.HttpServletResponseWrapper;

/**

*创建HTML静态页面

*功能:

创建HTML静态页面

*时间:

2009年1011日

*地点:

home

*@authormavk

*

*/

publicclassCreateStaticHTMLPage{

/**

*生成静态HTML页面的方法

*@paramrequest请求对象

*@paramresponse响应对象

*@paramservletContextServlet上下文

*@paramfileName文件名称

*@paramfileFullPath文件完整路径

*@paramjspPath需要生成静态文件的JSP路径(相对即可)

*@throwsIOException

*@throwsServletException

*/

publicvoidcreateStaticHTMLPage(HttpServletRequestrequest,HttpServletResponseresponse,ServletContextservletContext,StringfileName,StringfileFullPath,StringjspPath)throwsServletException,IOException{

response.setContentType("text/html;charset=gb2312");//设置HTML结果流编码(即HTML文件编码)

RequestDispatcherrd=servletContext.getRequestDispatcher(jspPath);//得到JSP资源

finalByteArrayOutputStreambyteArrayOutputStream=newByteArrayOutputStream();//用于从ServletOutputStream中接收资源

finalServletOutputStreamservletOuputStream=newServletOutputStream(){//用于从HttpServletResponse中接收资源

publicvoidwrite(byte[]b,intoff,intlen){

byteArrayOutputStream.write(b,off,len);

}

publicvoidwrite(intb){

byteArrayOutputStream.write(b);

}

};

finalPrintWriterprintWriter=newPrintWriter(newOutputStreamWriter(byteArrayOutputStream));//把转换字节流转换成字符流

HttpServletResponsehttpServletResponse=newHttpServletResponseWrapper(response){//用于从response获取结果流资源(重写了两个方法)

publicServletOutputStreamgetOutputStream(){

returnservletOuputStream;

}

publicPrintWritergetWriter(){

returnprintWriter;

}

};

rd.include(request,httpServletResponse);//发送结果流

printWriter.flush();//刷新缓冲区,把缓冲区的数据输出

FileOutputStreamfileOutputStream=newFileOutputStream(fileFullPath);

byteArrayOutputStream.writeTo(fileOutputStream);//把byteArrayOuputStream中的资源全部写入到fileOuputStream中

fileOutputStream.close();//关闭输出流,并释放相关资源

response.sendRedirect(fileName);//发送指定文件流到客户端

}

}

三:

高并发高负载类网站关注点之缓存、负载均衡、存储

缓存是另一个大问题,我一般用memcached来做缓存集群,一般来说部署10台左右就差不多(10g内存池)。

需要注意一点,千万不能用使用swap,最好关闭linux的swap。

负载均衡/加速

可能上面说缓存的时候,有人第一想的是页面静态化,所谓的静态html,我认为这是常识,不属于要点了。

页面的静态化随之带来的是静态服务的负载均衡和加速。

我认为Lighttped+Squid是最好的方式了。

LVS<------->lighttped====>squid(s)====lighttpd

上面是我经常用的。

注意,我没有用apache,除非特定的需求,否则我不部署apache,因为我一般用php-fastcgi配合lighttpd,性能比apache+mod_php要强很多。

squid的使用可以解决文件的同步等等问题,但是需要注意,你要很好的监控缓存的命中率,尽可能的提高的90%以上。

squid和lighttped也有很多的话题要讨论,这里不赘述。

存储

存储也是一个大问题,一种是小文件的存储,比如图片这类。

另一种是大文件的存储,比如搜索引擎的索引,一般单文件都超过2g以上。

小文件的存储最简单的方法是结合lighttpd来进行分布。

或者干

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1