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

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

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 (1.57 MB, 81 trang )

Đạ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 08520031
Hoàng Minh Hải 08520105
Huỳnh Xuân Tâm 08520326
Phan Thanh Hưng 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



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

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

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

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

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.
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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


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











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

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


- 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.

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

2011

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

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.
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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


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












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

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

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.
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011


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

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
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

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
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

- 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.


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

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

- 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)



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

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

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);

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

2011

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

- 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ủ.

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

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

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
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

6. objects.
7. */
8. public class ProductImpl
9. extends UnicastRemoteObject
10. implements Product
11. {
12. /**
13. Constructs a product implementation
14. @param n the product name
15. */
16. public ProductImpl(String n) throws RemoteException
17. {
18. name = n;
19. }
20.
21. public String getDescription() throws RemoteException
22. {
23. return "I am a " + name + ". Buy me!";
24. }
25.
26. private String name;

27. }

Example 5-3. Product.java
1. import java.rmi.*;
2.
3. /**
4. The interface for remote product objects.
5. */
6. public interface Product extends Remote
7. {
8. /**
9. Gets the description of this product.
10. @return the product description
11. */
12. String getDescription() throws RemoteException;
13. }

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 &
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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


- 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ủ.

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

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

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<NameClassPair> 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<NameClassPair> 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:
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

- 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/";
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

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";
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

20

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

};

NOTE
Nhiều đối tượng máy chủ trên cùng một máy chủ có thể chia sẻ một cổng. Tuy
nhiên, nếu một cuộc gọi từ xa được thực hiện và cảng bận rộn, cảng khác được mở
ra tự động. Vì vậy, bạn nên mong đợi cổng nào được sử dụng ít hơn có các đối
tượng từ xa trên máy chủ.

- Trong chương trình client, chúng tôi hướng dẫn quản lý an ninh để đọc các
file chính sách bằng cách thiết lập thuộc tính java.security.policy với tên file. (.
Chúng tôi sử dụng file client.policy trong các chương trình ví dụ của chúng
tôi)
System.setProperty ("java.security.policy", "client.policy");
- Ngoài ra, bạn có thể chỉ định thiết lập hệ thống tài sản trên dòng lệnh:
java-Djava security.policy =. client.policy ProductClient

NOTE
Trong JDK 1.1, một tập tin chính sách đã không được yêu cầu cho khách hàng
RMI. Bạn không cần một tập tin chính sách cho các applet, hoặc, cung cấp máy
chủ và đăng ký RMI RMI đều nằm trên máy chủ phục vụ các mã applet

- Nếu đăng ký RMI và máy chủ vẫn còn đang chạy, bạn có thể tiến hành để
chạy các máy khách. Hoặc, nếu bạn muốn bắt đầu từ đầu, giết RMI registry và máy
chủ. Sau đó làm theo các bước sau:
1) Compile the source files for the interface, implementation, client, and server
classes.
javac Product*.java


2) If you use JDK 1.4 or below, run rmic on the implementation class.
rmic -v1.2 ProductImpl

3) Start the RMI registry.
rmiregistry &
or
start rmiregistry
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

4) Start the server.
java ProductServer &
or
start java ProductServer
5) Run the client.
java ProductClient
(Make sure the client.policy file is in the current directory.)
- Chương trình đơn giản là in ra:
I am a Blackwell Toaster. Buy me!
I am a ZapXpress Microwave Oven. Buy me!

- Output này không có vẻ tất cả những gì ấn tượng, nhưng xem xét những gì
diễn ra ở hậu trường khi các chương trình client thực hiện các cuộc gọi đến các
phương pháp getdescription. Chương trình client có một tham chiếu đến một
đối tượng stub rằng nó thu được từ phương pháp tra cứu. Nó gọi phương pháp
geTDescription, đó gửi một thông điệp mạng cho một đối tượng thu trên phía
máy chủ. Các đối tượng tiếp nhận viện dẫn phương thức getdescription trên đối

tượng ProductImpl nằm trên máy chủ. Đó là phương pháp tính toán một chuỗi.
Người nhận sẽ gửi chuỗi trên mạng. stub Các nhận được nó và trả về nó như là kết
quả (xem Hình 5-6).

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

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

8/. Preparing for Deployment:
- Triển khai một ứng dụng sử dụng RMI có thể được khó khăn bởi vì rất
nhiều điều có thể đi sai và các thông báo lỗi mà bạn nhận được khi một cái gì đó
mơ hồ . Chúng tôi đã tìm thấy rằng nó thực sự đền đáp cho giai đoạn triển khai tại
địa phương. Trong bước chuẩn bị, riêng các lớp tập tin vào ba thư mục con:
server
download
client
- Các máy chủ thư mục chứa tất cả các file cần thiết để chạy các máy chủ.
Bạn sau đó sẽ di chuyển các tập tin này vào máy chạy quá trình máy chủ. Trong ví
dụ của chúng tôi, máy chủ thư mục chứa các tập tin sau đây:
server/
ProductServer.class
ProductImpl.class
Product.class
CAUTION
Nếu bạn sử dụng JDK 1.4 hoặc dưới đây, thêm các lớp stub (như
ProductImpl_Stub.class) vào thư mục máy chủ. Chúng là cần thiết khi máy
chủ đăng ký các đối tượng thực hiện. Trái ngược với niềm tin phổ biến, máy chủ sẽ
không xác định vị trí chúng trong thư mục tải về, ngay cả khi bạn thiết lập các cơ

sở mã. Cần :
client/
ProductClient.class
Product.class
client.policy
- Bạn sẽ triển khai những tập tin trên máy khách. Cuối cùng, các thư mục
chứa các tập tin tải về lớp cần thiết cho đăng ký RMI, khách hàng, và máy chủ,
cũng như các lớp họ phụ thuộc vào. Trong ví dụ của chúng tôi, các thư mục tải về
sẽ như thế này
download/
Product.class
CAUTION
Hãy nhớ rằng ba máy ảo sử dụng thư mục download: các khách hàng, máy chủ, và
đăng ký RMI. Việc đăng ký RMI cần các tập tin lớp học cho các giao diện từ xa
của các đối tượng mà nó liên kết. client và máy chủ cần có tập tin lớp học cho các
thông số và giá trị trả lại.
- Bạn cần phải chạy một máy chủ web để phục vụ các tập tin lớp học trên
máy tính của bạn. Nếu bạn không có một máy chủ web cài đặt, tải về từ
và cài đặt nó. Tạo một thư mục tomcat / webapps
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

/ download, nơi tomcat là thư mục gốc cài đặt Tomcat của bạn. Tạo một thư mục
tomcat / webapps / download / WEB-INF, và để các tập tin tối thiểu sau đây
web.xml trong thư mục WEB-INF:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web

Application 2.3//EN"
"
<web-app>
</web-app

- Sau đó copy file class từ thư mục download vào thư mục
tomcat/webapps/download.
- Kế tiếp, chỉnh sửa file client.policy. Nó cần phải cấp cho client những
quyền hạn sau:
+ Để kết nối với cổng 1024 và ở trên để đạt được đăng ký RMI và triển khai
máy chủ; Để kết nối với cổng 80 (cổng HTTP tiêu chuẩn) để tải các tập tin lớp
stub. Bạn có thể bỏ qua sự cho phép này nếu bạn sử dụng Tomcat như là một
serverit web sử dụng cổng 8080 mặc định
- Thay đổi file sao cho giống như sau:
grant
{
permission java.net.SocketPermission
"*:1024-65535", "connect";
permission java.net.SocketPermission
"*:80", "connect";
};

- Cuối cùng, bạn đã sẵn sàng để thử nghiệm thiết lập của bạn.
1. Khởi động máy chủ web.
2. Điểm một trình duyệt web vào URL download
(http://localhost:8080/download/Product.class cho Tomcat) để xác minh rằng các
máy chủ web đang chạy.
3. Bắt đầu một lớp vỏ mới. Hãy chắc chắn rằng đường dẫn lớp là không
được đặt để bất cứ điều gì. Thay đổi vào một thư mục mà không chứa các tập tin
lớp. Sau đó bắt đầu đăng ký RMI.

4. Bắt đầu một lớp mới. Thay đổi vào thư mục máy chủ. Khởi động máy
chủ, cho một URL vào thư mục tải về là giá trị của tài sản
java.rmi.server.codebase:
java -Djava.rmi.server.codebase=http://localhost:8080/download/
ProductServer &
Trường Đại Học Công Nghệ Thông Tin – Đại Học Quốc Gia Hồ Chí Minh
2011

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

5. Thay đổi vào thư mục client. Hãy chắc chắn rằng các file client.policy là
trong thư mục đó. Bắt đầu cho client
java -Djava.security.policy=client.policy ProductClient

TIP
Nếu bạn không muốn cài đặt một máy chủ web tại địa phương, bạn có thể sử dụng
một URL tập tin để kiểm tra nạp lớp. Tuy nhiên, thiết lập được một chút phức tạp
hơn. Thêm dòng
permission java.io.FilePermission "downloadDirectory", "read ";
vào tập tin chính sách client của bạn. Ở đây, các thư mục tải về là tên đường dẫn
đầy đủ đến thư mục tải về, kèm theo trong dấu ngoặc kép, và kết thúc bằng một
dấu trừ (để chỉ tất cả các file trong thư mục và thư mục con của nó). Ví dụ:
permission java.io.FilePermission "/ home/test/download/-",
"read";
Trong tên tập tin Windows, bạn phải tăng gấp đôi mỗi dấu chéo ngược. Ví dụ,
permission java.io. FilePermission "c: \ \ home \ \ test \ \
download \ \ -", "read";
Bắt đầu đăng ký RMI sau đó các bắt đầu máy chủ với
java -Djava.rmi.server.codebase=file://home/test/download/

ProductServer &
hoặc
start java -
Djava.rmi.server.codebase=file:/c:\home\test\download/
ProductServer

9./ Deploying the Program(Triển khai chương trình):
- Bây giờ bạn đã kiểm tra việc triển khai các chương trình của bạn, bạn đã
sẵn sàng để phân phối nó vào thực tế khách hàng và máy chủ. Di chuyển các lớp
trong thư mục tải về vào máy chủ web.
- Hãy chắc chắn để sử dụng URL khi bắt đầu các máy chủ. Di chuyển các
lớp trong thư mục server vào máy chủ của bạn và bắt đầu đăng ký RMI và máy
chủ. thiết lập máy chủ của bạn bây giờ hoàn thành, nhưng bạn cần phải thực hiện
hai thay đổi trong máy khách. Đầu tiên, chỉnh sửa các tập tin chính sách và thay
thế * với tên máy chủ của bạn:
grant
{
permission java.net.SocketPermission
"yourserver.com:1024-65535", "connect";
permission java.net.SocketPermission

×