日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

怎么注销midas服务器程序,MIDAS的服务器镜像技术

發布時間:2023/12/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 怎么注销midas服务器程序,MIDAS的服务器镜像技术 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

隨著互聯網的發展以及電子商務應用的興起,多層分布式系統的開發和應用已成為企業和開發者關注的焦點之一。在一個執行關鍵作業的多層應用系統中,系統的穩定性是非常重要的,尤其是當客戶端正在執行一些重要程序時,應用程序服務器或數據庫服務器發生的任何故障都將造成多層應用系統無法正常運作。另外,如果應用程序服務器的負荷過重也會影響整個系統的執行效率,因此對于企業級關鍵程序,系統的容錯能力和負載平衡能力是開發人員必須重視的首要問題。

一般來說,容錯能力和負載平衡能力就是讓應用程序服務器在多個機器上執行,當客戶端應用程序執行時,可以連接到任何一臺機器中的應用程序服務器要求服務,以確保系統穩定,同時平衡每一臺服務器的負荷。

然而,當應用程序服務器執行于多臺機器時,又給數據庫服務器提出了新的挑戰:一方面,如果所有的應用程序服務器都通過同一遠程數據庫服務器訪問數據,那么數據庫服務器的故障同樣會影響整個系統的穩定性,而且可能超負荷工作;另一方面,如果每一個應用程序服務器都擁用各自的數據庫服務器或本地數據庫,這樣雖能提高系統的穩定性,但不能保證數據的一致性。

基于以上情況,本文提出了基于MIDAS的應用程序服務器鏡像技術方案和實現方法,用以開發安全堅固的分布式系統。

二、安全堅固的多層應用系統

1.多層分布式系統結構

一個多層分布式應用系統被分割成在不同機器上協同運行的邏輯單元。各邏輯單元通過局域網或Internet共享數據和通信,這種結構具有集中控制的商業邏輯、瘦客戶端應用程序等許多優點。多層分布式系統最典型的模式為三層結構,各部分的名稱和功能如下:客戶端應用程序在用戶機器上提供用戶界面;應用程序服務器位于可連接到所有客戶端的中央網絡位置,并提供公共的數據服務。應用程序服務器可運行于多個機器上;遠程數據庫服務器提供數據庫管理系統(RDBMS)。

MIDAS(Multi-tier

Distributed Application Services

Suite)即多層分布式應用程序服務器,是Inprise提供的集成了多種技術規范的多層分布式數據庫解決方案,是由Borland C++Builder(BCB)/Delphi用來開發多層應用系統使用的中介透明引擎,它具有在客戶端無需任何數據庫工具可以讀取遠程數據、網絡通信量小、多線程、數據庫自動約束及平衡負載的特點。如圖1所示的三層結構是多層分布式系統的典型代表。

2.開發具備容錯能力的應用系統

多層應用系統的容錯能力就是讓應用程序服務器在多個機器上執行,當客戶端應用程序執行時可以連接到任何一臺機器中的應用程序服務器要求服務。如果客戶端應用程序連接的服務器發生任何問題而無法繼續執行時,客戶端應用程序可以立刻連接到其他機器中的服務器繼續要求服務。

圖1基于MIDAS的三層應用系統的結構

開發具備容錯能力的多層應用系統,在應用程序服務器端與平常的系統沒有什么區別,而在客戶端應用程序中必須配合MIDAS編寫一些額外的代碼來實現容錯能力。

實現容錯能力的觀念很簡單,當客戶端應用程序連接到應用程序服務器之后,它就可以向服務器要求服務。但是當應用程序服務器故障時,客戶端應用程序如果向服務器要求服務,那么客戶端應用程序就會產生一個錯誤例外。此時客戶端可以調用TSimpleObjectBroker的SetConnectStatus方法以設定目前的應用程序服務器成為不堪使用狀態,然后再調用GetComputerForProgID方法要求取得另外一個可以使用的機器,以便在這個新的機器中連接提供相同服務的應用程序服務器。最后再調用新的服務器以取得服務。這個切換過程可以用圖2來說明。

圖2實現容錯能力的流程圖

3.開發具備負載平衡能力的應用系統

負載平衡的觀念是指當有多個能夠執行相同應用程序服務器的機器時,當有許多客戶端應用程序需要連接應用程序服務器時,多層系統能夠分配不同的客戶端應用程序到每一個機器中,以便平衡每一個應用程序服務器的負荷。BCB的TSimpleObjectBroker提供了負載平衡的功能,程序員只需將其屬性LoadBalanced設為True就可以提供簡單的負載平衡能力。

三、鏡像技術

由于多層應用系統可能運行于不同地域的不同機器上,設計者永遠無法預測多層應用系統在執行時會發生什么狀況,因此在分布式計算環境中,多層應用系統除了必須能夠正確而且有效率地運作之外,系統的負載平衡能力和容錯能力也非常重要。

多層應用系統的容錯能力和負載平衡都要求應用程序服務器在多個機器中執行,對于數據庫服務器,將有兩種可能的連接方式:一種是多個應用程序服務器都與同一個遠程數據庫服務器連接。采用這種連接方式時,系統的穩定性較低,如果遠程數據庫服務器故障,整個多層應用系統將無法正常運作;另一種是每一個應用程序服務器均與各自的數據庫服務器或本地數據庫相連。采用這種方式雖然可以提高系統的穩定性,但各服務器之間的數據互不相同,客戶端取得的數據就會不完整或不一致。

為了使多層應用系統既具有穩定性,又能保持數據的完整性,在實際應用中我們采用第二種連接方式,并在應用程序服務器中添加額外的代碼,使各服務器之間的數據保持一致,我們稱這種方法為應用程序服務器鏡像技術。本文以雙服務器為例來說明服務器鏡像技術的原理及實現方法。

1.動態服務器鏡像技術

動態服務器鏡像就是當多層應用系統中有多個應用程序服務器提供數據服務時,使各服務器中的數據動態地保持一致。

動態服務器鏡像的原理如圖3所示,當連接服務器1的客戶端應用程序(如客戶A)要求更新數據時,服務器1將數據更新到數據庫1,同時還將這些數據傳送給服務器2,由服務器2負責更新至數據庫2;同理,連接服務器2的客戶端應用程序(如客戶B)更新的數據也會同時更新到兩個數據庫管理系統中。這樣,兩個互相獨立的數據庫管理系統中的數據就能夠保持一致。

圖3應用服務器鏡像示意圖

在BCB/Delphi中,提供者組件(TdataSetProvider)負責將數據封裝進數據包,然后發送給客戶端數據集,并更新從客戶端數據集接收到的數據。提供者組件的大多數工作是自動進行的,不需要在提供者組件中編寫任何程序代碼就可創建具有完整功能的應用程序服務器。然而,提供者組件包括一定的事件和屬性,它們允許應用程序服務器更直接地控制為客戶端封裝的信息以及應用服務器如何響應客戶端請求。利用其中的OnUpdateData事件或BeforeUpdateRecord事件即可實現動態服務器鏡像。使用OnUpdateData事件可以處理完整的Delta包,而使用BeforeUpdateRecord事件可以對更新的記錄逐一地進行處理。

2.靜態數據對照

在多層應用系統的運作過程中,如果一個或多個服務器故障,在容錯技術的支持下,雖然系統仍能正常運作,但客戶更新的數據不能記載到故障服務器的數據庫中,數據的完整性便得不到保障。為此,采用了靜態對照的方法,即當故障服務器修復并重新投入運行時,主動與其他服務器對照,以提取最新的數據,從而保證客戶端應用程序始終得到一致的數據服務。

數據對照可以采用自動對照,也可以由管理員根據具體情況,人為地進行對照。自動對照就是,當應用程序服務器啟動時,自動與在線的某一服務器對照數據;人為對照則是,開發專用的對照程序,由系統管理人員根據情況,決定何時進行數據對照。

四、實現方法

1.動態服務器鏡像

在服務器端,利用提供者組件的OnUpdateData事件可以在服務器更新數據之前將客戶端應用程序傳來的數據更新到鏡像服務器中,以實現應用程序服務器鏡像,使各服務器之間的數據動態地保持一致。

