设置Win 2003的本地策略应用

本文介绍了如何在工作组设置中基于Windows Server 2003 的计算机上将本地策略应用于除管理员以外的所有用户。

在工作组设置(而非域)中使用基于Windows Server 2003 的计算机时,可能需要在该计算机上实施本地策略,这些策略可应用于该计算机的所有用户,但不可应用于管理员。有了这一例外,管理员可以保留对计算机的无限制访问权和控制权,并且还可以限制可登录该计算机的用户。

将本地策略应用于除管理员以外的所有用户

要对除管理员以外的所有用户实施本地策略,请执行以下步骤:

1.以管理员身份登录到计算机。

打开本地安全策略。执行以下操作:

单击开始\运行,键入gpedit.msc,然后按ENTER 键。

或者单击开始\运行,键入mmc,按ENTER键,添加“组策略对象编辑器”,然后为本地安全策略对其进行配置。

如果删除运行命令是您所需要的策略之一,Microsoft 建议您通过“Microsoft 管理控制台”(MMC) 编辑该策略,然后将结果保存为图标。这样,您不需要使用运行命令就可以重新打开该策略了。

2.展开用户配置对象,然后展开管理模板对象。

启用您所需的任何策略(例如,“隐藏桌面上的‘网上邻居’”或“隐藏桌面上的Internet Explorer 图标”)。

备注:一定要选择正确的策略,否则,您可能会限制管理员登录计算机(以及完成配置计算机所需步骤)的能力。Microsoft 建议您记录所做的任何更改。

关闭“Gpedit.msc 组策略”管理单元,或者,如果您使用 MMC,请将控制台保存为图标,以便以后可以访问它,然后从计算机注销。

3.以管理员身份登录到计算机。

您可以在此登录会话中验证以前所做的策略更改,因为在默认情况下,本地策略会应用于包括管理员在内的所有用户。

从计算机注销,然后以此计算机所有其他用户(您希望他们应用这些策略)的身份登录到计算机。这些策略是为所有这些用户和管理员而实现的。

备注:对于在这一步未登录到计算机的任何用户帐户,都无法为其实现这些策略。

4.以管理员身份登录到计算机。

单击开始,指向控制面板,然后单击文件夹选项。选择查看选项卡,选中“显示隐藏文件或文件夹”,然后点确定以便可以查看“组策略”隐藏文件夹。或者,打开“Windows 资源管理器”,单击工具,然后单击文件夹选项以查看这些设置。

将位于 %Systemroot%\System32\GroupPolicy\User 文件夹中的 Registry.pol 文件复制到备份位置(例如,复制到另一硬盘、软盘或文件夹)。

使用“Gpedit.msc 组策略”管理单元或您的 MMC 图标再次打开本地策略,然后启用在为该计算机创建的原始策略中禁用的实际功能。

备注:执行此操作时,“策略编辑器”会创建一个新的 Registry.pol 文件。

关闭策略编辑器,然后将创建的备份 Registry.pol 文件复制回%Systemroot%\System32\GroupPolicy\User 文件夹中。

系统提示替换现有文件时,单击是。

5.从计算机注销,然后以管理员身份登录。

由于您是以管理员身份登录到计算机,您可以验证是否没有实施最初所做的更改。从计算机注销,然后以其他用户身份登录。

由于您是以用户(而非管理员)身份登录到计算机,您可以验证是否实施了最初所做的更改。

6.以管理员身份登录计算机,以确认本地策略不影响您以本地管理员身份登录该计算机。

恢复原始本地策略

要撤消本文中“将本地策略应用于除管理员以外的所有用户”一节介绍的过程,请执行以下步骤:

1.以管理员身份登录到计算机。

单击开始,指向控制面板,然后单击文件夹选项。单击查看 选项卡,单击“显示隐藏文件和文件夹”,然后单击确定 以便可以查看“组策略”隐藏文件夹。或者,打开“Windows 资源管理器”,单击工具,然后单击文件夹选项。

从 %Systemroot%\System32\GroupPolicy\User 文件夹中移动、重命名或删除Registry.pol 文件。

在您从计算机注销或重新启动计算机后,“Windows 文件保护”系统会创建另一个默认的 Registry.pol 文件。

2.打开本地策略。要实现这一点,请单击开始\运行,然后键入gpedit.msc。或者,单击开始\运行,键入mmc,加载本地安全策略。然后,将设为禁用或启用的所有项目设为未配置,以撤消 Registry.pol 文件所指定的对 Windows Server2003 注册表实施的任何策略更改。

3.以管理员身份从计算机注销,然后再次以管理员身份登录该计算机。

从计算机注销,然后以本地计算机的所有用户身份登录到该计算机,这样也可以针对它们的帐户撤消更改。

Win 2003中提高FSO的安全性

ASP提供了强大的文件系统访问能力,可以对服务器硬盘上的任何文件进行读、写、复制、删除、改名等操作,这给学校网站的安全带来巨大的威胁。现在很多校园主机都遭受过FSO木马的侵扰。但是禁用FSO组件后,引起的后果就是所有利用这个组件的ASP程序将无法运行,无法满足客户的需求。如何既允许FileSystemObject组件,又不影响服务器的安全性呢(即:不同虚拟主机用户之间不能使用该组件读写别人的文件)?以下是笔者多年来摸索出来的经验:
第一步是有别于Windows 2000设置的关键:右击C盘,点击“共享与安全”,在出现在对话框中选择“安全”选项卡,将Everyone、Users组删除,删除后如果你的网站连ASP程序都不能运行,请添加IIS_WPG组(图1),并重启计算机。
Click to Open in New Window

经过这样设计后,FSO木马就已经不能运行了。如果你要进行更安全级别的设置,请分别对各个磁盘分区进行如上设置,并为各个站点设置不同匿名访问用户。下面以实例来介绍(假设你的主机上E盘Abc文件夹下设Abc.com站点):
1. 打开“计算机管理→本地用户和组→用户”,创建Abc用户,并设置密码,并将“用户下次登录时须更改密码”前的对号去掉,选中“用户不能更改密码”和“密码永不过期”,并把用户设置为隶属于Guests组。
2. 右击E:\Abc,选择“属性→安全”选项卡,此时可以看到该文件夹的默认安全设置是“Everyone”完全控制(视不同情况显示的内容不完全一样),删除Everyone的完全控制(如果不能删除,请点击[高级]按钮,将“允许父项的继承权限传播”前面的对号去掉,并删除所有),添加Administrators及Abc用户对本网站目录的所有安全权限。
3. 打开IIS管理器,右击Abc.com主机名,在弹出的菜单中选择“属性→目录安全性”选项卡,点击身份验证和访问控制的[编辑],弹出图2所示对话框,匿名访问用户默认的就是“IUSR_机器名”,点击[浏览],在“选择用户”对话框中找到前面创建的Abc账户,确定后重复输入密码。
Click to Open in New Window

经过这样设置,访问网站的用户就以Abc账户匿名身份访问E:\Abc文件夹的站点,因为Abc账户只对此文件夹有安全权限,所以他只能在本文件夹下使用FSO。
常见问题:
如何解除FSO上传程序小于200k限制?
先在服务里关闭IIS admin service服务,找到Windows\System32\Inesrv目录下的Metabase.xml并打开,找到ASPMaxRequestEntityAllowed,将其修改为需要的值。默认为204800,即200K,把它修改为51200000(50M),然后重启IIS admin service服务。
ASP提供了强大的文件系统访问能力,可以对服务器硬盘上的任何文件进行读、写、复制、删除、改名等操作,这给学校网站的安全带来巨大的威胁。现在很多校园主机都遭受过FSO木马的侵扰。但是禁用FSO组件后,引起的后果就是所有利用这个组件的ASP程序将无法运行,无法满足客户的需求。如何既允许FileSystemObject组件,又不影响服务器的安全性呢(即:不同虚拟主机用户之间不能使用该组件读写别人的文件)?以下是笔者多年来摸索出来的经验:
第一步是有别于Windows 2000设置的关键:右击C盘,点击“共享与安全”,在出现在对话框中选择“安全”选项卡,将Everyone、Users组删除,删除后如果你的网站连ASP程序都不能运行,请添加IIS_WPG组(图1),并重启计算机。
经过这样设计后,FSO木马就已经不能运行了。如果你要进行更安全级别的设置,请分别对各个磁盘分区进行如上设置,并为各个站点设置不同匿名访问用户。下面以实例来介绍(假设你的主机上E盘Abc文件夹下设Abc.com站点):
1. 打开“计算机管理→本地用户和组→用户”,创建Abc用户,并设置密码,并将“用户下次登录时须更改密码”前的对号去掉,选中“用户不能更改密码”和“密码永不过期”,并把用户设置为隶属于Guests组。
2. 右击E:\Abc,选择“属性→安全”选项卡,此时可以看到该文件夹的默认安全设置是“Everyone”完全控制(视不同情况显示的内容不完全一样),删除Everyone的完全控制(如果不能删除,请点击[高级]按钮,将“允许父项的继承权限传播”前面的对号去掉,并删除所有),添加Administrators及Abc用户对本网站目录的所有安全权限。
3. 打开IIS管理器,右击Abc.com主机名,在弹出的菜单中选择“属性→目录安全性”选项卡,点击身份验证和访问控制的[编辑],弹出图2所示对话框,匿名访问用户默认的就是“IUSR_机器名”,点击[浏览],在“选择用户”对话框中找到前面创建的Abc账户,确定后重复输入密码。
经过这样设置,访问网站的用户就以Abc账户匿名身份访问E:\Abc文件夹的站点,因为Abc账户只对此文件夹有安全权限,所以他只能在本文件夹下使用FSO。
常见问题:
如何解除FSO上传程序小于200k限制?
先在服务里关闭IIS admin service服务,找到Windows\System32\Inesrv目录下的Metabase.xml并打开,找到ASPMaxRequestEntityAllowed,将其修改为需要的值。默认为204800,即200K,把它修改为51200000(50M),然后重启IIS admin service服务。

请求资源正在使用中

        昨天上海服务器中了arp病毒了,没有办法,机房非得让重新做系统不可了,真郁闷呀,上次做了系统以后,正正好好才一个星期,今天又要做,客户非得气死不可了.

       重新开通iis后,发现asp文件无法运行.显示HTTP500错误,把服务器里的IE选项里的"显示友好HTTP错误信息"取消,再浏览,请求的资源在使用中。",真晕了,看了其它配置都没有问题的,后来才百度一百度了一下,找了下面的解决办法.

    后来仔细看了看,发现:只要打开单机版杀毒的脚本监控IIS6.0就会不正常。这就说明这可能和脚本的出错有关。运行regsvr32 jscript.dll(命令功能:修复Java动态链接库) regsvr32 vbscript.dll(命令功能:修复VB动态链接库) 重新注册JAVA脚本和VB脚本的动态链接库后一切正常。

方法一:可能和脚本的出错有关,运行regsvr32 jscript.dll和 regsvr32 vbscript.dll重新注册JAVA脚本和VB脚本的动态链接库
方法二:在IIS中删除原来的网站,再删除原来的应用池。然后重新建应用池,重新建网站。就解决了。

        出现这个情况,可能是装了杀毒软件macfee的原因的.具体是不是那就不太清楚了.呵呵!

Smarty实例 – 使用ADODB连接数据库

今天就先来说说ADODB.说到ADODB,可能做过ASP的都知道WINDOWS平台的ADO组件,但我们这里的ADODB不是微软的那个数据库操作组件,而是由php语言写的一套数据库操作类库,先让我们来看看它倒底有什么样的优点.
1. 以标准的SQL语句书写的数据库执行代码在进行数据库移植时不用更改源程序,也就是说它可以支持多种数据库,包括ACCESS.

2. 提供与微软ADODB相似的语法功能.这一点对于从ASP转行到PHP的人们是一大福音,它的很多操作都与WINDOWS中的ADODB相似.

3. 可以生成Smarty循环需要的二维数组,这样会简化smarty开发.这一点是等会我给大家演示.
4. 支持数据库的缓存查询,最大可能的提高查询数据库的速度。
5. 其它的实用功能.
虽然说优点很多,但是由于这个类库非常的庞大,光它的主执行类就107K,所以如果大家考虑执行效率的话就要认真想想了.不过说实话,它的功能还是很强大的,有很多的很实用的功能,使用它的这些功能,可以非常方便的实现我们想要的功能.所以对于那些老板没有特殊要求时大家不防用用它.
一、如何得到ADODB? 它的运行环境是什么?
从http://sourceforge.net/project/show…簆hp4.0.5以上。
二、如何安装ADODB?
解压下载回的压缩文件,注意:大家下载回来的格式为ADODB.tar.gz,这是linux的压缩格式,在windows下大家可以使用winrar对其进行解压,解压完成后将目录拷贝到指定的目录的adodb目录下,像我在例子中将它拷贝到了/comm/adodb/中。
三、如何调用ADODB?
使用include_once (“./comm/adodb/adodb.inc.php”);这行就不用说了吧?包含ADODB的主文件。
四、如何使用ADODB?
1.进行初始化:
ADODB采用$conn = ADONewConnection();这样的语句进行初始化,对ADODB进行初始化有两种方式:
第一种方式为:传统方式。我暂时称它为这个名称。它使用的建立一个新连接的方式很像php中的标准连接方式:
$conn = new ADONewConnection($dbDriver);
$conn->Connect($host, $user, $passwd, $db);
简单吧?如果使用过phplib中的db类应该对它很熟悉的。

第二种方式:采用dsn方式,这样是将数据库的连接语句写成一条语句来进行初始化,dsn的写法有为:$dsn = “DBType://User:Passwd@Host/DBName”; 其中DBType表示数据库类型,User表示用户名,Passwd为密码,Host为服务器名,DBName为数据库名,像这样我使用oracle数据库,用户名:oracleUser,密码为oraclePasswd,数据库服务器为localhost, 数据库为oradb的dsn这样写:
$dsn = “oracle://oracleUserraclePasswd@localhost/oradb”;
$conn = new ADONewConnection($dsn);
这种方式可能从ASP转行来的程序员会更感兴趣。

这两种方式都可以使用,要看个人习惯来选用了.

2. 相关的概念:
使用ADODB有两个基本的类,一是是ADOConnection类,另一个是ADORecordSet类,使用过ASP的人看到这两个类会明白它的含义,ADOConnection指的是数据库连接的类,而ADORecordSet指的是由ADOConnection执行查询语句返回的数据集类,相关的资料大家可以查询ADODB类的手册。

3.基本的函数:

关于ADOConnection类的相关方法有:
1.Connect:数据库连接方法,上边我们介绍过的。对于mysql还有PConnect,与PHP语言中的用法一样
2.Execute($sql):执行查询语句结果返回一个ADORecordSet类。
3.GetOne($sql):返回第一行的第一个字段
4.GetAll($sql):返回所有的数据。这个函数可是大有用处,记得不记的我在以前的教程中写关于新闻列表的输入时要将需要在页面显示的

新闻列表做成一个二维数组?就是这样的语句:
=====================================================================================
while($db->next_record())
{
$array[] = array(“NewsID” => $db->f(“iNewsID”),
“NewsTitle” => csubstr($db->f(“vcNewsTitle”), 0, 20));
}
=====================================================================================
这一行是什么意思呢?就是将要显示的新闻例表生成
$array[0] = array(“NewsID”=>1, “NewsTitle”=>”这里新闻的第一条”);
$array[1] = array(“NewsID”=>2, “NewsTitle”=>”这里新闻的第二条”);

这样的形式,但如果我们不需要对标题进行控制,在ADODB中我们就有福了,我们可以这样写:
==================================================================================
$strQuery = “select iNews, vcNewsTitle from tb_news_ch”;
$array = &$conn->GetAll($strQuery);//注意这条语句
$smarty->assign(“News_CH”, $array);
unset($array);
==================================================================================
当然,这里的$conn应该进行初始化过了,不知大家看明白了没有?原来我要手工创建的二维数据在这里直接使用GetAll就行了!!!这也是为什么有人会说ADODB+Smarty是无敌组合的原因之一了…
4.SelectLimit($sql, $numrows=-1, $offset=-1, $inputarrr=false): 返回一个数据集,大家从语句上也不难看出它是一条限量查询语句,与mysql语句中的limit 有异曲同工之效,来一个简单的例子:
$rs = $conn->SelectLimit(“select iNewsID, vcNewsTitle from tb_news_CH”, 5, 1);
看明白了吗?$rs中保存的是数据库中从第一记录开始的5条记录。我们知道,在oracle数据库不支持在SQL语句中使用limit,但是我们如果使用ADODB的话,那这个问题就容易解决多了!
5.Close():关闭数据库,虽然说PHP在页面结束时会自动关闭,但为了程序的完整大家还是要在页面结束进行数据库的关闭。

关于ADORecordSet.ADORecordSet为$conn->Execute($sql)返回的结果,它的基本函数如下:
1. Fields($colname):返回字段的值.
2. RecordCount():所包含的记录数.这个记录确定数据集的记录总数.
3. GetMenu($name, [$default_str=”], [$blank1stItem=true], [$multiple_select=false], [$size=0], [$moreAttr=”])非常好的一个函数,使用它可以返回一个name=$name的下拉菜单(或多选框)!!!当然,它是一个HTML的字符串,这是一个令人激动的好东西,$name指的是option的name属性,$default_str是默认选中的字串,$blank1stItem指出第一项是否为空,$multiple_select指出是否为多选框,而我们得到这个字串后就可以使用$smarty->(“TemplateVar”, “GetMenuStr”)来在模板的”TemplateVar” 处输入一个下拉列表(或是多先框)
4. MoveNext():来看一段代码:
=========================================================
$rs = &$conn->Exceute($sql);
if($rs)
{
while($rs->EOF)
{
$array[] = array(“NewsID” => $rs->fields[“iNewsID”],
“NewsTitle” => csubstr($rs->fields[“vcNewsTitle”]), 0, 20);

$rs->MoveNext();
}
}
=========================================================
明白了吗?很像MS ADODB中的那一套嘛!
5. MoveFirst(),MoveLast(), Move($to):一样的,看函数名大家就可以知道它是什么意思了.
6. FetchRow():返回一行,看代码:
=========================================================
$rs = &$conn->Exceute($sql);
if($rs)
{
while($row = $rs-&g
t;FetchRow())
{
$array[] = array(“NewsID” => $row[“iNewsID”],
“NewsTitle” => csubstr($row[“vcNewsTitle”]), 0, 20);
}
}
=========================================================
它实现了与4一样的功能,但看起来更符合PHP的习惯,而4的习惯看起来更像是MS ADODB的办法.

7.GetArray($num):返回数据集中的$num行数据,将其组合成二维数组.这个方法我们在例子index.php要用到.

8. Close():同mysql_free_result($rs);清除内容占用.

好了,初步的函数就介绍到这里,够我们用的啦!实际上ADODB还有很多实用的技术,包括格式化日期时间,格式化查询语句,输出表格,更高级点的Cache查询,带参查询等等,大家可以自行查看手册.

下面我们开始学习我们的程序,同样还是那个Web程序,我将其中的comm目录重新组织了一下,同时为了提高效率对Smarty重新进行了封装,mySmarty.class.php是封装后的类,它继承自Smarty,所以以后所有的程序文件中只调用新的类MySmarty,先来看看目录结构:
+Web (站点根目录)
|
|—-+comm (Smarty相关文档目录)
| |
| |—-+smarty (Smarty原始文件目录)
| |—-+adodb (adodb原始文目录)
| |—–mySmarty.class.php (扩展后的smarty文件)
| |—–csubstr.inc (截取中文字符)
|
|—-+cache (Smarty缓存目录,*nix下保证读写权限)
|
|—-+templates (站点模板文件存放目录)
| |
| |—-header.tpl(页面页头模板文件)
| |—-index.tpl(站点首页模板文件)
| |—-foot.tpl(页面页脚模板文件)
| |—-news.tpl (新闻页模板文件)
|
|
|—-+templates_c (模板文件编译后存放目录,*nix下保证读写权限)
|
|—-+css (站点CSS文件目录)
|
|—-+image (站点图片目录)
|
|—-+media (站点Flash动画存放目录)
|
|—-indexbak.htm (首页原始效果图)
|
|—-newsbak,htm (新闻页原始效果图)
|
|—-index.php (Smarty首页程序文件)
|
|—-news.php (Smarty新闻显示文件)
|
|—-newsList.php (显示新闻列表)
|
|—-例程说明.txt (本文档)

相对于前两个教程,有将comm目录重新组织了一下,其它的文件结构没有变化,整个站点相对于上两个教程来讲,改变的地方只有comm目录与index.php与news.php,同时增加了新闻列表,大家可以在index.php执行后的页面中点击”国内新闻”,”国际新闻”, “娱乐新闻”来分别查看各自的新闻列表, 我们先来看看index.php:

======================================================
index.php
======================================================
<?php
/*********************************************
*
* 文件名: index.php
* 作 用: 显示实例程序
*
* 作 者: 大师兄
* Email: teacherli@163.com
*
*********************************************/
include_once(“./comm/mySmarty.class.php”); //包含smarty的扩展类文件
include_once(“./comm/adodb/adodb.inc.php”); //包含ADODB主执行文件
include_once(“./comm/csubstr.inc”); //包含中文截取类

define (“NEWS_NUM”, 5); //定义新闻列表显示数目

$smarty = new MySmarty(); //建立smarty实例对象$smarty

1. $conn = ADONewConnection(“mysql”); //初始化ADODB
2. $conn->Connect(“localhost”, “root”, “”, “News”); //连接数据库

//这里将处理国内新闻部分
3. $strQuery = “Select iNewsID AS NewsID, vcNewsTitle AS NewsTitle FROM tb_news_CH orDER BY iNewsID DESC”;
4. $rs = &$conn->Execute($strQuery);
5. $smarty->assign(“News_CH”, $rs->GetArray(NEWS_NUM));
6. unset($rs);

//这里处理国际新闻部分
$strQuery = “Select iNewsID AS NewsID, vcNewsTitle AS NewsTitle FROM tb_news_IN orDER BY iNewsID DESC”;
$rs = &$conn->Execute($strQuery);
$smarty->assign(“News_IN”, $rs->GetArray(NEWS_NUM));
unset($rs);

//这里将处理娱乐新闻部分
$strQuery = “Select iNewsID AS NewsID, vcNewsTitle AS NewsTitle FROM tb_news_MU orDER BY iNewsID DESC”;
$rs = &$conn->Execute($strQuery);
$smarty->assign(“News_MU”, $rs->GetArray(NEWS_NUM));
unset($rs);

7. $conn->close();

//编译并显示位于./templates下的index.tpl模板
$smarty->display(“index.tpl”);
?>
=============================================================================
同样,我在关键的地方加了数标,下面来说明一下它们的含义:

1. 建立一个连接对象$conn,大家在这里要注意的是它的初始不是以$conn = new ADONewConnection($dbType)这样的形式出现的,也就是说,ADONewConnection不是一个class,你不能使用new 对它进行初始化.看看它的源码你就会明白,这只不过是一个函数.

2. 这个就不用说了吧?打开一个News的数据库,主机为:localhost, 用户名为root, 密码为””

3. 一个查询语句,注意,这里要将查询的字段使用AS关键字来重新标识,名称为你在模板中设置的模板变量的名称.

4. 使用Execute来执行这个查询,结果返回一个RecordSet数据集

5. 这里有个方法:$rs->GetArray($num) 这个在上边介绍过,它是要从$rs这个数据集中返回$num行,结果为一个可被Smarty所识别的二维数据.这样ADODB就自动为我们构建起了这样的结构,而在我们以前的例子中,都是使用一个循环构建这样的数组的.

6. 这一句我看也不用说了吧?

7. 关闭内存中的相关资源.

大家可以看看,整个程序中再没有出现什么while语句,程序整体结构显的非常清楚,这就是为什么ADODB+Smarty是黄金组合的原因.不过话也说回来了,简单有简单的问题,不知大家想过没有,这里对显示的新闻标题的长度没有控制,也就是说,如果某条新闻标题的长度超出一行显示的范围,它就是自动折行到下一行,那么整个的版面就会变乱,所说大家自已适自己的情况来决定是否这样使用吧当然,你也可以使用像上一节中介绍的那样,使用一个循环语句重构这个二维数组,使它符合你的用途,怎么做大家自己去想吧,参考PHPLIB中的做法,上节我介绍过了…

再来看看新闻页吧

=============================================================
news.php
=============================================================
<?php
/*********************************************
*
* 文件名: news.php
* 作 用: 新闻显示程序
*
* 作 者: 大师兄
* Email: teacherli@163.com
*
*********************************************/
include_once(“./comm/mySmarty.class.php”); //包含smarty的扩展类文件
include_once(“./comm/adodb/adodb.inc.php”); //包含ADODB主执行文件

$smarty = new MySmarty(); //建立smarty实例对象$smarty

$conn = ADONewConnection(“mysql”); //初始化ADODB
$conn->Connect(“localhost”, “root”, “”, “News”); //连接数据库

$NewsID = $_GET[“id”]; //获取新闻编号
$NewsType = $_GET[“type”]; //要显示的新闻类型
switch($NewsType)
{
case 1: $dbName = “tb_news_CH”;
break;
case 2:
$dbName = “tb_news_IN”;
break;
case 3:
$dbName = “tb_news_MU”;
break;
}

$strQuery = “Select vcNewsTitle AS NewsTitle, ltNewsContent AS NewsContent FROM ” . $dbName;
1. $row = &$conn->GetRow($strQuery); //返回一个一维数组,下标为模板变量名

$smarty->display($row);
unset($row);

$conn->Close();
?>
=============================================================
说明一下关键的地方,其实在news.php中也只有一个地方值的说明一下了.

1. $conn->GetRow($strQuery):这一句返回一个一维数组,返回的形式为:

$array = (“NewsTitle”=>”xxxx”, “NewsContent”=>”yyyyy…”)
明白如果使用$smarty($array)后Smarty会干什么吗?对了,就是相当于:
$smarty->assign(“NewsTitle”, “xxxx”);
$smarty->assign(“NewsContent”, “yyyyy…”);

简单吧,确实很简单

下面再来看看新闻列表:
================================================================
newsList.php
================================================================
<?php
/*********************************************
*
* 文件名: newsList.php
* 作 用: 新闻列表显示程序
*
* 作 者: 大师兄
* Email: teacherli@163.com
*
*********************************************/
include_once(“./comm/mySmarty.class.php”); //包含smarty的扩展类文件
include_once(“./comm/adodb/adodb.inc.php”); //包含ADODB主执行文件

$smarty = new MySmarty(); //建立smarty实例对象$smarty

$conn = ADONewConnection(“mysql”); //初始化ADODB
$conn->Connect(“localhost”, “root”, “”, “News”); //连接数据库

$NewsID = $_GET[“id”]; //获取新闻编号
$NewsType = $_GET[“type”]; //要显示的新闻类型
switch($NewsType)
{
case 1:
$tbName = “tb_news_CH”;
break;
case 2:
$tbName = “tb_news_IN”;
break;
case 3:
$tbName = “tb_news_MU”;
break;
}

$strQuery = “Select iNewsID AS NewsID, vcNewsTitle AS NewsTitle FROM ” . $tbName;
1. $rs = &$conn->GetAll($strQuery);
2. $smarty->assign(“NewsType”, $NewsType); //这一句为新闻列表中的链接服务
3. $smarty->assign(“NewsList”, $rs);
unset($rs);
$conn->close();

$smarty->display(“newsList.tpl”);
?>
================================================================
分别来说明一下:

1. GetAll($strQuery):这个函数可是个好东东,它的作用是将$strQuery查询到的所有数据组合成为一个能够被Smarty所识别的二维数组,记住:它返回的是一个二维数组而不是一个RecordSet,所在你可以程序中直接在3处使用.
2. 这里是为了给新闻标题做链接时要GET参数type=XX而做的

后记:
大家在使用ADODB时有几个地方要注意:
1. 初始化: 初始化的方式不是使用new,因为它不是一个对象
2. 方 法: 基本上每个方法都是以大写字母开头大小写混合的名称,这一点好像与*NIX的习惯有些不同,也不同于PHP的整体风格,所以注意这里的大小写问题.

模板引擎SMARTY

于博翔 (yulair@postwebpro.com)对外经济贸易大学信息学院

2003 年 6 月 26 日

用PHP实现MVC开发模式的逻辑层和表示层有多种模板引擎可供选择,但是官方引擎SMARTY诞生后,选择就有了变化。它的理念和实现都是相当"前卫"的。本文主要讨论SMARTY之于其他模板引擎的不同特点,简要介绍了该引擎的安装及使用,并用一个小的测试案例对比了SMARTY和PHPLIB template的速度和易用性。

一、MVC需要模板

MVC最早是在SmallTalk语言的开发过程中总结出的一种设计模式,MVC分别代表了"模型"、"视图"和"控制",目的就是让不同的开发角色在大中型项目中各司其职。在网络应用程序的开发中,可以用下图来表示各概念之间的关系。

该图展示了一个简单的WEB应用程序,用户在浏览器上看到信息是数据库服务器上的内容,但在这之前经过了应用服务器加工。开发人员负责的就是建立数据结构、处理数据的逻辑以及表示数据的方法。

96年CGI在中国开始流行的时候,早期的WEB程序员都是从HTML开始自学成材的,在PERL中print一行行的HTML并不是一件难事,但是随着网络的一步步提速,页面大小也从当初的二、三十K暴涨了十倍。写CGI程序就产生了一个迫切的要求:分开PERL和HTML源码。于是,社会进步体现在开发小组内部的分工上。由于美工和程序员对互相的工作并不是十分熟悉,在进行合作的过程中需要用一种约定的"语言"进行交流。

这种语言并不是我们的母语或者英语,术语叫做"模板",逻辑和表示依靠它联系。它是结合了HTML和脚本语言特征的一种表达方式。通过这种方式,表示层可以按照用户所希望的格式来显示经过逻辑层处理过的数据。如果你有Windows平台下MFC的开发经验,那么一定会很熟悉Document/Document Template/View的封装,这就是一个很典型的MVC例子。对于Web应用来说,个人认为J2EE中的EJB/servlets/JSP是最强大的,当然还有简洁优美的Structs。另一个很有名的实现就是COM/DCOM+ASP,这个组合在我国是最多人使用的。

通过几种MVC实现在WEB应用程序里的对比,可以得到一个关于模板的概念:一组插入了HTML的脚本或者说是插入了脚本HTML,通过这种插入的内容来表示变化的数据。下面给出一个模板文件的例子,这个模板经过处理后在浏览器里显示"Hello, world!"

<html>
            <head>
            <title>$greetings</title>
            </head>
            <body>
            $greetings
            <body>
            </html>
            

这里暂且省略处理方式,在后面做专门对比讨论。


回页首

二、为什么选SMARTY?

对PHP来说,有很多模板引擎可供选择,比如最早的PHPLIB template和后起之秀Fast template,经过数次升级,已经相当成熟稳定。如果你对目前手中的模板引擎很满意,那么……也请往下看,相信你作为一个自由软件爱好者或者追求效率和优雅的开发者,下面的SMARTY介绍多少会有点意思。

除了个人偏好的影响,我一直倾向于使用官方标准的实现,比如APACHE的XML引擎Axis。好处就是可以获得尽可能好的兼容性(比如早期MFC对于Win3x的兼容性就比其它的应用程序框架好,当然现在各种版本都很完善了)。SMARTY发布之前我一直使用的是 PEAR 中的Integrated Template eXtension。这个引擎和PHPLIB template、Fast template几乎是兼容的,从模板的语法到对模板的处理同出一辙:都是将模板读入内存然后调用parse()函数,用数据对预置的标记进行替换。

下面看看SMARTY是怎么做的。接到request后,先判断是否第一次请求该url,如果是,将该url所需的模板文件"编译"成php脚本,然后redirect;如果不是,就是说该url的模板已经被"编译"过了,检查不需要重编译后可以马上redirect,重编译条件可以自己设定为固定时限,默认的是模板文件被修改。

怎么样,看起来是不是有点眼熟?想起来了──这不就是JSP的原理嘛!的确,这种"编译"用在PHP这样的解释性脚本引擎上显得匪夷所思,但是仔细想想,JAVA不也是由JVM解释执行的吗?这就叫"没有做不到,只有想不到"。

既然谈到了JAVA,就再对PHP的未来发表一点看法。PHP官方网站上宣布了要在2003年年底发布PHP5.0版。这个版本拥有很多崭新的特性:比如异常处理,命名空间,更加面向对象等等。可以说越来越向JAVA靠拢,SMARTY也是新特性之一,使得PHP更适用于大中型项目的开发。但是似乎离我当初选择它的原因──灵巧易用──越来越远了。但就一个软件的生存周期来看,PHP正处在成长期,开发者赋予它更多的功能,以期能胜任商业应用是利大于弊的。作为PHP的忠实用户,肯定不希望PHP总是被人指责"能力不足"吧?

为什么选择SMARTY,仅仅因为它很像JSP?当然有更为充分的理由。首先,除了第一次编译的成本比较高之外,只要不修改模板文件,编译好的cache脚本就随时可用,省去了大量的parse()时间;其次SMARTY像PHP一样有丰富的函数库,从统计字数到自动缩进、文字环绕以及正则表达式都可以直接使用;如果觉得不够,比如需要数据结果集分页显示的功能,SMARTY还有很强的扩展能力,可以通过插件的形式进行扩充。

事实胜于雄辩。我设计了一个测试程序,通过速度和开发难度这两个因素对比了一下SMARTY和PHPLIB template,选PHPLIB template的原因是在patrick的文章 《在PHP世界中选择最合适的模板》中有一个PHPLIB template对Fast template的竞赛,结果PHPLIB template大获全胜,这使得SMARTY有了一个很好的对手。在测试之前,先谈一下在安装过程中需要注意的问题。


回页首

三、可能遇到的问题

在SMARTY的 官方网站上,有详尽的用户手册,可以选择在线HTML和PDF格式的版本。这里就不再涉及手册上已有的内容,只是把初次使用可能遇到的问题做个解释。

第一个问题就很要命:提示说找不到所需文件?并不是每一个人都按照SMARTY默认目录结构来写应用的。这里需要手工指定,假设目录结构如下:

就需要在index.php里指定目录结构:

$smart->template_dir = "smarty/templates/";
            $smart->compile_dir = "smarty/templates_c/";
            $smart->config_dir = "smarty/configs/";
            $smart->cache_dir = "smarty/cache/";
            

第一个问题解决了,紧接着就是第二个:我刚用Dreamweaver生成的漂亮模板怎么不能用?并不是模板文件有什么问题,而是因为SMARTY默认的标记分隔符是{},不巧的是Javascript肯定包含这个标记。好在我们可以用任意字符当作分隔符,再加上这两句:

$smart->left_delimiter = "{/";
            $smart->right_delimiter = "/}";
            

这下安装就基本完成,没问题了。


回页首

四、反衬和类比

先构思一下对测试的设计。主要的评比因素当然是速度了。为了进行速度测试,采取了算术平均数的作法。在测试页面中重复将页面生成N遍,再对比总页面生成时间。另一个重要因素是易用性(至于扩展性不用比较已经有结果了),所以使用的模板不能太小。我用的是我个人主页的的页面,一个用Firework+Dreamweaver生成的HTML文件,大小约7K。其中的变量设置也采取最常用的区块,在PHPLIB template里叫block,而SMARTY则称section。别小看这称呼的不同,易用性标准分两块:模板文件和脚本文件的语法是否简明易用。

下面就深入到测试中来。先看看两种模板文件的语法:蓝条左边是PHPLIB template的模板,右边属于SMARTY。个人偏好是不一样的,所以这里不作评论。着重对比一下脚本里的处理语句,先看PHPLIB template的:

$tpl->set_file('phplib', 'bigfile.htm');
            $tpl->set_block('phplib', 'row', 'rows');
            for ($j = 0; $j < 10; $j++){
            $tpl->set_var('tag' ,"$j");
            $tpl->parse('rows', 'row', true);
            }
            $tpl->parse('out', 'phplib');
            $tpl->p('out');
            

下面是SMARTY的:

$smart->assign('row',$row);
            $smart->display('bigfile.htm');
            

SMARTY只用了tags和row两个变量,而PHPLIB template则多了模板文件的handler,还有一个莫名其妙的out。说实在的这个out我当初学的时候就不知道为什么要存在,现在看起来,还是别扭。为什么SMARTY少那么多处理语句呢?答案是工作由引擎完成了。如果你喜欢钻研源程序,可以发现在Smarty_compiler.class.php里有一个名叫_compile_tag()的函数,由它负责把section这个标签转换成php语句。这不是一个普通的标签,它带有参数和数据,节省了脚本编程的工作量,而模板标签上的工作量相差又不大,可以判定在易用性上SMARTY高出一畴。

