Trên máy A các đốitượng A1, A2 gọi 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 mà lập trình hướng đối tượng truyền thống vẫn sửdụng.. Đối
Trang 1ĐẢM BẢO GẮN BÓ DỮ LIỆU KHI CẬP
NHẬT TRONG CÁC CƠ SỞ DỮ LIỆU TẬP TRUNG TẠI CÁC NGÂN HÀNG
GVHD: PGS.TS Lê Văn Sơn
Học viên: Đỗ Trường Linh Chuyên ngành: Khoa học máy tính_ Khóa 24
Trang 2MỞ ĐẦU
Hệ tin học phân tán là một trong những lĩnh vực tri thức vừa mang tính chất cơ sởvừa mang tính chất tiên tiến của chuyên ngành công nghệ thông tin mà việc nắm bắt vàvận dụng tốt các nguyên lý của nó sẽ mang lại cho các hê thống thực tiễn những hứahẹn rất lớn về hiệu năng khai thác thiết bị trong các ứng dụng tin học Nó còn là hệthống tin học hiện đại, đa dạng, phức tạp và đang trên đà phát triển, được nhiều trườngđại học, nhiều viện nghiên cứu, nhiều chuyên gia công nghệ thông tin, quan tâmnghiên cứu với nhiều công trình khoa học có giá trị về mặt nguyên lý, phương phápcũng như ứng dụng trong thực tế
Việc lập trình giải quyết một bài toán hay giải quyết một yêu cầu xử lý phân táncác đối tượng vẫn là một vấn đề nóng bỏng của công nghệ ngày nay Trong khuôn khổmôn học Lập trình mạng phân tán, tiểu luận trình bày về vấn đề lập trình phân tán giảiquyết một bài toán cụ thể, đó là:
Viết chương trình đảm bảo gắn bó dữ liệu khi cập nhật trong các CSDL tập trung tại các ngân hàng.
Bài làm này tìm hiểu và vận dụng JAVA để lập trình giải quyết bài toán theo hai
cách là sử dụng đa tuyến và giả lập server Trong đó giả lập server theo hướng một
server tập trung để trao đổi dữ liệu với nhau
Tiểu luận gồm hai chương:
Chương 1 Tìm hiểu về lập trình phân tán trong môi trường Java
Chương 2 Giao tiếp theo mô hình Client/ Server và khái niệm Socket
Chương 3. Cài đặt bài toán đã nêu bằng ngôn ngữ Java để minh họa
Trang 3CHƯƠNG 1 TÌM HIỂU VỀ LẬP TRÌNH PHÂN TÁN TRONG JAVA 1.1 RMI và lập trình phân tán đối tượng
Thông thường các chương trình của chúng ta được viết dưới dạng thủ tục hay hàmgọi Mã lệnh của hàm hay thủ tục được nạp thẳng vào ký ức và thực thi ngay trên máycục bộ Đối với các hàm (hoặc đối tượng) thư viện như System.out.println() chẳng hạnbạn thường không cần phải quan tâm đến cách thức mà hàm thư viện được cài đặt.Điều mà hầu hết các lập trình viên quan tâm là đối số truyền cho hàm và kết quả trả
về Vậy thì có cách nào tập nội dung của hàm hay đối tượng ở một máy nào đó và gọichúng từ một máy khác hay không? Đây chính là nội dung của lập trình phân tán mã
lệnh RMI (Remote Method Invoke) – mang ý nghĩa triệu gọi phương thức từ xa – 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 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 1-1: Mô hình triệu gọi các đối tượng từ xa
Hình 1-1 cho thấy mô hình triệu gọi đối tượng phân tán Trên máy A các đốitượng A1, A2 gọi 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 mà lập trình hướng đối tượng truyền thống vẫn sửdụng Tương tự, tương tác giữa C1, C2, C3 là tương tác cục bộ
Tuy nhiên, đối tượng Java có thể gọi phương thức của đối tượng nằm trên một máykhác dựa vào giao thức triệu gọi từ xa RMI (như A1 gọi C1, A2 gọi B1, C3 gọi B1)
Computer A
A2
A1
Computer CC1
C2
Computer B
B1
C3
Trang 41.2 Gọi phương thức từ xa và các vấn đề phát sinh
Việc gọi phương thức của đối tượng 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ácnhau hoạt động trên hai tiến trình (hay không gian địa chỉ) khác nhau cho nên việctham chiếu biến, địa chỉ đối tượng là hoàn toàn khác nhau Ví dụ, khi bạn truyền contrỏ cho một phương thức ở xa, trên máy bạn con trỏ này tồn tại nhưng trên máy khác(nơi có đối tượng thực thi phương thức) sẽ không có bất kỳ vùng nhớ nào được cấpphát dành cho con trỏ Lời gọi các phương thức cục bộ thường luôn trả về kết quảtrong khi lời gọi các phương thức từ xa phải thông qua kết nối mạng và luôn có thể bịngắt ngang do mạng gặp sự cố
Đối với lời gọi hàm trên máy cục bộ, các tham số truyền cho hàm thường được đặt vàongăn xếp (stack) trong khi tham số truyền cho phương thức của các đối tượng ở xaphải đươc đóng gói và chuyển qua mạng để đến đươc với phương thức thực sự
1.3 Vai trò các lớp trung gian (Stub và Skeletion)
Để giải quyết các vấn đề trên, đối tượng Java trên hai máy khác nhau không gọinhau trực tiếp mà thông qua lớp trung gian Lớp trung gian này tồn tại ở cả hai phíamáy khách (Client - nơi gọi phương thức của đối tượng ở xa) và máy chủ (Server – nơiđối tượng thực sự được cài đặt để thực thi mã lệnh của phương thức) Phía máy kháchlớp trung gian này được gọi là Stub (lớp móc), phía máy chủ lớp trung gian này đượcgọi là Skeletion (lớp nối)
Hình 1 – 2: Gọi phương thức của các đối tượng thông qua lớp trung gian
Ví dụ, đối tượng C1 được cài đặt chạy trên máy C Trình Java sẽ tạo ra hai lớptrung gian C1_Skel và C1_Stub Lớp C1_Stub sẽ được đem về máy Computer A Khi
Trang 5A1 trên máy computer A gọi C1 nó sẽ chuyển lời gọi đến lớp C1_Stub C1_Stub chịutrách nhiệm đóng gói tham số, chuyển tham số qua mạng đến máy Computer C Trênmáy Computer C lớp nối C1_Skel sẽ nhận tham số chuyển vào vùng không gian địachỉ tương thích với đối tượng C1 sau đó gọi phương thức tương ứng Kết quả nếu có
do phương thức của đối tượng C1 trả về sẽ được lớp C1_Skel đóng gói trả ngược vềcho C1_Stub 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 nó đang hoạt động trực tiếp với đối tượng C1 ngay trên máy cục bộ.Hơn nữa, nhờ sự giúp đỡ của lớp trung gian C1_Stub, khi kết nối mạng gặp sự cố lớptrung 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 thế nào A1 tham chiếu đươc đến C1, một khi không có lớp C1 nàođược cài đặt ở máy A? C1_Stub trên máy A chỉ làm lớp nền trung gian chuyển đổitham số và thực hiện các giao thức mạng, nó không phải là hình ảnh của đối tượng C1
Để làm được điều này, đối tượng C1 cần cung cấp một giao tiếp interface tương ứngvới các phương thức cho phép đối tượng A1 gọi nó trên máy A
Stub thường trực trên máy khách, không ở trên máy chủ Nó có vai trò đóng gói
các thông tin bao gồm:
Định danh đối tượng từ xa cần sử dụng
Mô tả về phương thức cần triệu gọi
Mã hoá các tham số và truyền cho Skel
Stub sẽ chuyển những thông tin trên cho máy chủ Ở phía máy chủ, đối tượng Skelnhận thực hiện những công việc sau để gọi phương thức từ xa:
Giải mã các tham số
Xác định đối tượng để thực hiện lời gọi hàm tương ứng
Thực hiện lời gọi phương thức theo yêu cầu
Tập hợp kết quả để trả lời hoặc thông báo các lỗi ngoại lệ
Gửi trả lời gói các dữ liệu kết quả cho Stub ở trên máy khách
1.4 Cài đặt ứng dụng phân tán RMI
Sau đây là một ví dụ về cách làm việc của các đối tượng RMI Chương trình làmột hệ đối tượng phân tán (hình 1 – 3) Đối tượng Calculator chạy trên máy tínhComputer 2 sẽ được gọi bởi đối tượng CalculatorClient chạy trên máy tính Computer1
Hình 1-3: Triệu gọi đối tượng RMI giữa trình khách (Client) và
đối tượng chủ (Server) ở xa
Trang 6Muốn Calculator có khả năng giao tiếp được với các đối tượng ở xa thì phải báo choJava biết Calculator là một đối tượng có khả năng Remote Tất cả các phương thứctrong giao tiếp Calculator muốn được gọi từ xa đều phải có khả năng ném ra ngoại lệRemoteException vì khi triệu gọi từ xa có rất nhiều nguyên nhân làm nó thất bại,
ví dụ, máy chủ, kết nối mạng không sẵn sàng và nhiều vấn đề không bình thường,ngoại lệ khác gặp phải trên mạng Mã nguồn đầy đủ của giao tiếp Calculator như sau:
Calculator.java
import java.rmi.*;
public interface Calculator extends Remote {
public int addNumber (int x, int y)throws RemoteException;}
Lớp giao tiếp Remote thật ra chỉ là một interface rỗng, được dùng để đánh dấu chomáy ảo Java biết được đặc tính có khả năng “nói chuyện” với các đối tượng ở xa củaCalculator
CalculatorImpl.java
import java.rmi.*;
public class CalculatorImpl implements Calculator {
public int addNumber (int x, int y)throws RemoteException{
System.out.println(“Client request to calculator”);
Dựa vào lớp cài đặt CalculatorImpl.class, trình biên dịch rmic.exe của Java sẽcung cấp hai lớp trung gian Stub và Skel bằng lệnh sau:
public class CalculatorServer {
public static void main(String args[]){
try{
//Tạo đối tượng Calculator thật sự
CalculatorImpl c=new CalculatorImpl();
Trang 7Chương trình Calculator làm việc như sau:
- Đối tượng CalculatorImpl được tạo ra
CalculatorImpl c=new CalculatorImpl();
- Calculator gọi phương thức tĩnh exportObject() của lớpUnicastRemoteObject để máy ảo Java nhận diện được đối tượng c (Calculator) là đốitượng có khả năng truy xuất từ xa
Chương trình CalculatorClient phía máy khách có khả năng gọi và sử dụng đốitượng Calculator trên máy chủ như sau:
import java.rmi.*;
public class CalculatorClient{
public static void main(String args[]){
Trang 8Để truy tìm đối tượng ở xa, chương trình máy khách gọi phương thức tĩnhNaming.lookup() Phương thức này chỉ yêu cầu đối số là chuỗi định dạng chobiết địa chỉ máy chủ và tên đăng ký của đối tượng
Calculatorc=Calculator)Naming.lookup(rmi://localhost/MyCal”);
Địa chỉ máy chủ là localhost và tên của đối tượng là MyCal
Trên mô hình Client/ Server, máy server sẽ cần đến lớp CalculatorImpl.class,CalculatorImpl_Skel.class để cài đặt đối tượng; máy client chỉ cần dùng đến lớpCalculator.class và CalculatorImpl_Stub.class để gọi phương thức của đối tượng
Hình 1-4 diễn đạt cơ chế gọi hàm từ xa của các đối tượng RMI một cách tổng quát:
1 Đối tượng cài đặt các phương thức và gọi hàm Naming.bind() để đăng ký với
bộ quản lý rmiregistry trên máy chủ
2 Đối tượng trên máy khách muốn gọi phương thức của đối tượng trên máy chủtrước hết cần gọi hàm Naming.lookup() để truy tìm tham chiếu đến đốitượng ở xa theo tên
3 Bộ đăng ký rmiregistry sẽ trả về tham chiếu đến đối tượng ở xa thông qua lớpgiao tiếp interface mà đối tượng ở xa cung cấp
4 Dựa vào lớp giao tiếp interface đối tượng ở máy khách sẽ gọi các phương thứccủa đối tượng trên máy chủ
5 Khi một phương thức được gọi, lời goi sẽ được chuyển tiếp đến lớp trunggian_Stub Xử lý chuyển tham số của phương thức gọi đến lớp_Skel trên máychủ
6 Lớp trung gian_Skel trên máy chủ sẽ trực tiếp yêu cầu đối tượng thực thiphương thức và chuyển trả kết quả về cho máy khách Các bước cài đặt và thiết
kế đối tượng RMI có thể được tóm tắt như sau:
7 Đặc tả lớp giao tiếp của đối tượng (Calculator.java)
8 Dựa vào lớp đặc tả cài đặt chi tiết đối tượng (CalculatorImpl.java)
9 Biên dịch đối tượng (CalculatorImpl.class) Dựa vào đối tượng vừa càiđặt dùng trình rmi.exe (chương trình này nằm trong thư mục \jdk.3\bin) tạo rahai lớp trung gian Calculator_Stub và Calculator_Skel
10 Viết chương trình (CalculatorServer.class) cài đặt đối tượng trên máychủ Chú ý phải gọi phương thức UnicastRemoteObject.exportObject() đểthông báo cho java nhận dạng được sư tồn tại của đối tượng ở dạng truy xuấtđược từ xa bởi các đối tượng khác
11 Sử dụng lớp giao tiếp (Calculator.class) và CalculatorImpl_Stub từmáy khách để gọi các phương thức của đối tượng trên máy chủ
Trang 9Hình 1-4: Cơ chế RMI gọi phương thức của đối tượng từ xa
Khi chạy chương trình Java dựa vào biến môi trường CLASSPATH để truy tìm cáctâp tin class Chương trình minh họa bao gồm các tập tin sau:
ký đối tượng với rmiregistry
Chương trình chạy trên máy kháchgọi các phương thức của đối tượngtrên máy chủ
Máy khách và máy chủ.Máy chủ
Máy chủMáy khách và máy chủMáy chủ
Máy khách
Computer 1
CalculatorImplrmiregistry
CalculatorImpl_Skel
Trang 10CHƯƠNG 2 GIAO TIẾP THEO MÔ HÌNH CLIENT/SERVER
VÀ KHÁI NIỆM SOCKET 2.1 Giao tiếp theo mô hình khách/ chủ (Client/ Server)
Có rất nhiều dịch vụ hỗ trợ trên Internet như e-mail, nhóm tin (newgroup), filetransfer, đăng nhập từ xa (remote login), truy tìm các trang Web… Những dịch vụ nàyđươc tổ chức và kiến trúc theo mô hình khách/ chủ (Client/ Server) Các chương trình
ở máy khách (client) sẽ tạo ra kết nối (connection) với một máy chủ ở xa (server) sau
đó gửi các yêu cầu đến máy chủ, các chương trình dịch vụ trên máy chủ sẽ xử lý cácyêu cầu này và gửi kết quả ngược về cho máy khách Thông thường một dịch vụ trênmáy chủ phục vụ cho rất nhiều máy khách
1.5.2 Lập trình mạng thông qua Socket
Trước khi yêu cầu một dịch vụ trên máy chủ thực hiện điều gì đó, máy khách(client) phải có khả năng kết nối được với máy chủ (server) Quá trình kết nối nàyđược Java thực hiện thông qua môt cơ chế trừu tượng hóa gọi là Socket (tạm dịch là
“cơ chế ổ cắm”)
Nếu kết nối socket thành công thì máy khách và máy chủ có thể trao đổi sữ liệu vớinhau thực hiện các yêu cầu về dịch vụ trên máy chủ Việc kết nối theo cơ chế socketcần biết hai thông tin chủ yếu đó là địa chỉ của máy cần kết nối và số hiệu cổng củachương trình dịch vụ Java cung cấp lớp Socket (thường được dùng cho máy khách)
và lớp ServerSocket (thường được đặt trên máy chủ) Hai lớp này được đăt tronggói thư viện Java.net
Tuy nhiên, lớp Socket có thể được dùng kết nối chung cho cả máy khách và máychủ nhưng ta vẫn thường dùng lớp ServerSocket để thực hiện việc quản lý kếtnối đăt riêng ở máy chủ hơn
Tạo ra một socket kết nối máy có tên theo địa chỉ host và số cổng port
Public Socket(InetAddress address, int port) throws IOException
Tạo ra một socket kết nối từ địa chỉ là đối tượng InetAddress và số cổng port
Public Socket(String host, int port, boolean stream) throws IOException
Tạo ra một socket kết nối theo địa chỉ host và số cổng port, tham số tream cuối cùng
để quy định kết nối theo TCP (stream=true) hay UDP (stream=false)
Các phương thức khác hỗ trợ cho lớp Socket từ phía máy khách bao gồm:
InputStream getInputStream() throws IOException
Lấy về luồng nhập để máy khách có thể đọc dữ liệu trả về từ phía máy chủ
Trang 11 OutputStream getOutputStream() throws IOException
Lấy về luồng xuất để máy khách có thể ghi dữ liệu gửi đến máy chủ
InetAddress getInetAddress()
Lấy địa chỉ kết nối socket của máy chủ
Int getPort()
Lấy về số cổng dùng kết nối của máy chủ
Synchronized void close () throws IOException
Cắt đứt kết nối với máy chủ
Ví dụ đoạn mã sau sẽ thực hiện kết nối với máy chủ có địa chỉ
“my.testing.server” và mở ra hai luồng xuất nhập để đọc và gửi thông tin đếnmáy chủ có theo số cổng 1234:
try{
Socket me=new Socket(“my.testing.server”, 1234);
//Luồng nhập để đọc thông tin trả về từ máy chủ kết nối
DataInputStream in =
New DataInputStream(me.getInputStream());
//Luồng xuất để ghi thông tin gửi đến máy chủ
DataOutputStream out=new DataOutputStream(me.getOutputStream()); Catch (Exception e){
từ phương thức sau:
Public ServerSocket(int port)throws IOEXception
port là số hiệu cổng mà đối tượng ServerSocket phải lắng nghe để nhận biết những kếtnối từ phía máy khách gửi đến
Để chờ đợi kết nối từ các máy khách gửi đến đối tương ServerSocket thường đến phươngthức accept như sau:
Socket accept()throws IOEXception
Phương thức này thực sự dừng lại chờ đợi cho đến khi nhận được thông tin kết nối sẽ trả vềđối tượng socket của máy khách nơi có yêu cầu nối vào máy chủ
Cuối cùng máy chủ có thể cắt đứt mọi kết nối bằng cách gọi phương thức close của đốitượng ServerSocket:
Public void close()throws IOEXception
Ví dụ đoạn mã sau sẽ tạo ra một đối tượng ServerSocket trên máy chủ luôn lắngnghe kết nối từ máy khách gửi đến qua số cổng 1234