Tải bản đầy đủ (.pdf) (11 trang)

Lập trình phân tán với Java RMI (remote method invole)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (594.03 KB, 11 trang )

Trang 222
Chng 10: LP TRÌNH PHÂN TÁN VI
JAVA RMI ( REMOTE METHOD INVOKE)
Lp trình phân tán vi RMI là mt trong nhng vn  nóng bng ca nn công
nghip phn mm ngày nay.  giúp các bn có các kin thc c bn v lp trình phân tán
và công ngh lp trình phân tán RMI. Chng này ta tho lun v các khía cnh ó.
Sau khi hc xong chng này ngi hc có th:
Hiu c khái nim v lp trình phân tán và công ngh RMI
ng dng công ngh RMI  xây dng các ng dng phân tán
Chuyn tham s cho phng thc triu gi t xa và nhn kt qu tr v t phng thc
triu gi t xa
I. RMI và lp trình phân tán i tng
Thông thng mã lnh ca mt chng trình khi thc thi c tp trung trên cùng
t máy, ây là cách lp trình truyn thng. S phát trin nh v bão ca mng máy tính
c bit là mng Internet toàn cu, ã khin các chng trình truyn thng này không còn
áp ng c yêu cu na. Các chng trình bây gi yêu cu phi có s hp tác x lý, tc
là mã lnh ca nó ã không tp trung trên mt máy mà c phân tán trên nhiu máy. Khi
t ng dng có mã lnh thc thi c phân tán trên nhiu máy thì chng trình ó c
i là chng trình phân tán và vic lp trình  to ra các chng trình này c gi là lp
trình phân tán. Có rt nhiu công ngh lp trình phân tán nh: DCOM, CORBA, RMI,
EJB.. trong ó RMI là công ngh thun Java và d lp trình nht.
Thông thng nu các i tng c tp trung trên cùng mt máy thì bn có th
triu gi các phng thc ca nó bng cách gu cho nó mt thông báo, câu hi t ra là
làm th nào  có th triu gi các phng thc ca mt i tng nm trên mt máy khác.
ây chính là ni dung ca lp trình phân tán mã lnh RMI (Remote Method Invoke – tm
ch là triu gi phng thc t xa). RMI là cách thc giao tip gia các i tng Java có
mã lnh cài t (bao gm c phng thc và thuc tính) nm trên các máy khác nhau có th
triu gi ln nhau.
Hình sau mô hình triu gi i tng phân tán. Trên máy A các i tng A1, A2
i các phng thc ca nhau c gi là triu gi phng thc cc b (local method
invoke) ây là cách lp trình hng i tng truyn thng vn s dng, tng t các i


ng B1, B2, B3 là các i tng cc b.
Tuy nhiên các i tng Java có th triu gi phng thc ca mt i tng nm
trên mt máy khác da vào giao thc triu gi t xa RMI. Trong mô hình di ây thì li
triu gi phng thc ca i tng B2 ( nm trên máy B) ti tng A1 ( nm trên máy
A) là li gi phng thc t xa.
Trang 223
II. Gi phng thc t xa và các vn  phát sinh
Vic triu gi mt phng thc t xa thot nhìn có vn gin nhng thc t li
phc tp hn triu gi phng thc cc b. Các i tng trên hai máy khác nhau hot
ng trên hai tin trình khác nhau (có hai không gian a ch khác nhau) nên vic tham
chiu bin a chi tng là khác nhau. Ví d khi bn truyn mt i tng cho mt
phng thc triu gi t xa thì thc s bn truyn mt tham chiu i tng n phng
thc t xa, tuy nhiên vùng nh thc s ca i tng li nm trên mt máy khác. Li gi
phng thc cc b luôn tr v kt qu thông qua ngn xp trong khi li gi phng thc
 xa kt qu tr v phi thông qua kt ni mng chính vì vy các s c v truyn thông
