[摘要]最近闲来无事就对“分布式系统”做了一点小小的研究,我觉得这种技术相当不错,可能很多朋友都听说过“分布式”这个概念,我对这种技术的个人理解就是:分布式系统包括很多成员,它们之间资源是相互共享的,从大的方面看是共同担负处理任务,但是以个体为单位单独处理每个小的任务,然后被一个中央处理单元将所有信息合并...
最近闲来无事就对“分布式系统”做了一点小小的研究,我觉得这种技术相当不错,可能很多朋友都听说过“分布式”这个概念,我对这种技术的个人理解就是:分布式系统包括很多成员,它们之间资源是相互共享的,从大的方面看是共同担负处理任务,但是以个体为单位单独处理每个小的任务,然后被一个中央处理单元将所有信息合并的一个系统。这种技术就是基于服务器端的一种技术,我就按照我的理解来做了一个简单的模型(做错的地方请大家指教J)
下面我就来介绍一下这个模型的构造以及数据库设计问题:
服务器A:担任数据库服务器同时又担任WEB服务器(平台WIN SERVER2000 , IIS5.0 , SQL SERVER 2000 , IP地址为192.168.0.1)
服务器B,C,D:担任WEB服务器(平台WIN SERVER2000 , IIS5.0 )
首先我们设计数据库的时候要考虑的问题就是这个系统的特性“分布”,即A,B,C,D四台服务器在实际应用中他们的地理位置不一定是集中的,比如SOHU的服务器,遍布各地,但是我们每个人看到的消息都是一样的,它也是一个较大的分布式网站系统,由于地域的差异造成服务器端时间的差异,我们既要对用户正确的表示本地的时间,又要方便管理数据库,那么就要对入库的数据有一个统一的时间编号,这个工作当然就只有在数据库中实现了,于是我设计了2个时间的字段,一个WEB_TIME用来存储从WEB服务器传递过来的日期时间,一个DATA_TIME用来存储数据入库时当前数据库服务器的系统日期时间
这样就完成了重要的一部,(本人遇到的在A服务器添加数据时可以写入DATA_TIME,而无法在B,C,D服务器上写入DATA_TIME的原因就在于忘了在该字段设置该字段不为空,呵呵,只要设置了不允许为空就ok了)然后将DATA_TIME默认值设置威getdate()这样在写入每条数据的时候就由SQL自己自动取得当前数据库服务器的系统时间并写入,呵呵,这样就完成了时间的统一问题,然后我比如做一个注册系统再设置name和pass两个字段来存储用户的用户名和密码,呵呵,完成了数据库的设计,接下来就是WEB程序了,呼呼
WEB程序部分:
1. 连接数据库(conn.asp)
对于A服务器来讲,它本身既是数据库服务器又是WEB服务器,所以它连接数据库的代码如下:
<%
set conn=server.createobject("ADODB.connection")
conn.open"PROVIDER=SQLOLEDB;DATASOURCE=localhost;UID=sa;PWD=;DATABASE=db"
%>
对于其他WEB服务器来讲他们连接的时远端的数据库服务器所以代码改为:
<%
set conn=server.createobject("ADODB.connection")
conn.open"PROVIDER=SQLOLEDB;DATA SOURCE=192.168.0.1;UID=sa;PWD=;DATABASE=db"
%>
2.服务器任务分配解决思路
这个页面的代码在B,C,D服务器基本上都是一样的了,比较特殊的就是A服务器
不过这里还有一个服务器登陆选择的问题,(我正在研究中,呵呵,具体程序的实现做出来再告诉大家),不过我的设想是这样的,我把服务器A设置为第一连接的服务器,就是所有访问这个站点的客户机首先都是访问A服务器,然后A服务器再比较B,C,D三个服务器的繁忙程度,有选择的将URL地址指向其中闲置的一台服务器,这样就不会出现服务器之间负担的任务不均衡,这里就有一个关于统计服务器繁忙程度,我的思路是做一个在线统计程序,加在网站代码中,但是A,B,C,D的程序代码必须要带有该服务器的标识,然后将四台服务器的统计结果在服务器A数据库中汇合,然后服务器A通过判断他们存入的统计数据来选择服务器(有兴趣的同志我们可以共同来研究)
我们先在数据库建立一统计三台服务器在线人数的数据表命名为count,设立字段NUM和SERVER_VAL和SERVER_URL分别代表在线人数,和服务器名和服务器地址,并且添加进3台WEB服务器的基本信息NUM默认为0,和每台服务器名,以及网址。
――――――――――――――――――――――――――――――――――――――
然后我们在每个用户在选择服务器后从A服务器进入B,C,D其中的一台服务器时,开始执行对该服务器进行在线人数统计,并将结果写入数据库服务器A,同样当一个用户离线时,也将在线人数结果写入数据库服务器A,这里我采用的是GLOBAL.ASA来进行统计(具体的统计方法各位可以按照您的思路来,我在这里只是抛砖引玉)
这样基本的原理就完成了,剩下的就是网站建设了,在这里我把一些基本代码写出,请大家指教:
主服务器(数据库服务器A SQL SERVER 2000 IIS5.0):
建立数据库db
db下建数据表message和count
1. message数据表有字段
id(编号,主键) int类型 不允许为空
name char类型
pass char类型
tim datetime类型 不允许为空 (设置默认值为getdate())用于统一管理入库记录的时间,该时间以数据库服务器系统时间为标准
备注:该数据表用于调试各个服务器间协作处理用户和数据库服务器间会话的任务
并无特殊意义。
2. count数据表有字段
id(编号,主键) int类型 不允许为空
num int类型
server_url nchar类型 记录WEB服务器的ip地址
server_name nchar类型 记录WEB服务器的编号
备注:该数据表为各个WEB服务器在线统计结果,以及服务器基本信息,用于主服务器判断各个WEB服务器的繁忙程度来对来访人数的协调。
主服务器WEB程序部分:
conn.asp 连接数据库部分
<%
set conn=server.createobject("ADODB.connection")
conn.open"PROVIDER=SQLOLEDB;DATA SOURCE=localhost;UID=sa;PWD=;DATABASE=db"
%>
close.asp关闭数据库程序
<%
rs.close
conn.close
set rs=nothing
set conn=nothing
%>
index.asp 判断程序
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<!--#include file=conn.asp -->
<%
dim SERVER_URL
set rs=server.createobject("ADODB.recordset")
sql="select * from count order by num desc"
rs.open sql,conn,1,3
if not rs.eof and not rs.bof then
RS.MOVELAST
SERVER_URL=RS("SERVER_URL") ‘将闲置服务器IP付给改变量
End if
%>
<!--#include file=close.asp -->
<%
SERVER_URL="http://"&SERVER_URL ‘转换成URL格式
response.Redirect(SERVER_URL) ‘转置闲置服务器
%>
WEB服务器程序部分:(主要就是向主服务器反馈当前该服务器在线人数情况)
Conn.asp连接数据库服务器程序
<%
set conn=server.createobject("ADODB.connection")
conn.open"PROVIDER=SQLOLEDB;DATA SOURCE=192.168.0.1;UID=sa;PWD=;DATABASE=db"
%>
close.asp关闭数据库程序
<%
rs.close
conn.close
set rs=nothing
set conn=nothing
%>
GLOBAL.ASA程序
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
sub application_onstart
application.lock
application("count1")=0
application.unlock
end sub
sub session_onstart
application.lock
application("count1")= application("count1")+1
application.unlock
end sub
sub session_onend
application.lock
application("count1")= application("count1")-1
application.unlock
end sub
sub application_onend
application.lock
application("count1")=0
application.unlock
end sub
</script>
Count.asp(统计程序)
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%><meta http-equiv="refresh" content="5">
<%session.Timeout=1%>
<%response.buffer=true%>
<!--#include file=conn.asp -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title></title>
当前服务器<%=request.ServerVariables("LOCAL_ADDR")%>在线<%=application("count1")%>人
<br>
<%
server_url=request.ServerVariables("LOCAL_ADDR")
set rs=server.createobject("ADODB.recordset")
sql="select * from count where server_url='"&server_url&"'"
rs.open sql,conn,3,3
if not rs.eof then
rs("num")=application("count1")
rs.update
else
response.Write("该服务器URL在数据库中没有发现")
response.End()
end if
%>
<%
num=0
set rs=server.createobject("ADODB.recordset")
sql="select * from count"
rs.open sql,conn,3,3
while not rs.eof
num=num+cint(rs("num"))
rs.movenext
wend
%>
<br>
共计在线<%=num%>人
</body>
</html>
default.asp用户浏览页面
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<html>
<head>
<title>无标题文档</title>
</head>
<!--#include file=conn.asp -->
<body><iframe src="count.asp" marginheight="5" marginwidth="5" frameborder="0" scrolling="no"></iframe>
<form name="form1" method="post" action="write.asp">
<p>
<input name="user_name" type="text" id="user_name">
</p>
<p>
<input name="user_pass" type="password" id="user_pass">
</p>
<p>
<input type="submit" name="Submit" value="提交">
<input type="reset" name="Submit2" value="重置">
</p>
</form>
<form name="form1" method="post" action="s.asp">
<p>
<input name="condition" type="text" id="condition">
<input type="submit" name="Submit3" value="提交">
</p>
</form>
<%
x=request.Form("aa")
%>
<%set rs=server.createobject("ADODB.recordset")
sql="select * from message order by id desc"
rs.open sql,conn,3,3
%>
<%if not rs.eof and not rs.bof then%>
<%
rs.pagesize=10
pages=rs.pagecount
records=rs.recordcount
nowpage=request("page")
if nowpage="" then
nowpage=1
else
nowpage=cint(nowpage)
end if
rs.absolutepage=nowpage
%>
<%
dim m
m=0
while not rs.eof and m<rs.pagesize
%>
<table width="600" border="1" cellspacing="0" cellpadding="0">
<tr>
<td width="107"><%=rs("id")%></td>
<td width="263"><%=rs("name")%></td>
<td width="222"><%=rs("tim")%></td>
</tr>
</table>
<%
m=m+1
rs.movenext
wend
%>
<table width="600" border="1" cellspacing="0" cellpadding="0">
<tr>
<td>共[<%=pages%>]页 共[<%=records%>]记录
<%if nowpage<>1 then%>
<a href="default.asp?page=<%=nowpage-1%>">[上一页]</a>
<%else%>
[上一页]
<%end if%>
<%if nowpage<>pages then%>
<a href="default.asp?page=<%=nowpage+1%>">[下一页]</a>
<%else%>
[下一页]
<%end if%>
</td>
</tr>
</table>
<!--#include file=close.asp -->
<%end if%>
</body>
</html>
write.asp写入数据代码页
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<%response.buffer=true%>
<!--#include file=conn.asp -->
<%
dim user_name,user_pass
user_name=request.Form("user_name")
user_pass=request.Form("user_pass")
set rs=server.createobject("ADODB.recordset")
sql="select * from message"
rs.open sql,conn,3,3
if not rs.eof and not rs.bof then
rs.movelast
id=rs("id")+1
rs.movefirst
else
id=1
end if
rs.addnew
rs("id")=id
rs("name")=user_name
rs("pass")=user_pass
rs.update
rs.close
conn.close
set rs=nothing
set conn=nothing
response.Redirect("default.asp")
%>
s.asp查询页
<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<%response.buffer=true%>
<!--#include file=conn.asp -->
<%
dim condition
condition=request.Form("condition")
set rs=server.createobject("ADODB.recordset")
sql="select * from message where name like '%"&condition&"%'"
rs.open sql,conn,3,3
if not rs.eof then
m=rs.recordcount
response.Write(m)
response.Write("<br>")
while not rs.eof
response.Write(rs("name"))
response.Write("<hr>")
rs.movenext
wend
end if
rs.close
conn.close
set rs=nothing
set conn=nothing
%>
这样整个站点的代码就完成了,由于小弟水平有限加上时间仓促(5555,要期末考试了)请各位大侠指教,需要注意的是该程序在运行时需在数据库中count数据表中添加进WEB服务器的基本信息,具体更具情况而言,本程序在IIS5.0 +WIN 2000SERVER+SQL SERVER2000下运行通过
3台参加调试WEB服务器IP分别为: 192.168.0.253 192.168.0.250 192.168.0.251
……