Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活。
Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个 web应用就会连同这个身份Cookie一起发送到服务端。服务端上的授权设置就可以根据不同目录对不同用户的访问授权进行控制了。
问题来了,在实际是用中我们往往需要的是基于角色,或者说基于用户组的验证和授权。对一个网站来说,一般的验证授权的模式应该是这样的:根据实际需求把用户分成不同的身份,就是角色,或者说是用户组,验证过程不但要验证这个用户本身的身份,还要验证它是属于哪个角色的。而访问授权是根据角色来设置的,某些角色可以访问哪些资源,不可以访问哪些资源等等。要是基于用户来授权访问将会是个很不实际的做法,用户有很多,还可能随时的增减,不可能在配置文件中随时的为不断增加的新用户去增加访问授权的。 下面大概的看一下Forms的过程。
Forms身份验证基本原理:
一 身份验证
要采用Forms身份验证,先要在应用程序根目录中的Web.config中做相应的设置:
<authentication mode="forms"> <forms name=".ASPXAUTH " slidingExpiration="true" loginUrl="/login.aspx" timeout="30" path= "/" domain=".abc.com">
</forms> </authentication>
其中<authentication mode= "forms"> 表示本应用程序采用Forms验证方式。
1. <forms>标签中的name表示指定要用于身份验证的 HTTP Cookie。默认情况下,name 的值是 .ASPXAUTH。采用此种方式验证用户后,以此用户的信息建立一个FormsAuthenticationTicket类型的身份验证票,再加密序列化为一个字符串,最后将这个字符串写到客户端的name指定名字的Cookie中.一旦这个Cookie写到客户端后,此用户再次访问这个web应用时会将连同Cookie一起发送到服务端,服务端将会知道此用户是已经验证过的. 再看一下身份验证票都包含哪些信息呢,我们看一下FormsAuthenticationTicket类:
CookiePath: 返回发出 Cookie 的路径。注意,窗体的路径设置为 /。由于窗体区分大小写,这是为了防止站点中的 URL 的大小写不一致而采取的一种保护措施。这在刷新 Cookie 时使用
Expiration: 获取 Cookie 过期的日期/时间。
IsPersistent: 如果已发出持久的 Cookie,则返回 true。否则,身份验证 Cookie 将限制在浏览器生命周期范围内。
IssueDate: 获取最初发出 Cookie 的日期/时间。
Name: 获取与身份验证 Cookie 关联的用户名。
UserData :获取存储在 Cookie 中的应用程序定义字符串。
系统结构范畴下的吞吐量 定义:吞吐量是指在单位时间内中央处理器 (CPU)从存储设备读取->处理->存储信息的量。
影响吞吐量因素:
1、存储设备的存取速度,即从存储器读出数据或数据写入存储器所需时间;
2、CPU 性能:1)时钟频率;
2)每条指令所花的时钟周期数(即CPI );
3)指令条数;
3、系统结构,如并行处理结构可增大吞吐量。
网络范畴下的吞吐量 定义:吞吐量是指在没有帧丢失的情况下,设备能够接受的最大速率。
相关知识:
1、吞吐量的大小主要由防火墙内网卡,及程序算法的效率决定,尤其是程序算法,会使防火墙系统 进行大量运算,通信量大打折扣。因此,大多数防火墙虽号称100M防火墙,由于其算法依靠软件实现,通信量远远没有达到100M,实际只有10M- 20M。纯硬件防火墙,由于采用硬件进行运算,因此吞吐量可以达到线性90-95M,是真正的100M防火墙。
2、吞吐量和报文转发率是关系防火墙应用的主要指标,一般采用FDT(Full Duplex Throughput)来衡量,指64字节数据包的全双工吞吐量,该指标既包括吞吐量指标也涵盖了报文转发率指标。
3、吞吐量的测试方法是:在测试中以一定速率发送一定数量的帧,并计算待测设备传输的帧,如果发送的帧与接收的帧数量相等,那么就将发送速率提高并重新测试;如果接收帧少于发送帧则降低发送速率重新测试,直至得出最终结果。吞吐量测试结果以比特/秒或字节/秒表示。
概念区别:
吞吐量与带宽 的区分:吞吐量和带宽是很容易搞混的一个词,两者的单位都是Mbps.先让我们来看两者对应的英语,吞吐量:throughput ; 带宽: Max net bitrate 。当我们讨论通信链路的带宽时,一般是指链路上每秒所能传送的比特数。我们可以说以太网 的 带宽是10Mbps。但是,我们需要区分链路上的可用带宽(带宽)与实际链路中每秒所能传送的比特数(吞吐量)。我们倾向于用“吞吐量”一次来表示一个系 统的测试性能。这样,因为实现受各种低效率因素的影响,所以由一段带宽为10Mbps的链路连接的一对节点可能只达到2Mbps的吞吐量。这样就意味着, 一个主机上的应用能够以2Mbps的速度向另外的一个主机发送数据。
只讨论IPv4 1. 概念 简单说,UDP的checksum计算,就是伪首部+UDP首部+UDP数据。伪首部并不是IP首部的一部分,而是由IP首部中的源IP(32 bit)、目的IP(32 bit)、协议号(8 bit),和UDP首部中的UDP长度(16 bit)共同拼凑起来的。 2. 实现 《TCP/IP详解》卷1第11章第3节中指出:UDP检验和的基本计算方法与IP首部检验和计算方法相类似(16 bit字的二进制反码和),但是它们之间存在不同的地方。 首先,UDP数据报的长度可以为奇数字节,但是检验和算法是把若干个16 bit字相加。解决方法是必要时在最后增加填充字节0,这只是为了检验和的计算(也就是说,可能增加的填充字节不被传送)。 其次,UDP数据报和TCP段都包含一个12字节长的伪首部,它是为了计算检验和而设置的。伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地(例如,IP没有接受地址不是本主机的数据报,以及IP没有把应传给另一高层的数据报传给UDP)。 《TCP/IP详解》卷2第23章第6节第2小节中说明: 在计算UDP检验和时使用以下三个事实:(1)在伪首部中的第三个32 bit字看起来与IP首部中的第三个32bit字类似:两个8 bit值和一个16 bit值。(2)伪首部中三个32 bit值的顺序是无关的。事实上,Internet检验和的计算不依赖于所使用的16 bit值的顺序。(3)在检验和计算中另外再加上一个全0的32 bit字没有任何影响。 需要注意的是,并不是所有的UDP都一定包含checksum,这是一个可选填的区域。《RFC 768》中说:假如checksum的运算结果为0,那么传输的checksum将全为1(即用0xFFFF代替0x0000),因为这在补码运算中是等效的。而如果传输的checksum为全0(0x0000),就说明发送方并没有计算checksum (for debugging or for higher level protocols that don't care)。所以实现代码需要在验证checksum之前,先判断checksum是否存在。 BSD 4.4中的实现代码如下: /* udpcksum.c - udpcksum */ #include #include #include /*------------------------------------------------------------------------ * udpcksum - compute a UDP pseudo-header checksum *------------------------------------------------------------------------ */ unsigned short udpcksum(struct ep *pep, int len) { struct ip *pip = (struct ip *)pep->ep_data; struct udp *pudp = (struct udp *)pip->ip_data; unsigned short *sptr; unsigned long ucksum; int i; ucksum = 0; sptr = (unsigned short *) &pip->ip_src; /* 2*IP_ALEN octets = IP_ALEN shorts.
作者:朱金灿
来源:http://blog.csdn.net/clever101
对于xml文件,目前我的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐。因此对于简单的xml文件的解析,我更愿意使用开源的TinyXml。
首先介绍一下TinyXml吧。TinyXML是目前非常流行的一款基于DOM模型的XML解析器,简单易用且小巧玲珑,非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作,其主页是:http://www.grinninglizard.com/tinyxml/ ,目前最新版本是2.5.3 版本。
TinyXml网上的教程很多,但是我觉得写得都不怎样(感觉就是看完之后就没学会)。没办法,只得自己整理一篇适合自己的,至于适不适合别人,就见仁见智了。我感觉xml文件本质就是小型的数据库,换个角度来说就是,你对数据库有什么操作你对xml文件就应能实现什么操作。一般而言,对数据库的操作包括以下几种:新建数据库、查询数据库、修改数据库和删除数据库。那么对应xml文件就是新建xml文件、查询xml文件的指定节点的值,修改xml文件中节点的值和删除xml文件中节点的值。
首先我们认识一下xml文件有哪几种形式。下面我列出一些常用的xml文件的形式:
example1.xml: <?xml version="1.0" ?> <Hello>World</Hello> example2.xml: <?xml version="1.0" ?> <poetry> <verse> Alas Great World Alas (again) </verse> </poetry> example3.xml: <?xml version="1.0" ?> <shapes> <circle name="int-based" x="20" y="30" r="50" /> <point name="float-based" x="3.5" y="52.1" /> </shapes> example4.xml: <?xml version="1.0" ?> <MyApp> <Messages> <Welcome>Welcome to MyApp</Welcome> <Farewell>Thank you for using MyApp</Farewell> </Messages> <Windows> <Window name="MainFrame" x="5" y="15" w="400" h="250" /> </Windows> <Connection ip="192.168.0.1" timeout="
这两个星期在学习xml、JavaScript和ajax的东西,laoxi要求我们先看这些知识,然后用这些知识做一个搜索引擎的东西。一开始用两天看了一下关于xml的东西,但发现只是看根本就是,前脚看后脚忘。干脆先做出这个东西出来,用到哪些知识再看吧,于是我跟一名叫做小猪的家伙一起研究起了这个东西。一开始是做了一个服务器端控件的搜索引擎,后来才慢慢转到ajax上来,先把基于ajax的东西贴上来,哈哈 废话不多讲 基于ajax的搜索引擎,其原理其实是,利用了windows已经做好的一个搜索引擎接口,这个借口想必大家也都见过,就是一个被叫做bing的接口。 ajax向该接口提出请求,并将参数传递过去,服务器相应,并返回结果,JavaScript处理结果并显示。 看起来描述的这么简单,但是确实也费了我们一番功夫。 首先利用ajax发出请求,光这一请求,就花了我们大约两天的时间,首先请求的地址要写对,其次传递的参数也要写对,因为bing接口在处理参数的时候其实是以xml的形式来处理参数,所以我们的参数要写成xml结构的字符串。这样服务器端才能返回正确的结果,其实返回的结果既可以是普通的字符串形式,直接显示,也可以使xml的形式.xml的形式需要利用dom进行处理。才能正确显示在浏览器中 function sendHttpRequest(url,callbackFunc,respXml,ParameterStr) { // var xmlobj=null; try { xmlobj=new XMLHttpRequest(); } catch(e) { try { xmlobj=new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { alert("AJAX is not supported by your browser!"); return false; } } xmlobj.onreadystatechange=function() { if(xmlobj.readyState==4) {//当请求发送完毕 if(xmlobj.status==200) {//当正确接收到服务器端响应内容 respXml?eval(callbackFunc+"(xmlobj.responseXML)"):eval(callbackFunc+'(xmlobj.responseText)');//调用回调函数显示服务器端响应的内容 } } } // open socket connection xmlobj.open('post',url,true); // send http header xmlobj.setRequestHeader("Content-Type","text/html;charset=UTF-8"); // send http request xmlobj.send(ParameterStr); } // display search results function displayResults(results) {//显示结果的回调函数 var rootDom=results.
1.利用新浪提供给的iframe直接嵌入,这种方式非常的简单,但是却没有交互性。代码如下:
< iframe frameborder = " 0 " src = " http://php.weather.sina.com.cn/widget/weather.php " scrolling = " no " width = " 246 " height = " 360 " ></ iframe > 2.抓取当天的天气,以指定格式输出。
涉及的核心代码如下:
Code public static ArrayList GetWeather( string code)
{
/* [0] "北京 "string
[1] "雷阵雨 "string
[2] "9℃" string
[3] "29℃"string
[4] "小于3级"string
*/ string html = "" ;
try {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( " http://weather.sina.com.cn/iframe/weather/ "
区别一:throw 是语句抛出一个异常;throws 是方法抛出一个异常;
throw语法:throw <异常对象>
在方法声明中,添加throws子句表示该方法将抛出异常。
throws语法:[<修饰符>]<返回值类型><方法名>([<参数列表>])[throws<异常类>]
其中:异常类可以声明多个,用逗号分割。
区别二:throws可以单独使用,但throw不能;
区别三:throw要么和try-catch-finally语句配套使用,要么与throws配套使用。但throws可以单独使用,然后再由处理异常的方法捕获。
大家也许在编程的过程中,会意识到这里出错,但不知道会抛出什么异常,也是一件头疼的事,现将这部分总结如下:
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
文件未找到异常:FileNotFoundException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException
正则表达式是用来校验文本框中所输入的值是否匹配。一般在swing里面和js脚本校验中用得蛮多的。
喜欢上正则是在一次做小数点的验证上,就是要判断输入的值的长度在5位,可以有小数点。如果不用正则,那么我得判断小数点是不是只有一个,小数点是不是在第一位,是不是在最后一位,那些情况都要排除的。当然,这样做一下,可以练习自己对string里面的方法的熟练度,还有一个好处就是给用户的提示也蛮多的。不过,个人觉得在判断这个还不如用正则,因为正则一句话就搞定,那个地方也没必要搞那么麻烦。以下就说说正则吧!
在正则里面有11个字符被保留作特殊用途,它们分别是[ ] / ^ $ . | ? * + ( )。
[]:它是表示一个字符集,比如[0-9a-zA-Z],其中0-9,a-z,A-Z,这三者是或的关系,如果是且的关系的话,得加上其他的符号,这里就不展开了,因为没怎么碰到过,作为一个开发人员,只需要了解基本的正则就行了,正则这一块深入下去蛮难的。
/:转义字符,像/d,在java中String str="/d",这样是错误的,因为"/d"根本就没有,所以还要转义一次,而在js里面是不用的,下面会提到。
补充:java中的带"/"的,下面这些是不需要再转义的
/t代表Tab
/r代表回车符
/n 代表换行符 ^:表示起始,举个例子,^[0-9]表示以数字开头,但是当^放在“[]”里面时,意思就不一样了,[^0-9]表示非数字 $:表示结尾,有需要时可以加上。。 .:表示匹配除换行符以外的任何字符。。(个人觉得没啥用,当然既然提出来了,也有适合它用的场合) |:表达式中“|”表示选择。例如:cat|dog|mouse|fish ?:重复0次或1次 *:重复0次或多次 +:重复1次或多次,(在实际的运用中,*和+用得还是蛮多的,当然+也有用到) ():是表示分组,可能我们对一个字符重复很简单,但是当多个字符重复时,这个就有用了。比如(/d{1,3}/.){3},中间的{}是表示限定个数。 {n}重复 n次 {n,}重复 n次或更多次 {n,m}重复 n到 m次,包括n,m 匹配中文字符的正则表达式: [/u4e00-/u9fa5],曾经看到一个帖子说,这个在某个场合下不适用,不过一般在java里面或者js里面是能够判断的 以下就举一个例子吧: String s="1423";
String reg="//d{0,7}";
boolean b=s.matches(reg);
System.out.println(b); 在java里面有这样两个类: Pattern,Matcher,大家可以去看一下相关的用法,我就举一个简单的例子吧,或者说我题目做得太少,一直都没怎么用过这两个类。 Pattern p = Pattern.compile("a*b"); //这个“a*b”类似于上面例子中的reg;
boolean b = m.matches(); 下面谈谈js里面的正则吧: 表达式的写法: var re = / pattern / [ flags ],还有另外一种写法: var re = new RegExp("
中国作为世界上第一大的无线用户国家,而无线搜索又是一个新兴且被寄予厚望的应用,目前为止还鲜有文章专门阐述中国人的搜索习惯。这个行业要做大,需要更 多人来关注我们的用户,而搜索作为一大入口,其数据自然有绝对的代表性。这里有一篇年前发表的文章,以08-09年的部分样本数据分析了中国人的搜索习 惯,分享给大家。
引用请注明:
author = {Shunkai Fu and Song Han and Bingfeng Pi and Michel Desmarais and
Ying Zhou and
Jianhui Zhuo and
Gang Zou and
Weilei Wang},
title = {Large Scale Analysis of Chinese Mobile Query Behavior},
booktitle = {IKE},
year = {2009},
pages = {258-264},
crossref = {DBLP:conf/ike/2009},
bibsource = {DBLP, http://dblp.uni-trier.de}
}
下载地址
这几天的时间,把新闻管理系统用ssh和ssh2整了一遍。想写一点对这两者的看法。
ssh在昨天已经写过了。先把ssh2的流程说一下吧。
在web.xml里面配置struts2.0用filter代码如下:
<filter>
<filter-name>struts2Control</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
<init-param>
<param-name>struts.i18n.encoding</param-name>
<param-value>GB18030</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2Control</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
中间的<param-name>struts.i18n.encoding</param-name><param-value>GB18030</param-value>这个是设置他的编码。。
写的路径也有点不同。。原先在struts1.2中路径一般都以.do结尾的,而struts2.0中是以.action结尾的。并且参数是写在"."之前,以"!"打头,举个例子:UserAction!login.action
路径是跳到struts.xml里面去。。在struts.xml里面有个package的属性,可以用它来控制权限。
<action name="UserAction" class="springUserAction">
这个name必须和发过来的请求相对应,而class是跳到spring的配置文件里面去,由它帮忙注入serice层。。
spring的配置文件和ssh的几乎相同,可以增加一层model层,由spring来负责new出model,当然还得重写一下scope,在上篇文章中有提到。
action层的类,不再是继承DispatchAction的类,而是继承ActionSupport,再重写它的方法,为了需要,可以把相应的代码给修改掉。。
例如在jsp层传过来的参数是save,代码如下:
public String save() throws Exception {
//逻辑代码
return "str";//这个str与struts.xml里面的需要跳转的名字对应起来
}
在struts.xml的路径是这样的:
<result name="">/xx.jsp</result>
在action那个类里面还有一个问题,原先的request没有了。。那么该怎样获得呢?代码如下,它是通过上下文来取得的
ActionContext act = ActionContext.getContext();
HttpServletRequest request = (HttpServletRequest) act
.get(ServletActionContext.HTTP_REQUEST); 另外说一下struts2.0的标签,我就用到了三个:一个是 <s:iterator>,一个是<s:property>,最后一个是<s:if>
第一个是用来迭代的,用法如下:
<s:iterator id="news" value="#request.newslist">
这个id就是用来标识的,和c标签的用法相同,后面的value值是表示用数据库里面拿过来的newslist,后台的代码是这样的
request.setAttribute("newslist", list);
关于这个“#”号,大家可以理解成"${}",看到这个EL标签,应该很熟悉了吧,呵呵。。
第二个是用来输出值:
可配合迭代使用,当然其他地方也一样的。。
接上的:<s:property value="#news.id"/>
第三个是可以用来做一些逻辑判断。。
和java中的if 、elseif、else用法差不多。。大家可以去尝试一下。。
整合完ssh2,我的感觉是确实要比struts1.X简单,至少少写了一个form层,本来这个form层是和struts打交道的,model和hibernate打交道,现在就只剩下model层了。。
find(String queryString, Object[] values); 这个方法后者的参数必须是一个数组,而不能是一个List。
在做项目时,要查询数据库里面用户名与密码是否匹配时,要传两个参数进去。。如下:
String hql="from User u where u.username=? and u.password=?";
其中User是对应的类名,不是表名。这时候如果这样做:
List list1=new ArrayList();
list1.add(user.getUserName);
list1.add(user.getPassword);
this.getHibernateTemplate.find(hql,list1);
程序运行后,报SQLException
但是如果这样写就不会错了。
程序如下:
List list=this.getHibernateTemplate().find(hql, new String[]{user.getUsername(),user.getPassword()});
另外dao继承HibernateDaoSupport后还是有session方法的,所以查询也可以用session来解决
通过session可以得到Query
在一个工程个配置多个spring的配置文件,应该是没问题的。
但在测试的时候,我是这样写的:
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext_*.xml");
User user = (User)factory.getBean("user");
user.setName("lisi");
System.out.println(user.getName());
两个配置文件分别是:applicationContext_bean.xml和applicationContext_other.xml;
结果报个了错:
Exception in thread "main" java.lang.IllegalArgumentException: Resource path [D:/寮犺氨/spring_ioc/bin] does not denote a directory
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.retrieveMatchingFiles(PathMatchingResourcePatternResolver.java:503)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.doFindMatchingFileSystemResources(PathMatchingResourcePatternResolver.java:483)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.doFindPathMatchingFileResources(PathMatchingResourcePatternResolver.java:466)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.findPathMatchingResources(PathMatchingResourcePatternResolver.java:323)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.getResources(PathMatchingResourcePatternResolver.java:257)
at org.springframework.context.support.AbstractApplicationContext.getResources(AbstractApplicationContext.java:867)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:146)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:173)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:112)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:79)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:101)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:389)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:324)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:122)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:66)
at com.aowin.client.Test_IOC.main(Test_IOC.java:30)
然后,我把BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext_*.xml");里面的"*"给改成bean,因为上面有这个文件。。
他就不报错了,能正常输出!
这是为什么呢??
有两个问题一直没有很好的对自己能解释通,尤其是在没有弄明白这两个问题的相关术语的时候,又去研究相关的衍生问题,搞得自己差点口吐白沫。这两个问题是这样的:
1.集群软件能否实现负载均衡的功能,两者有何差别
2.如何实现数据库的均衡。
现在看起来蛮easy的问题,可是当初俺是菜菜哦。不过说起来,要讲清楚这个问题也是蛮考察功力的哦。好了,俺把俺研究的东东分享一下。
集群一般有两种:高可用和高性能集群,一般的集群,包括现在的低端双机容错、IBM的HACMP、HP的MC ServiceGuard都是高可用性集群,不能做负载均衡;而高性能集群主要是科学计算、科研等一些特殊环境用,在现实应用中比较少。而ORACLE 的RAC是基于特殊环境下的应用系统,要求有操作系统层面的分布式锁(DLM)。具体使用起来要作相应的规划,而且不能随便使用,弄不好性能适得其反的差。
前面说过,负载均衡不能完全算高可用性集群的一种,是高性能性集群,普通的HA软件没办法支持象ORACLE RAC一样的环境,这不完全是集群软件的功能。
高可用性集群与负载均衡集群的工作原理不同,适用于不同类型的服务。通常,负载均衡集群适用于提供静态数据的服务,如HTTP服务;而高可用性集群既适用于提供静态数据的服务,如HTTP服务,又适用于提供动态数据的服务,如数据库等。高可用性集群之所以能适用于提供动态数据的服务,是由于节点共享同一存储介质,如SAN阵列。也就是说,在高可用性集群内,每种服务的用户数据只有一份,存储在共用存储设备上,在任一时刻只有一个节点能读写这份数据。
高可用性集群对一种服务而言不具有负载均衡功能,它可以提高整个系统的可靠性,但不能增加负载的能力。当然,高可用性集群可以运行多种服务,并适当分配在不同节点上,比如节点A提供Oracle服务,同时节点B提供Sybase服务,这也可以看成是某种意义上的负载均衡,不过这是对多种服务的分配而言。
负载均衡集群适用于提供相对静态的数据的服务,比如HTTP服务。因为通常负载均衡集群的各节点间通常没有共用的存储介质,用户数据被复制成多份,存放于每一个提供该项服务的节点上。
这个困扰我已久一直没有系统整理的问题到这里基本明了了,各位看官到这里旋即也会想到,如果用户有一个由两个节点组成的最小集群,是否可以同时获得高可用性集群和负载均衡集群的效益呢?答案是肯定的。由于高可用性集群适用于提供动态数据的服务,而负载均衡集群适用于提供静态数据的服务,所以我们不妨假设要同时提供Oracle和HTTP服务。用户要在节点A和B上安装HA和NLB软件。把节点A作为Oracle正常工作的节点,节点B作为Oracle服务的后备节点,这是对HA软件而言。对于NLB软件而言,要设置节点B为主ATM(Application Traffic Management)节点,节点A为后备ATM节点,而节点A和节点B同时又都是HTTP的服务节点。
这样一来,节点A和节点B都是身兼两职,而用户同时得到了一个具有高可用性的Oracle服务和一个具有负载均衡功能的HTTP服务。即使有一个节点发生故障,Oracle服务和HTTP服务都不会因此而中断。
这里涉及到一个关键问题:对于同一种服务,是不能同时获得高可用性与负载均衡能力的(有不同意见的么?)。对一种服务,要么是只有一份数据,放在共用存储设备上,一次被一个节点访问,获得高可用性;要么是把数据复制为多份,存储于每个节点的本地硬盘上,用户的请求同时发送到多个节点上,获得负载均衡能力。这也是F5设备没有提供数据库均衡的解决方案的难点所在。
引文:
--------------------------------------
首先申明,除了只读型数据库在某些特定条件下可能使用BIGIP实现负载均衡外。F5迄今未推广过读写型数据库的负载均衡方案。
数据库的Cluster和HA是两个概念。在HA方式下,两台数据库服务器只有一台在工作,并且是由Active设备控制盘阵。在发生HA切换时,Backup设备接管盘阵。在Cluster状态下,比如Oracle RAC,可以实现两台服务器对同一盘阵的同时控制,并且使用的是同一份数据库文件。在RAC存在的情况下,理论上有可能使用BIGIP实现负载均衡,但实际上很难发挥作用,只有在C/S结构下有可能实现,或者是多台应用服务器访问少量数据库服务器的状况下有可能。现在F5中国还未有进行此类测试,如果那位有此类环境可以做一个测试。F5会全力支持测试。
---------------------------------------
对于高可用性集群,由于它在设计时的目的就是为了最大可能地减少服务中断时间,因此服务的切换受到很大的关注。当一个节点上的服务故障时,会被很快地检测到并被切换到其他节点上。但在切换时,不能忽略对数据完整性的保护。
再研究一下:在什么情况下数据完整性会被破坏呢?由于高可用性集群中至少有两个节点,连接在一个共用的存储设备上,对于非裸分区而言,如果被两个节点同时读写,就会造成文件系统被破坏。因此就需要利用I/O屏障来防止这一事件的发生。
I/O屏障的目的是为了保证故障节点不能再继续读写某一服务的共用分区,实现的方式有多种。Kimberlite使用硬件开关来实现,当一个节点发生故障时,另一节点如果能侦测到,就会通过串行口发出命令,控制连接在故障节点电源上的硬件开关,通过暂时断电,而后又上电的方式使得故障节点被重启动。
I/O屏障有多种形式。对于支持SCSI Reserve/Release命令的存储设备,也可以用SG命令实现I/O屏障。正常节点应使用SCSI Reserve命令“锁住”共用存储设备,保证其不被故障节点读写。如果故障节点上的集群软件仍在运行,如发现共用存储设备已被对方锁住,就应把自己重启动,以恢复正常工作状态。
实际上,使用F5设备有变通的方法:把两台服务器放入一个POOL中,设不同的优先级,让优先级高的服务器对磁盘有读写操作,当高优先级的服务器宕机时,切到低优先级的机器上,这也实现了HA,这有点强词夺理,但也能解释,比HA软件切换的快,因为用HA软件做双机时,备机上的各个服务都是宕的,只能当备机探测到主机服务宕机时,才开始启动相应的服务,有时服务还启不了;而用F5做双机时,备机的各服务都是正常启动着的,只是F5设备不把客户请求发到备机上去而已,当主机宕机时,F5设备才把客户请求发到备机,而备机的各服务都是正常启动着的,所以…………
呵呵,想明白了为什么我说是强词夺理么?
如果按照上面的方法作数据库负载均衡,则必须解决一个重要的问题:数据库的同步,如果切换的速度很快,则要求两台数据库的同步也很快…………。其它可能还存在一些问题,所以迄今为止还是没有见过类似结构。
OOPS,扯远了。我来详细说说为什么高可用集群不能对数据库系统进行负债均衡。俺的理由是对负债均衡的定义。
就如我开篇所说
引文:
--------------------------------
集群一般有两种高可用性和高性能集群,…………负载均衡不能完全算高可用性集群的一种,是高性能性集群
普通的HA软件没办法支持象ORACLE RAC一样的环境,这不完全是集群软件的功能。
--------------------------------
我们就拿OPS来说事儿吧,OPS的核心组件是分布式锁管理器(DLM),它为OPS实例提供并行高速缓存管理。OPS群集的每个节点在加入群集时都启动DLM进程的一个实例,然后这些实例就可以通过网络互相通信。
因此我的结论一:没有DLM,不管你是HACMP还是ServiceGuard或者TurboCluste都不能并行跑数据库。(不了解mssql、sybase和DB2,欢迎举反例)
然后,OPS的工作机制和simon说的没错,但是最终,它对库文件的读写还是靠缓存排队的,最终仍然同一时刻只有一台主机在读写。可是,真正的负债均衡是N份文件的分布式读取哦。负债均衡是所有资源的均衡哦。
因此我的结论二:即使HA软件配合OPS,仍然不是真正的负债均衡。当然,我们和客户不能这么说。
不过,我有一个想法,在数据库只读的应用环境下,比如高考考分查询,是不是可以多台机器建多个库,库内容都一样,这样的话由于不涉及数据同步的问题,应该可以实现真正均衡的。
顺便分享一下我查到的OPS介绍。总会有人不了解的。
引文:
----------------------------------
1、什么是OPS
OPS(Oracle Parallel Server)可以让位于不同系统的多个实例同时访问同一个数据库。并行服务器可以有效地提高系统的可用性和对多系统的访问性能,但是,如果你的数据没有做很好的分割,性能可能还会下降。
安装OPS时,多个实例mount同一数据库文件,实例间的通讯由分布式锁管理器(DLM)来管理。需要注意的是分布式锁管理器与你所使用的硬件和操作系统有着密切的关系。为了确定多个企图同时修改同一数据的实例,Oracle使用了十个后台进程:LCK0-LCK9,来锁定某一实例所使用的资源。
OPS主要用于UNIX/LINUX集群环境中。
3、所有的应用都是适合OPS吗?
可以根据功能或数据进行分割的应用最适合OPS。那些有"热数据"(经常被多实例同时访问的数据)的应用并不适合使用OPS。
-----------------------------------
结束语:尽管HA软件的功能足够强大,但是我们在系统设计的时候尽量用专用硬件来代替软件能实现的功能比如F5实现http负债均衡。理由1:利润更丰厚2:服务器应该只做单一的服务器从而最大化利用服务资源3:出现问题便于排错4:降低用户的维护成本5:……很多啦,不一一说了
附件:simon写的HA情况下,数据库的操作
-----------------------------------
a、在一个多节点数据库系统的集群中,是将数据保存在一个公用的磁盘空间上的方式来保证数据的统一性的。而在没有外来机制的情况下,一个磁盘空间上的逻辑空间也是只能被一个主机系统所控制的,即该主机取得了逻辑空间的读写控制权后,其他的主机系统是无法再去进行读写的(UNIX/Windoes平台均是如此),这是由阵列卡的工作机制所决定的。而这个时候HACMP软件(或者其他的集群软件)出马了,它通过接管控制阵列卡,协调多个主机的操作系统,使他们可以同时去读写同一个逻辑空间(这里的同时只是指访问同一个逻辑空间,而不是同时一个数据记录),这使得多数据库节点共同处理访问请求成为可能,因为它们可以读写同一个后台数据库了。
b、从另一个方面来说,一个数据记录同时只能被一个I/O操作所控制,即一个节点上的数据库系统对数据记录进行读写时,其他的数据库系统是无法去读写该记录的;而在一个多节点的数据库集群中,这就需要对数据记录进行协作、控制,即保证该记录在被一个I/O读写时必须被缩定,禁止其他的数据库对它进行读写,而当该I/O操作完成时必须能释放掉该数据记录,使之能被其他的数据库系统读写。这点显然是NLB所不能实现的,是需要数据库系统本身的功能支持(主流的数据库Oracle/SQL/Sybase均可实现该功能)。而这点实现了多节点数据库系统间的共同协作处理,也保证了多节点数据库系统的处理能力均衡分载的应用层基础。
在以上2点的保证下,通过HACMP集群软件对外提供同一个公用IP地址(ServiceIP)接受访问请求,由数据库系统的集群组件将请求分配给各个节点上的数据库系统,并协调他们进行后台数据的读写,真正的实现了数据库系统的处理能力上的负载分担、均衡。
------------------------------------
起因:线上的一台服务器,最近总是出现 访问 很慢的情况发生,点击一个链接要2秒钟以上才能打开,按照我们对于访问人数的估计,服务器应该不至于响应这么慢,从而需要针对这个问题进行分析,来解决网站访问过慢。 分析: 1、首先,在页面访问变慢情况发生时,使用 top 命令查看了服务器的负载情况,发现负载并不高,初步估计不是程序的问题。 2、然后,查看了线程中的 httpd 的数量, ps -aux | grep httpd | wc -l 发现,线程数已经达到了 apache 设置的最大值。由此断定是网站访问人数过多造成了访问过慢。 3、为了验证,查看了连接数和当前的连接数,分别是 netstat -ant | grep $ip:80 | wc -l netstat -ant | grep $ip:80 | grep EST | wc -l 发现果然,连接数特别多,远远超过我们的估计值。 4、刚开始的时候,对于服务器的 MPM 配置方式不是特别的熟悉,认为修改服务器配置可以解决问题。主要的配置部分包括 prefork 模式 或者 work 模式的配置,下面是一些简单的介绍。 prefork 模式: 以 prefork 模式工作的 apache 的默认配置: <IfModule mpm_prefork_module> ServerLimit 2000 StartServers 5 #指定服务器启动时建立的子进程数量 MinSpareServers 5 #指定空闲子进程的最小数量 MaxSpareServers 10 #指定空闲子进程的最大数量 MaxClients 150 #指定同一时间客户端最大接入请求的数量(单个进程并发线程数),任何超过该限制的请求都将进入等候队列,一旦一个连接被释放,队列中的请求将得到服务 MaxRequestsPerChild 0 #指定每个子进程在其生存周期内允许伺服的最大请求数量,默认为10000,0表示子进程永远不结束 </IfModule> prefork 控制进程在最初建立“StartServers”个子进程后,为了满足 MinSpareServers 设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。 MaxSpareServers 设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比 MinSpareServers小,Apache会自动把其调整为 MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。 MaxClients是这些指令中最为重要的一个,设定的是 Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep httpd|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。在 apache2 中通过ServerLimit指令无须重编译Apache就可以加大MaxClients。 虽然通过设置ServerLimit,我们可以把MaxClients加得很大,但是往往会适得其反,系统耗光所有内存。以一台服务器为例:内存2G,每个apache进程消耗大约0.
刚解决了一个HttpSendRequest超时的问题。
目的:使用internet api进行get或post数据给服务器。
方法:通过线程进行get或post数据给服务器。
问题:刚开始的几个线程是可以进行正常操作的。但是在后面的线程会出现在HttpSendRequest中阻塞超时。
问题原因:internet 的句柄没有及时关闭。
解决方法:使用相应的api关闭句柄,解决方法就这么简单。
今天遇到一个很奇怪的问题,我的ORACLE10G监听程序启动后一刷新就自动停止,后来上网找了很多方法,什么修改注册表,什么是不是机器名改过啦,以及去netmanager下面啦, 发现网上的方法统统不管用.
静下心来仔细分析了一下日志发现原来是有字符不能处理,后来去分析了一下listener.ora文件,发现里面内容很杂乱,于是重新编辑了一下listener.ora文件,把以前加入的没有用的监听删除,后来再lsnrctl start 监听启动正常,一切OK
jquery 的 ajax 在 非阻塞 时返回 是 [object XMLHttpRequest] 对象(firefox 下 alert(对象名) 也可以直接看到对象类型)
返回的内容用 request.responseText 就可得到 var request = $.ajax(...);
//Firefox浏览器 打开跨域访问权限
if (navigator.userAgent.indexOf("Firefox") > 0) netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
//alert(request.responseText);
//alert(request.responseXML);
var json_data = eval("(" + request.responseText + ")");
alert(json_data.aaa);
var request = $.ajax({
type: "POST"
,cache : false
//非阻塞
,async : false
,dataType: "text"
,url: url
,data: {"act":"batch_pid","html":'aaa'}
,success: function(data){
alert(data);
}
});
alert(request.responseText);
摘要: 本文试图成为学习TCP/IP网络组播技术的入门材料。文中介绍了组播通信的概念及原理,以及用于组播应用编程的Linux API的详细资料。为了使读者更加完整的了解Linux 组播的整体概念,文中对实现该技术的核心函数也做了介绍。在文章的最后给出了一个简单的C语言套接字编程例子,说明如何创建组播应用程序。
一、导言
在网络中,主机间可以用三种不同的地址进行通信:
单播地址(unicast):即在子网中主机的唯一地址(接口)。如IP地址:192.168.100.9或MAC地址:80:C0:F6:A0:4A:B1。
广播地址:这种类型的地址用来向子网内的所有主机(接口)发送数据。如广播IP地址是192.168.100.255,MAC广播地址:FF:FF:FF:FF:FF。
组播地址:通过该地址向子网内的多个主机即主机群(接口)发送数据。
如果只是向子网内的部分主机发送报文,组播地址就很有用处了;在需要向多个主机发送多媒体信息(如实时音频、视频)的情况下,考虑到其所需的带宽,分别 向每一客户端主机发送数据并不是个好办法,如果发送主机与某些接收端的客户主机不在子网之内,采用广播方式也不是一个好的解决方案。
二、组播地址
大家知道,IP地址空间被划分为A、B、C三类。第四类即D类地址被保留用做组播地址。在第四版的IP协议(IPv4)中,从224.0.0.0到239.255.255.255间的所有IP地址都属于D类地址。
组播地址中最重要的是第24位到27位间的这四位,对应到十进制是224到239,其它28位保留用做组播的组标识,如下图所示:
图1 组播地址示意图
IPv4的组播地址在网络层要转换成网络物理地址。对一个单播的网络地址,通过ARP协议可以获取与IP地址对应的物理地址。但在组播方式下ARP协议无法完成类似功能,必须得用其它的方法获取物理地址。在下面列出的RFC文档中提出了完成这个转换过程的方法:
RFC1112:Multicast IPv4 to Ethernet physical address correspondence RFC1390:Correspondence to FDDI RFC1469:Correspondence to Token-Ring networks
在最大的以太网地址范围内,转换过程是这样的:将以太网地址的前24位最固定为01:00:5E,这几位是重要的标志位。紧接着的一位固定为0,其它23位用IPv4组播地址中的低23位来填充。该转换过程如下图所示:
图2 地址转换示意图
例如,组播地址为224.0.0.5其以太网物理地址为01:00:5E:00:00:05。
还有一些特殊的IPv4组播地址:
224.0.0.1:标识子网中的所有主机。同一个子网中具有组播功能的主机都是这个组的成员。
224.0.0.2:该地址用来标识网络中每个具有组播功有的路由器。
224.0.0.0----224.0.0.255范围内的地址被分配给了低层次的协议。向这些范围内的地址发送数据包,有组播功能的路由器将不会为其提供路由。
239.0.0.0----239.255.255.255间的地址分配用做管理用途。这些地址被分配给局部的每一个组织,但不可以分配到组织外部,组织内的路由器不向在组织外的地址提供路由。
除了上面列出的部分组播地址外,还有许多的组播地址。在最新版本的RFC文档“Assinged Numbers”中有完整的介绍。
下面的表中列出了全部的组播地址空间,同时还列出了相应的地址段的常用名称及其TTL(IP包的存活时间)。在IPv4组播方式下,TTL有双重意义: 正如大家所知的,TTL原本用来控制数据包在网络中的存活时间,防止由于路由器配置错误导致出现数据包传播的死循环;在组播方式下,它还代表了数据包的活 动范围,如:数据包在网络中能够传送多远?这样就可以基于数据包的分类来定义其传送范围。
范围 TTL 地址区间 描述
节点(Node) 0 只能向本机发送的数据包,不能向网络中的其它接口传送
链路(Link) 1 224.0.0.0-224.0.0.255 只能在发送主机所在的一个子网内的传送,不会通过路由器转发。
部门 32 239.255.0.0-239.255.255.255 只在整个组织下的一个部门内(Department) 传送
组织 64 239.192.0.0--239.195.255.255 在整个组织内传送(Organization)
全局(Global)255 224.0.1.0--238.255.255.255 没有限制,可全局范围内传送
三、组播的工作过程
1 public String decode(ByteBuffer buffer)
2 {
3 System.out.println( " buffer= " + buffer);
4 Charset charset = null ;
5 CharsetDecoder decoder = null ;
6 CharBuffer charBuffer = null ;
7 try 8 {
9 charset = Charset.forName( " gb2312 " );
10 decoder = charset.newDecoder();
11 charBuffer = decoder.decode(buffer);
12 System.out.println( " charBuffer= " + charBuffer);
13 System.out.println(charBuffer.toString());
14 return charBuffer.toString();
15 } 16 catch (Exception ex)
一、RAID介绍<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> RAID是Redundent Array of Inexpensive Disks的缩写,直译为“廉价冗余磁盘阵列”,也简称为“磁盘阵列”。后来RAID中的字母I被改作了Independent,RAID就成了“独立冗余磁盘阵列”,但这只是名称的变化,实质性的内容并没有改变。可以把RAID理解成一种使用磁盘驱动器的方法,它将一组磁盘驱动器用某种逻辑方式联系起来,作为逻辑上的一个磁盘驱动器来使用。 RAID的优点: 1. 传输速率高。在部分RAID模式中,可以让很多磁盘驱动器同时传输数据,而这些磁盘驱动器在逻辑上又是一个磁盘驱动器,所以使用RAID可以达到单个的磁盘驱动器几倍的速率。因为CPU的速度增长很快,而磁盘驱动器的数据传输速率无法大幅提高,所以需要有一种方案解决二者之间的矛盾。 2. 更高的安全性。相较于普通磁盘驱动器很多RAID模式都提供了多种数据修复功能,当RAID中的某一磁盘驱动器出现严重故障无法使用时,可以通过RAID中的其他磁盘驱动器来恢复此驱动器中的数据,而普通磁盘驱动器无法实现,这是使用RAID的第二个原因。 RAID的分类: RAID 0:无冗余无校验的磁盘阵列。数据同时分布在各个磁盘上,没有容错能力,读写速度在RAID中最快,但因为任何一个磁盘损坏都会使整个RAID系统失效,所以安全系数反倒比单个的磁盘还要低。一般用在对数据安全要求不高,但对速度要求很高的场合, 如:大型游戏、图形图像编辑等。此种RAID模式至少需要2个磁盘,而更多的磁盘则能提供更高效的数据传输。
RAID 1:镜象磁盘阵列。每一个磁盘都有一个镜像磁盘,镜像磁盘随时保持与原磁盘的内容一致。RAID1具有最高的安全性,但只有一半的磁盘空间被用来存储数据 。主要用在对数据安全性要求很高,而且要求能够快速恢复被损坏的数据的场合。此种RAID模式每组仅需要2个磁盘。
RAID 0+1:从其名称上就可以看出,它把RAID0和RAID1技术结合起来,数据除分布在多个磁盘上外,每个磁盘都有其物理镜像盘,提供全冗余能力,允许一个以下磁盘故障,而不影响数据可用性,并具有快速读写能力。但是RAID0+1至少需要4个磁盘才能组建。 RAID 5: 无独立校验盘的奇偶校验磁盘阵列。同样采用奇偶校验来检查错误,但没有独立的校验盘,而是使用了一种特殊的算法,可以计算出任何一个带区校验块的存放位置。这样就可以确保任何对校验块进行的读写操作都会在所有的RAID磁盘中进行均衡,既提高了系统可靠性也消除了产生瓶颈的可能,对大小数据量的读写都有很好的性能。为了能跨越数组里的所有磁盘来写入数据及校验码信息,RAID 5设定最少需要三个磁盘,因此在这种情况下,会有1/3的磁盘容量会被备份校验码占用而无法使用,当有四个磁盘时,则需要1/4的容量作为备份,才能让最坏情况的发生率降到最低。当磁盘的数目增多时,每个磁盘上被备份校验码占用的磁盘容量就会降低,但是磁盘故障的风险率也同时增加了,一但同时有两个磁盘故障,则无法进行数据恢复。
JBOD:JBOD(Just Bundle Of Disks) 既简单磁盘捆绑。JBOD是在逻辑上把几个物理磁盘一个接一个串联到一起,从而提供一个大的逻辑磁盘。JBOD上的数据简单的从第一个磁盘开始存储,当第一个磁盘的存储空间用完后, 再依次从后面的磁盘开始存储数据。JBOD存取性能完全等同于对单一磁盘的存取操作,也不提供数据安全保障。它只是简单的提供一种利用磁盘空间的方法,JBOD的存储容量等于组成JBOD的所有磁盘的容量的总和。
Matrix RAID:矩阵磁盘阵列。是Intel 新近创立的一种针对SATA接口的专利RAID模式,特点是能在2个磁盘上同时实现RAID 0与RAID 1两种模式,其工作原理是将2个磁盘中的每个磁盘的部分磁盘空间划分出来组成RAID 0或1,而将剩余空间组成RAID1或0。Matrix RAID还有一个功能:支持RAID 1阵列分区的“热备份”硬盘。通常支持Matrix RAID功能的主板具有四个SATA接口,而建立一组Matrix RAID只需要两块硬盘,使用两个SATA接口。另外两个闲置的SATA接口就可以插上硬盘,启动“热备份”功能。当Matrix RAID系统中的一块硬盘出现故障时,“热备份”硬盘便会立刻接替它的工作,以保证RAID 1阵列分区中数据的安全。由于RAID 0阵列分区中的数据在一块硬盘崩溃的时候就已经损毁了,所以“热备份”硬盘对RAID 0阵列是无效的。 以上是目前主流升技主板上搭载的RAID控制器所能支持的全部RAID模式,并且由于RAID控制器厂商和产品型号的不同,所能支持的RAID模式种类也各不相同,只有极少数主板能够全部支持上述的RAID模式,而每块主板具体所支持的RAID模式种类请至http://www.abit.com.cn 升技官方主页的产品介绍当中核对查找。另有一些其他 RAID 模式基本用于专业服务器及工作站上使用,此处便不做介绍了。 RAID 模式下磁盘空间的使用: 针对不同RAID 模式在实际运用中可以使用的磁盘空间分别有多少,在用列表举例说明: * Matrix RAID由于其特殊的磁盘分配概念,所以在此单独举例说明: 例如,使用2 块 <?xml:namespace prefix = st1 ns = "