Lập trình phân tán là gì

Đại Học Công Nghệ Thông Tin
ĐH Quốc Gia Tp HCM
____________***********_____________

Báo cáo môn học Lập Trình
Hệ Thống với Java
Đề tài số 7: Tìm hiểu Lập trình phân tán trong Java
(Nguồn Chương 5 cuốn Core Java™ 2 Volume II - Advanced Features, Seventh Edition)

GVHD: Bùi Thanh Hiếu(Msc)

Thành viên nhóm:
Huỳnh Thái Bình
Hoàng Minh Hải
Huỳnh Xuân Tâm
Phan Thanh Hưng

08520031
08520105
08520326
08520164

26/04/2011

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

Lời nói đầu
Lập trình đối tượng phân tán là một trong những vấn đề nóng bỏng của
công nghệ phần mền ngày nay. Java là ngôn ngữ đi tiên phong trong
việc giải quyết vấn đề lập trình phân tán. Ngày nay nếu bạn không biết
đến kỹ thuật lập trình này thì quả là một thiếu sót lớn. Từ .NET của
Microsoft cho đến Java của Sun tất cả đều hướng đến môi trường hợp
tác và tận dụng nguồn tài nguyên phân tán trên mạng. Chương này sẽ
giới thiệu với bạn khái niệm và cách cài đặt các đối tượng phân tán
bằng kỹ thuật RMI trong Java.
Nội dung chính:






The Roles of Client and Server.
Remote Method Invocations.
Setup for Remote Method Invocation.
Parameter Passing in Remote Methods.
Server Object Activation.
Java IDL and CORBA.
Remote Method Calls with SOAP.

Phân chia công việc trong nhóm:
 Bạn Huỳnh Thái Bình phụ trách phần:
The Roles of Client and Server.
Remote Method Invocations
 Bạn Hoàng Minh Hải phụ trách phần:
Setup for Remote Method Invocation
 Bạn Huỳnh Xuân Tâm phụ trách phần:
Parameter Passing in Remote Methods
Server Object Activation
 Bạn Phan Thanh Hưng phụ trách 2 phần cuối:
Java IDL and CORBA
Remote Method Calls with SOAP

1 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

I/. The Roles of Client and Server(Vai trò của Client và
Server):
- Lấy ý tưởng là thu thập thông tin trên một máy tính khách hàng và gửi
thông tin qua mạng cho máy chủ. Giả sử rằng một người sử dụng trên một máy
tính cá nhân sẽ điền vào mẫu yêu cầu thông tin. Dữ liệu được gửi đến máy chủ của
nhà cung cấp. Các máy chủ xử lý yêu cầu và gửi lại thông tin sản phẩm cho khách
hàng.
Figure 5-1. Transmitting objects between client and server

- Trong mô hình truyền thống client/server, khách hàng yêu cầu một định
dạng truyền tải và gửi dữ liệu yêu cầu đến máy chủ. Các máy chủ phân tích yêu
cầu định dạng và các định dạng phản ứng để truyền cho khách hàng. Khách hàng
sau đó phân tích những phản ứng và hiển thị nó cho người dùng.
- Nếu bạn thực hiện bằng tay, có một rắc rối lớn: Bạn phải thiết kế một định
dạng truyền tải, và bạn phải viết code cho việc chuyển đổi giữa dữ liệu và định
dạng truyền.

2 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

Note:
Trong ví dụ này, chúng tôi giả định rằng khách hàng là một máy tính tương tác với
một người sử dụng. Tuy nhiên, khách hàng đều có thể chạy một ứng dụng web và
yêu cầu một dịch vụ từ một chương trình chạy trên máy tính khác. Có hai đối
tượng giao tiếp, đối tượng khách hàng trong ứng dụng web và các đối tượng máy
chủ thực hiện các dịch vụ. Đây là một mô hình rất phổ biến trong thực tế.
- Chúng tôi quan tâm vào mô hình truyền thống client/server bởi vì nó làm
cho vai trò của các máy khách và máy chủ trực quan hơn.
- Cơ chế mà các lập trình viên làm cho khách hàng một phương pháp gọi
thường xuyên, mà không lo lắng về việc gửi dữ liệu qua mạng hay phân tích phản
ứng.đối tượng đã thực hiện công việc đó không nằm trong cùng một máy ảo. Nó có
thể không được thực hiện trong các ngôn ngữ lập trình Java.
- Giải pháp là cài đặt một proxy(sử uỷ quyền) cho các đối tượng server trên
client. Proxy là một phương pháp phổ biến. Các proxy client liên lạc với server.
- Lập trình viên của đối tượng máy chủ không muốn phiền phức với các giao
tiếp khách hàng. Giải pháp là cài đặt một đối tượng proxy thứ hai trên máy chủ.
Các máy chủ proxy giao tiếp với các proxy của khách hàng, và nó làm cho phương
pháp này phổ biến.
Figure 5-2. Remote method call with proxies

