Bước đầu tiên để viết một dịch vụ Grid là định nghĩa giao diện dịch vụ. Một dịch vụ Grid có nhiều người dùng tương tác. Mỗi người dùng tương tác với dịch vụ bằng cách gửi yêu cầu. Dịch vụ tiếp nhận yêu cầu người dùng, xử lý yêu cầu và trả lại đáp ứng yêu cầu của người dùng đó. Giao diện dịch vụ để xác định những chức năng mà dịch vụ có thể cung cấp cho người dùng. Trong chương trình Math Service, giao diện dịch vụ là những phép toán mà người dùng có thể yêu cầu đến dịch vụ. Theo mô tả bài toán ở trên, giao diện dịch vụ của chương trình Math Service gồm 3 phép toán: cộng, trừ và lấy giá trị. Giao diện dịch vụ còn gọi là port type (được viết là portType). Một giao diện dịch vụ Web cũng như dịch vụ Grid được viết trong tệp dưới dạng .wsdl. Đây là tệp mô tả giao diện dịch vụ Web/Grid. Có 2 cách để viết tệp mô tả này:
Cách 1: Định nghĩa giao diện bằng tệp Java, sau đó chuyển đổi tệp Java sang tệp wsdl. Giao diện dịch vụ Math Service viết bằng Java như sau:
public interface Math {
public void add(int a); public void subtract(int a); public int getValueRP(); }
Cách 2: Viết trực tiếp một tệp wsdl. Tệp mô tả giao diện wsdl có các thành phần sau: • Phần HEADER: Đầy là phần định nghĩa tên, đường dẫn và namespace của dịch vụ • Phần TYPES: Phần này định nghĩa các biến, kiểu biến và các thuộc tính tài nguyên. • Phần MESSAGES: Là phần định nghĩa các thông điệp mà người dùng và dịch vụ tương tác với nhau
• Phần PORTTYPE: Là phần định nghĩa các phép toán mà người dùng và dịch vụ tương tác với nhau.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="MathService" targetNamespace="http://www.globus.org/namespaces/examples/core/MathService_instance"xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.globus.org/namespaces/examples/core/MathService_instance" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd" xmlns:wsrpw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl" xmlns:wsdlpp="http://www.globus.org/namespaces/2004/10/WSDLPreprocessor" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <wsdl:import namespace="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl" location="../../wsrf/properties/WS-ResourceProperties.wsdl" /> <!— T Y P E S --> <types> <xsd:schema targetNamespace="http://www.globus.org/namespaces/examples/core/MathService_instance" xmlns:tns=http://www.globus.org/namespaces/examples/core/MathService_instance xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- REQUESTS AND RESPONSES -->
<xsd:element name="add" type="xsd:int"/> <xsd:element name="addResponse">
<xsd:complexType/> </xsd:element>
<xsd:element name="subtract" type="xsd:int"/> <xsd:element name="subtractResponse"> <xsd:complexType/> </xsd:element> <xsd:element name="getValueRP"> <xsd:complexType/> </xsd:element>
<xsd:element name="getValueRPResponse" type="xsd:int"/> <!-- RESOURCE PROPERTIES -->
<xsd:element name="Value" type="xsd:int"/> <xsd:element name="LastOp" type="xsd:string"/> <xsd:element name="MathResourceProperties"> <xsd:complexType>
<xsd:sequence>
<xsd:element ref="tns:Value" minOccurs="1" maxOccurs="1"/> <xsd:element ref="tns:LastOp" minOccurs="1" maxOccurs="1"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </types> <!— M E S S A G E S --> <message name="AddInputMessage">
<part name="parameters" element="tns:add"/> </message>
<message name="AddOutputMessage">
<part name="parameters" element="tns:addResponse"/> </message>
<message name="SubtractInputMessage">
<part name="parameters" element="tns:subtract"/> </message>
<message name="SubtractOutputMessage">
<part name="parameters" element="tns:subtractResponse"/> </message>
<message name="GetValueRPInputMessage">
<part name="parameters" element="tns:getValueRP"/> </message>
<message name="GetValueRPOutputMessage">
<part name="parameters" element="tns:getValueRPResponse"/> </message>
<!— P O R T T Y P E --> <portType name="MathPortType" wsdlpp:extends="wsrpw:GetResourceProperty" wsrp:ResourceProperties="tns:MathResourceProperties"> <operation name="add"> <input message="tns:AddInputMessage"/> <output message="tns:AddOutputMessage"/> </operation> <operation name="subtract"> <input message="tns:SubtractInputMessage"/> <output message="tns:SubtractOutputMessage"/> </operation> <operation name="getValueRP"> <input message="tns:GetValueRPInputMessage"/> <output message="tns:GetValueRPOutputMessage"/> </operation> </portType> </definitions> 10.2.2. Bước 2: Thực thi dịch vụ.
Trong khi bước định nghĩa giao diện cho biết dịch vụ làm những cài gì? thì ở bước này – thực thi dịch vụ cho biết dịch vụ làm như thế nào? Sau đây là các thành phần của bước thực thi dịch vụ
a- Thành phần Qnames
Trong dịch vụ Grid, QName là một tên bao gồm tên của namespace và tên local. Ví dụ QName của Value RP là:
{http://www.globus.org/namespaces/examples/core/MathService_instance}Value Sử dụng lớp MathQNames để định nghĩa rút gọn QName.
package org.globus.examples.services.core.first.impl; import javax.xml.namespace.QName;
public interface MathQNames {
public static final String NS = "http://www.globus.org/namespaces/\ examples/core/MathService_instance";
public static final QName RP_VALUE = new QName(NS, "Value"); public static final QName RP_LASTOP = new QName(NS, "LastOp"); public static final QName RESOURCE_PROPERTIES = new
QName(NS,"MathResourceProperties"); }
b- Thực thi dịch vụ
Lớp MathService để thực thi dịch vụ:
public class MathService implements Resource, ResourceProperties{ }
MathService thực thi 2 giao diện là Resource (mô tả tài nguyên dịch vụ Grid) và ResourceProperties (mô tả các thuộc tính tài nguyên dịch vụ Grid).
Tài nguyên dịch vụ gồm 2 thành phần: Value: kiểu xsd:int và LastOp: kiểu xsd:string.
/* Resource properties */ private int value;
private String lastOp;
Các phép toán: lấy giá trị và đặt giá trị được thực thi như sau: /* Get/Setters for the RPs */
public int getValue() { return value;
}
public void setValue(int value) { this.value = value;
}
public String getLastOp() { return lastOp;
public void setLastOp(String lastOp) { this.lastOp = lastOp;
}
Các giá trị thuộc tính của tài nguyên dược khởi tạo trong constructor của lớp MathService:
/* Constructor. Initializes RPs */
public MathService() throws RemoteException { this.propSet = new SimpleResourcePropertySet( MathQNames.RESOURCE_PROPERTIES);
try { /* Initialize the RP's */
ResourceProperty valueRP = new ReflectionResourceProperty( MathQNames.RP_VALUE, "Value", this);
this.propSet.add(valueRP); setValue(0);
ResourceProperty lastOpRP = new ReflectionResourceProperty( MathQNames.RP_LASTOP, "LastOp", this);
this.propSet.add(lastOpRP); setLastOp("NONE");
} catch (Exception e) {
throw new RuntimeException(e.getMessage()); }
}
Hàm add() và getValueRP() thực thi các phép toán cộng và lấy giá trị: public AddResponse add(int a) throws RemoteException {
value += a;
lastOp = "ADDITION"; return new AddResponse(); }
public int getValueRP(GetValueRP params) throws RemoteException { return value;
}
10.2.3.Bước 3: Định nghĩa việc triển khai dịch vụ.
Hai bước quan trọng để lập trình một dịch vụ Grid đã được tiến hành bao gồm định nghĩa và thực thi dịch vụ. Vậy làm thế nào để các Client có thể kết nối với dịch vụ này? Bước 3 sẽ thực hiện công việc đó. Định nghĩa việc triển khai dịch vụ nói cho Grid container (là thành phần chứa các dịch vụ Grid, có trong bộ công cụ Globus Toolkit 4.0) biết được làm thế nào để quảng bá dịch vụ Math Service này. Chẳng hạn như nói cho Grid container biết được địa chỉ URI của dịch vụ. Tệp định nghĩa việc triển khai như sau: <?xml version="1.0" encoding="UTF-8"?> <deployment name="defaultServerConfig" xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<service name="examples/core/first/MathService" provider="Handler" use="literal" style="document">
<parameter name="className"
value="org.globus.examples.services.core.first.impl.MathService"/>
<wsdlFile>share/schema/examples/MathService_instance/Math_service.wsdl</wsdlFile> <parameter name="allowedMethods" value="*"/>
<parameter name="handlerClass" value="org.globus.axis.providers.RPCProvider"/> <parameter name="scope" value="Application"/>
<parameter name="providers" value="GetRPProvider"/> <parameter name="loadOnStartup" value="true"/> </service>
</deployment>
Các thành phần được định nghĩa bao gồm:
• service name: xác định địa chỉ URI của dịch vụ trong Grid container. Ở đây là:
• className: xác định lớp thực thi giao diện dịch vụ
• tệp WSDL: xác định tệp định nghĩa giao diện dịch vụ wsdl
• Load on startup: cho phép dịch vụ được nạp khi khởi động Grid container
10.2.4.Bước 4: Biên dịch và tạo tệp GAR
Ở các bước trên, mỗi khi hoàn thành mỗi bước lại tạo ra mỗi loại thành phần riêng rẽ. Vậy làm thế nào để triển khai được các thành phần đó vào trong Grid container cũng như biên dịch các tệp thực thi Java. Bước này sẽ thực hiện việc tạo tệp nén GAR chứa các thành phần trên. Chức năng của tệp GAR:
• Liên kết các tệp wsdl
• Khởi tạo và biên dịch các lớp từ các thành phần trong tệp wsdl • Biên dịch các tệp thực thi Java
• Tổ chức các tệp lại với nhau trong một cấu trúc đường dẫn xác định.
Công cụ Ant (có trong phần mềm Apache Ant đã cài đặt) có chức năng biên dịch và tạo tệp GAR từ các thành phần ở trên. Mô hình sau đây mô tả chức năng đó của Ant.
Hình 24: Chức năng tạo tệp GAR của công cụ Ant
Để tạo tệp GAR, ta dùng script globus-build-service có trong bộ Globus Service Build Tools (GSBT) tại http://gsbt.sourceforge.net/ . Cấu trúc dòng lệnh để tạo tệp GAR như sau:
./globus-build-service.sh -d <đường dẫn tới dịch vụ> -s <tệp WSDL của dịch vụ>
Đối với Math Service, dòng lệnh như sau: ./globus-build-service.sh \
-d org/globus/examples/services/core/first/ \
-s schema/examples/MathService_instance/Math.wsdl
10.2.5.Bước 5: Triển khai dịch vụ
Đây là bước để triển khai dịch vụ trong Grid container. Việc triển khai dịch vụ vào trong Grid container tương đương với việc bung tệp nén GAR được tạo ra ở bước 4 và đưa các thành phần thích hợp vào Grid container. Thực hiện dòng lệnh sau:
Để xóa bỏ dịch vụ trong Grid container, dùng lệnh globus-undeploy-gar: globus-undeploy-gar org_globus_examples_services_core_first
10.3. Chạy thử chương trình Math Service
Sau khi đã triển khai dịch vụ Math Service vào Grid container, khởi động Grid container bằng lệnh: globus-start-container, dịch vụ sẽ bắt đầu hoạt động. Nhận biết dịch vụ đã hoạt động bằng địa chỉ URI của dịch vụ:
http://127.0.0.1:8080/wsrf/services/examples/core/first/MathService
Để kiểm tra hoạt động của dịch vụ, ta viết một Client đơn giản, gửi yêu cầu đến dịch vụ Math Service thực hiện các phép toán: cộng, trừ và lấy giá trị. Lớp Client được viết như sau:
public class Client {
public static void main(String[] args) {
MathServiceAddressingLocator locator = new MathServiceAddressingLocator(); try {
String serviceURI=args[0];
EndpointReferenceType endpoint = new EndpointReferenceType(); endpoint.setAddress(new Address(serviceURI));
MathPortType math = locator.getMathPortTypePort(endpoint); math.add(10); // Perform an addition
math.add(5); // Perform another addition // Access value
System.out.println("Current value:" + math.getValue(new GetValueRP())); // Perform a subtraction
math.subtract(5); // Access value
System.out.println("Current value:" + math.getValue(new GetValueRP())); } catch (Exception e) {
e.printStackTrace(); }
} }
• EndpointReferenceType: là đối tượng tham chiếu đến địa chỉ của tài nguyên dịch vụ. • MathPortType: là đối tượng tham chiếu đến giao diện (gọi là portType) của dịch vụ.
Chương trình trên sẽ thực hiện phép cộng 10, cộng 5, in ra kết quả, sau đó trừ 5 và in ra kết quả. Biên dịch và chạy tệp Client, ta được kết quả:
Current value: 15 Current value: 10
Chạy chương trình lần thứ 2, ta được kết quả: Current value: 25
Current value: 20
Chứng tỏ kết quả tính toán ở lần thực hiện cuối cùng đều được lưu vào tài nguyên của dịch vụ Grid.
Chương 11. Tự xây dựng một dịch vụ Grid: Bài toán số nguyên tố
Ở chương 10, chúng tôi đã mô tả các bước lập trình cũng như chạy thử nghiệm một chương trình có sẵn là: Math Service. Tuy nhiên, Math Serivce là một chương trình mang tính thử nghiệm, không có ứng dụng gì trong thực tiễn. Trong chương này, chúng tôi sẽ phát triển chương trình riêng của mình, phức tạp hơn và có ý nghĩa ứng dụng trong thực tiễn, đó là chương trình Số nguyên tố.
Số nguyên tố là số nguyên lớn hơn 1, chỉ chia hết cho 1 và chính nó. Số nguyên tố không chỉ là số có ý nghĩa lớn trong lĩnh vực toán học mà còn có ý nghĩa quan trọng trong lĩnh vực công nghệ thông tin, đặc biệt là vấn đề bảo mật và mã hoá. Mỗi tổ chức đều muốn sử dụng một số nguyên tố riêng, đủ lớn để đảm bảo bí mật trong việc mã hoá thông tin nội bộ. Vậy, làm thế nào để tìm được số nguyên tố đủ lớn đảm bảo yêu cầu đó?
Việc tìm một số nguyên tố nhỏ là không khó. Phương pháp đơn giản nhất là dùng sàng Eratosthenes. Với phương pháp này, để kiểm tra số nguyên n có phải là số nguyên tố hay không, ta kiểm tra n có chia hết cho số nguyên k từ 2 đến [ n]+1 hay không? Nếu n không chia hết cho mọi ki (i = 2,[ n]+1) thì n là số nguyên tố. Ngược lại, n là hợp số.
Tuy nhiên, việc tìm số nguyên tố lớn (khoảng từ 30 chữ số trở lên) không phải là đơn giản. Bởi vì công việc đó nảy sinh một số vần đề sau đây:
• Vấn đề 1: Làm thế nào để tìm được số nguyên tố lớn cũng như chứng minh tính nguyên tố của số đó khi mà các phương pháp duyệt thông thường không còn khả thi. • Vấn đề 2: Thời gian cần thiết để hoàn thành việc tìm kiếm và kiểm tra một số nguyên tố là rất lớn. Mặc dù ngày nay đã có sự hỗ trợ của máy tính điện tử, nhưng việc tìm các số nguyên tố có hàng triệu chữ số phải mất đến hàng nghìn năm. Chẳng hạn, số nguyên tố lớn nhất hiện nay là số có khoảng 9,1 triệu chữ số. Với một máy tính Pentium 4 thông thường, phải mất khoảng 4500 năm để tìm được số này (Theo: George Woltman - một lập trình máy tính của Great Internet Mersenne Prime Search (GIMPS); thông tin từ:
Vì vậy, chúng tôi phát triển bài toán Tìm số nguyên tố Mersenne trên môi trường Grid Computing với hi vọng có thể giải quyết được các vấn đề trên trong thời gian chấp nhận được.
Với vấn đề 1, chúng tôi không thực hiện việc tìm kiếm các số nguyên tố thông thường. Thay vào đó, chúng tôi tìm các số nguyên tố dạng Mersenne.
• Định nghĩa 1: Nếu n là số nguyên có dạng: 2p - 1 (p∈Ν,p >1) thì n gọi là số Mersenne.
• Định nghĩa 2: Số nguyên n gọi là số nguyên tố Mersenne nếu: n là số Mersenne đồng thời là số nguyên tố.
Để tìm một số nguyên tố Mersenne, chúng tôi tìm hiểu và lựa chọn thuật toán thích hợp.
Với vấn đề 2, chúng tôi không thực thi bài toán trên một máy tính mà sử dụng giải pháp Grid Computing để thực thi bài toán trong mạng Grid Computing gồm nhiều máy tính khác nhau. Grid Computing là một lĩnh vực khá mới mẻ ở nước ta hiện nay. Được xem như là một “siêu máy tính giá rẻ”, Grid Computing đang được phát triển rộng rãi cho các tổ chức trên thế giới.
Hiện nay, trên thế giới đã có một số tổ chức ứng dụng Grid Computing trong bài toán Tìm số nguyên tố. Tiêu biểu là Great Internet Mersenne Prime Search (GIMPS). Tuy nhiên, trong mô hình bài toán của họ đưa ra còn có một số vấn đề như là: thời gian tìm kiếm lâu, mô hình phân chia công việc chưa hợp lý trong vấn đề xử lý song song…Với những thách thức đó, chúng tôi cố gắng đưa một giải phát Tìm số nguyên tố ở dạng số nguyên tố Mersenne trên Grid hy vọng có được một giải pháp tốt.
11.1. Giới thiệu công cụ phát triển
Ở chương 10, chúng tôi đã trình bày quá trình xây dựng một dịch vụ Grid gồm các bước: định nghĩa giao diện, thực thi dịch vụ, cấu hình việc triển khai dịch vụ, tạo tệp nén GAR và triển khai dịch vụ Grid trong Grid container. Trong mỗi bước, người lập trình phải tạo ra các tệp ứng với các chức năng nhất định. Ví dụ, bước định nghĩa giao diện, tạo các tệp .wsdl để định nghĩa giao diện dịch vụ web; Bước thực thi dịch vụ, tạo các tệp .java để thực thi dịch vụ…Cuối cùng, người lập trình liên kết với các thư viện Globus Toolkit để biên dịch các tệp, nén thành tệp GAR và triển khai dịch vụ. Quá trình này có vẻ đơn giản khi xây dựng một chương trình dịch vụ Grid đơn giản. Tuy nhiên, đối với các chương trình dịch vụ Grid phức tạp sẽ gây khó khăn cho người lập trình
trong việc viết chương trình và sửa lỗi. Nó đòi hỏi người lập trình mất nhiều thời gian để viết các tệp, tìm kiếm và phát hiện lỗi.
Khó khăn trên đòi hỏi phải có công cụ hỗ trợ những người phát triển dịch vụ Grid. Chúng tôi giới thiệu một trong các công cụ đó. GT4IDE là một công cụ hỗ trợ đắc lực cho người phát triển dịch vụ Grid trên nền ngôn ngữ Java.
11.1.1.Giới thiệu công cụ GT4IDE
GT4IDE là một khung làm việc, hỗ trợ việc phát triển các dịch vụ Grid Serivice 4.0 trên nền ngôn ngữ Java. GT4IDE là một plug-in của Eclipse - một IDE của Java, phát triển độc lập trên các môi trường.
Chức năng của GT4IDE gồm có:
1 - Tương tác với các thư viện của Globus Toolkit 4.0, tạo project Globus Toolkit 4.0 để phát triển các dịch vụ Grid trên nền ngôn ngữ Java
2 - Tự động tạo các tệp cần thiết trong một project Globus Toolkit như: tệp wsdl - mô tả giao diện; tệp .java - thực thi dịch vụ…
3 - Cùng với Eclipse, khả năng phát hiện và sửa lỗi của GT4IDE là khá tốt. 4 - Tự động biên dịch, tạo tệp GAR cho một project Globus Toolkit 4.0.
Với các chức năng đó, GT4IDE là một công cụ rất hữu ích cho các nhà phát triển các dịch vụ Grid Serivce 4.0
11.1.2.Cài đặt GT4IDE
GT4IDE là một plug-in của Eclipse. Trước khi cài đặt GT4IDE phải cài đặt