客戶端的更新請求包括修改、插入和刪除三種。OnUpdateData事件處理函數應分別進行處理,下面給出的代碼,以插入操作為例來說明應用程序服務器鏡像技術的實現方法:

void __fastcall

TmsRDM::DataSetProvider1UpdateData(TObject

*Sender,

TCustomClientDataSet

*DataSet)

{

TClientDataSet?*table;?//table連接到鏡像服務器

TDateTime?dtValue=StrToDateTime(Now());?//當前時間

table=mTable;

table->Active=false;

DataSet->First();

if(Form1->SocketConnection1->Connected)

{

while(!DataSet->Eof)

{

switch(DataSet->UpdateStatus())

{

case

usUnmodified:?//處理修改的數據

table->Active=false;

//向服務器傳遞SQL

table->CommandText=AnsiString("select * from

demo where編號='")

+DataSet->FieldByName("編號")->AsString

+"'

and姓名='"+DataSet->FieldByName("姓名")->AsString+"'";

table->Active=true;?//查詢

if(table->RecordCount>0)?//鏡像服務器中已存在該記錄,則修改

table->Edit();

else

{?//不存在則添加此記錄

able->Append();

for(int

i=0;iFieldCount;i++)

if(DataSet->Fields->Fields[i]->AsString!="")

table->Fields->Fields[i]->AsString=DataSet->Fields->Fields[i]->AsString;

}

DataSet->Next(); //修改狀態下,DataSet中有兩條相鄰的記錄說明修改情況,

//前一條是原始數據,后一條是修改的數據

DataSet->Edit();

DataSet->FieldByName("DATE_TIME")->AsDateTime=dtValue;

//記錄修改時間

DataSet->Post();

for(int

i=0;iFieldCount;i++)

if(DataSet->Fields->Fields[i]->AsString!="")

table->Fields->Fields[i]->AsString=DataSet->Fields->Fields[i]->AsString;

table->FieldByName("DATE_TIME")->AsDateTime=dtValue;

//記錄修改時間

table->Post();

break;

case

usInserted:?//處理插入記錄

DataSet->Edit();

DataSet->FieldByName("DATE_TIME")->AsDateTime=dtValue;

DataSet->Post();

table->Active=false;

table->CommandText=AnsiString("select

* from demo where編號='")

+DataSet->FieldByName("編號")->AsString

+"'

and姓名='"+DataSet->FieldByName("姓名")->AsString+"'";

table->Active=true;

if(table->RecordCount>0)

table->Edit();

else

table->Append();

for(int

i=0;iFieldCount;i++)

if(DataSet->Fields->Fields[i]->AsString!="")

table->Fields->Fields[i]->AsString=DataSet->Fields->Fields[i]->AsString;

table->FieldByName("DATE_TIME")->AsDateTime=dtValue;

table->Post();

break;

case

usDeleted:?//刪除記錄

table->Active=false;

table->CommandText=AnsiString("select

* from demo where編號='")

+DataSet->FieldByName("編號")->AsString

+"'

and姓名='"+DataSet->FieldByName("姓名")->AsString+"'";

table->Active=true;

if(table->RecordCount>0)?//鏡像服務器中存在此記錄則刪除

table->Delete();

break;

}

table->ApplyUpdates(-1);

table->Active=false;

DataSet->Next();

}

}

//記錄修改時間

DataSet->First();

while(!DataSet->Eof)

{

switch(DataSet->UpdateStatus())

{

case

usUnmodified:

DataSet->Next();

DataSet->Edit();

DataSet->FieldByName("DATE_TIME")->AsDateTime=dtValue;

DataSet->Post();

break;

case

usInserted:

DataSet->Edit();

DataSet->FieldByName("DATE_TIME")->AsDateTime=dtValue;

DataSet->Post();

break;

}

DataSet->Next();

}

DataSet->First();

//實際更新時從第一條記錄開始

}

2.容錯處理

在客戶端更新數據時,若原先連接的服務器故障,用以下代碼能自動連接到提供相同服務的機器,繼續取得數據服務:

if (ClientDataSet1->ChangeCount > 0)

{

try {

ClientDataSet1->ApplyUpdates(-1);?//數據更新

ClientDataSet1->Refresh();

}

catch(...)

{

SimpleObjectBroker1->SetConnectStatus(

SocketConnection1->Address,false);?//記錄服務器失敗

SocketConnection1->Connected=false;

SocketConnection1->Address=

SimpleObjectBroker1->GetComputerForProgID("mirrorserver.msRDM");

SocketConnection1->Connected=true;

updateBtn->Click();?//用新的服務器更新

}

}

3.靜態數據對照

Table1->Active=true;

ClientDataSet1->Active=true;

while(!ClientDataSet1->Eof)

{

AnsiString?Filter,Num,Name;

Num=ClientDataSet1->FieldByName("編號")->AsString;

Name=ClientDataSet1->FieldByName("姓名")->AsString;

Filter=AnsiString("編號='")+Num

+"'

and姓名='"+Name+"'";

Table1->Filter=Filter;?//設置過濾器,用于條件導航

if(Table1->FindFirst())

{?//如果存在相同的記錄

if(Table1->FieldByName("DATE_TIME")->AsString

!=ClientDataSet1->FieldByName("DATE_TIME")->AsString)

Table1->Edit();?//更新時間不同時,修改

else

{

ClientDataSet1->Next();

//數據相同時,繼續處理下一記錄

continue;

}

}

else

{?//不存在時,插入記錄

Table1->Insert();

}

for(int

i=0;iFieldCount;i++)?//使兩個服務器的數據一致

Table1->Fields->Fields[i]->AsString

=ClientDataSet1->Fields->Fields[i]->AsString;

Table1->Post();

ClientDataSet1->Next();

}

Table1->Active=false;

ClientDataSet1->Active=false;

4.軟件握手

軟件握手是指服務器向在線的某一服務器發送啟動或關閉鏡像服務請求,并在收到鏡像請求后,進行相應的處理。

void __fastcall TForm1::Timer1Timer(TObject

*Sender)

{//用定時器監視鏡像狀態

if(Mirror)

{

Timer1->Enabled=false;

Button1->Click();?//連接鏡像服務器

}

else

if(SocketConnection1->Connected) {

Timer1->Enabled

=false;

ClientDataSet1->DataRequest(AnsiString("Mirror"));?//發送啟動請求

}

}

void __fastcall TForm1::FormClose(TObject

*Sender, TCloseAction &Action)

{//服務器關閉時,通知與其有鏡像關系的服務器

if(SocketConnection1->Connected)

{

ClientDataSet1->DataRequest(AnsiString("Close"));?//停止鏡像服務

SocketConnection1->Connected=false;

ShowMessage("關閉服務器");

}

if(ChangeIp||(!FileExists("ipaddress.txt")))

{?//保存鏡像服務的IP地址

TFileStream?*fStream=new

TFileStream("ipaddress.txt",fmCreate);

int?size=Edit1->Text.Length();

fStream->Write(Edit1->Text.c_str(),size);

fStream->Size=size;

delete

fStream;

}

}

//處理握手信息

OleVariant __fastcall

TmsRDM::DataSetProvider1DataRequest(TObject

*Sender,

OleVariant

&Input)

{

AnsiString?TmpStr=(WideString)Input;

if(TmpStr=="Close")

Form1->SocketConnection1->Connected=false;?//與鏡像服務器斷開連接

else

if(TmpStr=="Mirror")

Form1->Mirror=true;?//啟動鏡像

}

五、結語

通過分析MIDAS容錯處理和負載平衡機制,提出了在多服務器系統中的服務器鏡像技術,并介紹了服務器鏡像技術的原理和實現方法。文中所介紹的服務器鏡像技術,只需少量的代碼,卻能使多層應用系統既具有穩定性,又能保持數據的完整和一致性,在實際應用中加以改進和完善,將有很好的參考和利用價值。

總結

以上是生活随笔為你收集整理的怎么注销midas服务器程序,MIDAS的服务器镜像技术的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。