最近閑來無事就對“分布式系統”做了一點小小的研究,我覺得這種技術相當不錯,可能很多朋友都聽說過“分布式”這個概念,我對這種技術的個人理解就是:分布式系統包括很多成員,它們之間資源是相互共享的,從大的方面看是共同擔負處理任務,但是以個體為單位單獨處理每個小的任務,然后被一個中央處理單元將所有信息合并的一個系統。這種技術就是基于服務器端的一種技術,我就按照我的理解來做了一個簡單的模型(做錯的地方請大家指教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
|