下面该轮到我们最关注的速度了,毕竟对于一个熟练的web开发者来说,掌握再困难的工具不过是时间问题,何况模板引擎这种学习曲线平缓的技术。而速度则是web应用程序的生命,尤其是模板引擎使用在并发访问量很大的站点上,这点就更重要了。测试开始前,我觉得PHPLIB template会在这一环节上胜出,因为它经历了很多次升级,已经基本没有什么bug,而且SMARTY的引擎个头太大,不像它的对手只有两个文件。

果然,测试结果如下图,PHPLIB template有25%的速度优势:

但不会一直这样,我又按了一次刷新,这次得到了不一样的结果:

PHPLIB基本没变化,但是SMARTY提高了25%的速度。继续刷新,得到的都是类似于第二次的结果:SMARTY比PHPLIB template 快上近10%。我想这就是编译型比解释型快的原理了。SMARTY引擎本身就很大,加上还要把模板编译成php文件,速度当然比不上小巧的PHPLIB template。但这只是第一次的情况。第二次接到请求的时候,SMARTY发现该模板已经被编译过了,于是最耗时的一步被跳过了,而对手还要按部就班地进行查找和替换工作。这是编译原理里讲到的很经典的"用空间换时间"例子。


回页首

五、结论

结论就是如果你已经爱上SMARTY了,那么还等什么呢?当然并不是说它就全能,就如同我用MVC模式来写我的个人网站,非但没有减少工作量,反而总是要为不同层次间的耦合劳神。

SMARTY不适合什么呢?举个手册里的经典例子:天气预报网站。我还想到一个:股市大盘。在这种网站上用SMARTY会由于经常的重编译而效率偏低,还是PHPLIB template更为适合。

本文并不是为了对比两种引擎,而是为了说明SMARTY的优势。使用它最有意义之处在于它是PHP新体系的一部份,作为一支独立的力量,除了.NET和JAVA ONE这两大体系之外,大中型web开发还有别的选择。这对于GNU项目来说,其意义无异于刘邓大军千里跃进大别山。

参考资料

关于作者

 

于博翔,笔名于莱,来自对外经济贸易大学信息学院。GNU痴迷者,喜欢练习各种编程语言,研究各种体系框架。有个人网站 www.postwebpro.com。欢迎来信交流: yulair@postwebpro.com

磁盘阵列(Disk Array)

1.为什么需要磁盘阵列

       如何增加磁盘的存取(access)速度,如何防止数据因磁盘的故障而失落及如何有效的利用磁盘空间,一直是电脑专业人员和用户的困扰;而大容量磁盘的价格非常昂贵,对用户形成很大的负担。磁盘阵列技术的产生一举解决了这些问题。
        过去十年来,CPU的处理速度增加了五十倍有多,内存(memory)的存取速度亦大幅增加,而数据储存装置–主要是磁盘(hard disk)–的存取速度只增加了三、四倍,形成电脑系统的瓶颈,拉低了电脑系统的整体性能(throughput),若不能有效的提升磁盘的存取速度,CPU、内存及磁盘间的不平衡将使CPU及内存的改进形成浪费。
        目前改进磁盘存取速度的的方式主要有两种。一是磁盘快取控制(disk cache controller),它将从磁盘读取的数据存在快取内存(cache memory)中以减少磁盘存取的次数,数据的读写都在快取内存中进行,大幅增加存取的速度,如要读取的数据不在快取内存中,或要写数据到磁盘时,才做磁盘的存取动作。这种方式在单工环境(single-tasking environment)如DOS之下,对大量数据的存取有很好的性能(量小且频繁的存取则不然),但在多工(multi-tasking)环境之下(因为要不停的作数据交换(swapping)的动作)或数据库(database)的存取(因为每一记录都很小)就不能显示其性能。这种方式没有任何安全保障。
        其二是使用磁盘阵列的技术。磁盘阵列是把多个磁盘组成一个阵列,当作单一磁盘使用,它将数据以分段(striping)的方式储存在不同的磁盘中,存取数据时,阵列中的相关磁盘一起动作,大幅减低数据的存取时间,同时有更佳的空间利用率。磁盘阵列所利用的不同的技术,称为RAID level,不同的level针对不同的系统及应用,以解决数据安全的问题。
         一般高性能的磁盘阵列都是以硬件的形式来达成,进一步的把磁盘快取控制及磁盘阵列结合在一个控制器(RAID controller)或控制卡上,针对不同的用户解决人们对磁盘输出入系统的四大要求:
(1)增加存取速度,
(2)容错(fault tolerance),即安全性
(3)有效的利用磁盘空间;
(4)尽量的平衡CPU,内存及磁盘的性能差异,提高电脑的整体工作性能。

2.磁盘阵列原理
        磁盘阵列中针对不同的应用使用的不同技术,称为RAID level, RAID是Redundant Array of Inexpensive Disks的缩写,而每一level代表一种技术,目前业界公认的标准是RAID 0~RAID 5。这个level并不代表技术的高低,level 5并不高于level 3,level 1也不低过level 4,至于要选择那一种RAID level的产品,纯视用户的操作环境(operating environment)及应用(application)而定,与level的高低没有必然的关系。RAID 0及RAID 1适用于PC及PC相关的系统如小型的网络服务器(network server)及需要高磁盘容量与快速磁盘存取的工作站等,因为比较便宜,但因一般人对磁盘阵列不了解,没有看到磁盘阵列对他们价值,市场尚未打开;RAID 2及RAID 3适用于大型电脑及影像、CAD/CAM等处理;RAID 5多用于OLTP,因有金融机构及大型数据处理中心的迫切需要,故使用较多而较有名气,但也因此形成很多人对磁盘阵列的误解,以为磁盘阵列非要RAID 5不可;RAID 4较少使用,因为两者有其共同之处,而RAID 4有其先天的限制。其他如RAID 6,RAID 7,乃至RAID 10等,都是厂商各做各的,并无一致的标准,在此不作说明。介绍各个RAID level之前,先看看形成磁盘阵列的两个基本技术:
        译为磁盘延伸,能确切的表示disk spanning这种技术的含义。如下图所示,DFTraid 磁盘阵列控制器,联接了四个磁盘:
        这四个磁盘形成一个阵列(array),而磁盘阵列的控制器(RAID controller)是将此四个磁盘视为单一的磁盘,如DOS环境下的C:盘。这是disk spanning的意义,因为把小容量的磁盘延伸为大容量的单一磁盘,用户不必规划数据在各磁盘的分布,而且提高了磁盘空间的使用率。DFTraid的SCSI磁盘阵列更可连接几十个磁盘,形成数十GB到数百GB的阵列,使磁盘容量几乎可作无限的延伸;而各个磁盘一起作取存的动作,比单一磁盘更为快捷。很明显的,有此阵列的形成而产生RAID的各种技术。我们也可从上图看出inexpensive(便宜)的意义,因为四个250MBbytes的磁盘比一个1GBytes的磁盘要便宜,尤其以前大磁盘的价格非常昴贵,但在磁盘越来越便宜的今天,inexpensive已非磁盘阵列的重点,虽然对于需要大磁盘容量的系统,仍是考虑的要点。
        磁盘
     
  因为磁盘阵列是将同一阵列的多个磁盘视为单一的虚拟磁盘(virtual disk),所以其数据是以分段(block or segment)的方式顺序存放在磁盘阵列中,如下图:

 

磁盘0

 

 

磁盘1

 

 

磁盘2

 

 

磁盘3

A0-A1

 

B0-B1

 

C0-C1

 

D0-D1

 

 

 

 

A2-A3

 

B2-B3

 

C2-C3

 

D2-D3

 

 

 

 

A4-A5

 

B4-B5

 

C4-C5

 

D4-C5

 

 

 

 

A6-A7

 

B6-B7

 

C6-C7

 

D6-D7

 

 

        数据按需要分段,从第一个磁盘开始放,放到最後一个磁盘再回到第一个磁盘放起,直到数据分布完毕。至于分段的大小视系统而定,有的系统或以1KB最有效率,或以4KB,或以6KB,甚至是4MB或8MB的,但除非数据小于一个扇区(sector,即521bytes),否则其分段应是512byte的倍数。因为磁盘的读写是以一个扇区为单位,若数据小于512bytes,系统读取该扇区后,还要做组合或分组(视读或写而定)的动作,浪费时间。从上图我们可以看出,数据以分段于在不同的磁盘,整个阵列的各个磁盘可同时作读写,故数据分段使数据的存取有最好的效率,理论上本来读一个包含四个分段的数据所需要的时间约=(磁盘的access time +数据的transfer time)X4次,现在只要一次就可以完成。

      若以N表示磁盘的数目,R表示读取,W表示写入,S表示可使用空间,则数据分段的性能为:
R:N(可同时读取所有磁盘)
W:N(可同时写入所有磁盘)
S:N(可利用所有的磁盘,并有最佳的使用率)
        Disk striping也称为RAID 0,很多人以为RAID 0没有甚么,其实这是非常错误的观念,因为RAID 0使磁盘的输出入有最高的效率。而磁盘阵列有更好效率的原因除数据分段外,它可以同时执行多个输出入的要求,因为阵列中的每一个磁盘都能独立动作,分段放在不同的磁盘,不同的磁盘可同时作读写,而且能在快取内存及磁盘作并行存取(parallel access)的动作,但只有硬件的磁盘阵列才有此性能表现。
        从上面两点我们可以看出,disk spanning定义了RAID的基本形式,提供了一个便宜、灵活、高性能的系统结构,而disk striping解决了数据的存取效率和磁盘的利用率问题,RAID 1至RAID 5是在此基础上提供磁盘安全的方案。

RAID 1
        RAID 1是使用磁盘镜像(disk mirroring)的技术。磁盘镜像应用在RAID 1之前就在很多系统中使用,它的方式是在工作磁盘(working disk)之外再加一额外的备份磁盘(backup disk),两个磁盘所储存的数据完全一样,数据写入工作磁盘的同时亦写入备份磁盘。磁盘镜像不见得就是RAID 1,如Novell NetWare亦有提供磁盘镜像的功能,但并不表示NetWare有了RAID 1的功能。一般磁盘镜像和RAID 1有二点最大的不同:
      RAID 1无工作磁盘和备份磁盘之分,多个磁盘可同时动作而有重叠(overlapping)读取的功能,甚至不同的镜像磁盘可同时作写入的动作,这是一种最佳化的方式,称为负载平衡(load-balance)。例如有多个用户在同一时间要读取数据,系统能同时驱动互相镜像的磁盘,同时读取数据,以减轻系统的负载,增加I/O的性能。 
      RAID 1的磁盘是以磁盘延伸的方式形成阵列,而数据是以数据分段的方式作储存,因而在读取时,它几乎和RAID 0有同样的性能。从RAID的结构就可以很清楚的看出RAID 1和一般磁盘镜像的不同。

 下图为RAID 1,每一笔数据都储存两份

 

磁盘0

 

 

磁盘1

 

 

磁盘0

 

 

磁盘1

A0

 

A2

 

A4

 

B1

 

 

 

 

A1

 

A3

 

B0

 

B2

 

 

 

 

A0

 

A2

 

A4

 

B1

 

 

 

 

A1

 

A3

 

B0

 

B2

 

 

从上图可以看出:
R:N(可同时读取所有磁盘)
W:N/2(同时写入磁盘数)
S:N/2(利用率)

        读取数据时可用到所有的磁盘,充分发挥数据分段的优点;写入数据时,因为有备份,所以要写入两个磁盘,其效率是N/2,磁盘空间的使用率也只有全部磁盘的一半。
        很多人以为RAID 1要加一个额外的磁盘,形成浪费而不看好RAID 1,事实上磁盘越来越便宜,并不见得造成负担,况且RAID 1有最好的容错(fault tolerance)能力,其效率也是除RAID 0之外最好的。我们可视应用的不同,在同一磁盘阵列中使用不同的RAID level,如华艺科技公司的DFTraid系列都可同一磁盘阵列中定义八个逻辑磁盘(logic disk),分别使用不同的RAID level,分为C:,D:及E:三个逻辑磁盘(或LUN0,LUN1,LUN2). 
        RAID 1完全做到了容错包括不停机(non-stop),当某一磁盘发生故障,可将此磁盘拆下来而不影向其他磁盘的操作;待新的磁盘换上去之后,系统即时做镜像,将数据重新复上去,RAID 1在容错及存取的性能上是所有RAID level之冠。
        在磁盘阵列的技术上,从RAID 1到RAID 5,不停机的意思表示在工作时如发生磁盘故障,系统能持续工作而不停顿,仍然可作磁盘的存取,正常的读写数据;而容错则表示即使磁盘故障,数据仍能保持完整,可让系统存取到正确的数据,而SCSI的磁盘阵列更可在工作中抽换磁盘,并可自动重建故障磁盘的数据。磁盘阵列之所以能做到容错及不停机,是因为它有冗余的磁盘空间可资利用,这也就是Redundant的意义。

