您的位置:首页 > 编程语言 > Java开发

java web开发之高并发处理

2014-09-26 16:35 429 查看
java处理高并发高负载类网站中数据库的设计方法(java教程,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对应的cluster
id,然后再到指定的cluster找到nightsailer的实际数据。

每个cluster可以用m-m方式,或者m-m-slaves方式。这是一个可以扩展的结构,随着负载的增加,你可以简单的增加新的mysql
cluster进去。

需要注意的是:

1、禁用全部auto_increment的字段

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

3、要具有比较好的方法来监控mysql主机的负载和服务的运行状态。如果你有30台以上的mysql数据库在跑就明白我的意思了。

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

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

其实大家都知道,效率最高、消耗最小的就是纯静态化 http://www.ablanxue.com/shtml/201207/776.shtml的html页面,所以我们尽可能使我们的网站上的页面采 用静态页面来实现,这个最简单的方法其实也是
最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点
的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限
管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。

  

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

  

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

  

网站HTML静态化解决方案

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

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

HTML静态化之后:

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

静态访求如下

Servlet:

public void doGet(HttpServletRequest request, HttpServletResponse
response)

       
throws ServletException, IOException {

   
if(request.getParameter("chapterId") != null){

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

       
String chapterFilePath = getServletContext().getRealPath("/") +
chapterFileName;

       
File chapterFile = new File(chapterFilePath);

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

       
INovelChapterBiz novelChapterBiz = new NovelChapterBizImpl();

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

       
int lastPageId =
novelChapterBiz.searchLastCHapterId(novelChapter.getNovelId().getId(),
novelChapter.getId());

       
int nextPageId =
novelChapterBiz.searchNextChapterId(novelChapter.getNovelId().getId(),
novelChapter.getId());

       
request.setAttribute("novelChapter", novelChapter);

       
request.setAttribute("lastPageId", lastPageId);

       
request.setAttribute("nextPageId", nextPageId);

       
new CreateStaticHTMLPage().createStaticHTMLPage(request, response,
getServletContext(), 

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

    }

}

生成HTML静态页面的类:

package com.jb.y2t034.thefifth.web.servlet;

import java.io.ByteArrayOutputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpServletResponseWrapper;

public class CreateStaticHTMLPage {

   

    public void
createStaticHTMLPage(HttpServletRequest request,
HttpServletResponse response,ServletContext servletContext,String
fileName,String fileFullPath,String jspPath) throws
ServletException, IOException{

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

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

       
final ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();//用于从ServletOutputStream中接收资源 

       
final ServletOutputStream servletOuputStream = new
ServletOutputStream(){//用于从HttpServletResponse中接收资源 

           
public void write(byte[] b, int off,int len){

               
byteArrayOutputStream.write(b, off, len);

           
}

           
public void write(int b){

               
byteArrayOutputStream.write(b);

           
}

       
};

       
final PrintWriter printWriter = new PrintWriter(new
OutputStreamWriter(byteArrayOutputStream));//把转换字节流转换成字符流 

       
HttpServletResponse httpServletResponse = new
HttpServletResponseWrapper(response){//用于从response获取结果流资源(重写了两个方法) 

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: