Lập trình phân tán – Cách chạy một ứng dụng Java RMI

RMI (Remote Method Invocation) được sử dụng cho hệ thống tham chiếu đối tượng phân tán. Đối tượng phân tán là một đối tượng cung cấp giao diện (Interface) của nó trên các máy khác. Remote Object là một đối tượng phân tán có trạng thái được đóng gói. Stub và Skeleton là hai đối tượng dùng để giao tiếp với đối tượng từ xa.

Stub: Stub là một cổng cho chương trình client được sử dụng để giao tiếp với đối tượng Skeleton, bằng cách thiết lập kết nối giữa chúng.

Skeleton: Cư trú trong chương trình Server được sử dụng để chuyển yêu cầu (request) từ Stub tới Remote Interface.

Để viết một ứng dụng với Java RMI, bạn cần phải theo các bước sau:

  • Định nghĩa một lớp giao diện (Remote Interface)
  • Triển khai lớp thực thi của lớp giao diện (remote object)
  • Viết code cho chương trình chạy ở Server
  • Viết code cho chương trình chạy ở Client
  • Biên dịch ứng dụng
  • Chạy ứng dụng


Cách xử lý và giao tiếp diễn ra trong RMI

Giao tiếp trong lập trình Java RMI

Các bước chạy một ứng dụng Java RMI bằng dòng lệnh

Yêu cầu: Viết một chương trình tính giai thừa bằng lập trình phân tán với Java RMI

1. Tạo các lớp (Class) và các lớp giao diện (Interface) cho bài toán

Bước 1: Tạo một Interface kết thừa từ lớp java.rmi.Remote

Remote Interface định nghĩa đối tượng có thể được gọi từ xa bởi Client. Interface này có thể được kết nối với chương trình của Client. Interface này phải được thừa kế từ java.rmi.Remote.


//Code: timoday.edu.vn
import java.math.BigInteger;

//Tạo một lớp Interface
public interface Factorial
	extends java.rmi.Remote {

	//Khai báo một phương thức tính giai thừa
	public BigInteger fact(int num)
		throws java.rmi.RemoteException;
}

Bước 2: Tạo một Class thừa kế từ java.rmi.server.UnicastRemoteObject và thực thi lớp Interface ở bước 1

Lớp này sẽ triển khai Interface bước trước. Thực hiện các tính toán cần thiết cho bài toán tính gia thừa.


//Code: timoday.edu.vn
import java.math.BigInteger;

//Class này thừa kế và thực thi Interface ở bước 1
public class FactorialImpl
	extends java.rmi.server.UnicastRemoteObject
	implements Factorial {

	// Khai báo Constructor
	public FactorialImpl()
		throws java.rmi.RemoteException
	{
		super();
	}

	// Tính toán thuật toán giai thừa
	// Thực thi phương thức fact()
	// để tính giai thừa của một số
	public BigInteger fact(int num)
		throws java.rmi.RemoteException
	{
		BigInteger factorial = BigInteger.ONE;

		for (int i = 1; i <= num; ++i) {
			factorial = factorial.multiply(BigInteger.valueOf(i));
		}
		return factorial;
	}
}

Bước 3: Tạo một Class chạy ở phía Server (với địa chỉ localhost và tên Service)

Để cung cấp Service, chương trình Server được tạo bằng cách sử dụng phương thức java.rmi.Naming.rebind () có thể được gọi với hai đối số: đối tượng tham chiếu (tên dịch vụ) và tham chiếu đến đối tượng thực thi.


//Code: timoday.edu.vn
import java.rmi.Naming;

public class FactorialServer {

	//Triển khai constructor của class
	public FactorialServer()
	{
		try {
			//Tạo một object tham chiếu tới Interface
			Factorial c = new FactorialImpl();

			//Gắn địa chỉ localhost với Service này
			Naming.rebind("rmi://localhost/FactorialService", c);
		}
		catch (Exception e) {
			//Nếu có lỗi xảy ra
			System.err.println("Lỗi khởi tạo Server, chi tiết lỗi: " + e);
		}
	}

	public static void main(String[] args)
	{
		//Tạo một Object
		new FactorialServer();
	}
}

Bước 4: Tạo một Class chạy ở phía Client (với địa chỉ localhost và tên Service)

Chương trình Client sẽ gọi phương thức java.rmi.Naming.lookup() với URL RMI và trả về một instance của kiểu đối tượng (Interface Factorial). Tất cả RMI được thực hiện trên đối tượng này


//Code: timoday.edu.vn
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class FactorialClient {
	public static void main(String[] args)
	{

		try {
			//Tạp một Remote Object với cùng tên
			//Truyền kết quả tra cứu đến giao diện
			Factorial c = (Factorial)Naming.lookup("rmi://localhost/FactorialService");

			//Gọi phương thức và in kết quả
			System.out.println(c.fact(30));
		}

		//Nếu có lỗi xảy ra
		catch (MalformedURLException murle) {
			System.out.println("\nMalformedURLException: "+ murle);
		}

		catch (RemoteException re) {
			System.out.println("\nRemoteException: "+ re);
		}

		catch (NotBoundException nbe) {
			System.out.println("\nNotBoundException: "+ nbe);
		}

		catch (java.lang.ArithmeticException ae) {
			System.out.println("\nArithmeticException: " + ae);
		}
	}
}

2. Biên dịch toàn bộ chương trình

Sử dụng javac để biên dịch tất cả bốn chương trình và rmic (RMI Compiler) để tạo các lớp Stub và Skeleton.
Biện dịch chương trình Java

3. Chạy ứng dụng

Sau giai đoạn biên dịch, hệ thống đã sẵn sàng để chạy. Để chạy hệ thống, hãy mở ba màn hình Console (di chuyển đến đường dẫn nơi chứa chương trình). Một cho Client, một cho Server và một cho Registry RMI.

Bước 1: Bắt đầu với registry, sử dụng rmiregistry

Chạy Registry RMI
Nếu không có lỗi registry sẽ bắt đầu chạy và bây giờ chuyển sang màn hình thứ hai.

Bước 2: Chạy chương trình Server và để bật Service

Nó sẽ khởi động và đợi kết nối Client và nó sẽ tải quá trình thực thi vào bộ nhớ.
Chạy Server RMI

Bước 3: Chạy chương trình Client

Start Client RMI

Với cách này, RMI có thể được chạy trên ba màn hình Console cho localhost. RMI sử dụng Ngăn xếp Network và Ngăn xếp TCP/IP để giao tiếp ba chương trình JVM khác nhau.

Có thể bạn sẽ thích…

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

EnglishVietnamese