RAID 2
        RAID 2是把数据分散为位元(bit)或块(block),加入海明码Hamming Code,在磁盘阵列中作间隔写入(interleaving)到每个磁盘中,而且地址(address)都一样,也就是在各个磁盘中,其数据都在相同的磁道(cylinder or track)及扇区中。RAID 2的设计是使用共轴同步(spindle synchronize)的技术,存取数据时,整个磁盘阵列一起动作,在各作磁盘的相同位置作平行存取,所以有最好的存取时间(access time),其总线(bus)是特别的设计,以大带宽(band wide)并行传输所存取的数据,所以有最好的传输时间(transfer time)。在大型档案的存取应用,RAID 2有最好的性能,但如果档案太小,会将其性能拉下来,因为磁盘的存取是以扇区为单位,而RAID 2的存取是所有磁盘平行动作,而且是作单位元的存取,故小于一个扇区的数据量会使其性能大打折扣。RAID 2是设计给需要连续且大量数据的电脑使用的,如大型电脑(mainframe to supercomputer)、作影像处理或CAD/CAM的工作站(workstation)等,并不适用于一般的多用户环境、网络服务器(network server),小型机或PC。
        RAID 2的安全采用内存阵列(memory array)的技术,使用多个额外的磁盘作单位错误校正(single-bit correction)及双位错误检测(double-bit detection);至于需要多少个额外的磁盘,则视其所采用的方法及结构而定,例如八个数据磁盘的阵列可能需要三个额外的磁盘,有三十二个数据磁盘的高档阵列可能需要七个额外的磁盘。

RAID 3
        RAID 3的数据储存及存取方式都和RAID 2一样,但在安全方面以奇偶校验(parity check)取代海明码做错误校正及检测,所以只需要一个额外的校检磁盘(parity disk)。奇偶校验值的计算是以各个磁盘的相对应位作XOR的逻辑运算,然后将结果写入奇偶校验磁盘,任何数据的修改都要做奇偶校验计算,如下图:

 

磁盘0

 

 

磁盘1

 

 

磁盘2

 

 

磁盘3

 

 

磁盘4

A0

 

A4

 

B3

 

C2

 

 

 

 

A1

 

B0

 

B4

 

C3

 

 

 

 

A2

 

A1

 

C0

 

C4

 

 

 

 

A3

 

A2

 

C1

 

D0

 

 

 

 

P

 

P

 

P

 

P

 

 

        如某一磁盘故障,换上新的磁盘后,整个磁盘阵列(包括奇偶校验磁盘)需重新计算一次,将故障磁盘的数据恢复并写入新磁盘中;如奇偶校验磁盘故障,则重新计算奇偶校验值,以达容错的要求.

         较之RAID 1及RAID 2,RAID 3有85%的磁盘空间利用率,其性能比RAID 2稍差,因为要做奇偶校验计算;共轴同步的平行存取在读档案时有很好的性能,但在写入时较慢,需要重新计算及修改奇偶校验磁盘的内容。RAID 3和RAID 2有同样的应用方式,适用大档案及大量数据输出入的应用,并不适用于PC及网络服务器。

RAID 4

    RAID 4也使用一个校验磁盘,但和RAID 3不一样,如下图:

 

磁盘0

 

 

磁盘1

 

 

磁盘2

 

 

磁盘3

 

 

磁盘4

A0-A1

 

B3-B4

 

D1-D2

 

E4-F0

 

 

 

 

A2-A3

 

C0-C1

 

D3-D4

 

F1-F2

 

 

 

 

A4-B0

 

C2-C3

 

B0-B1

 

F3-F4

 

 

 

 

B1-B2

 

C4-D0

 

B2-B3

 

G0-G1

 

 

 

 

P

 

P

 

P

 

P

 

 

        RAID 4是以扇区作数据分段,各磁盘相同位置的分段形成一个校验磁盘分段(parity block),放在校验磁盘。这种方式可在不同的磁盘平行执行不同的读取命今,大幅提高磁盘阵列的读取性能;但写入数据时,因受限于校验磁盘,同一时间只能作一次,启动所有磁盘读取数据形成同一校验分段的所有数据分段,与要写入的数据做好校验计算再写入。即使如此,小型档案的写入仍然比RAID 3要快,因其校验计算较简单而非作位(bit level)的计算;但校验磁盘形成RAID 4的瓶颈,降低了性能,因有RAID 5而使得RAID 4较少使用。

RAID 5
 

     RAID5避免了RAID 4的瓶颈,方法是不用校验磁盘而将校验数据以循环的方式放在每一个磁盘中,如下图:

磁盘0

 

 

磁盘1

 

 

磁盘2

 

 

磁盘3

 

 

磁盘4

P

 

B3-B4

 

D1-D2

 

E4-F0

 

 

 

 

A0-A1

 

P

 

D3-D4

 

F1-F2

 

 

 

 

A2-B3

 

C0-C1

 

P

 

F3-F4

 

 

 

 

A4-B0

 

C2-C3

 

B0-B1

 

P

 

 

 

 

B2-B2

 

C4-D0

 

B2-B3

 

G0-G1

 

 

            磁盘阵列的第一个磁盘分段是校验值,第二个磁盘至后一个磁盘再折回第一个磁盘的分段是数据,然后第二个磁盘的分段是校验值,从第三个磁盘再折回第二个磁盘的分段是数据,以此类推,直到放完为止。图中的第一个parity block是由A0,A1…,B1,B2计算出来,第二个parity block是由B3,B4,…,C4,D0计算出来,也就是校验值是由各磁盘同一位置的分段的数据所计算出来。这种方式能大幅增加小档案的存取性能,不但可同时读取,甚至有可能同时执行多个写入的动作,如可写入数据到磁盘1而其parity block在磁盘2,同时写入数据到磁盘4而其parity block在磁盘1,这对联机交易处理(OLTP, on-line Transaction Processing)如银行系统、金融、股市等或大型数据库的处理提供了最佳的解决方案(solution),因为这些应用的每一笔数据量小,磁盘输出入频繁而且必须容错。

        事实上RAID 5的性能并无如此理想,因为任何数据的修改,都要把同一parity block的所有数据读出来修改后,做完校验计算再写回去,也就是RMW cycle(Read-Modify-Write cycle,这个cycle没有包括校验计算);正因为牵一而动全身,所以:
R:N(可同时读取所有磁盘)
W:1(可同时写入磁盘数)
S:N-1(利用率)
         RAID 5的控制比较复杂,尤其是利用硬件对磁盘阵列的控制,因为这种方式的应用比其他的RAID level要掌握更多的事情,有更多的输出入需求,既要速度快,又要处理数据,计算校验值,做错误校正等,所以价格较高;其应用最好是OLTP,至于用于PC等,不见得有最佳的性能。

3.RAID的对比:

 下面几个表列是RAID的一些性质:

操作

工作模式

最少硬盘需求量

可用容量

RAID 0

 

磁盘延伸和数据分布

2

 

T

 

RAID 1

 

数据分布和镜像

2

 

T/2

 

RAID 2

 

共轴同步,并行传输,ECC

3

 

T*(n-1)/n

 

RAID 3

 

共轴同步,并行传输,Parity

3

 

T*(n-1)/n

 

RAID 4

 

数据分布,固定Parity

3

 

T*(n-1)/n

 

RAID 5

 

数据分布,分布Parity

3

 

T*(n-1)/n

 

RAID的性能与可用性:

RAID Level

 

用户数据利用率

Bandwidth Performance

 

Transaction
Performance

 

数据可用性

RAID 0

 

1

 

0.25

 

1

 

0.0005

 

RAID 1

 

0.5

 

0.25

 

0.85

 

1

 

RAID 2

 

0.67

 

1

 

0.25

 

0.9999

 

RAID 3

 

0.75

 

1

 

0.25

 

0.9999

 

RAID 4

 

0.75

 

0.25

 

0.61

 

0.9999

 

RAID 5

 

0.75

 

0.25

 

0.61

 

0.9999

 

以上数据基于4个磁盘,传输块大小1K,75%的读概率,数据可用性的计算基于同样的损坏概率

 

4.RAID的概述:

 RAID 0
         没有任何额外的磁盘或空间作安全准备,所以一般人不重视它,这是误解,其实它有最好的效率及空间利用率,对于追求效率的应用,非常理想,可同时用其他的RAID level或其他的备份方式以补其不足,保护重要的数据。
 RAID 1
          有最佳的安全性,100%不停机,即使有一个磁盘损坏也能照常作业而不影向其效能(对能并行存取的系统稍有影响),因为数据是作重复储存。RAID1的并行读取几乎有RAID 0的性能,因为可同时读取相互镜像的磁盘;写入也只比RAID 0略逊,因为同时写入两个磁盘并没有增加多少工作。虽然RAID 1要增加一倍的磁盘做镜像,但作为采用磁盘阵列的进入点,它是最便宜的一个方案,是新设磁盘阵列的用户之最佳选择。

RAID 5
        在不停机及容错的表现都很好,但如有磁盘故障,对性能的影响较大,大容量的快取内存有助于维持性能,但在OLTP的应用上,因为每一笔数据或记录(record)都很小,对磁盘的存取频繁,故有一定程度的影响。某一磁盘故障时,读取该磁盘的数据需把共用同一parity block的所有数据及校验值读出来,再把故障磁盘的数据计算出来;写入时,除了要重覆读取的程序外,还要再做校验值的计算,然后再写入更新的数据及校验值;等换上新的磁盘,系统要计算整个磁盘阵列的数据以回复故障磁盘的数据,时间要很长,如系统的工作负载很重的话,有很多输出入的需求在排队等候时,会把系统的性能拉下来。但如使用硬件磁盘阵列的话,其性能就可以得到大幅度的改进,因为硬件磁盘阵列如DFTraid系列本身有内置的CPU与主机系统并行运作,所有存取磁盘的输出入工作都在磁盘阵列本身完成,不花费主机的时间,配合磁盘阵列的快取内存的使用,可以提高系统的整体性能,而优越的总线控制更能增加数据的传输速率,即使在磁盘故障的情况下,主机系统的性能也不会有明显的降低。RAID 5要做的事情太多,所以价格较贵,不适于小系统,但如果是大系统使用大的磁盘阵列的话,RAID 5却是最便宜的方案。

      总而言之,RAID 0及RAID 1最适合PC及图形工作站的用户,提供最佳的性能及最便宜的价格,所以RAID 0及RAID 1多是使用IDE界面,以低成本符合PC市埸的需求。RAID 2及RAID 3适用于大档案且输入输出需求不频繁的应用如影像处理及CAD/CAM等;而RAID 5则适用于银行、金融、股市、数据库等大型数据处理中心的OLTP应用;RAID 4与RAID 5有相同的特性及应用方式,但有其先天的限制,所以并不受推荐。

 5.磁盘阵列的额外容错功能:

Spare or Standby driver

        事实上容错功能已成为磁盘阵列最受青睐的特性,为了加强容错的功能以及使系统在磁盘故障的情况下能迅速的重建数据,以维持系统的性能,一般的磁盘阵列系统都可使用热备份(hot spare or hot standby driver)的功能,所谓热备份是在建立(configure)磁盘阵列系统的时候,将其中一磁盘指定为后备磁盘,此一磁盘在平常并不操作,但若阵列中某一磁盘发生故障时,磁盘阵列即以后备磁盘取代故障磁盘,并自动将故障磁盘的数据重建(rebuild)在后备磁盘之上,因为反应快速,加上快取内存减少了磁盘的存取,所以数据重建很快即可完成,对系统的性能影响不大。对于要求不停机的大型数据处理中心或控制中心而言,热备份更是一项重要的功能,因为可避免晚间或无人持守时发生磁盘故障所引起的种种不便。

        另一个额外的容错功能是坏扇区转移(bad sector reassignment)。坏扇区是磁盘故障的主要原因,通常磁盘在读写时发生坏扇区的情况即表示此磁盘故障,不能再作读写,甚至有很多系统会因为不能完成读写的动作而死机,但若因为某一扇区的损坏而使工作不能完成或要更换磁盘,则使得系统性能大打折扣,而系统的维护成本也未免太高了。坏扇区转移是当磁盘阵列系统发现磁盘有坏扇区时,以另一空白且无故障的扇区取代该扇区,以延长磁盘的使用寿命,减少坏磁盘的发生率以及系统的维护成本。所以坏扇区转移功能使磁盘阵列具有更好的容错性,同时使整个系统有最好的成本效益比。其他如可外接电池备援磁盘阵列的快取内存,以避免突然断电时数据尚未写回磁盘而损失;或在RAID 1时作写入一致性的检查等,虽是小技术,但亦不可忽视。

 6.硬件磁盘阵列还是软件磁盘阵列

         市面上有所谓硬件磁盘阵列与软件磁盘阵列之分,因为软件磁盘阵列是使用一块SCSI卡与磁盘连接,一般用户误以为是硬件磁盘阵列。以上所述主要是针对硬件磁盘阵列,其与软件磁盘阵列有几个最大的区别:

l 一个完整的磁盘阵列硬件与系统相接。
l 内置CPU,与主机并行运作,所有的I/O都在磁盘阵列中完成,减轻主机的工作负载,增加系统整体性能。
l 有卓越的总线主控(bus mastering)及DMA(Direct Memory Access)能力,加速数据的存取及传输性能。
l 与快取内存结合在一起,不但增加数据的存取及传输性能,更因减少对磁盘的存取而增加磁盘的寿命。
l 能充份利用硬件的特性,反应快速。

         软件磁盘阵列是一个程序,在主机执行,透过一块SCSI卡与磁盘相接形成阵列,它最大的优点是便宜,因为没有硬件成本(包括研发、生产、维护等),而SCSI卡很便宜(亦有的软件磁盘阵列使用指定的很贵的SCSI卡);它最大的缺点是使主机多了很多进程(process),增加了主机的负担,尤其是输出入需求量大的系统。目前市面上的磁盘阵列系统大部份是硬件磁盘阵列,软件磁盘阵列较少。

 7.IDE磁盘阵列还是SCSI磁盘阵列

目前使用在磁盘输出入的界面主要有两种:

 1. IDE (Integrated Drive Electronics)
        是广泛使用在PC上的磁盘驱动器界面,一般而言,其传输速度从磁盘到磁盘缓冲器(medium to drive buffer)是1.5-2.5MB/Sec,从缓冲器到界面(drive buffer to drive interface)约4.0-6.0MB/Sec,而且新的设计其速率有大幅的改进,如增强型IDE界面(mode 4)在PCI(Peripheral Component Interconnect)总线上的传输速率可达33MB/Sec。

 2. SCSI (Small Computer Standard Interface)
           SCSI是较高级(high level)的界面,可用于主机,磁盘,磁带,打印机等,因为是高阶的界面,规格较为复杂,一般自带控制器,也较为复杂,这就是SCSI磁盘为什么比IDE磁盘费的原因。但SCSI界面能较有效的利用硬件特性而提高其速度。其控制器还能对主机发给SCSI磁盘的命令进行缓冲、排队,并进行优化处理(命令队列)。现在较流行的是标准SCSI-2和SCSI-3。有两种规格,FAST SCSI(SCSI-2)的同步传输速率为10MB/Sec,数据传输宽度为8 bit, WIDE SCSI的数据传输宽度可达16-bit。Ultra SCSI(SCSI-3)的同步传输速率为20MB/Sec,Ultra Wide SCSI的同步传输速率为40MB/Sec,数据传输宽度可达32-bit。SCSI磁盘有虽有较高的传输速度,但受限于磁盘的存取速度及磁盘至SCSI界面的传输速度而不能充分发挥其性能(因为磁盘的机械动作难于有大幅度的改进);其命令分析程序(command phase)也较复杂。对单机来言,磁盘数量越多,主机找到特定的数据的时间越长,但对磁盘阵列来言,由于是多个磁盘一起并行处理,则表现为磁盘数量越多,速度越快。

        以上界面的直接反应是单任务时IDE比SCSI快,多任务时SCSI较快,这可从用IDE盘和SCSI盘做多用户、多任务的操作系统(如UNIX、Windows/NT等)的系统盘时的启动时间的差别中明显看出。在单机时则不一定。我们看一个界面是否较快,不应只看其传崐输速度的高低而应就整个输入/输出的流程看,因为磁盘存取的机械动作比不上电脑的传输速率。IDE界面简单,反应快速,用于PC单机的小型的磁盘阵列其效果可能比SCSI为佳;但较大型的磁盘阵列就非SCSI界面莫属,因为阵列中的各个磁盘一起作存取的动作,能充分发挥SCSI的传输速率快及多工的特点。

        此外IDE因为其配线规格的关系,不能作热插拔(hot swap),也就是不能在工作中带电插拔磁盘,而其线缆即使是增强型IDE也只有18寸,不能接在机箱之外,难于形成大的阵列,也就是只适用于PC低层次的用户。SCSI缆线在差分传输模式(differential transmission mode)下最大长度为25米,单端传输模式(single-ended transmission mode)时最大长度为6米,而一条SCSI总线可连接8台系统或各种不同的装置,扩充性很强,可形成很大的磁盘阵列空间;SCSI规格完备,容错能力很好,可带电插拔磁盘,是外接式装置无可取代的界面。

 8. 磁盘阵列卡还是磁盘阵列控制器

        磁盘阵列控制卡一般用于小系统,供单机使用。与主机共用电源,在关闭主机电源时存在丢失Cache中的数据的的危险。磁盘阵列控制卡只有常用总线方式的接口,其驱动程序与主机、主机所用的操作系统都有关系,有软、硬件兼容性问题并潜在地增加了系统的不安定因素。在更换磁盘阵列卡时要冒磁盘损坏,资料失落,随时停机的风险。

独立式磁盘阵列控制一般用于较大型系统,可分为两种:
        单通道磁盘阵列和多通道式磁盘阵列,单通道磁盘阵列只能接一台主机,有很大的扩充限制。多通道磁盘阵列可接多个系统同时使用,以群集(cluster)的方式共用磁盘阵列,这使内接式阵列控制及单接式磁盘阵列无用武之地。DFT数据容错公司的DFTraid Rack Mount和DFTraid Tower等系统,都是独立形式的磁盘阵列子系统,其本身与主机系统的硬件及操作环境无关,只通过SCSI线缆与主机相接,主机把它当作一般的磁盘,所有的输出入动作都在磁盘阵列上完成,与主机的操作无关,所以可接任何可使用SCSI界面的主机。DFTraid Rack Mount和DFTraid Tower两系统最多可有六个SCSI通道,可同时连接5台主机;而DFTraid 5000系列则有9个通道,可同时连接多达8台主机,使之一起共用磁盘阵列子系统。这种方式的磁盘阵列既可给单机使用,又可给群集多机使用,对用户对增加阵列中的磁盘数量限制较小,并可用于备援及并行的容错电脑系统,特别适合较大的系统用户,使这些用户可从封闭的环境中解放出来。

ASP 类 Class入门 推荐

Class 声明

声明一个类的名字,就是定义一些变量,属性,方法来组成一个类。我们常常看到别的程序语言中中都有类的说明,PHP,VB,C++,这个在VBScript中的类的说明,我是第一次听到,我们的日常工作就是网站开发,在这个里面多多少少搞出点经验,像模像样也能自诩为"内行",所以我就来分享一下我所知道的这个新的东东。我们来看看下面的这个代码吧!(window2000+IIS5.0通过测试)

类的定义1

yyh.asp
<%
”声明一个名为yh的类
Class yh

Private yh

”类的初始化
Private Sub Class_Initialize
yh="天涯风云"
End Sub

”定义一个函数
Public Function yyh(a,b)
yyh=a+b
End Function

”定义一个方法
Public sub yyh1(stat)
Response.write stat
End Sub

End Class

Set myyyh=New yh ”定义一个名为yh的myyyh对象实例
response.write myyyh.yyh(6,6)&"<br>"
mystring="这是天涯风云方法"
myyyh.yyh1 mystring

%>

这是很简单的一个程序,我们在其中声明了一个名为yh的类,建立了一个yyh函数,一个yyh1方法,这个程序很简单相信大家能看懂,它的显示如下:

12
这是天涯风云的方法

可以把我们常用到的程序写成一个类,到时候就用<!–#include file="yyh.asp"–>来包含进来就行了,这给我们开发程序又提供了新的空间.

类的定义2

这里采用类的属性定义方法。

<%
”声明一个名为myclass的类
Class myclass

Private a1,b1

”类的初始化
Private Sub Class_Initialize
a1=0
b1=0
End Sub

”定义一个属性
Public Property Let width(ax)
a1=ax
End Property

”定义另个一个属性
Public Property Let height(bx)
b1=bx
End Property

”计算两个属性值的结果,得到一个新的属性
Public Property Get area
area=b1*a1
End Property

End Class

Set tianya=New myclass ”定义一个名为tianya的对象myclass的实例
tianya.width=50
tianya.height=60
response.write tianya.area
%>

一个完全数据库管理的asp类模型

‘天涯风云原创

先建一个数据库user,有一个表名为user,
表里有三个字段,分别为id,name,content

先写数据库连接文件:
‘conn.asp

<%
StrSQL="DBQ="+server.mappath("user.mdb")+";DRIVER={Microsoft Access Driver (*.mdb)};"
Set conn=server.createobject("ADODB.CONNECTION")
Conn.open StrSQL
%>

构造userclass类:
,mycls.asp
<%
Class userclass
Private id,name,content

Private Sub Class_Initialize()     ‘类的初始化,连接数据库
username=""
usercontent=""
end sub

‘以下设置类的几个属性
Public Property Let userid(vNewvalue)
id=Cint(vNewvalue)
End Property

Public Property Get userid
userid=id
End Property

Public Property Let username(vNewvalue)
name=vNewvalue
End Property

Public Property Get username
username=name
End Property

Public Property Let usercontent(vNewvalue)
content=vNewvalue
End Property

Public Property Get usercontent
usercontent=content
End Property

‘添加记录
Public sub adduser()
if username <> "" and usercontent <> "" then
Set rs = Server.Createobject("adodb.Recordset")
SQL="Select * From user"
rs.Open SQL,Conn,1,3
rs.AddNew
rs("name") = username
rs("Content") = usercontent
rs.Update
rs.Close
Set rs = Nothing
Response.write "添加记录成功!"
end if
end sub

‘显示一条记录
Public sub showuser()
set rs=server.createobject("adodb.recordset")
sql="select * from user where id=" & userid
rs.open sql,conn,1,3
username=rs("name")
usercontent=rs("content")
rs.close
end sub

‘编辑记录
Public sub edit()
set rs=server.createobject("adodb.recordset")
sql="select * from user where id=" & userid
rs.open sql,conn,1,1
username=rs("name")
usercontent=rs("content")
rs.close
end sub

‘保存编辑
Public sub saveedit()
set rs=server.createobject("adodb.recordset")
sql="select * from user where id =" & userid
rs.open sql,conn,1,3
rs("name")=username
rs("content")=usercontent
rs.update
rs.close
Response.write "更新记录成功!"
end sub

‘删除记录
public sub deluser()
set rs=server.createobject("adodb.recordset")
sql="delete from user where id="& userid
rs.open sql,conn,1,1
set rs=nothing
Response.write "删除记录成功!"
end sub

‘挑战分页显示~~!!
public sub list(n)
dim page
page=request("page")
PageSize = n
dim rs,strSQL,news
strSQL ="Select * FROM user orDER BY id DESC"

Set rs = Server.CreateObject("ADODB.Recordset")
rs.open strSQL,Conn,3,3
rs.PageSize = PageSize
totalfilm=rs.recordcount
pgnum=rs.Pagecount
if page="" or clng(page)<1 then page=1
if clng(page) > pgnum then page=pgnum
if pgnum>0 then rs.AbsolutePage=page