3 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

- Vậy làm thế nào để các proxy giao tiếp với nhau?
-> Điều đó phụ thuộc vào công nghệ thực hiện.
- Có ba sự lựa chọn phổ biến:
 RMI, Java Remote Method Invocation Technology hỗ trợ phương thức gọi
phân phối giữa các đối tượng Java.
 CORBA, Common Object Request Broker Architecture hỗ trợ phương thức
gọi giữa các đối tượng của bất kỳ ngôn ngữ lập trình. CORBA sử dụng
Internet Inter-ORB Protocol, hoặc IIOP, để giao tiếp giữa các đối tượng.
 SOAP, Simple Object Access Protocol cũng là ngôn ngữ lập trình trung gian.
Tuy nhiên, SOAP sử dụng một định dạng truyền dẫn dựa trên XML.
Note:
Microsoft sử dụng COM. Trong quá khứ, Microsoft đặt COM là một đối thủ so với
CORBA. Tuy nhiên, tại thời điểm này, Microsoft tập trung vào SOAP.
- CORBA và SOAP hoàn toàn là ngôn ngữ trung gian. Chương trình client
và server có thể được viết bằng C, C + +, Java, hoặc ngôn ngữ khác. Bạn cung cấp
một giao diện để xác định tín hiệu của các phương thức và các loại dữ liệu đối
tượng của bạn có thể xử lý. Những mô tả được định dạng bằng một ngôn ngữ đặc
biệt, được gọi là ngôn ngữ định nghĩa giao diện (IDL) cho CORBA và ngôn ngữ
mô tả các dịch vụ Web (WSDL) cho SOAP.
- Khá ít người tin rằng CORBA là mô hình đối tượng của tương lai. Thành
thật mà nói CORBA đã có ích trong việc triển khai các vấn đê phức tạp và các vấn
đề tương thích.
- SOAP có thể đơn giản, nhưng nó cũng có thể trở nên khá phức tạp, vì nó
yêu cầu nhiều tính năng hơn mà CORBA đã có. Các giao thức XML có lợi thế là
ngôn ngữ gần gũi với con người nên giúp ích cho việc gỡ rối. Nhìn chung,
CORBA hiệu quả hơn, mặc dù SOAP là một phù hợp tốt hơn cho một kiến trúc
web.
- Nếu cả hai đối tượng giao tiếp được thực hiện trong code Java, thì việc
dùng CORBA và SOAP là không cần thiết. Sun đã phát triển một cơ chế đơn giản,
đó là phương pháp triệu gọi phương thức từ xa-Remote Method Invocation (RMI),
đặc biệt dùng cho giao tiếp giữa các ứng dụng Java.

4 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

II./ Remote Method Invocations(Gọi phương thức từ xa):
- Nếu bạn có quyền truy cập vào một đối tượng trên một máy tính khác, bạn
có thể gọi các phương thức của đối tượng từ xa. Tất nhiên, các tham số phương
thức bằng cách nào đó phải được gửi đến các máy khác, máy chủ phải được thông
báo để thực hiện các phương thức, và giá trị trả về phải được return trở lại. RMI xử
lý việc này.
- Ví dụ: client tìm kiếm thông tin sản phẩm có thể truy vấn một đối tượng
trên máy chủ. Nó gọi một phương thức từ xa, tìm kiếm, trong đó có một tham số:
một đối tượng khách hàng. Việc tìm thấy trả về một đối tượng cho client: đối
tượng của sản phẩm
Figure 5-3. Invoking a remote method on a server object

- Trong thuật ngữ RMI , các đối tượng của phương thức tạo ra lời gọi từ xa
được gọi là client object. Các đối tượng từ xa được gọi là server object. Điều quan
trọng là phải nhớ rằng thuật ngữ client/server chỉ áp dụng cho một lời gọi phương
thức duy nhất. Các máy tính đang chạy code Java mà gọi phương thức từ xa là
client và máy tính lưu trữ các đối tượng mà thực hiện lời gọi là server. Điều này
hoàn toàn làm cho vai trò được đảo ngược lại. Server của một lời gọi trước đó có
thể trở thành client khi gọi một một đối tượng bằng phương thức từ xa ở trên máy
tính khác.

5 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

1/. Stubs and Parameter Marshalling:
- Khi client muốn gọi một phương thức từ xa trên một đối tượng từ xa, thì nó
gọi 1 phương pháp thông thường trên một đối tượng proxy gọi là stub. Stub nằm
trên máy client, không phải trên server. Ví dụ, trong giao thức RMI các đối tượng
được mã hoá với cơ chế tuần tự. Quá trình mã hóa các thông số được gọi là tham
số marshalling(parameter marshalling). Mục đích của tham số marshalling là
chuyển đổi các tham số vào một định dạng thích hợp cho việc vận chuyển từ máy
ảo với nhau.
- Phương thức stub trên client xây dựng một khối thông tin bao gồm:
o Nhận dạng đối tượng từ xa sẽ được sử dụng;
o Một mô tả của phương thức được gọi ;
o Các tham số marshalled.
- Phương thức stub sau đó gửi thông tin này tới server. Về phía server, một
đối tượng thực hiện các hành động cho mỗi lời gọi phương thức từ xa:
o Nó không có các thông số marshals.
o Nó định vị đối tượng được gọi .
o Nó gọi phương thức mong muốn.
o Nó sẽ giữ và sắp đặt giá trị trả về hoặc ngoại lệ của cuộc gọi.
o Nó sẽ gửi một gói gồm các dữ liệu trả về marshalled tới stub trên client

6 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

Figure 5-4. Parameter marshalling

- Quá trình này rõ ràng là phức tạp, nhưng nó hoàn toàn tự động và minh
bạch cho các lập trình viên. Hơn nữa, các nhà thiết kế của các đối tượng Java từ xa
đã cố gắng để cung cấp cho các đối tượng từ xa cùng "look and feel(xem và cảm
thấy)" như các đối tượng nội tại.

2./ Dynamic Class Loading:
- Khi truyền một đối tượng từ xa đến một chương trình khác, như là một
tham số hay giá trị trả về của một phương thức từ xa, thì chương trình đó phải có
các file class cho đối tượng đó. Ví dụ, hãy xem xét một phương thức với kiểu trả
về là các sản phẩm. Tất nhiên, chương trình client cần các lớp Product.class để
biên dịch. Nhưng bây giờ giả sử server khởi tạo và trả về một đối tượng sách, và
sách là một phân nhóm của sản phẩm. Các client có thể chưa bao giờ thấy class
Book, và nó có thể đã không biết nơi để tìm file lớp Book.class
- Do đó, một bộ nạp lớp đó sẽ được tải từ máy chủ. Quá trình này cũng
tương tự như quá trình nạp lớp của các applet chạy trong trình duyệt. Bất cứ khi
nào một chương trình tải mới mã từ một vị trí mạng, sẽ phát sinh vấn đề an ninh.

7 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

Vì lý do đó, bạn cần sử dụng một chương trình quản lý bảo mật(security manager)
trong các ứng dụng client RMI. Đây là một cơ chế an toàn để bảo vệ các chương
trình từ virus trong mã stub. Đối với các ứng dụng chuyên ngành, các lập trình có
thể thay thế bộ tải lớp của mình và quản lý an ninh, nhưng được cung cấp bởi hệ
thống RMI là đủ cho sử dụng bình thường.

III/. Setup for Remote Method Invocation(Cài đặt cho
phương pháp truyền dẫn dữ liệu từ xa):
- Ngay cả khi chạy những ví dụ đơn giản nhất các đối tượng từ xa(remote
object) yêu cầu nhiều hơn những thiết lập không chạy một chương trình độc lập
hoặc applet. Bạn phải chạy các chương trình trên cả các máy tính máy chủ và máy
khách. Các thông tin object cần thiết phải được tách vào vào phía giao diện máy
khách và giao diện máy chủ phía triển khai. Ngoài ra, một cơ chế đặc biệt cho phép
client tra cứu để xác định vị trí các object trên máy chủ.
- Để bắt đầu, chúng ta đi qua từng yêu cầu, sử dụng ví dụ đơn giản. Trong ví
dụ đầu tiên của chúng ta tạo ra một vài đối tượng của một loại sản phẩm trên máy
chủ. Sau đó chúng ta chạy một chương trình trên một máy tính client để xác định
vị trí và truy vấn các đối tượng này.

1/. Interfaces and Implementations(Giao diện và Triển khai):
- Chương trình client cần để thao tác các đối tượng server nhưng nó không
thực sự copy chúng . Các đối tượng tự cư trú trên máy chủ. Mã client vẫn phải biết
những gì nó có thể làm với các đối tượng, khả năng của chúng được thể hiện trong
một giao diện được chia sẻ giữa client và server và để cư trú đồng thời trên cả hai
máy.
interface Product // shared by client and server
extends Remote
{
String getDescription() throws RemoteException;
}

- Cũng như trong ví dụ này tất cả các giao diện cho các remote object phải
mở rộng giao diện từ xa được xác định trong gói java.rmi. Tất cả các phương
pháp trong các giao diện cũng phải biểu thị một Remote Exception. Lý do cho việc
khai báo là cuộc gọi phương thức từ xa vốn ít tin cậy hơn cuộc gọi địa phương,
luôn luôn có thể có một cuộc gọi từ xa sẽ thất bại. Ví dụ, máy chủ hoặc kết nối
mạng có thể tạm thời không có hoặc có vấn đề mạng. Code máy client của bạn
phải được chuẩn bị để đối phó với những khả năng này. Đối với những lý do này.
Ngôn ngữ lập trình Java buộc bạn phải theo kịp Remote Exception với tất cả các

8 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

cuộc gọi phương thức từ xa và để xác định các hành động thích hợp để có khi cuộc
gọi không thành công. Các khách hàng truy cập các đối tượng máy chủ thông qua
stub để thực hiện giao diện này.
Product p = . . .; // see below how the client gets a stub
reference
String d = p.getDescription();
System.out.println(d);

- Trong phần tiếp theo, bạn sẽ thấy làm thế nào client có thể có được một
tham chiếu đến loại đối tượng từ xa.
- Tiếp theo, ở phía máy chủ, bạn phải thực hiện các lớp mà thực sự thực hiện
các phương pháp quảng cáo trong giao diện từ xa.
public class ProductImpl // server
extends UnicastRemoteObject
implements Product
{
public ProductImpl(String d)
throws RemoteException
{
descr = d;
}
public String getDescription()
throws RemoteException
{
return "I am a " + descr + ". Buy me!";
}
private String descr;
}

NOTE
constructor ProductImpl được khai báo để dịch chuyển RemoteException vì
UnicastRemoteObject có thể dịch chuyển ngoại lệ nếu nó không thể kết nối
với dịch vụ mạng theo dõi các đối tượng máy chủ
- Lớp này có một phương pháp duy nhất, geTDescription ,có thể được gọi
từ các khách hàng từ xa

9 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

- Bạn có thể nói rằng class là một máy chủ cho các phương pháp điều khiển
từ xa bởi vì nó mở rộng UnicastRemoteObject, mà là một lớp Java nền tảng cho
các đối tượng truy cập từ xa.
NOTE
Lớp ProductImpl không phải là một lớp máy chủ điển hình bởi vì nó làm việc quá
ít. Thông thường, bạn chỉ muốn có máy chủ làm một số công việc nặng mà một
client không thể thực hiện. Chúng tôi chỉ sử dụng các ví dụ sản phẩm để hướng
dẫn bạn qua các cơ chế gọi các phương thức từ xa.
- Các class server thường mở rộng lớp RemoteServer từ gói
java.rmi.server. nhưng RemoteServer là một lớp trừu tượng mà chỉ xác định
các cơ chế cơ bản trong giao tiếp giữa máy chủ và các đối tượng khai từ xa Lớp
UnicastRemoteObject mà đi kèm với RMI mở rộng lớp trừu tượng và là
RemoteServer bạn có thể sử dụng nó mà không cần viết bất kỳ mã nào ."path of
least resistance "cho một lớp máy chủ là có nguồn gốc từ UnicastRemoteObject,
và tất cả các lớp máy chủ trong chương này làm như vậy.
Hình 5-5 cho thấy mối quan hệ thừa kế giữa các lớp này.

10 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

- Một đối tượng UnicastRemoteObject nằm trên máy chủ. Nó còn chạy
được khi một dịch vụ được yêu cầu và phải được truy cập thông qua giao thức TCP
/ IP. Đây là lớp mà chúng tôi mở rộng cho tất cả các lớp máy chủ trong cuốn sách
này và là lớp máy chủ chỉ có trong phiên bản hiện tại của gói RMI. Sun(mặt trời)
hoặc bên thứ ba nhà cung cấp có thể, trong tương lai, thiết kế các lớp khác để sử
dụng bởi các máy chủ cho RMI.
NOTE
Thỉnh thoảng, bạn có thể không muốn có một lớp máy chủ mở rộng lớp
UnicastRemoteObject, có lẽ bởi vì nó đã được mở rộng một lớp khác. Trong tình
hình đó, bạn cần phải tự khởi tạo các đối tượng máy chủ và truyền cho phương
thức exportObject tĩnh. Thay vì mở rộng UnicastRemoteObject,ta gọi:
UnicastRemoteObject.exportObject(this, 0);

Trong xây dựng của các đối tượng máy chủ. Tham số thứ hai là 0 để chỉ ra rằng bất
kỳ cổng thích hợp có thể được sử dụng để lắng nghe các kết nối client
- Khi bạn sử dụng RMI (hoặc bất kỳ cơ chế đối tượng phân tán, cho từng
vấn đề), bạn sẽ cần phải nắm vững một chút bối rối tập các lớp. Trong chương này,
chúng tôi sử dụng một quy ước đặt tên thống nhất cho tất cả các ví dụ của chúng
tôi mà chúng tôi hy vọng làm cho nó dễ dàng hơn để nhận ra mục đích của từng
loại(xem Bảng 5-1)

11 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

2/. Stub Class Generation:
- Theo JDK 5.0, tất cả các lớp stub được tạo ra tự động, sử dụng cơ chế
proxy thảo luận trong Tập 1, chương 6. Tuy nhiên, trước khi JDK 5.0, bạn phải tự
tạo ra khai với công cụ rmic, như trong ví dụ sau đây
rmic -v1.2 ProductImpl

-Điều này gọi đến các công cụ rmic tạo ra một lớp tập tin
ProductImpl_Stub.class

- Nếu bạn sử dụng JDK 1.1 hãy gọi:
rmic -v1.1 ProductImpl

- Hai tập tin được tạo ra: các tập tin stubs và lớp một tập tin thứ hai tên là
ProductImpl_Skel.class.
NOTE
Hãy nhớ đến đầu tiên biên dịch tập tin nguồn với javac trước khi chạy rmic. Nếu
bạn đang tạo ra khai cho một lớp trong một gói, bạn phải cung cấp cho rmic tên gói
đầy đủ.

3/. Locating Server Objects:
- Để truy cập một đối tượng từ xa mà tồn tại trên máy chủ, khách hàng cần
có một đối tượng stub địa phương, Làm thế nào có thể yêu cầu client như một stub.
Phương pháp phổ biến nhất là để gọi một phương thức từ xa của một đối tượng
server và nhận được một đối tượng stub như là một giá trị trả về.
- Tuy nhiên,có một vấn đề "con gà và quả trứng” ở đây. Các đối tượng máy
chủ đầu tiên đã được đặt một cách khác. The Sun RMI thư viện cung cấp dịch vụ
đăng ký khởi động để định vị các đối tượng máy chủ đầu tiên, Một chương trình
máy chủ đăng ký các đối tượng với dịch vụ đăng ký khởi động, và client truy khai
cho các đối tượng. Bạn đăng ký một đối tượng máy chủ bằng cách cho cơ quan
đăng ký khởi động dịch vụ một tham chiếu đến các đối tượng và tên một. Tên này
là một chuỗi được (hy vọng) độc đáo
// server
ProductImpl p1 = new ProductImpl("Blackwell Toaster");
Context namingContext = new InitialContext();
namingContext.bind("rmi:toaster", p1);

12 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

- Mã khách hàng nhận được một stub đối tượng để truy cập máy chủ bằng
cách chỉ định tên máy chủ và tên các đối tượng theo cách sau:
// client
Product p = (Product)
namingContext.lookup("rmi://yourserver.com/toaster");

- RMI URL bắt đầu với rmi: / / và được theo sau bởi một máy chủ, một
số cổng tùy chọn, giảm khác, và tên của các đối tượng từ xa. Một ví dụ khác là:
rmi://localhost:99/central_warehouse
- Mặc định thì server là localhost và port là 1099.

NOTE
Bởi vì nó là rất khó khăn để giữ các tên duy nhất trong một đăng ký toàn cầu, bạn
không nên sử dụng kỹ thuật này là phương pháp chung để định vị đối tượng trên
máy chủ. Thay vào đó, cần có tương đối ít đối tượng máy chủ tên đăng ký với dịch
vụ khởi động. đối tượng có thể xác định vị trí các đối tượng khác cho bạn. Trong ví
dụ của chúng tôi, chúng tôi tạm thời hành vi vi phạm quy tắc này và đăng ký các
đối tượng tương đối nhỏ để cho bạn thấy cơ chế đăng ký, định vị đối tượng.
- Vì lý do an ninh, ứng dụng có thể mở ra ràng buộc, hoặc đăng ký tài liệu
tham khảo đối tượng rebind chỉ khi nó chạy trên máy chủ giống như đăng ký. Điều
này ngăn cản các client thù địch từ thay đổi thông tin đăng ký. Tuy nhiên, bất kỳ
client cũng có thể tra cứu các đối tượng. Các dịch vụ RMI đặt tên là tích hợp vào
trong đặt tên Java và mục thông tin (JNDI) dịch vụ. Trong JDK 1.3 và dưới đây,
bạn sử dụng một dịch vụ RMI đặt tên độc, như thế này:
Naming.bind("toaster", p1); // on the server
Product p = (Product) Naming.lookup("rmi://yourserver.com/toaster");

TIP
Nếu bạn so sánh các máy chủ của chúng tôi với các ví dụ máy chủ trong tài liệu
hướng dẫn Sun, bạn sẽ lưu ý rằng chúng tôi không cài đặt một trình quản lý bảo
mật trong máy chủ. Trái ngược với các báo cáo trong hướng dẫn này, một quản lý
an ninh là không cần thiết cho các máy chủ RMI. Bạn cần một quản lý an ninh, nếu
client gửi đến các đối tượng máy chủ thuộc về các lớp mà máy chủ không biết. Tuy
nhiên, trong dịch vụ của chúng tôi, client chỉ gửi các thông số String. Nói chung,
nó có vẻ khôn ngoan để hạn chế nạp lớp động trên các máy chủ.

13 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

