940 likes | 1.2k Views
Chapter 9 RMI Remote Method Invocation. GV: Nguyễn Thị Thanh Vân. Nội dung. Giới thiệu Hoạt động của RMI Hoạt động của lớp trung gian Thiết kế và cài đặt một chương trình RMI Thực thi hệ chương trình RMI, ex Chuyển tham số trong RMI, ex Tham trị Tham chiếu Tuần tự hóa đối tượng, ex
E N D
Chapter 9RMI Remote Method Invocation GV: Nguyễn Thị Thanh Vân
Nội dung • Giới thiệu • Hoạt động củaRMI • Hoạt động của lớp trung gian • Thiết kế và cài đặt một chương trình RMI • Thực thi hệ chương trình RMI, ex • Chuyển tham số trong RMI, ex • Tham trị • Tham chiếu • Tuần tự hóa đối tượng, ex • Factory Object, ex • RMI với firewall
Giới thiệu • Lập trình HĐT phân tán: • Môi trường hợp tác • Tận dụng nguồn tài nguyên phân tán trên mạng • Java: giải quyết vấn đề lập trình phân tán • Có .NET của Microsoft • Trong Java, sử dụng kỹ thuật RMI để cài đặt các đối tượng phân tán. • KT xuyên suốt trong toàn bộ kiến trúc của Java
Giới thiệu • Local method Invocation: mã lệnh của hàm (hay thủ tục) được nạp thẳng vào bộ nhớ và thực thi ngay trên máy cục bộ Muốn nạp nội dung hàm hay đối tượng ở 1 máy nào đó gọi chúng từ một máy khác? • Remote Method Invocation (RMI): là cách thức giao tiếp giữa các đối tượng Java có mã lệnh cài đặt nằm trên máy khác nhau có thể gọi lẫn nhau.
Mô hình triệu gọi các đối tượng từ xa Computer A Computer B A2 B2 B2 A1 B3 Computer C C1
RMI và RPC (Remote Procedure Calling) • Like RPC ,RMI has the following similarities • Remote calls can be made • Client/server contract based on interface • Unlike • RPC : hỗ trợ đa ngôn ngữ • RMI: chỉ hỗ trợ các ứng dụng được viết bằng Java
RMI – Client/Server Client Server Client (nơi gọi phương thức của các đối tượng ở xa) Server (nơi đối tượng thật sự được cài đặt để thực thi mã lệnh của phương thức).
Mục đích của RMI • Hỗ trợ gọi phương thức từ xa trên các đối tượng trong các máy ảo (JVM) khác nhau • Tích hợp mô hình đối tượng phân tán vào ngôn ngữ lập trình Java theo một cách tự nhiên, có tin cậytrong khi vẫn duy trì các ngữ cảnh đối tượng của ngôn ngữ lập trình Java • Làm cho mô hình đối tượng phân tán và mô hình đối tượng cục bộ không có sự khác biệt.
Vấn đề phát sinh • Việcgọiphươngthứccủađốitượngtừxa luôn phứctạphơngọiphươngthứccụcbộ: • Việc tham chiếu đến biến, địa chỉ của đối tượng khác nhau ở các máy khác nhau • Các tham số truyền cho phương thức của đối tượng ở xa phải được đóng gói và chuyển qua mạng đến phương thức thực sự. (local-stack) • Lờigọiphươngthứctừxa phảithông qua mạngvà có thểbịngắtngang do mạnggặpsựcố • Phụ thuộc vào kết nối mạng
Giải pháp • Đốitượngtrên hai máy khácnhau không gọitrựctiếpmà thông qua lớptrung gian. • Lớp trung gian tồntạiởcảhai phía Client và Server. • Lớpởmáy Client gọilàStub, • Lớpởmáy Server gọilàSkel(Skeletion) • Lớp trung gian Stub sẽ biết cách thông báo lỗi khi có các sự cố về mạng cho Client
Lớp trung gian Stub và Skeletion Computer A Computer B A2 B1 A1 B1_Stub B1_Skel C1_Stub Computer C C1_Skel C1
Lớp trung gian Stub và Skeletion • Trình biên dịch Java (rmic.exe) sẽ tạo ra 2 lớp trung gian: • Lớp Stub (lớp móc): chuyển về cho client • Lớp Skeleton (lớp nối): Phía Server • Stub và Skeletion sẽ giúp các đối tượng ở xa giao dịch với nhau ? • Đối tượng Server (trên máy Server) cần cung cấp một giao diện tương ứng với các phương thức của nó (Server Object) cho phép đối tượng Clientgọi nó trên máy Client dễ dàng. • Đối tượng client sẽluôn nghĩ rằng nó đang hoạt động trực tiếp với đối tượng servertrên máy cục bộ.
Lớp trung gian Stub và Skeletion • Ví dụ: PhươngthứcA truyềnchophươngthứcB hai sốa,b.PhươngthứcB sẽcộnghai sốa,b cho ra kếtquảc và trảvềphươngthứcA. Quá trình diễnranhưsau: a,b c
Kiến trúc của RMI • The Stub and Skeleton layer, which intercepts method calls made by the client to the interface reference variable and redirects these calls to a remote RMI service. • The Remote Reference layer understands how to interpret and manage references made from clients to the remote service objects. • The Transport layer, which is based on TCP/IP connections between machines in a network. It provides basic connectivity, as well as some firewall penetration strategies.
Quá trình hoạt động của RMI Remote Machine (Server) bind RMI Server Registry Skeleton lookup call return Stub RMI Client Local Machine (Client)
Quá trình hoạt động của RMI B1: RMI-server đăng ký tên của đối tượngvới bộ q.lý Registry. B2: Bộ quản lý Registry trả về tham chiếu đến đối tượng ở xa (RMI Server) thông qua lớp giao tiếp B3-4: RMI-client liên lạc với bộ Registry để lấy về tham chiếu đến đối tượng trên Server. Các quá trình đăng ký và truy tìm tên đối tượng được Java quản lý bằng các hàm giao tiếp API JNDI B5-7: Client sẽ gọi các phương thức của đối tượng trên Server Khi một phương thức được gọi, sẽ được chuyển tiếp đến lớp trung gian Stub, rồi gọi đến lớp Skeleton (hđ Stub). B8-10: Lớp Skeleton sẽ trực tiếp yêu cầu đối tượng thực thi phương thức và trả kết quả cho Client (hđ Skeletion)
Trình (bộ quản lý)đăng ký Registry • là một chương trình dịch vụ chạy ở hậu trường (rmiregistry.exe), thực hiện mở ổ cắm socket và lắng nghe các yêu cầu gởi đến cổng mặc định 1099, có thể chỉ định một cổng khác với cổng 1099. • Ví dụ: C:\j2sdk1.4.0\bin\ rmiregistry.exe 9999 • Đóng vai trò như là một DNS nhỏ cho các đối tượng từ xa thực hiện tìm kiếm dịch vụ, Registry Client Server
Hoạt động của Stub, Skeleton • Client gọi một phương thức từ xa, lời gọi này được chuyển tiếp đến Stub. • Stub có nhiệm vụ gửi tiếp lời yêu cầu này đến Skeleton phía server bằng cách • Stub mở mộtsocket đến server, • đóng gói các tham số: • Gói nhận dạng đối tượng từ xa • Gói phương pháp nhận dạng • truyền luồng dữ liệu này đến Skeleton. • Skeleton chứa đựng một phương thức nhận cáclời yêu cầu từ xa, • mở gói tham số, • gọi hàm thực sự trên server để tính toán • trả kết quả về Stub phía client.
Các lớp và các giao tiếp trong gói java.rmi • Giao tiếp Remote Giao tiếp này không khai báo bất kỳ phương thức nào. Các phương thức được khai báo trong phương thức này là các giao tiếp có thể được gọi từ xa. • Lớp Naming Lớp java.rmi.Naming truyền tin trực tiếp với một trình đăng ký đang chạy trên server để ánh xạ các URL rmi://hostname/Objectname thành các đối tượng từ xa cụ thể trên host xác định: • Rmi là giao thức dùng để đăng kí. • Hostname và port là đ/c IP và số hiêu cổng của Server nơi bộ Registry đang chạy. • Objectname là tên tự đặt, các ct phía client sẽ dựa vào tên này để truy tìm tham chiếu đến đối tượng cần dùng. URL rmi vs. URL http.
Naming class - methods • Lớp Naming cung cấp các phương thức sau: • public static String[] list(String url) throws RemotException trả về một mảng các xâu ký tự, mỗi xâu là một URL đã được gắn với một tham chiếu. url là URL của trình đăng ký Naming. • public static Remote lookup(String url)throws RemotException, NotBoundException, AccessException, MalformedURLException Client lookupđể tìm kiếm một đối tượng từ xa gắn liền với tên đối tượng. NotBoundException: server ở xa không nhận ra tên của nó.
Naming class - methods • Public static void bind(String url, Remote object)throws RemotException, AlreadyBoundException, MalformedURLException, AccessException để liên kết một tên với một đối tượng ở xa. Nếuthành công thì client có thể tìm kiếm đối tượng stub từ trình đăng ký. • Có rất nhiều tình huống có thể xảy ra khigán tên. • MalformedURLException:url không đúng cú pháp. • RemoteException: không thể liên lạc được với trình đ.ký • AccessException: client không được phép gán các đối tượng trong trình đăng ký. • AlreadyBoundException:nếu đối tượng URL đã gắn với một đối tượng cục bộ
Naming class - methods • public static void rebind(String url, Remote obj)throws RemoteException, AccessException, MalformedURLException • Phương thức này giống như phương thức bind() ngoại trừ việc là nó gán URL cho đối tượng ngay cả khi URL đã được gán.
RemoteObject class • RemoteObject class • Các đối tượng từ xa là thể hiện của các lớp con của RemoteObject. • RemoteServer class • là lớp con của lớp RemoteObject; • là lớp cha của lớp UnicastRemoteObject. • UnicastRemoteObject class • là một lớp con cụ thể của lớp RemoteServer. • Để tạo ra một đối tượng ở xa: • ta phải thừa kế lớp UnicastRemoteServer • khai báo lớp này thực thi giao tiếp Remote • PhươngthứcexportObject(Object): làm cho máyảoJava nhậndiệnđượcđốitượngObject. RemoteObject RemoteServer UnicastRemoteObject UnicastRemoteServer UnicastRemoteServer Remote Object
Giao tiếp Registry • cho phép các client tìm kiếm các đối tượng ở xa trên một server theo tên. • Các phương thức • Bind() để gán một tên với một đối tượng từ xa cụ thể • List() liệt kê tất cả các tên đã được đăng ký với trình đăng ký • Lookup() tìm một đối tượng từ xa cụ thể với một URL cho trước gắn với nó • Rebind() gán một tên với một đối tượng ở xa khác • Unbind() loại bỏ một tên đã được gán cho một đối tượng ở xa trong trình đăng ký • Registry.REGISTRY_PORT là cổng mặc định để lắng nghe các các yêu cầu. Giá trị mặc định là 1099.
Các bước thiết kế và cài đặt RMI 1. Đặc tả một giao tiếp từ xa (remote interface) trênserver. 2. Hiện thực giao tiếp từ xa (remote interface) để Xây dựng một đối tượng từ xa (remote object) . 3. Sinh ra các Stub phía client và Skeleton phía server. 4. Xây dựng chương trình phíaServer 5.Xây dựng chương trình phía Client. 6. Khởi động bộ đăng ký RMI (RMI registry) 7. Khởi động các đối tượng từ xa phía server 8. Chạychương trình phía client.
Ex, Cài đặt chương trinhg cộng 2 số nguyên • Triệu gọi đối tượng RMI giữa trình khách và đối tượng chủ ở xa
1. Đặc tả một Remote Interface (at Srv) • Các đối tượng trong Remote Inteface phải có khả năng giao tiếp với các đối tượng ở xa (Kế thừa Remote class) • Các phương thức phải có khả năng phát ra ngoại lệ Remote Exception. // Calculator.java import java.rmi.*; publicinterface Calculator extends Remote { publicint addNum(int x,int y) throws RemoteException; } Biên dịch
2. Hiện thực Remote Interface • Từ giao tiếp RI đã định nghĩa, đối tượng thực sự phải được cài đặt: /* CalculatorImpl.java*/ import java.rmi.*; publicclass CalculatorImpl implements Calculator { publicint addNum(int x,int y) throws RemoteException { System.out.println("Client request to calculate"); return (x+y); } } Biên dịch
3. Sinh trung gian Stub và Skeleton • Dựa vào lớp cài đặt CalImpl.class, trình biên dịchrmic.exe của Java sẽ cung cấp hai lớp trung gian C:\RMI>rmicCalculatorImpl • Kết quả • CalculatorImpl_Stub.class • CalculatorImpl_Skel.class //ko
4. Xây dựng chương trình trên Server /* CalServer.java*/ publicclass CalculatorServer{ publicstaticvoid main(String[] args) throws AlreadyBoundException { try{ //tao doi tuong Calculator thuc su CalculatorImpl c= new CalculatorImpl(); System.out.println("Exporting Calculator ! "); //thông báo sự hiện diện c là đối tượng có khả năng Remote cho JVM UnicastRemoteObject.exportObject (c); //đăng ky doi tuong với trình quản lý rmi Naming.bind("rmi://localhost/Van",c); System.out.println("Register Calculator!"); } catch(Exception e) { System.out.println(e); } } } Biên dịch
5. Xây dựng chương trình trên Client • Chương trình phía bên máy clientcó khả năng gọi và sử dụng đối tượng Cal trên máy server: /* CalculatorClient.java*/ import java.rmi.*; publicclass CalculatorClient { publicstaticvoid main(String[] args){ try{ System.out.println("Finding Object … "); // tìm đối tượng cần truy xuất theo tên Calculator c= (Calculator)Naming.lookup ("rmi://localhost/Van"); // goi phuong thuc cua doi tuong System.out.println(c.addNum(5,10)); } catch(Exception e) { System.out.println(e); } } } Biên dịch
6. Kích hoạt bộ đăng ký • C:\RMI>rmiregistry.exe • Nó có nhiệm vụ đón nhận (luôn trong trạng thái sẵn sàng phục vụ) các kết nối chứa thông tin về đối tượng do phương thức Naming.bind() gửi đến. • Mặc định rmiregistry.exe lắng nghe các kết nối gửi đến cổng 1099, có thể chỉ định lại: • C:\RMI>rmiregistry.exe 2012 • rmiregistry.exe có trong ..\Java\jdk1.7.0_05\bin • Không cần chạy service trên nếu có: LocateRegistry.createRegistry(1099); trong main của trình Server
7. K.động các đối tượng phía Server C:\RMI>java CalculatorServer Exporting Calculator… Register Calculator! • Cũng như rmiregistry.exe, saukhiCalculator Server được gọi, hàm Naming.bind() sẽ đi vào vòng lặp vô tận để chờ nhận yêu cầu từ client đến.
8. Chạy chương trình phía Client C:\RMI>java CalculatorClient Finding Object… 15 -> kết quả trả về là lời gọi đến phương thức addNum() của đối tượng CalculatorImpl. Quay lại cửa sổ DOS trên Server thấy: Client request to calculate -> hàm addNum() đã được gọi thực hiện
Lưu ý cách vận hành • Dựa vào JVM ta có thể tạo tùy ý các máy tính ảo (cho các ct chạy trên các cửa sổ DOS khác nhau) giao tiếp với nhau giả lập mạng. • Đặc điểm: cùng IP, cùng chung thư viện Java, cùng 1 chính sách bảo mật -> dễ vận hành. • Khi vận hành trên các máy tính vật lý khác nhau cần chú ý về thư viện, security policy
RMI trên máy thực cài đặt của đối tượng
Tựtạobộđăngkí(ko dùng rmiregistry.exe • Tự tạobộđăngkí và tựđăngkí đốitượng: • Dùng: createRegistry()củalớpLocateRegistry. • Đăng ký mộtđốitượng khác: LocateRegistry.createRegistry(1234); Naming.bind("rmi://localhost:1234/myCal",c2); LocateRegistry.createRegistry(1099); Calculator cal = new CalculatorImpl(); System.out.println("Exporting Calculator ! "); UnicastRemoteObject.exportObject(cal); System.out.println("Registering object …"); Naming.bind("rmi://localhost/myCal", cal); System.out.println(“Register Calculator"); System.out.println("Waiting for client request…");
Các lớp được tạo ra trong RMI • Các lớp và phạm vi sử dụng
Biến Classpath và tùy chọn Codebase • CLASSPATH: • Java dựa vào biến môi trường CLASSPATH để truy tìm các tập tin .class. • Nếu CLASSPATH chỉ sai đường dẫn tới lỗi xảy ra: java.lang.ClassNotFoundException:ClassName • Để thay đổi giá trị cho CLASSPATH, dùng lệnh: Set Classpath. Ví dụ: Set Classpath=.;C:\RMI\
Biến Classpath và tùy chọn Codebase • Codebase (HTML) • [CODEBASE = URLDirectory] //xác định vị trí tệp từ xa • Codebase cho phép nạp tự động các lớp _Stub.class từ xa. (khi đăng ký đối tượng với rmiregistry trên máy chủ) • Thực hiện: • máy chủ phải hỗ trợ thêm dịch vụ WebServer chạy trên máy nơi rmiregistry đang chạy . • chép tập tin (_Stub.class) vào thư mục (myclass) của trình chủ web server. • biến Classpath trên máy ảo nơi rmiregistry đang chạy không được trỏ đến cùng thư mục chứa class
Nạp stub từ xa xuống client thông qua web server 2. RMI registry nhận yêu cầu, truy tìm stub trong CLASSPATH nhưng không có, theo sự chỉ dẫn của server nó tìm đến web server để lấy stub về, đồng thời ghi nhớ lại đường dẫn đến web server 3. Client yêu cầu rmi registry trả về tham chiếu đối tượng, nhưng client chưa có stub, rmi registry cho nó biết địa chỉ webserver để nó lên download stub về 4. Client yêu cầu webserver cung cấp stub 1. Server đăng ký đối tượng với rmi registry, yêu cầu rmi registry truy tìm đối stub thông qua web server rmiregistry sẽhướngdẫnmáy khách tựđộngnạplớp _Stub từđịachỉcodebase: http://172.16.11.12/myclass/ 5. Client sử dụng stubđó để giao tiếp với server (IP: 172.16.11.12
Nạp file từ xa và security policy phía client • VớiJava tấtcảcác thao tác kếtnốivà chép tậptin lạtừmộtmáykhác vềmộtmáyđềuphảithông qua lớpbảovệ: SecurityManager • Khi nạp lớp Stub tự động, chương trình của client cần bổ sung thiết lập lớp phòng vệ: System.setSecurityManager(new RMISecurityManager()); //sau try{
Nạp file từ xa và security policy phía client /* CalculatorClient.java*/ import java.rmi.*; publicclass CalculatorClient { publicstaticvoid main(String[] args){ try{ System.setSecurityManager(new RMISecurityManager()); System.out.println("Finding Object … "); // tìm đối tượng cần truy xuất theo tên Calculator c= (Calculator)Naming.lookup ("rmi://localhost/Van"); // goi phuong thuc cua doi tuong System.out.println(c.addNum(5,10)); } catch(Exception e) { System.out.println(e); } } }
Nạp file từ xa và security policy phía client • Hệ thống phòng vệ RMISecurityManager sẽ cho phép hoặc cấm các kết nối từ xa dựa trên thiết lập trong file: ..\java\jdk1.7.0_05\jre\lib\security\java.policy • Mở tập tin java.policy, edit: grant { permission java.security.AllPermission; // ko phòng vệ permission java.net.SocketPermission "*:1099", "connect, accept, resolve"; // This allows RMI clients to contact the RMIRegistry of any host };
Chuyển tham số trong RMI • Đối với việc truyền tham số qua mạng theo cơ chế RMI thì có hai nguyên tắc sau: • Tất cả các kiểu dữ liệu đơn giản như int, char,… đều được truyền theo thamtrị. • Tất cả các dữ liệu kiểu đối tượng muốn truyền qua mạng đềubuộc phải cài đặt một trong hai tiếp là Remote hoặc Serializable. • Các đối tượng cài giao tiếp Remote sẽ được truyền theo tham chiếu • Các đối tượng cài đặt giao tiếp Serializable sẽ được truyền theo tham trị. • Các đối tượng ko được cài đặt giao tiếp Serializable hay Remote thì ko thể dùng làm tham số truyền qua mạng được
Chuyển đối tượng theo tham trị • Giao tiếp Serializable dùng cho mục đích báo hiệu: • Tất cả các lớp đối tượng cài đặt trong giao tiếp Serializable đều có khả năng tuần tự hóa. • Khi gọi một phương thức của đối tượng từ xa, nếu trong lời gọi có y/c tham số kiểu đối tượng: • đối tượng sẽ được đóng gói và chuyển toàn bộ đến server (nơi tiếp nhận và thực thi phương thức). • Tại Server, đối tượng được bung ra lại trạng thái ban đầu và được sử dụng