if rs.eof then
response.write "<font color=’#003366′ class=’3dfont’>没有记录!</font>"
else
count=0
do while not (rs.eof or rs.bof) and count<rs.PageSize
with response
.write "<table><tr><td> "
.write  rs("id")&" "
.write "<a href=show.asp?id="&rs("id")&">"
.write rs("name")
.write "</a>  "
.write "内容: "&rs("content")
.write "</td></tr></table>"
end with
rs.movenext
count=count+1
loop
end if
with response
.write "<table><tr><td> 共<b>"
.write rs.pagecount
.write "</b>页"
for i=1 to rs.pagecount
.write " <a href=list.asp?page="&i&">"
.write i
.write "</a>"
next
rs.close
set rs=nothing
.write "</td></tr></table>"
end with
end sub

‘类退出后,作清理工作
Private Sub class_terminate()
If IsObject(Conn) Then Conn.Close:Set Conn = Nothing
End Sub
End Class
%>
(以上程序在winxpsp2+netbox通过)

日志文件分析工具—AWStats在IIS中的配置

AWStats是sourceforge.net上很有名的Web/Mail/FTP服务器日志文件分析工具,可以运行在windows系统上分析IIS日志文件,本文讲的是AWStats在windows下的安装及配置。

运行环境说明:

操作系统Microsoft Windows Server 2003 SP2简体中文企业版
Web服务器IIS 6.0
Perl:ActivePerl 5.8.8.820
AWStats 6.7

一、IIS配置

1.启用IIS日志记录:打开windows运行对话框(Windows+R),输入inetmgr,打开Internet 信息服务(IIS)管理器控制台界面,在控制台左边“网站”项目上点击鼠标右键,打开“网站属性”设置窗口,在“网站”标签中,将“启用日志记录”前的复选框选中,再点击“应用”按钮,使设置生效。

2.日志格式设置:活动日志格式选择“W3C扩展日志文件格式,再点击“属性”按钮,进入日志记录属性配置界面,新日志计划选择“每天”,勾选“文件名和创建使用当地时间”,日志文件目录默认为C:\WINDOWS\system32\LogFiles,由于Web服务器的长期运行会使日志文件会变得非常大,因此建议不要将日志文件存放在默认的目录中,应该保存到特定的目录中,确保磁盘空间充足,并做好备份和维护工作,如果您不在意以前的数据丢失与否或者您仅仅是在本机做测试,就没必要更改默认目录了,在本项目中,日志文件保存路径设定为:D:\site\LogFiles\,在设置了日志文件目录后,日志文件其实并不是直接保存在该目录下,系统会在设定的目录中根据需要建立不同的子目录,分别保存不同的日志文件,在下图中,日志文件名:W3SVCX\exyymmdd.log是站点的日志的实际存储路径。其中W3SVCX中的X表示不同的WEB站点的标识符,为数字,组合后目录名称为W3SVC1,W3SVC2等,文件名为字母ex加上年月日。实际日志文件名例如:W3SVC1\ex070712.log。

3.日志记录属性高级设置:在设置了新日志计划以及日志文件命名规则以后,还需要对日志文件包含的内容进行配置,选择“高级”标签,进入“扩展日志选项”的界面。 勾选以下12个项目,项目必须完全一致。

  • date(日期)
  • time(时间)
  • c-ip(客户端IP地址)
  • cs-username(用户名)
  • cs-method(方法)
  • cs-uri-stem(URI资源)
  • cs-uri-query(URI查询)
  • sc-status(协议状态)
  • sc-bytes(发送的字节数)
  • cs-version(协议版本)
  • cs(User-Agent)(用户代理)
  • cs(Refer)(引用站点)

4.应用配置方案:您可以对服务器上的所有站点进行相同的配置,也可以分别对每个站点进行不同的配置!停止IIS,删除原有的日志文件,然后启动IIS,并访问一次站点,即可生成新格式下的IIS日志记录文件。

二、 Perl语言运行环境

AWStats软件是使用动态语言Perl开发的应用程序,因此服务器上必须具有Perl运行环境,我们这里使用ActivePerl 5.8.x软件,它的安装配置比较简单。

1.下载软件:

2.安装ActivePerl :

  • 安装用户必须是Administrators组的用户,否则安装不能成功或者不完整,导致软件不能正常运行。
  • Perl环境变量:如果已经存在PERLLIB, PERL5LIB 或者 PERL5OPT这几个环境变量,必须在安装ActivePerl之前使它们无效,否则这些变量会在安装处理过程中导致Perl模块的版本不兼容问题。
  • 在安装ActivePerl之前,请先停止Web服务器,安装完毕以后再启动WEB服务器。
  • MSI安装包:双击安装文件,直接进行安装。ZIP安装包,直接拷贝到想要放置的目录。如果已经安装过其他版本,请首先卸载,然后再安装新版本。不要直接在以前版本上安装。 本方案中将ActivePerl安装到C:\Perl目录下。

3.配置:

  • 启用Perl服务扩展:安装ActivePerl以后,还需要配置WEB服务扩展,使得IIS能够支持perl脚本,打开IIS, 选择左边窗口目录树中的“Web 服务扩展”项,则右边窗口中显示出系统已经安装的服务扩展及状态(默认多为禁止),对于ActivePerl 5.8.x在Windows Server 2003上的默认安装,我们可以看到以下两个项目: Perl CGI Extension 禁止、Perl ISAPI Extension 禁止。默认情况下它们处于禁止状态,需要将它们的状态改变为“允许”,请分别选择这两个服务扩展,点击“允许”按钮,启用它们,使得perl脚本程序可以被IIS执行。
  • 添加Perl服务扩展:如果没有以上两项服务扩展(使用ZIP包安装或者安装其他版本的ActivePerl),那么我们需要手工添加这两项配置信息。 选择管理控制台左边窗口上的“Web 服务扩展”,点击鼠标右键,选择“添加一个新的Web服务扩展(A)…”,在“扩展名”中输入一个完整说明名称(不是文件的扩展名),例如:Perl CGI Extension,点击“添加”按钮,在“文件路径”中输入进行扩展处理的文件的完整路径以及参数,例如:C:\Perl\bin\Perl.exe  "%s"  %s ,并勾选“设置扩展状态为允许”
  • 配置IIS脚本程序映射:ActivePerl安装完毕以后,应该会在IIS主目录配置中添加脚本程序映射,如果没有,那么在你希望配置Perl脚本的虚拟目录、应用程序或网站上点击鼠标右键,选择“属性”,打开网站属性界面,选择“主目录”标签,点击“配置”按钮,(如果配置按钮不可用,点击创建按钮,创建一个默认的配置方案),进行应用程序配置。如果在应用程序扩展列表中,没有发现.pl的扩展名项,那么点击“添加”按钮,进行应用程序扩展名映射。在“可执行文件”中输入和前面添加Web服务扩展中相同的命令行C:\Perl\bin\Perl.exe  "%s"  %s ,在“扩展名”中输入.pl,在“动作”中输入:GET,HEAD,POST

 

三、  AWStats的安装与配置

1、下载AWStats

2.安装AWStats

  • 文件安装在D:\AWStats
  • 安装目录说明:
    • x:\aswtats\docs软件的相关文档)
    • x:\aswtats\tools(软件的相关工具)
    • x:\aswtats\wwwroot(Web日志分析统计程序及相关文件)
    • x:\aswtats\wwwroot\cgi-bin(分析结果主显示程序 )
    • x:\aswtats\wwwroot\classes(软件的相关类文件)
    • x:\aswtats\wwwroot\css(样式表)
    • x:\aswtats\wwwroot\icon(该软件所用图片)
    • x:\aswtats\wwwroot\js(javascript脚本)

3、IIS相关配置

  • 映射虚拟目录AWStats:在AWSTATS 软件安装以后,需要将主程序所在的路径wwwroot 映射成网站的一个虚拟目录,当然,也可以将该目录下的所有子目录复制到你的网站中,但是这样对于管理很不方便,而且权限设置也存在安全问题,因此,我们选择将wwwroot映射成虚拟目录。启动“Internet 信息服务管理器”,选择你的网站,如“默认网站”,右键,“新建虚拟目录”,虚拟目录名称我们命名为AWStats,路径为安装程序所在的路径,如 x:\awstats\wwwroot。
  • 虚拟目录相关属性设置:虚拟目录建立完毕以后,还需要对虚拟目录的属性进行设置。选择建立的虚拟目录,点击鼠标右键,选择“属性”,将“记录访问”、“索引资源”前的复选框选项去掉,表示对于该虚拟目录的访问不记录进访问日志中,并且全文索引不对该虚拟目录进行索引。 将“执行权限”选择为“脚本和可执行文件”,该选项必须如此,否则不能显示统计信息。