luôn có th sy ra, nh vy vic bt và kim soát li trong các ng dng phân tán là rt t.
III. Vai trò ca các lp trung gian
 i vi li gi phng thc cc b, các tham s truyn vào phng thc cng nh
t qu tr v t phng thc c thc hin thông qua ngn xp (stack) trong khi li gi
phng thc t xa phi c óng gói và chuyn qua mng.
 n gin và trong sut i vi ngi lp trình i tng Java trên hai máy khác
nhau không triu gi phng thc ca nhau mt cách trc tip mà thông qua lp trung gian.
p trung gian tn ti  c hai phía: phía máy khách (ni gi phng thc ca i tng 
xa) và máy ch (ni i tng thc sc cài t). Phía máy khác lp trung gian này
c gi là stub (lp móc), phía máy ch lp trung gian c gi là skeletion (lp ni).
Ta có th hình dung lp trung gian stub và skel là hai ngi trung gian giúp các i
ng  xa có th giao dch c vi nhau.
Máy A
A1
A2

Máy B
B1
B2
B3
Máy C
C
Hình 1: Mô hình triu gi các phng thc t xa
Trang 224
Trong hình trên bn có i tng C1 c cài t trên máy C. trình biên dch Java
giúp ta to ra hai lp trung gian C1_stub và C1_skel. Lp C1_stub c mang v máy A.
Khi A1 trên máy A triu gi phng thc ca i tng C1 nó s chuyn li gi phng
thc cho lp trung gian C1_stub. Lp trung gian C1_stub có trách nhim óng gói các tham
 chuyn tham s qua mng n phng thc c triu gi ca i tng C1. Trên máy
C lp trung gian C1_Skel có nhim v nhn các tham s và chuyn vào vùng a ch thích
p sau ó gi phng thc tng ng. Kt qu tr v (nu có) ca phng thc do C1 tr
 sc lp C1_Skel óng gói và chuyn ngc v cho trình khách. Trên máy khách lp
trung gian C1_Stub chuyn giao kt qu cui cùng li cho A1. Bng c ch này A1 luôn
ngh rng i tng C1 ang tn ti ngay trên cùng máy vi nó nh các i tng cc b
khác. Hn na nh có lp trung gian C1_Stub mà khi kt ni mng gp s c thì lp trung
gian stub s luôn bit cách thông báo li n i tng A1.
Thc t làm cách nào A1 tham chiu c n C1, mt khi không có i tng C1 c
cài t trên máy A? C1_Stub trên máy A ch thc hin vic chuyn tham s, nhn kt qu
tr v nu có và thc hin các giao thc mng, nó không phi là hình nh ca C1.  làm
c u này i tng C1 cn cung cp mt giao din tng ng vi các phng thc mà
các i tng trên máy khác có th triu gi. Chúng ta tip tc làm sáng tìêu này khi nói
 giao din t xa.
IV. Cài t i tng phân tán
1. Giao din t xa
Khi bn mun to ra mt s vt t xa thì bn che mt n cài t nn bng cách
truyn qua mt giao din. Vy khi khách thu c mt tham chiu n i tng t

xa thì thc cht ó là mt giao din.
Máy A
C1_stub
A1
A1
B1_stub
Máy C
C1_skel
C1
Máy B
B1
B1_skel
Hình 2: Gi phng thc ca i tng thông qua lp trung gian
Trang 225
Khi to ra mt giao din t xa, thì bn phi tuân theo các hng dn sau:
Giao din t xa phi là mt giao din public, tc là khi to ra mt giao din t xa ta phi
thêm t khoá public vào trc nh ngha giao din. Bng không, khi bn tham chiu
n i tng t xa bn s thu c mt ngoi l
Giao din t xa phi là giao din c k tha t giao din Remote
i phng pháp trong giao din t xa phi khai báo RemoteException trong mnh 
throws bên bt c ngoi l nào khác, tc là tt c các phng thc trong giao din t xa
u phi ném ra ngoi l RemoteException
u tham s truyn cho phng thc hoc giá tr nhn v t thc triu gi t xa là mt
i tng thì i tng ó phi trin khai giao din Remote hoc giao din Serializable
Thông thng bn thng thy mt giao din t xa có cu trúc nh sau:
import java.rmi.*;
public interface RemoteInterface extends Remote{
[public] ReturnDataType method1([DataType arg1,][ DataType arg2,] ) throws
RemoteException;
[public] ReturnDataType method2() throws RemoteException;

}
Ví d 1-1: Sau ây là mt giao din t xa n gin ca ng dng HelloRMI
HelloRMI.java
import java.rmi.*;
public interface HelloRMI extends Remote{
public String sayHello() throws RemoteException;
}
Nhìn vào giao din này ta thy nó ging bt k giao din nào khác ngoi tr nó c
 rng t giao din Remote và tt c các phng thc trong giao din này u phi nem