Example 5-1. ProductServer.java
1. import java.rmi.*;
2. import java.rmi.server.*;
3. import javax.naming.*;
4.
5. /**
6.
This server program instantiates two remote objects,
7.
registers them with the naming service, and waits for
8.
clients to invoke methods on the remote objects.
9. */
10. public class ProductServer
11. {
12.
public static void main(String args[])
13.
{
14.
try
15.
{
16.
System.out.println("Constructing server
implementations...");
17.
18.
ProductImpl p1 = new ProductImpl("Blackwell
Toaster");
19.
ProductImpl p2 = new ProductImpl("ZapXpress
Microwave Oven");
20.
21.
System.out.println("Binding server implementations
to registry...");
22.
Context namingContext = new InitialContext();
23.
namingContext.bind("rmi:toaster", p1);
24.
namingContext.bind("rmi:microwave", p2);
25.
System.out.println("Waiting for invocations from
clients...");
26.
}
27.
catch (Exception e)
28.
{
29.
e.printStackTrace();
30.
}
31.
}
32. }

Example 5-2. ProductImpl.java
1. import java.rmi.*;
2. import java.rmi.server.*;
3.
4. /**
5.
This is the implementation class for the remote product

14 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.

objects.
*/
public class ProductImpl
extends UnicastRemoteObject
implements Product
{
/**
Constructs a product implementation
@param n the product name
*/
public ProductImpl(String n) throws RemoteException
{
name = n;
}
public String getDescription() throws RemoteException
{
return "I am a " + name + ". Buy me!";
}
private String name;
}

Example 5-3. Product.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.

import java.rmi.*;
/**
The interface for remote product objects.
*/
public interface Product extends Remote
{
/**
Gets the description of this product.
@return the product description
*/
String getDescription() throws RemoteException;
}

4/. Starting the Server:
- Chương trình máy chủ của chúng tôi là không hoàn toàn sẵn sàng để chạy
được. Bởi vì nó sử dụng các chương trình khởi động RMI Registry, dịch vụ đó
phải có sẵn. Để bắt đầu đăng ký RMI theo UNIX, thực hiện các tuyên bố
rmiregistry &

15 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

- Nếu là Windows thì gọi:
start rmiregistry

- Giờ thì bạn có thể khởi động Server. Nếu là Unix thì chạy lệnh:
java ProductServer &

- Nếu là Windows thì chạy lệnh:
start java ProductServer

- Nếu bạn chạy chương trình theo cách sau:
java ProductServer

thì chương trình sẽ không bao giờ thoát ra bình thường.Điều này có vẻ kỳ lạ sau
khi tất cả, chương trình chỉ tạo ra hai đối tượng và đăng ký chúng.Trên thực tế,các
chức năng chính không xuất cảnh ngay lập tức sau khi đăng ký,như bạn mong đợi.
Tuy nhiên,khi bạn tạo 1 đối tượng của một lớp mở rộng UnicastRemoteObject,
một chủ đề riêng biệt để duy trì chương trình còn sống vô thời hạn được bắt đầu.
Vì vậy, chương trình tồn tại xung quanh để cho phép khách hàng để kết nối với nó.
TIP
Các phiên bản Windows của JDK bao gồm một lệnh, javaw, mà bắt đầu các phiên
dịch bytecode là một quá trình Windows riêng biệt và giữ nó chạy. Một số nguồn
khuyên bạn nên sử dụng javaw, không phải start java, để chạy một phiên Java
trong nền trong Windows cho RMI. Làm như vậy không phải là một ý tưởng tốt, vì
hai lý do. Windows không có công cụ để giết một quá trình nền javaw không hiển
thị trong danh sách công việc. Nó chỉ ra rằng bạn cần phải giết và khởi động lại
dịch vụ đăng ký khởi động khi bạn thay đổi STUB của một lớp đăng ký. Để giết
một quá trình mà bạn bắt đầu với lệnh bắt đầu, tất cả các bạn phải làm là nhấp
chuột vào cửa sổ và nhấn Ctrl + C
Còn có một lý do quan trọng để sử dụng lệnh start. Khi bạn chạy một quá trình
máy chủ bằng cách sử dụng javaw, tin nhắn gửi tới đầu ra hoặc lỗi được loại bỏ.
Đặc biệt, họ không được hiển thị ở bất cứ đâu. Nếu bạn muốn xem kết quả hoặc
thông báo lỗi, sử dụng start. Sau đó, thông báo lỗi ít nhất là hiển thị trên giao
diện điều khiển. Và tin tưởng chúng TÔI, bạn sẽ muốn nhìn thấy những tin nhắn
này. Rất nhiều những thứ có thể đi sai khi bạn thử nghiệm với RMI. Các lỗi phổ
biến nhất có lẽ là bạn quên chạy rmic. Sau đó, máy chủ than phiền về việc thiếu
STUB . Nếu bạn sử dụng javaw, bạn sẽ không thấy thông báo lỗi, và bạn sẽ gãi
đầu của bạn tự hỏi tại sao các CLIENT không có thể tìm thấy các đối tượng máy
chủ.

16 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

5/. Listing Remote Objects:
- Trước khi viết chương trình client, hãy xác minh rằng chúng ta đã thành
công trong việc đăng ký các đối tượng từ xa. Ta gọi:
NamingEnumeration

e = namingContext.list("rmi:");
để có được một điều tra của tất cả các đối tượng máy chủ với một rmi: URL. Việc
liệt kê sản lượng các đối tượng của loại NameClassPair, một lớp học bổ trợ có

chứa cả tên của đối tượng bị ràng buộc và tên của các lớp . Chúng tôi chỉ quan tâm
đến những cái tên:
while (e.hasMore()) System.out.println(e.next().getName());

- Ví dụ 5-4 chứa chương trình đầy đủ. Output sẽ là:
toaster
microwave

Example 5-4. ShowBindings.java
1. import java.rmi.*;
2. import java.rmi.server.*;
3. import javax.naming.*;
4.
5. /**
6.
This programs shows all RMI bindings.
7. */
8. public class ShowBindings
9. {
10.
public static void main(String[] args)
11.
{
12.
try
13.
{
14.
Context namingContext = new InitialContext();
15.
NamingEnumeration

e =
namingContext.list("rmi:");
16.
while (e.hasMore())
17.
System.out.println(e.next().getName());
18.
}
19.
catch (Exception e)
20.
{
21.
e.printStackTrace();
22.
}
23.
}
24. }

6/. The Client Side:

17 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

- Bây giờ, chúng ta có thể viết các chương trình CLIENT có yêu cầu từng
đối tượng sản phẩm mới được đăng ký để in mô tả của nó. chương trình CLIENT
có sử dụng RMI nên cài đặt một trình quản lý an ninh để kiểm soát các hoạt động
của các STUB động nạp. RMISecurityManager là như một người quản lý bảo
mật. Bạn cài đặt nó với chỉ dẫn sau:
System.setSecurityManager(new RMISecurityManager());

NOTE
Nếu tất cả các lớp (bao gồm cả stub ) có sẵn tại địa phương, sau đó bạn không thực
sự cần một người quản lý bảo mật. Nếu bạn biết tất cả các tập tin lớp của chương
trình của bạn tại thời gian triển khai, bạn có thể triển khai chúng tất cả các địa
phương. Tuy nhiên, nó thường xảy ra rằng chương trình tiến hóa máy chủ và các
lớp mới được thêm vào theo thời gian. Sau đó, bạn được hưởng lợi từ việc nạp lớp
năng động. Bất cứ lúc nào bạn mã tải từ một nguồn khác, bạn cần một người quản
lý bảo mật.
NOTE
Applet đã có một người quản lý bảo mật mà có thể kiểm soát tải của các lớp stub.
Khi sử dụng RMI từ applet, bạn không cài đặt một người quản lý bảo mật.
Example 5-5. ProductClient.java
[View full width]

1. import java.rmi.*;
2. import java.rmi.server.*;
3. import javax.naming.*;
4.
5. /**
6.
This program demonstrates how to call a remote method
7.
on two objects that are located through the naming
service.
8. */
9. public class ProductClient
10. {
11.
public static void main(String[] args)
12.
{
13.
System.setProperty("java.security.policy",
"client.policy");
14.
System.setSecurityManager(new RMISecurityManager());
15.
String url = "rmi://localhost/";

18 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java

Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh 2011

16.
// change to "rmi://yourserver.com/" when server
runs on remote machine
yourserver.com
17.
try
18.
{
19.
Context namingContext = new InitialContext();
20.
Product c1 = (Product) namingContext.lookup(url +
"toaster");
21.
Product c2 = (Product) namingContext.lookup(url +
"microwave");
22.
23.
System.out.println(c1.getDescription());
24.
System.out.println(c2.getDescription());
25.
}
26.
catch (Exception e)
27.
{
28.
e.printStackTrace();
29.
}
30.
}
31. }

7/. Running the Client:
- Theo mặc định, RMISecurityManager những hạn chế tất cả các mã trong
chương trình từ việc thiết lập kết nối mạng. Tuy nhiên, chương trình cần để làm
cho các kết nối mạng. Để đạt được đăng ký RMI, và để liên hệ với các đối tượng
máy chủ.
- Một khi các chương trình client được triển khai, nó cũng cần sự cho phép
để tải các lớp stub của nó. Chúng tôi quyết vấn đề này sau khi chúng tôi thảo luận
triển khai.
- Để cho phép các client để kết nối đến cơ quan đăng ký RMI và đối tượng
máy chủ, bạn cung cấp một tập tin chính sách. Chúng tôi thảo luận về các tập tin
chính sách cụ thể hơn trong chương 9. Để bây giờ, chỉ cần sử dụng và sửa đổi các
mẫu mà chúng tôi cung cấp. Dưới đây là một tập tin chính sách cho phép một ứng
dụng để thực hiện bất kỳ kết nối mạng vào một cổng với số cổng ít nhất là 1024.
(Cổng RMI là 1099 theo mặc định, và các đối tượng máy chủ cũng sử dụng cổng ≥
1024.)
grant
{
permission java.net.SocketPermission
"*:1024-65535", "connect";

19 Lập Trình Hệ Thống Với Java – Tìm hiểu lập trình phân tán trong Java