2004年08月31日

在Oracle9i之前,仅有的两个CBO模式是ALL_ROWS以及FIRST_ROWS。传统的FIRST_ROWS SQL最优化的缺点之一是,它的运算法则并没有特别指定行检索的范围。

但是,在Oracle9i中包含了几个新的最优化指令:

  • FIRST_ROWS_1
  • FIRST_ROWS_10
  • FIRST_ROWS_100
  • FIRST_ROWS_1000

FIRST_ROWS_n最优化会指示选择一个查询执行计划,这个计划会缩短生成最初n行查询结果的时间。

你可以把这个新的CBO模式设置到数据库中的几个层次上:systemwide,在会话层或者在查询层次上。


alter system set optimizer_mode=first_rows_100;
alter session set optimizer_mode = first_rows_100;
select /*+ first_rows(100) */ from student;

根据来自Oracle公司的说法,使用FIRST_ROWS_n最优化,Oracle查询能够使用最少的反应时间来给出最初的n行结果。更快速的给出最初n行的结果能够提高用户对应用软件的满意程度的原因是由于用户能够更为快速的得到最初的那些数据。

当使用FIRST_ROWS最优化索引的时候,ALL_ROWS最优化支持完整表的搜寻。但是,Oracle通过FIRST_ROWS_n最优化扩展了这个概念的范畴。

在传统的FIRST_ROWS最优化中,Oracle CBO支持索引扫描,甚至当全部成本高于完整表扫描的时候也是如此。在对于完整表扫描不太昂贵的较小型表的情况下,这种情况也是尤为明显。

请看一看下面的这个例子。


Set autotrace on explain
alter session set optimizer_goal = choose;
select * from emp where sal < 1200;
PLAN —————————————————–
SELECT STATEMENT (OPTIMIZER=CHOOSE) (COST=62) (ROWS=99)
TABLE ACCESS FULL EMP (COST=62) (ROWS=99)

现在,我们要使用FIRST_ROWS最优化来进行相同的查询工作。


alter session set optimizer_goal = first_rows;
select * from emp where sal < 1200;
The explain plan is now transformed to:
PLAN —————————————————–
SELECT STATEMENT (OPTIMIZER=FIRST_ROWS) (COST=102)
TABLE ACCESS BY INDEX ROWID EMP (COST=102) (ROWS=99)
INDEX RANGE SCAN SA L_IDX (COST=2) (ROWS=99)

我们希望CBO能够对索引进行支持,但是我们还是非常惊奇的看到选择了一种比完整表扫描更为昂贵的方式。这是一个临界点。在Oracle9i之前,FIRST_ROWS最优化是一种对内部规则和费用的一种综合,而且Oracle9i FIRST_ROWS最优化也是完全基于成本的。

在Oracle9i之前,我们使用OPTIMIZER_INDEX_COST_ADJ参数来控制CBO选择索引。

虽然Oracle公司声称FIRST_ROWS_n最优化能够让查询变得更加快速,但是要记住, Oracle9i CBO所负责的是最初那些行的查询访问的成本。换一种说法,所有的FIRST_ROWS_n模式所做的就是决定出更为明智的选择,决定是使用索引还是使用完整表扫描来进行对小型表的访问。由于多数的Oracle9i DBA会把这些小型表存储于KEEP池中,因此该参数使用的范围并不广。

  实现Web应用程序的安全机制是Web应用程序的设计人员和编程人员必须面对的任务。在J2EE中,Web容器支持应用程序内置的安全机制。

  Web应用程序的安全机制有二种组件:认证和授权。基于J2EE的Web容器提供三种类型的认证机制:基本认证、基于表单的认证、相互认证。由于能够对认证用户界面进行定制,大多数的Web应用程序都使用基于表单的认证。Web容器使用在Web应用程序的部署描述符中定义的安全角色对应用程序的Web资源的访问进行授权。

  在使用基于表单的认证机制中,应用程序的设计人员和开发人员会遇到3类问题:

  ·基于表单的认证如何与数据库和LDAP等其他领域的安全机制协同工作。(这是非常必要的,因为许多组织已经在数据库和LDAP表单中实现了认证机制。)

  ·如何在Web应用程序的部署描述符(web.xml)中增加或删除军政府的授权角色。

  ·Web容器在Web资源层次上进行授权;应用程序则需要在单一的Web资源中执行功能层次上的授权。

  尽管有许多与基于表单的认证有关的文档和例子,但都没有能够阐明这一问题。因此,大多数的应用程序都以自己的方式襀安全机制。

  本篇文章说明了基于表单的认证如何与其他方面的安全机制,尤其是数据库中的安全机制协作的问题。它还解释了Web窗口如何使用安全角色执行授权以及应用程序如何扩展这些安全角色,保护Web资源中的功能。

  基于表单的认证

  基于表单的认证能够使开发人员定制认证的用户界面。web.xml的login-config小节定义了认证机制的类型、登录的URI和错误页面。
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>
  登录表单必须包含输入用户姓名和口令的字段,它们必须被分别命名为j_username和j_password,表单将这二个值发送给j_security_check逻辑名字。

  下面是一个该表单如何在HTML网页中实现的例子:

<form method=”POST” action=”j_security_check”>
<input type=”text” name=”j_username”>
<input type=”password” name=”j_password”>
</form>
  除非所有的连接都是在SSL上实现的,该表单能够透露用户名和口令。当受保护的Web资源被访问时,Web容器就会激活为该资源配置的认证机制。

  为了实现Web应用程序的安全,Web容器执行下面的步骤:

  1、在受保护的Web资源被访问时,判断用户是否被认证。

  2、如果用户没有得到认证,则通过重定向到部署描述符中定义的注册页面,要求用户提供安全信任状。

  3、根据为该容器配置的安全领域,确认用户的信任状有效。

  4、判断得到认证的用户是否被授权访问部署描述符(web.xml)中定义的Web资源。

  象基本的安全认证机制那样,在Web应用程序的部署描述符中,基于表单的认证不指定安全区域。也就是说,它不明确地定义用来认证用户的安全区域类型,这就会在它使用什么样的安全区域认证用户方面引起混淆。

  要对用户进行验证,Web窗口需要完成下面的步骤:

  1、判断该容器配置的安全区域。

  2、使用该安全区域进行认证。

  由于数据库和LDAP在维护信息方面提供了更大的灵活性,因此大多数组织都会希望继续使用它们维护安全认证和授权信息。

  许多Web窗口都支持不同类型的安全区域:数据库、LDAP和定制区域。例如,在Tomcat Web容器中,server.xml将数据库配置为其安全区域。
<Realm className=”org.apache.catalina.realm.JDBCRealm” debug=”99″ driverName=”oracle.jdbc.driver.OracleDriver” connectionURL=”jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}” connectionName=”{DB Username}” connectionPassword=”{Password}” userTable=”users” userNameCol=”username” userCredCol=”password” userRoleTable=”user_roles” roleNameCol=”rolename” />
  Tomcat的server.xml的<Realm>标志定义了窗口用来识别一个用户的安全区域的类型。注意,容器对Web应用程序使用该区域,应用程序的认证机制是基于表单的。
  授权

  一旦用户被识别后,容器就会得到认证用户的安全角色,看用户是否属于在部署描述符中的<auth-constraint>标志中定义的安全角色之一。如果用户不属于任何一个安全角色,则容器会返回一个错误。
部署描述符(web.xml)的<security-constraint>标志定义了被保护的Web资源和能够访问这些资源的安全角色清单。
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPages</web-resource-name>
<description> accessible by authorised users </description>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>These are the roles who have access</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
  Web窗口在网页层次上执行认证。然而,商业性应用程序可能还希望对一个网页内的功能进行认证,这会要求在应用程序中定义一些新的附加的与应用程序有关的安全角色。为了控制对功能的访问,应用程序需要理解角色的权限概念。Web容器标准没有解决权限的问题。

  由于授权角色是动态的,开发人员常常会感到迷惑,即这些安全角色是否需要添加到部署描述符中。为了使应用程序充分利用安全支持,Web容器只需要在部署描述符中定义的一个角色。因此,应用程序可以定义一个高层次的角色,然后将所有的用户都指派给该角色。这将使该角色中的所有用户都拥有能够访问Web资源的权限。

  另外,应用程序还可以定义额外的角色,执行对一种Web资源中较低层次的功能的授权。由于应用程序已经配置有一个包含应用程序中所有用户的高层次安全角色,这些低层次的安全角色也就不需要在部署描述符中进行定义。这使得Web应用程序能够利用容器的授权支持,实现与指定应用程序有关的授权。

  我们可以在部署描述符中为所有用户定义一个高层次的管理员角色,保护管理类Web资源,这使得管理员角色中的所有用户都能够访问管理网页。为了控制管理网页中的其他功能,我们可以在应用程序中创建 sysadmin或appadmin等新的角色。

  应用程序可以对这些安全角色进行扩展,使它们拥有一定的权限。然后,应用程序可以使用这些权限来控制对其功能的访问。

  尽管与特定应用程序相关的安全角色不是定义在部署描述符中的,这些角色仍然可以在isUserInRole方法中使用,判断用户是否在这些安全角色中。

  优点

  ·Web应用程序无需实现认证机制,简化Web应用程序的配置。

  ·Web应用程序能够使用getRemoteUser、IsUserInRole和getUserPrincipal方法实现有规划的安全。

  ·Web应用程序能够将认证信息传播给EJB容器。

  在Tomcat中配置数据库安全区域

  1、创建用户表。

  该数据库表需要有username和password二个字段。

create table users (username varchar(20) not null, password(20) not null)

  2、创建角色表

  该表维护着应用程序中角色的清单,它仅仅有rolename一个字段。

create table roles (rolename varchar(20) not null)

  3、创建用户-角色关联表

  该表维护着一个用户和各个角色之间的关联,一个用户可以属于一个或多个角色。

create table user_roles (username varchar(20) not null, rolename varchar(20) not null)

  4、在表中插入数据

insert into users values(‘user1′, ‘password’)

insert into role values(‘manager’)
insert into user_roles values(‘user1′, ‘manager’)

  5、创建用户表。

  该数据库表需要有username和password二个字段。

create table users (username varchar(20) not null, password(20) not null)

  6、创建角色表

  该表维护着应用程序中角色的清单,它仅仅有rolename一个字段。

create table roles (rolename varchar(20) not null)

  7、创建用户-角色关联表

  该表维护着一个用户和各个角色之间的关联,一个用户可以属于一个或多个角色。

create table user_roles (username varchar(20) not null, rolename varchar(20) not null)

  8、在表中插入数据

insert into users values(‘user1′, ‘password’)

insert into role values(‘manager’)

insert into user_roles values(‘user1′, ‘manager’)

  9、通过将下面的信息拷贝到{tomcat}\conf\文件夹的server.xml文件中,配置Tomcat。(本例使用了薄客户端驱动程序,Tomcat使用内存区域作为缺省的安全区域。)
<Realm
className=”org.apache.catalina.realm.JDBCRealm”
debug=”99″
driverName=”oracle.jdbc.driver.OracleDriver”
connectionURL=”jdbc:oracle:thin:@{IP address}:{Port}:{Servicename}”
connectionName=”{DB Username}”
connectionPassword=”{Password}”
userTable=”users”
userNameCol=”username”
userCredCol=”password”
userRoleTable=”user_roles”
roleNameCol=”rolename”
/>
 用环境变量替换下面的值:

  {IP Address} ━━数据库服务器的IP地址

  {Port} ━━端口号

  {Servicename} ━━服务名字

  {DB Username} ━━数据库登录

  {Password} ━━数据库登录的口令

  10、将Oracle的薄客户机驱动程序JAR文件或数据库的JDBC驱动程序拷贝到{tomcat_home}/server/lib目录中。

  11、用下面的安全约束配置Web应用程序的部署描述符
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!– 定义需要被保护的URL –>
<url-pattern>/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint><transport-guarantee>
NONE</transport-guarantee></user-data-constraint>

</security-constraint>

<!– 缺省的登录配置使用基于表单的认证 –>

<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/jsp/login.jsp</form-login-page>
<form-error-page>/jsp/error.jsp</form-error-page>
</form-login-config>
</login-config>
  需要注意的是,<auth-constraint>中<role-name>的值应当是用户-角色关联表中中角色之一。
  在Tomcat中配置例子文件

  1、使用上面介绍的命令配置Tomcat。

  2、下载security-form-based.war文件,并将它拷贝到Tomcat的webapps目录。

  3、启动Tomcat服务器

  4、打开一个浏览器,输入下面的地址:http://{ip address:port no}/security-form-based/protected/index.jsp
  5、输入用户名和口令。

  在WebLogic中配置数据库安全区域

  配置Web应用程序的部署描述符,这一过程与在Tomcat中配置非常相似。Tomcat和WebLogic的配置描述符之间的一个差别是,WebLogic配置描述符要求下面的小节,而Tomcat不需要下面的小节:

<security-role>
<description>
Manager security role
</description>
<role-name>
manager
</role-name>
</security-role>
 结论

  通过本篇文章,读者应该会对基于表单的认证、以及它如何与数据库安全区域配合进行认证有个比较深刻的认识。Web应用程序能够利用基于表单的认证机制,保护它的资源,同时允许使用以前的安全认证机制。

  另外,本篇文章还描述了J2EE Web提供的授权支持层次,以及在不修改Web应用程序的部署描述符的情况下如何定义新的安全角色。

在weblogic中利用应用服务器本身的配置,可以比较全面的实现用户认证。由于我们主要是面向开发,这里主要讲解在servlet中使用用户角色规则(也就是我们常说的http用户认证,下面还是使用这个我们熟悉的名词吧)。

Weblogic用户认证的三种方式

  在weblogic应用服务器中,系统提供了三种不同的用户认证方式:

BASIC

  基本的身份认证方式,使用WEB浏览器弹出一个要求输入用户名和密码的对话框。这个用户名和密码将在网站的某个(些)内容模块中被强制要求。

FORM

  基于FORM的用户认证要求你返回一个包括用户名和密码的HTML表单,这个表单相对应与用户名和密码的元素必须是j_username和j_password,并且表单的action描述必须为j_security_check。下面是一个表单的例子:

  包括这个表单的资源可以是一个HTML页面、一个JSP页面或者一个servlet。你可以在
元素中定义。当这个认证页面被提交的时候,将创建一个HTTP session。所以,当认证成功后,使用session.isNew()方法将获得一个FALSE的返回。

CLIENT-CERT

  就是使用客户数字证书来认证请求,一般都和SSL相联系。如果需要使用请参考有关SSL相关内容。

  使用何种认证方法,可以在web.xml里的元素中的子元素里定义。可能的选择的值为BASIC或FORM或CLIENT-CERT三者之一。

在servlet中使用用户认证

  要在servlet中使用用户认证,必须先对web application进行相应的配置。

  1、修改weblogic.xml文件中的相关条目:

  mgr
al
george
ralph  

  注:是角色名,例如现在这是管理员,然后 元素中指定角色所包括的所有用户名。

  2、在web.xml的元素中定义要使用的角色名mgr(在元素中),并在注册项中为mgr角色做一个链接(manager)

  ... manager mgr ...   mgr  

  到这里服务器上的配置文件就完成了所需要的修改。

  3、在servlet中引用服务器的角色认证,只需要在合适的地方加入下一语句即可。

isUserInRole("manager");

  值得注意的是,当用户认证顺利返回后,一个session将被建立。而在weblogic中,缺省的情况下各个web appliction都使用相同的cookie名(JSESSIONID),所以当任何一个认证成功以后,所有的Web Application都将使用这个相同的cookie名来保存有关认证的信息,从而实现“全站通”概念。假如你想对某个Web Application使用一个单独的认证,你可以为这个应用单独定义一个cookie名,这可以通过对weblogic.xml里的元素有关内容进行相应修改。

  一、Apache 服务器的功能
  
  Apache Serve的前身是NCSA的httpd,曾经在1995年成为最为流行的万维网的服务器。因为强大的功能和灵活的设置及平台移植性,Apache Server取得了广泛的信赖。Apache Server的主要功能有:

  1、支持最新的HTTP1.1协议(RFC2616)。
  2、极强的可配置和可扩展性,充分利用第三方模快的功能。
  3、提供全部的源代码和不受限制的使用许可(License)。
  4、广泛应用于Windows 2000/NT/9x、Netware 5.x,OS/2 和UNIX家族极其他操作系统,所支持的平台多达17余种。
  5、强大的功能,涵盖了用户的需求,包括:认证中的DBM数据库支持;错误和问题的可定制响应的目录导向功能;不受限的灵活的URL别名机制和重定向功能;虚拟主机(多宿主主机)支持多个域主页共存一台主机;超强的日志文件功能;利用站点的分析;拓展于维护等等。

  正因为这些强大的优势,使Apache Server与其他的Web服务器相比,充分展示了高效、稳定及功能丰富的特点。Apache Server 已用于超过600万个Internet站点。

  二、Apache 服务器的安全特性

  作为最流行的Web服务器,Apache Server提供了较好的安全特性,使其能够应对可能的安全威胁和信息泄漏。

1、采用选择性访问控制和强制性访问控制的安全策略

  从Apache 或Web的角度来讲,选择性访问控制DAC(Discretionary Access Control)仍是基于用户名和密码的,强制性访问控制MAC(Mandatory Access Control)则是依据发出请求的客户端的IP地址或所在的域号来进行界定的。对于DAC方式,如输入错误,那么用户还有机会更正,从新输入正确的的密码;如果用户通过不了MAC关卡,那么用户将被禁止做进一步的操作,除非服务器作出安全策略调整,否则用户的任何努力都将无济于事。

  2、Apache 的安全模块

  Apache 的一个优势便是其灵活的模块结构,其设计思想也是围绕模块(Modules)概念而展开的。安全模块是Apache Server中的极其重要的组成部分。这些安全模块负责提供Apache Server的访问控制和认证、授权等一系列至关重要的安全服务。

  mod_access模块能够根据访问者的IP地址(或域名,主机名等)来控制对Apache服务器的访问,称之为基于主机的访问控制。

  mod_auth模块用来控制用户和组的认证授权(Authentication)。用户名和口令存于纯文本文件中。mod_auth_db和mod_auth_dbm模块则分别将用户信息(如名称、组属和口令等)存于Berkeley-DB及DBM型的小型数据库中,便于管理及提高应用效率。

  mod_auth_digest模块则采用MD5数字签名的方式来进行用户的认证,但它相应的需要客户端的支持。

  mod_auth_anon模块的功能和mod_auth的功能类似,只是它允许匿名登录,将用户输入的E-mail地址作为口令。

  SSL(Secure Socket Lager),被Apache所支持的安全套接字层协议,提供Internet上安全交易服务,如电子商务中的一项安全措施。通过对通讯字节流的加密来防止敏感信息的泄漏。但是,Apache的这种支持是建立在对Apache的API扩展来实现的,相当于一个外部模块,通过与第三方程序的结合提供安全的网上交易支持。

三、Apache服务器的安全配置

  在前面的内容中提到过,Apache具有灵活的设置。所有Apache的安全特性都要经过周密的设计与规划,进行认真地配置才能够实现。Apache服务器的安全配置包括很多层面,有运行环境、认证与授权设置及建立安全的电子交易链接等。

  1、Apache的安装配置和运行

  (1)以Nobody用户运行一般情况下,Apache是由Root 来安装和运行的。如果Apache Server进程具有Root用户特权,那么它将给系统的安全构成很大的威胁,应确保Apache Server进程以最可能低的权限用户来运行。通过修改httpd.conf文件中的下列选项,以Nobody用户运行Apache 达到相对安全的目的。

  User nobody
  Group# -1

  (2) ServerRoot目录的权限

  为了确保所有的配置是适当的和安全的,需要严格控制Apache 主目录的访问权限,使非超级用户不能修改该目录中的内容。Apache 的主目录对应于Apache Server配置文件httpd.conf的Server Root控制项中,应为:

  Server Root /usr/local/apache

  (3)SSI的配置

  在配置文件access.conf 或httpd.conf中的确Options指令处加入IncludesNOEXEC选项,用以禁用Apache Server 中的执行功能。避免用户直接执行Apache 服务器中的执行程序,而造成服务器系统的公开化。

  <Directory /home/*/public_html>
  Options Includes Noexec
  </Directory>

  (4)阻止用户修改系统设置

  在Apache 服务器的配置文件中进行以下的设置,阻止用户建立、修改 .htaccess文件,防止用户超越能定义的系统安全特性。

  <Directory />
  AllowOveride None
  Options None
  Allow from all
  </Directory>

  然后再分别对特定的目录进行适当的配置。

  (5)Apache 服务器的确省访问特性

  Apache 的默认设置只能保障一定程度的安全,如果服务器能够通过正常的映射规则找到文件,那么客户端便会获取该文件,如http://local host/~ root/ 将允许用户访问整个文件系统。在服务器文件中加入如下内容:

  <Directory />
  order deny,ellow
  Deny from all
  </Directory>

  将禁止对文件系统的缺省访问。

  (6)CGI脚本的安全考虑

  CGI脚本是一系列可以通过Web服务器来运行的程序。为了保证系统的安全性,应确保CGI的作者是可信的。对CGI而言,最好将其限制在一个特定的目录下,如cgi-bin之下,便于管理;另外应该保证CGI目录下的文件是不可写的,避免一些欺骗性的程序驻留或混迹其中;如果能够给用户提供一个安全性良好的CGI程序的模块作为参考,也许会减少许多不必要的麻烦和安全隐患;除去CGI目录下的所有非业务应用的脚本,以防异常的信息泄漏。

  以上这些常用的举措可以给Apache Server 一个基本的安全运行环境,显然在具体实施上还要做进一步的细化分解,制定出符合实际应用的安全配置方案。

四、Apache Server基于主机的访问控制

  Apache Server默认情况下的安全配置是拒绝一切访问。假定Apache Server内容存放在/usr/local/apache/share 目录下,下面的指令将实现这种设置:

  <Directory /usr/local/apache/share>
  Deny from all
  AllowOverride None
  </Directory>

  则禁止在任一目录下改变认证和访问控制方法。

  同样,可以用特有的命令Deny、Allow指定某些用户可以访问,哪些用户不能访问,提供一定的灵活性。当Deny、Allow一起用时,用命令Order决定Deny和Allow合用的顺序。

  1、拒绝某类地址的用户对服务器的访问权(Deny)

  如:Deny from all
  Deny from test.cnn.com
  Deny from 204.168.190.13
  Deny from 10.10.10.0/255.255.0.0

  2、允许某类地址的用户对服务器的访问权(Allow)

  如:Allow from all
  Allow from test.cnn.com
  Allow from 204.168.190.13
  Allow from 10.10.10.0/255.255.0.0
  Deny和Allow指令后可以输入多个变量。

  3、实例:

  Order Allow, Deny
  Allow from all
  Deny from www.***.com

  则,想让所有的人访问Apache服务器,但不希望来自www.***.com的任何访问。

  Order Deny, Allow
  Deny from all
  Allow from test.cnn.com

  则,不想让所有人访问,但希望给test.cnn.com网站的来访。

  有关访问控制的高级设置请阅读UNIX系统管理书籍。

  五、Apache Sever的用户认证与授权

  概括的讲,用户认证就是验证用户的身份的真实性,如用户帐号是否在数据库中,及用户帐号所对应的密码是否正确;用户授权表示检验有效用户是否被许可访问特定的资源。在Apache中,几乎所有的安全模块实际上兼顾这两个方面。从安全的角度来看,用户的认证和授权相当于选择性访问控制。

  建立用户的认证授权需要三个步骤:

  (1)建立用户库

  用户名和口令列表需要存在于文件(mod_auth模块)或数据库(mod_auth_dbm模块)中。基于安全的原因,该文件不能存放在文挡的根目录下。如,存放在/usr/local/etc/httpd下的users文件,其格式与UNIX口令文件格式相似,但口令是以加密的形式存放的。应用程序htpasswd可以用来添加或更改程序:

  htpasswd –c /usr/local/etc/httpd/users martin

  -c表明添加新用户,martin为新添加的用户名,在程序执行过程中,两次输入口令回答。用户名和口令添加到users文件中。产生的用户文件有如下的形式:

  martin:WrU808BHQai36
  jane:iABCQFQs40E8M
  art:FadHN3W753sSU

  第一域是用户名,第二个域是用户密码。

(2)配置服务器的保护域

  为了使Apache服务器能够利用用户文件中的用户名和口令信息,需要设置保护域(Realm)。一个域实际上是站点的一部分(如一个目录、文档等)或整个站点只供部分用户访问。在相关目录下的.htaccess文件或httpd.conf(acces.conf)中的<Directory>段中,由AuthName来指定被保护层的域。在.htaccess文件中对用户文件有效用户的授权访问及指定域保护有如下指定:

  AuthName “restricted stuff”
  Authtype Basic
  AuthUserFile /usr/local/etc/httpd/users
  Require valid-user

  其中,AuthName指出了保护域的域名(Realm Name)。valid-user参数意味着user文件中的所有用户都是可用的。一旦用户输入了一个有效的用户/口令时,同一个域内的其他资源都可以利用同样的用户/口令来进行访问,同样可以使两个不同的区域共用同样的用户/口令。

  (3)告诉服务器哪些用户拥有资源的访问权限

  如果想将一资源的访问权限授予一组客户,可以将他们的名字都列在Require之后。最好的办法是利用组(group)文件。组的操作和标准的UNIX的组的概念类似,任一个用户可以属于一个和数个组。这样就可以在配置文件中利用Require对组赋予某些权限。如:

  Require group staff
  Require group staff admin
  Require user adminuser

  指定了一个组、几个组或一个用户的访问权限。

  需要指出的是,当需要建立大批用户帐号时,那么Apache服务器利用用户文件数据库将会极大地降低效率。这种情况下,最好采用数据库格式的帐号文件,譬如 DBM数据库格式的文件。还可以根据需要利用db格式(mod_auth_db)的数据文件,或者直接利用数据库,如:mSQL(mod_auth_msql)或DBI兼容的数据库(mod_auth_dbi)。

  六、在Apache中使用DBM用户认证

  DBM 文件是一种简单而标准的用于加快读取效率的保存信息的方法。文件中存放的每一个记录由两个部分组成部分:键和值。由于DBM的格式,使得与键相关的信息非常有效。在Web用户认证中,这里的键将是用户名,而与该键相关的值将是该用户经过加密的口令信息。从DBM文件中查找用户名和口令,要比从一个纯文本文件中查找有效得多。对于有很多用户的站点,这种方法将大大提高用户认证的效率。

  (1) 在Apache服务器中增加DBM模块

  在默认的条件下,Apache不使用DBM文件来完成用户认证,因此编译时一定要加入可选的DBM认证模块。重新配置Apache服务器文件,去掉其中的注释行

  #Module dbm_auth_module mod_auth_dbm.o

  前的“#”,并重新编译。但是,在编译之前,需要指出Apache DBM函数的位置。

  (2) 创建DBM用户文件(假设文件名为users)

  Apache提供了一个“dbmmanage”的程序,用于创建和管理DBM文件。其中:

  Dbmmanage /usr/local/etc/httpd/usersdbm     创建DBM文件
  Dbmmanage /usr/local/etc/httpd/users adduser martin hamster 新增用户
  Dbmmanage /usr/local/etc/httpd/usersdbm delete martin   删除用户
  Dbmmanage /usr/local/etc/httpd/usersdbm view 显示DBM中所有用户

  有了DBM数据库文件,还要替换目录访问控制,即将Apache配置文件(access.conf)中的AuthUserFile部分替换成:AuthUserFile /usr/local/etc/usersdbm 告诉Apache现在的用户文件是DBM的格式。

通过JAVA连接数据库的几种方式
步骤:
1、Import Packages.
2、Register the JDBC Drivers.
3、Open a Connection to a Database
4、Create a Statement Object
5、Execute a Query and Return a Result Set Object
6、Process the Result Set

import java.sql.*;    //for standard JDBC packages
import oracle.jdbc.driver.*;
import oracle.sql.*;   //for Oracle extensions to JDBC

Class.forName(“oracle.jdbc.driver.OracleDriver”);  //is valid only for JDK-compliant Java virtual machines
or
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); //buth Microsoft Java virtual machines and JDK-compliant Java virtual machines
//getConnection(String URL,String user,String password)
//where the URL is of the form: jdbc:oracle:<drivertype>:@<database>
Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@myhost:1521:orcl”,”scott”,”tiger”);
or
Connection conn = DriverManager.getConnection(“jdbc:oracle.oci8:scott/tiger@”);
or
Connection conn = DriverManager.getConnection(“jdbc:oracle:oci8:@myhoststring”,”scott”,”tiger”);

Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(“select * from emp”);
while (rset.next())
 System.out.println(rest.getString(1));
 
rset.close();
stmt.close();
conn.close();

2004年08月18日

建立基于 JDBC 的 Tomcat 连接池

使用传统的方式开发 JDBC 应用时,要为每一次请求建立一次数据库连接,因此在一个这样 Web 应用中,建立数据库连接的操作是系统中代价最大的操作之一。而且,你必须去管理每一个连接,确保他们能被正确关闭,如果出现程序异常而导致某些连接未能关闭,将导致数据库系统中的内存泄露,最终将不得不重启数据库。针对以上问题,首先想到可以采用一个全局的 Connection 对象,创建后就不关闭,以后程序一直使用它,这样就不存在每次创建、关闭的问题了。但是,同一个连接使用次数过多,将会导致连接的不稳定,进而会导致 Web 服务器的频频重启。故而,这种方法也不可取。而连接池技术可以解决上述问题。连接池最基本的思想就是预先建立一些连接放置于内存对象中以备使用,当程序需要建立数据库连接时,只须从内存中取出一个来使用,使用完毕后,只需放回内存即可。而连接的创建和关闭都由连接池来管理。同时,还可以通过设置连接池的参数来控制连接池中的连接数、每个连接的最大使用次数等。通过使用连接池,将大大提高程序效率。

做为 Sun 公司推荐的 JSP、Servlet 容器,Tomcat 在 4.0 以上版本支持连接池机制,本文的讨论基于 Tomcat 4.1.24 以及 Oracle 8i 数据库环境。

准备

假设你的 Tomcat 和 Oracle 已经分别跑起来,下面首先为 Tomcat 增加 Oracle 的 JDBC 驱动,Oracle 8.1.7 自带的 JDBC 驱动是 classes12.zip 和 nls_charset12.zip,为了使它们能够被 Tomcat 自动加载,要把他们变为 JAR 格式。实际上 JAR 文件就是包含了 META-INF/MANIFEST.MF 的 zip 文件。

unzip classes12.zip jar cf classes12.jar javax oracle rm -rf javax oracle unzip nls_charset12.zip jar cf nls_charset12.jar oracle rm -rf oracle cp classes12.jar nls_charset12.jar $CATALINA_HOME/common/lib 

其中 jar 随 JDK 提供。

配置

假设应用所在的目录别名为 test,Oracle 运行在本地,SID 为 orcl,一个可用的用户名为 dev,口令为 dev123,那么把 Tomcat 的配置文件 server.xml 中的相应上下文修改为:

  
 factory org.apache.commons.dbcp.BasicDataSourceFactory 
 driverClassName oracle.jdbc.driver.OracleDriver 
 url jdbc:oracle:thin:@localhost:1521:orcl 
 username dev 
 password dev123 
 maxActive 10 
 maxIdle 10 
 maxWait -1    

在应用的 web.xml 文件中添加如下 DataSource 声名:

 jdbc/testpool javax.sql.DataSource Container  

重新启动 Tomcat:

/etc/init.d/catalina stop /etc/init.d/catalina start 

执行一个 SQL 语句的演示

以下是这个测试 JSP 文件的核心内容:

<%@ page contentType="text/html; charset=GBK"%> <%@ page import="java.sql.*, javax.naming.*"%> <% try { Context initCtx = new InitialContext(); Context ctx = (Context) initCtx.lookup("java:comp/env"); Object obj = (Object) ctx.lookup("jdbc/testpool"); javax.sql.DataSource ds = (javax.sql.DataSource)obj; Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); String strSQL = "SELECT * FROM emp"; ResultSet rs = stmt.executeQuery(strSQL); %>  ... <% rs.close(); stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); throw e; } %> 

http://vip.6to23.com/hanson/htdocs/tomcat.htm

1 – Tomcat Server的组成部分

1.1 – Server

A Server element represents the entire Catalina servlet container. (Singleton)

1.2 – Service

A Service element represents the combination of one or more Connector components that share a single Engine
Service是这样一个集合:它由一个或者多个Connector组成,以及一个Engine,负责处理所有Connector所获得的客户请求

1.3 – Connector

一个Connector将在某个指定端口上侦听客户请求,并将获得的请求交给Engine来处理,从Engine处获得回应并返回客户
TOMCAT有两个典型的Connector,一个直接侦听来自browser的http请求,一个侦听来自其它WebServer的请求
Coyote Http/1.1 Connector 在端口8080处侦听来自客户browser的http请求
Coyote JK2 Connector 在端口8009处侦听来自其它WebServer(Apache)的servlet/jsp代理请求

1.4 – Engine

The Engine element represents the entire request processing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmission back to the client
Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名
当Engine获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该Host来处理
Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理

1.5 – Host

代表一个Virtual Host,虚拟主机,每个虚拟主机和某个网络域名Domain Name相匹配
每个虚拟主机下都可以部署(deploy)一个或者多个Web App,每个Web App对应于一个Context,有一个Context path
当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理
匹配的方法是“最长匹配”,所以一个path==”"的Context将成为该Host的默认Context
所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配

1.6 – Context

一个Context对应于一个Web Application,一个Web Application由一个或者多个Servlet组成
Context在创建的时候将根据配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml载入Servlet类
当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类
如果找到,则执行该类,获得请求的回应,并返回

2 – Tomcat Server的结构图

3 – 配置文件$CATALINA_HOME/conf/server.xml的说明

该文件描述了如何启动Tomcat Server

 <!----------------------------------------------------------------------------------------------->   <!-- 启动Server 在端口8005处等待关闭命令 如果接受到"SHUTDOWN"字符串则关闭服务器 -->  <Server port="8005" shutdown="SHUTDOWN" debug="0">  <!-- Listener ??? 目前没有看到这里 -->  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0"/> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0"/>  <!-- Global JNDI resources ??? 目前没有看到这里,先略去 -->  <GlobalNamingResources> ... ... ... ... </GlobalNamingResources>  <!-- Tomcat的Standalone Service Service是一组Connector的集合 它们共用一个Engine来处理所有Connector收到的请求 -->  <Service name="Tomcat-Standalone">  <!-- Coyote HTTP/1.1 Connector className : 该Connector的实现类是org.apache.coyote.tomcat4.CoyoteConnector port : 在端口号8080处侦听来自客户browser的HTTP1.1请求 minProcessors : 该Connector先创建5个线程等待客户请求,每个请求由一个线程负责 maxProcessors : 当现有的线程不够服务客户请求时,若线程总数不足75个,则创建新线程来处理请求 acceptCount : 当现有线程已经达到最大数75时,为客户请求排队 当队列中请求数超过100时,后来的请求返回Connection refused错误 redirectport : 当客户请求是https时,把该请求转发到端口8443去 其它属性略 -->  <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="8080" minProcessors="5" maxProcessors="75" acceptCount="100" enableLookups="true" redirectPort="8443" debug="0" connectionTimeout="20000" useURIValidationHack="false" disableUploadTimeout="true" />  <!-- Engine用来处理Connector收到的Http请求 它将匹配请求和自己的虚拟主机,并把请求转交给对应的Host来处理 默认虚拟主机是localhost -->  <Engine name="Standalone" defaultHost="localhost" debug="0">  <!-- 日志类,目前没有看到,略去先 -->  <Logger className="org.apache.catalina.logger.FileLogger" .../>  <!-- Realm,目前没有看到,略去先 -->  <Realm className="org.apache.catalina.realm.UserDatabaseRealm" .../>  <!-- 虚拟主机localhost appBase : 该虚拟主机的根目录是webapps/ 它将匹配请求和自己的Context的路径,并把请求转交给对应的Context来处理 -->  <Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true">  <!-- 日志类,目前没有看到,略去先 -->  <Logger className="org.apache.catalina.logger.FileLogger" .../>  <!-- Context,对应于一个Web App path : 该Context的路径名是"",故该Context是该Host的默认Context docBase : 该Context的根目录是webapps/mycontext/ -->  <Context path="" docBase="mycontext" debug="0"/>  <!-- 另外一个Context,路径名是/wsota -->  <Context path="/wsota" docBase="wsotaProject" debug="0"/> </Host> </Engine> </Service> </Server>  <!----------------------------------------------------------------------------------------------->  

4 – Context的部署配置文件web.xml的说明

一个Context对应于一个Web App,每个Web App是由一个或者多个servlet组成的
当一个Web App被初始化的时候,它将用自己的ClassLoader对象载入“部署配置文件web.xml”中定义的每个servlet类
它首先载入在$CATALINA_HOME/conf/web.xml中部署的servlet类
然后载入在自己的Web App根目录下的WEB-INF/web.xml中部署的servlet类
web.xml文件有两部分:servlet类定义和servlet映射定义
每个被载入的servlet类都有一个名字,且被填入该Context的映射表(mapping table)中,和某种URL PATTERN对应
当该Context获得请求时,将查询mapping table,找到被请求的servlet,并执行以获得请求回应

分析一下所有的Context共享的web.xml文件,在其中定义的servlet被所有的Web App载入

 <!----------------------------------------------------------------------------------------------->  <web-app>  <!-- 概述: 该文件是所有的WEB APP共用的部署配置文件, 每当一个WEB APP被DEPLOY,该文件都将先被处理,然后才是WEB APP自己的/WEB-INF/web.xml -->   <!-- +-------------------------+ --> <!-- | servlet类定义部分 | --> <!-- +-------------------------+ -->   <!-- DefaultServlet 当用户的HTTP请求无法匹配任何一个servlet的时候,该servlet被执行 URL PATTERN MAPPING : / -->  <servlet> <servlet-name>default</servlet-name> <servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>  <!-- InvokerServlet 处理一个WEB APP中的匿名servlet 当一个servlet被编写并编译放入/WEB-INF/classes/中,却没有在/WEB-INF/web.xml中定义的时候 该servlet被调用,把匿名servlet映射成/servlet/ClassName的形式 URL PATTERN MAPPING : /servlet/* -->  <servlet> <servlet-name>invoker</servlet-name> <servlet-class> org.apache.catalina.servlets.InvokerServlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet>  <!-- JspServlet 当请求的是一个JSP页面的时候(*.jsp)该servlet被调用 它是一个JSP编译器,将请求的JSP页面编译成为servlet再执行 URL PATTERN MAPPING : *.jsp -->  <servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>logVerbosityLevel</param-name> <param-value>WARNING</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet>  <!-- +---------------------------+ --> <!-- | servlet映射定义部分 | --> <!-- +---------------------------+ -->  <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping>  <!-- +------------------------+ --> <!-- | 其它部分,略去先 | --> <!-- +------------------------+ -->  ... ... ... ... </web-app>  <!----------------------------------------------------------------------------------------------->  

5 – Tomcat Server处理一个http请求的过程

假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp

1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为”"的Context去处理)
7) path=”/wsota”的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser

2004年07月29日

 Oracle的解析器按照从右到左的顺序处理from字句中的表名
 因此from字句中写在最后的表(基础表)将被最先处理
 在from字句中包含多个表的情况下,必须选择记录条数最少的表作为基础表
 当Oracle处理多个表时,会运用排序及合并的方法连接他们,首先,扫描第一个表(from字句中最后的那个表)并对记录进行排序,然后扫描第二个表(from字句中倒数第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适的记录进行合并。
 根据优化器的不同, SQL语句中基础表的选择是不一样的.
 如果你使用的是CBO (COST BASED OPTIMIZER),优化器会检查SQL语句中的每个表的物理大小,索引的状态,然后选用花费最低的执行路径.
 如果你用RBO (RULE BASED OPTIMIZER) , 并且所有的连接条件都有索引对应, 在这种情况下, 基础表就是FROM 子句中列在最后的那个表.

 例如:
  表 tab1 16,384条记录
  表 tab2 1条记录

  选择tab2作为基础表(最好的方法)
  select count(*) from tab1,tab2  耗时0.96秒

  选择tab1作为基础表(不佳的方法)
  select count(*) from tab2,tab1   耗时26.09秒

 如果有3个以上的表连接查询,那就需要选择交叉表作为基础表,交叉表是指那个被其他表所应用的表。

 例如:
  emp表描述了location表和category表的交集
  select * from location l,category c emp e
  where e.emp_no between 1000 and 2000 and e.cat_no=c.cat_no and e.locn=l.locn
  将比下列sql更有效率
  select * from emp e,location l,category c
  where e.cat_no=c.cat_no and e.locn=l.locn and e.emp_no between 1000 and 2000

选择合适的优化器
 OPTIMIZER_MODE = (RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS)

 如果设为COST,(基于成本的优化器),必须经常对表运行analyze命令。
 如果设为CHOOSE,那么优化器的选择将和表是否运行过analyze命令有关,如果表已经被analyze过,则优化器选择COST,否则选择RULE。

 Oracle默认使用CHOOSE,所以为了避免不必要的全表扫描,必须尽量避免使用CHOOSE,而直接采用COST或RULE。

2004年07月22日

 在你的Movable Type环境下,编辑你的Blog,可以实现网站之间的互相通告,也就是从一个web服务器发送到其他的服务器的短消息(a small message)。在详细阅读中转载了有关的介绍。

TrackBack

TrackBack新手指南(编译)
  TrackBack ping:在这种情况下,一个ping就是一条从一个web服务器发送到另一个服务器的短消息(a small message)。
  “A Beginner’s Guide to TrackBack”一文,对在MT中如何使用TrackBack做了详细地说明,下面就是学习笔记。

什么是TrackBack?
  简单说来,TrackBack被设计用来提供一种方法以实现网站之间的互相通告:它是一种方法,能让甲对乙说(甲、乙指两个人,下同),“这篇文章可能是你感兴趣的”。要实现这个动作,甲向乙发送一个TrackBack ping即可。
  TrackBack ping:在这种情况下,一个ping就是一条从一个web服务器发送到另一个服务器的短消息(a small message)。

历史
  TrackBack在2002年秋第一次以开放规范的形式发布。MT2.2作为一种协议和一项功能对其进行了实现,这是TrackBack的第一个实现。由于只有众多的站点都支持TrackBack,它的真正价值才能得以体现,所以TrackBack从一开始就被设计为一个开放系统:一个其它的blog工具能很简单地实现的开放系统。
  截止目前,已有下列工具支持TrackBack:

Movable Type
Bloxsom
Blojsom
Nucleus
B2
Radio
TrackBack standalone Tool

如何使用TrackBack
  TrackBack的使用依赖于具体的blog/trackback工具。下面主要针对MT的TrackBack使用。
小书签(bookmarklet)
  在MT中使用TrackBack的最简单的方法,是借助小书签,它利用其自动发现功能可以从你正在阅读的当前页面中找到一组可进行TrackBack的文章链接。(自动发现意味着你无需做任何相关的工作,因为系统会替你完成)。如果你还没有在MT中设置过小书签,则:

登录MT

点击“设置小书签”(Set Up Bookmarklets)

配置小书签的显示
  注意:一定要确保选中了”TrackBack items”选项,因为这是神奇的自动发现功能的开关。
  通过点击下列选项前的框,来选择你想在小书签中显示的内容。然后点击“创建”(create)。

安装小书签
  将“Post to MT Weblog”链接用鼠标拖到”链接”工具栏(或是者收藏夹里中),它的标题就是“Post to MT Weblog”。(对IE用户来说,还可以把一个”MT It!”加入右键菜单,对当前的页面点击右键时选中此菜单项,也能实现小书签的功能).

在MT的某些汉化版本中,需要将$MTHOME/lib/MT/L10N/zh_cn.pm做如下修改:
‘Post to MT Weblog’ => ”,
改为
‘Post to MT Weblog’ => ‘Post to MT Weblog’,

,否则看不到这个链接。
  当你阅读其它blog上感兴趣的文章时,点击“Post to MT Weblog”,如果当前页面中可以TrackBack的文章,它的标题将会自动加入到一个下拉列表中供选择来ping(如果只有一个满足要求的文章,则会用checkbox选项代替的下拉列表)。页面上显示其它元素,都是你在前面配置时选中的。如果那时所有项都选择了,则页面跟正常的”新增文章”非常相似。相关的项都输入完后,点击“保存”(post),则在重建立文章以后,系统会自动ping你从下拉列表中选中的那篇文章。

  这儿有一个操作演示录像(9M大小),是mov格式,需要apple的QuickTime播放器播放。
通过文章编辑表单来TrackBack ping
  如果你不想用小书签,仍可以在MT中使用TrackBack ping功能,只是不是那么简单而已。这时,需要找到被ping的目标文章的TrackBack Ping URL。下面描述一下如何一步步的操作。注意:TrackBack Ping Url不是文章的永久链接,而是另外一个链接。

找到你感兴趣的文章
  这是你的评论对象,也将是你的文章发送TrackBack Ping到的目标对象。如果这个目标文章,接收“TrackBack Ping”,则会自动显示一个”TrackBack”链接,紧挨着“Comments”链接。

找到TrackBack Ping Url
  点击上述”TrackBack”链接,页面上会显示此文章的”TrackBack Ping URL”,接下来是一些收到的“TrackBack ping”。复制这个”TrackBack Ping URL”。

登录到你的MT
选择一个BLOG
点击”新增文章“(New Entry)
将刚才复制的内容粘贴到“Urls to ping”输入框中。
  如果看不到这个输入框,则点击右下角的”Customize the display of this page “链接来修改你的编辑页面显示。

编辑文章内容,点击保存按钮
  当文章被创建以后,接着显示”Ping…”窗口。此时,MT自动发送”TrackBack Ping”去通知目标文件。

利用”自动发现“功能来发送”TrackBack Ping”
  在MT中,最后一种使用”TrackBack Ping”的方法,是在你的blog设置中打开“自动发现(TrackBack auto-discovery,也有人译为自动挖掘)”选项。

  当此选项打开后,MT利用自动发现在功能分析你的文章中的链接所对应的页面,是否接收“TrackBack Ping”,如果接收,则自动从你的文章发送一个”TrackBack Ping”到那个页面。此时,你不需要在”Urls to Ping”输入框中输入内容,也不需要用小书签来查找可ping的链接。

协议
  TrackBack是一个基于REST的点对点(peer-to-peer)通信和网站间通告的架构。协议基于”推送(Push)”的原理,而不是“拉取(pull)”:如果你想和其它站点分享信息,你要初始化连接,而不是等待其它站点发现你(和你的信息)。借助TrackBack,站点可以交流相关资源。例如,如果甲想通知乙他写了一些有意思的/想关的/震撼性的东东,甲发送一个TrackBack ping给乙。这完成了两件事:
 
乙能自动列出那些引用他的某篇文章的网站,到他网站的访问者能读到网络上所有相关的文章,包括甲的文章。网页机器人也能访问这些信息,从而能得站点间的联系图。
ping在他的文章和你的文章间提供了一种稳固的、直接的链接,而不是那种依赖于外部行为(某人点击那个连接)的非直接连接(如反向连接referrer)。

  TrackBack协议对任何blog工具都是开放的,具体规范参见http://www.movabletype.org/docs/mttrackback.html, 或我的翻译.

目前的应用
远程评论
  目前,TrackBack主要被用作一个远程评论系统:如果我在我的blog上发表了一篇文章来评价你在你的blog上的文章,我的blog工具会通报给你的blog工具以通知你此事。接着你的blog将显示我的文章的摘录部分,并提供了一个回到我的文章的链接。这使那些到你的网站的访问者知道其他人是如何评价你的文章的--换句话说,就是评论(comment)一样,只是这评论是在我的网站而不是在你的网站上,而在以前我只是在你的文章后留言评论。这让我能控制我的文章。如果我想修改一个打字错误,或者改变一些措词,于是我就可以做到。如果我在你的站点上留言,我没有权限来修改那些文字。换句话说,TrackBack使你更能控制你的内容。
  TrackBack ping的威力,在于它创建了你我站间的一个直接引用。这个引用可以用来建立一个分布式的交谈(conversation)。例如,另外一个blogger(女)发布文章阐述了对我的文章的想法,并发送给我一个TrackBack ping.这个交谈(conversation)可从你最初的文章,追踪到我这儿,再到她那儿。这个线路可以通过TrackBack的元数据自动画出来。请看这个线路:http://www.sixapart.com/safari-thread.html,它开始的文章是http://www.sixapart.com/log/2003/01/initial_reactio.shtml.

内容聚合
  虽然到目前TrackBack最流行的应用,是以远程评论的形式,一个更令人兴奋的使用已经开始出现了:利用TrackBack来将相关的内容聚合到一个基于主题的仓库(repository)中。这其实是TrackBack最初的设计用途:远程评论来源于一个主题仓库的特殊,即此时的“主题”是一篇blog文章。
  内容聚合站点收集关于某个主题的内容。如果你曾试图查找关于某个特定题目的blog文章,这非常不可能,除非是新闻故事或新近发生的事。如果你的题目是关于80年代的音乐,你要花费更多艰苦的时间来找到所有的关于那个主题的blog文章。这到了TrackBack显示身手的时候:通过建立一个关于80年代音乐的文章仓库,其它的内容作者可以利用TrackBack自动ping这个仓库。任何查找关于80年代音乐的文章的人,可到这个页面,找到那些指向这个站点的文章。
  这些内容仓库可以集中存放(如Internet Topic Exchange),也可以分布式存放。以MT为例,你可以设置任何blog分类来接收TrackBack ping,这使你成为你感兴趣的某个主题的信息源。

登录MT
选择blog,用以存放允许TrackBack的分类
点击“分类(categories)”
编辑类别属性
点击某类别的“编辑类别属性(edit category attribute)”连接

设置接收TrackBack ping 为on.

在模板中增加显示收到的ping的代码


“><$MTPingTitle$>


在这个例子中,TrackBack字符串是一个分类的名字,实际应用中以真实的分类名替换它。
公开发布分类的TrackBack URL
是为了让更多的人向这个类另发送ping.这个URL你可以从类编辑页面得到。

一些以这种方式使用TrackBack的站点:
Austin Bloggers
SXSWTrack
BlogPopuli

将来可能的应用
内容控制
  随着时间的流失,你在你的blog上的花费的时间越来越多,你的blog的内容也越来越充实,你可能想控制所有你在其它的blog或系统中发布的内容。例如,如果你曾就某人的文章在其站点上发布过自己的想法,他想将这些想法发布到自己的blog中来,于是你可就可控制它们了。或者,如果你在amazon.com上发表过评述(review),你可能想把这个评述组织到你的自己的站点中来。TrackBack有助于做到这些。有个例子,Matt Haughey的Posted Elsewhere工具条(http://a.wholelottanothing.org/),将他在别外写的内容聚合起来。
  反过来,TrackBack可以工作:不是在别人的站点上发表文章,而是作者在自己的blog上发表文章,然后将TrackBack ping发往其它站点。例如,如果amazon.com评述可以接收TrackBack ping,你可信息控制在自己的网站上,让amazon.com连到你这儿。

我的一点想法
  一个页面,要想提高自己在google的pagerank值,关键在于能得到来自高pagerank值的页面的链接。一般说来,这种连接的建立,低值的页面只能被动的接收,而blog工具中的comments和trackback,提供了一种在别人的页面上主动建立连接的方法。如果google没有针对这种情况调整算法,这将成为一种快速提升pagerank的途径。尤其是“自动发现”功能,能自动找出链接,检查相关的页面是否接收trackback ping,将会更加剧对这种手段的利用。
  真的是这样的吗?
参考资料
A Beginner’s Guide to TrackBack
http://www.movabletype.org/trackback/beginners/

Posted by Hilton at November 6, 2003 04:49 PM | TrackBack

Comments
五:Google的前1,000项搜索结果
  一般说来,网站排名因素包括网页标题(META TITLE),网页正文中的关键词密度,锚文本(也叫链接文本,指链接或超链的文本内容)和PageRank所决定的。

  请记住:单靠PageRank是无法使你获得比较理想的网站排名的。PageRank只是网站排名算法中的一个乘积因子,若你网站的其它排名因子的得分是零,就算你的PageRank是两百亿,最后的得分还是零。但这并不是说PageRank就毫无价值,而是在什么情况下PageRank才能完全发挥其功力。

  如果在Google上进行广泛搜索,看起来好象有几千个结果,但实际显示最多前1,000项结果。例如对“car rental”,显示搜索结果为5,110,000,但实际显示结果只有826个。而且用时只有0.81秒。试想一下,0.84秒的时间就可以计算这五百万搜索结果的每个排名因子得分,然后给出最终我们所看到的网站排名结果吗?

  答案就在于:搜索引擎选取与查询条件最相关的那些网页形成一个子集来加速搜索的速度。例如:假设子集中包含2,000个元素,搜索引擎所做的就是使用排名因子中的两到三个因素对整个数据库进行查询,找到针对这两三个排名因子得分较高的前2,000个网页。(请记住,虽然可能有五百多万搜索结果,但最终实际显示的1,000项搜索结果却是从这个2,000页的子集中提炼出来的。) 然后搜索引擎再把所有排名因子整合进这2,000项搜索结果组成的子集中并进行相应的网站排名。由于按相性进行排序,子集中越靠后的搜索结果(不是指网页)相关性(质量)也就越低,所以搜索引擎只向用户显示与查询条件最相关的前1,000项搜索结果。

  请注意,在搜索引擎生成这2,000项网页的子集中我们强调了“相关性”这个词。即搜索引擎找寻的是与查询条件有共同主题的网页。如果这时候我们把PageRank考虑进去,就很可能得到一些PageRank很高但主题只是略微相关的一些搜索结果。显然这有违搜索引擎为用户提供最为相关和精准的搜索结果的原则。

  一旦理解了为什么会如此,就说明了为什么你应当首先努力在“页面”因子和锚文本上下足工夫,最后才是PageRank。所以关键在于:

  你必须首先在页面因素和/或锚文本上下足工夫,使这些排名因子能够获得足够的得分,从而使你的网站能够按目标关键词跻身于这2,000项搜索结果的子集中,否则PageRank再高也与事无补。

资料来源:
http://www.jeast.net/jiahou/archives/000596.html
http://hedong.3322.org/archives/000350.html