ra ngoi l RemoteException, bn hãy nh rng tt c các phng thc c khai báo trong
giao din s tng là public, th nên trong giao din trên bn có th b t khoá public khi
khai báo phng thc sayHello.
Bn tin hành biên dch javac HelloRMI.java bn s thu c tp tin HelloRMI.class
2. Trin khai giao din t xa
Sau khi bn to ra giao din t xa, công vic tip theo mà bn cn phi làm là trin
khai tt c các phng thc trong giao din t xa.
Ví d 1-2: Sau ây là cài t ca giao din t xa HelloRMI
HelloRMIImpl.java
import java.rmi.*;
public class HelloRMIImpl implements HelloRMI {
public String sayHello() throws RemoteException
{
return "Hello RMI";
}
}
Vn t ra là làm th nào  cài t i tng HelloRMI lên mt máy (máy 2) và gi
phng thc sayHello() ca HelloRMI t máy khác (máy 1)? Nhã nêu  trên ta không
i c phng thc sayHello ca HelloRMI mt cách trc tip mà cn có thêm hai lp
trung gian là HelloRMIImpl_Stub và HelloRMIImpl_Skel. Da vào lp
Trang 226

HelloRMIImpl.class, trình biên dch rmic.exe ca Java s giúp ta to ra hai lp trung gian
Stub và Skel. Bn m ca s DOS – Prompt và gõ vào dòng lnh
Rmic HelloRMIImpl.class
t qu bn s thu c hai tp HelloRMIImpl_Stub.class và HelloRMIImpl_Skel.class
3. Cài t, ng kí i tng t xa
Bc tip theo sau khi bn cài t giao din t xa là công vic ng ký nó vi trình
rmiregistry theo mu sau:
Ví d 1-4: Ví d sau là chng trình ng ký và cài t i tng HelloRMIImpl vi trình
ch rmiregistry.
Setup.java
import java.rmi.server.*;
import java.rmi.*;
import java.net.*;
public class Setup {
public static void main(String[] args) {
// to ra mt th hin ca i tng t xa
HelloRMI h=new HelloRMIImpl();
try {
// Khai báo i tng có kh nng triu gi t xa
UnicastRemoteObject.exportObject(h);
// ng ký nó vi trình rmiregistry
Naming.bind("//localhost/hello, h);
// có th thay phng thc bind bi phng thc rebind nh sau:
// Naming.rebind("//localhost/hello, h);
}
catch (MalformedURLException ex) {
}
catch (AlreadyBoundException ex) {
}
catch (RemoteException ex) {

}
}
}
Công vic u tiên bn phi làm khi cài t i tng t xa là to ra mt th hin
a i tng t xa.
HelloRMI h=new HelloRMIImpl(); bn có th thay bng dòng lnh
HelloRMIImpl h=new HelloRMIImpl();
Tip theo bn gi phng thc tnh exportObject ca lp UnicastRemoteObject  máy o
java bit i tng h (HelloRMI) là i tng có kh nng truy xut t xa.
UnicastRemoteObject.exportObject(h);
u ý  s dng c lp UnicastRemoteObject bn phi khai báo import
java.rmi.server.*; u chng trình

×