4.AWStats运行配置

  • 创建网站的AWStats配置信息:网站配置文件存放在x:\AWStats\wwwroot\cgi-bin\目录下,默认文件名称为:awstats.model.conf,我们将它复制成一个新配置文件:awstats.myvirtualhostname.conf,其中myvirtualhostname是网站的域名或者IP,因此,我们创建了配置文件:awstats.www.mysite.com.cn.conf
  • 编辑配置文件中相应配置信息:
    • LogType:日志文件的类型,W—web日志、M—email日志、F—FTP日志。LogType=W
    • LogFile:日志文件存储的路径或位置,以及文件名,在前面我们进行IIS配置时,将日志文件存储在D:\site\LogFiles目录下,我们查看得到MYSITE网站的标识为W3SVC1(不同的安装会导致此标识不同,因此需要根据实际查看得到),日志文件命名为exYYMMDD.log。LogFile="D:\site\LogFiles\W3SVC1\ex%YY-0%MM-0%DD-0.log"
    • LogFormat:日志文件的格式,它必须与log文件中的格式完全一致(查看log文件中的#Fields字段),栏目多少与顺序也必须一致,因此,IIS日志记录格式必须按照前面介绍的配置进行。LogFormat="date time cs-method cs-uri-stem cs-uri-query cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-bytes"
    • DirData由于网站访问的日志有可能极大,每次统计可能需要耗时几小时,因此统计信息不是即时的,而是以天为单位,因此分析得到的统计数据需要存放到专用的数据文件中。注意,必须首先手工建立该数据存放目录。DirData="D:\AWStats\wwwroot\cgi-bin\data"
    • CreateDirDataIfNotExists:如果分析结果数据保存路径不存在,是否创建该路径,1表示立即创建。CreateDirDataIfNotExists=0
    • DirIcons:AWStats需要使用的图片文件的存储路径,由于我们将x:\awstats\wwwroot设置为虚拟路径,因此,在此处
      DirIcons="../icon"
    • SiteDomain:网站完整域名,SiteDomain="www.mysite.com.cn"
    • AllowFullYearView:是否运行以年为单位分析日志。AWStats默认是以月为单位分析日志数据,如果需要以年为单位进行查看分析,需要按照下面设置。AllowFullYearView=3
    • DefaultFile:网站主页名称。DefaultFile="index.asp"
    • Lang: 网站分析统计结果界面的语言,cn表示中文。Lang="cn"
    • NotPageList:NotPageList="css js class gif jpg jpeg png bmp ico swf zip pdf xml htc"
  • 插件安装以及设置:
    • Plugin: TimeZone:由于采用W3C标准格式记录日志,日期时间记录的是格林威治时间,因此需要根据时区进行调整,否则得到的统计结果就是错误的。 该插件的配置在网站配置文件中(与上面的参数配置相同)。LoadPlugin="timezone +8"
    • IP地址插件:如果需要对访问用户的IP地址进行分析,需要使用IP地址插件,安装该插件以后,可以按照国家进行统计,它的安装稍微复杂一些。 我们使用GeoIPfree插件,首先在配置文件中打开该插件。 LoadPlugin="geoipfree"
    • 下载GeoIPfree软件:该软件为免费软件, 网址为:http://search.cpan.org/~gmpassos/Geo-IPfree-0.2/,文件为:Geo-IPfree-0.2.tar.gz
    • 安装配置GeoIPfree软件:首先使用winzip等解压缩该软件,再进行软件的编译链接,在命令行执行:perl makefile.pl,再将lib目录下的geo目录复制到Perl的库文件目录中或者AWStats的插件目录中。其中Perl的库目录为x:\Perl\lib ,AWStats插件目录为x:\AWStats\wwwroot\cgi-bin\plugins。
  • 初始化统计信息:
    • 在以上配置信息以及插件都安装完毕以后,首次运行之前的需要手工在命令行进行统计信息初始化工作。
    • 在命令行,切换目录到x:\awstats\wwwroot\cgi-bin,运行 (如果pl没有与perl解释程序相关联,请加上x:\Perl\bin\perl.exe )awstats.pl –config=www.mysite.com.cn –update
    • 按照awstats.www.mysite.com.cn.conf网站配置信息进行初次统计分析,它会使用前一天的日志文件进行分析,如果日志文件数据量很大,分析可能持续几小时。
    • 每日定时执行统计分析:AWStats是以天为单位进行统计分析的,统计分析需要用户执行,因此我们需要使用操作系统的计划任务使它每日定时进行,定时时间为每日00:05。 首先在x:\awstats\wwwroot\cgi-bin目录中创建批处理文件update.bat,文件内容为:Perl.exe awstats.pl –config=www.mysite.com.cn –update
    • 如果有多个网站的日志需要进行统计分析,那么创建一个全部更新的命令更加方便。在x:\awstats\tools目录下,创建一个批处理文件updateall.bat,文件内容为:Perl.exe awstats_updateall.pl now -awstatsprog=../wwwroot/cgi-bin/awstats.pl -configdir=../wwwroot/cgi-bin
    • 在Windows Server 2003命令行中创建计划任务:schtasks /create /tn "AWStats Update Statistics" /tr d:\awstats\wwwroot\cgi-bin\update.bat /sc daily /st 00:05或者schtasks /create /tn "AWStats UpdateAll Statistics" /tr d:\awstats\tools\updateall.bat /sc daily /st 00:05或者或者使用计划任务向导创建计划,每日00:05分执行批处理程序,更新统计信息,注意在执行计划任务时需要指定运行该计划的用户和密码,最好为该任务创建一个专用用户帐号,并为适当的目录指定相应的权限。
  • 查看统计信息:AWStats的日志统计分析信息以Web方式提供给用户,查看方式为:http://www.mysite.com.cn/awstats/cgi-bin/awstats.pl?config=www.mysite.com.cn

PHP生成动态WAP页面

  WAP(无线通讯协议)是在数字移动电话、个人手持设备(PDA等)及计算机之间进行通讯的开放性全球标准。由于静态的WAP页面在很多方面不能满足用户个性化的服务请求,因此通过WAP服务器端语言产生动态的WML页面,具有很广泛的应用价值和很高的商业价值。
  WAP应用结构非常类似于Internet,一个典型的WAP应用请求是这样的:首先,具有WAP用户代理功能的移动终端(WAP手机等)通过内部运行的微浏览器(Micro Browser)对某一网站以无线方式发送WAP服务请求。该请求先由WAP网关截获,对信息内容进行编码压缩,以减少网络数据流量,同时根据需要将WAP协议转换成HTTP协议,然后将处理后的请求转送到相应WAP服务器。在WAP服务器端,根据页面扩展名等性质,被请求的页面直接或由服务器端脚本解释后输出,再经网关传回用户。
  从上述WAP应用流程可以看到,生成动态WAP页面与动态产生Web网页的过程非常类似。但是由于WAP应用使用的WML语言来源于语法严格的XML,因此要求输出的格式必须按WAP网页的规范输出。同时,由于WAP协议的应用范围、移动客户端的软硬件水平等特殊性,对每次输出的页面的大小、图像的格式及容量都有一定限制。下面我们以PHP脚本语言为例,看看如何动态输出WAP页面。
  一、设置WEB服务器

  首先你的 Web服务器要安装好PHP,即能处理PHP脚本程序。其次,为使Web服务器能同时识别和处理PHP、WML、WBMP等文件,Web 服务器的MIME表需添加以下的几种文件类型。

  text/vnd.wap.wml .wml 
  image/vnd.wap.wbmp .wbmp 
  application/vnd.wap.wmlc .wmlc 
  text/vnd.wap.wmls.wmls
  application/vnd.wap.wmlsc .wmlsc 

  二、用PHP输出简单动态WAP页面 

  下面有一个最简单的PHP生成WAP页面的例子。注意由于需要PHP解释器来解释该程序,并输出WAP页面,因此所有类似程序应以.php为扩展名。

  <?php
  header(″Content-type: text/vnd.wap.wml″);
  echo (″<wml> <card> <p>″);
  echo date( ″l dS of F Y h:i:s A″ ); 
  echo (″</p></card></wml>″);
  ?> 

  该例子在WAP手机模拟器中可以浏览,输出当前日期时间,而在普通的浏览器中无法识别,甚至会被认为是错误下载。这是因为在程序开头就声明了该输出文档为WML类型,该类型只有WAP设备能够识别并解释。值得注意的是,我们常见的HTML语言对规范性要求不严,大多数浏览器能“容忍”其中相当多的编写错误,而WML规范相当严格,一点失误都可能导致无法输出所需页面。

  一旦我们知道了用PHP脚本输出WAP页面的标准过程,我们就能够使用PHP强大的功能配合以WML语言的交互处理以及WML Script的简单脚本,开发出适合我们需要的应用系统了。

   三、用PHP动态生成图像 

  WAP应用使用一种特殊黑白的图像格式WBMP。我们可以用一些工具来将已有图像转换成WBMP格式,然后在WML文档中使用。但是在WAP站点上如果能动态地生成所需图像如K线图等,将会有广阔的应用前景。幸运的是,PHP的GD库(版本1.8以上)已经提供了相应函数。

  <?PHP
  Header(″Content-type: image/vnd.wap.wbmp″);
  Sim = ImageCreate(50, 50);
  Swhite = ImageColorAllocate(Sim,255,255,255);
  Sblack = ImageColorAllocate(Sim,0,0,0);
  ImageRectangle(Sim, 5, 5, 20, 20, Sblack);
  ImageWBMP(Sim);   ImageDestroy(Sim);
  ?>

  该文件将在WAP模拟器中显示一个黑色矩形框。注意要使用GD的图像函数库,必须在PHP配置中加载PHP_GD.DLL库文件。

  四、在PHP中处理汉字

  WAP作为一种全球应用,选择了UNICODE 2.0作为其标准字符集编码,以便能同时处理包括英文、中文、日文、法文等多种文字。而我们平常处理汉字使用的是GB2312编码,不同的内码标准势必不能通用,因此如果不在两种编码之间通过码表进行转换,就会出现汉字乱码现象。现在已经有较成熟的GB-2312与UNICODE编码转换的程序和函数,并在ASP、PHP、JSP等系统中使用,我们可以在一些技术站点上找到它们。

  目前的大多数WAP手机(Nokia7110、爱立信R320S等等)都是使用UTF-8编码的,也就是采用UNICODE来编码。这样,如果我们直接在WML使用中文字符(GB2312编码),将会产生乱码,手机用户无法识别,所以我们在输出中文之前,要使用程序或函数对中文进行UNICODE的编码。而在少数支持GB2312编码的手机或WAP终端设备中,我们可以在程序中定义好文档的内码类型后即可直接正确显示汉字,例如:

  <?php 
  header(″Content-type: text/vnd.wap.wml; charset=gb2312″);
  echo (″<wml><card><p>″);
  echo (″中文测试″);
  echo (″</p></card></wml>″);
  ?> 

Apache+php+Mysql在windows下的安装步骤

Win2000+Apache+php+mysql安装笔记

RTDT

安装环境:Win2000 server SP4

关闭了IIS服务器

准备工作:所需软件下载

apache_2.0.52-Win32

php-5.0.2-Win32

mysql-4.0.22-win-noinstall

phpMyAdmin-2.5.7

如果网速超快,大概几分钟就搞定了下载,ok,闲话少讲,开工。

第一, Apache的安装

由于我下载的是apache安装版的,所以就非常简单,有非常友好的安装界面,三下五除二,很容易就安装成功了,我安装在c:\webser\apache目录下面的(为了便于管理,我把所有的软件都安装在webser目录下面),这里对于apache的安装就不在详细叙述了,呵呵。如果你看见一张apache的图片,就说明你的apache安装成功了。

 第二, PHP的安装

下载回来的php文件是一个压缩包,直接解压到c:\webser\php\目录下面就ok了,

下面,要稍微的对php进行设置一下:

1, 将php.ini-dist 重命名为 php.ini 并拷贝到c:\winnt目录里

2, 将php目录里的 php5ts.dll和libmysql.dll 拷贝系统目录(c:\winnt\system32)

第三, 配置apache使其支持php

打开apache配置文件httpd.conf

配置如下:

1, 在DirectoryIndex后面添加上 index.php

2, 在LoadModule后面添加上:

LoadModule php5_module c:\webser\php\php5apache2.dll

3, 在AddType和面添加上:

AddType application/x-httpd-php .php

备注:我采用的模块化来配置php,当然,你也可以采用CGI的方式来配置,如果你采用CGI方式,可以参考一下其它文档,呵呵

配置工作就是这么多了,好了,写一个php测试程序,看看行不行,代码如下:

<?
phpinfo();
?>

如果出现一个显示当前配置的画面,恭喜你,配置成功,如果没有出现这幅图片,也不要灰心,仔细看看前面的内容,看是不是有些细节问题没有搞定。

如何使你的Apache服务器支持SSI?

Apache默认是不支持SSI的,需要我们更改httpd.conf来进行配置。我这里以windows平台的Apache 2.0.x为例,打开conf目录下的httpd.conf文件,搜索“AddType text/html .shtml”,搜索结果:

# AddType text/html .shtml
# AddOutputFilter INCLUDES .shtml

把这两行前面的#去掉。

然后搜索“Options Indexes FollowSymLinks”
在搜索到的那一行后面添加“ Includes”
即将该行改变为 Options Indexes FollowSymLinks Includes

保存httpd.conf,重起apache即可。

到此我们就完成了对Apache SSI的设置。

第四, 安装mysql

Mysql也是直接加压安装到c:\webser\mysql就ok了,

设置如下:

打开c:\webser\mysql\bin(也就是mysql的bin目录)

点击winmysqladmin.exe这个文件,这相当于是一个监视mysql运行状况的小程序,第一次使用时,会提示你输入用户名和密码,随便设定一个(这个不是mysql的用户名和密码),然后任务栏上会出现三个"交通灯"标志,点击这个图标,启动mysql服务。

在cmd模式下进入c:\webser\mysql\bin,执行如下命令:

mysqladmin -u root -p password rtdtblog

来创建一个root用户,按回车后,会出现:

Enter Password:

这是叫你输入原来的密码.。刚安装时密码为空,所以直接回车即可,以后就不一样了哦,呵呵

Ok,这样,在mysql里面就创建了一个名为root,密码为rtdtblog的用户

第五, 配置php.int文件,使其支持mysql

打开c:\winnt\php.int,

找到extension_dir,将路径更改为:extension_dir="c:\webser\php\ext"

找到extension=php_mysql.dll 去掉前面的前面的";"号

找到session.save_path,更改为session.save_path="c:\webser\php\session_tmp";

Ok,配置内容就是这些,这时候,你需要重启一下apache,然后建立一个测试数据库连接的页面,内容如下:

 <?php
$link=mysql_connect(’localhost’,’root’,’rtdtblog’);

if(!$link) echo "不好意思,连接数据库有点问题哦,不要灰心,继续努力";

else echo "恭喜恭喜,你小子连接数据库成功";

mysql_close();

?>

如果你的设置是正确的,会出现第二行文字。如果一不小心,你的出现第一行文字,不要担心,仔细检查一下,再次,多试几遍,就知道是怎么回事了,呵呵,我就从这样一遍一遍的失败中过来的,哈哈哈哈

说句实在的,安装到这里基本上算是完工了,要收工也可以了,呵呵,如果你还想知道phpMyadmini的安装,继续看下面

第六, phpMyAdmin的安装

phpMyAdmin是一款超强的基于php的管理mysql数据库的软件,非常有用,安装也很方便,解压到你设置的web目录里面,我这里采用的是默认的目录,apache下面的htdocs目录(c:\webser\apache\apache2\htdocs),解压完成后,需要进行简单的设置,

打开config.inc.php文件,修改下面这些内容:

$cfg[’Servers’][$i][’user’] = ’root’; // MySQL user

$cfg[’Servers’][$i][’password’] = ’rtdtblog’; // MySQL password

Ok,一切正常的话,打开浏览器,输入正确的路径,就可以打开phpMyAdmin的控制界面了,

以上就是我自己安装apache+php+mysql的详细过程,这个也是最基本的安装过程,呵呵,网上其他一些文章在讲解类似的安装时,设置的内容太多了,其实对于我等初学者来讲,很多都不必要,因为设置了也不明白什么意思,哈哈(个人意见,仅供参考)。