Phát triển tư duy thuật giải cho học sinh thông qua dạy học các cấu trúc điều khiển và dữ liệu có cấu trúc trong Tin học 11

MỤC LỤC

2Các công việc đã giải quyết được

Vì đây là một chương trình chạy trên nhiều máy, do đó để hợp tác với nhau làm việc thì các Object phải gửi nhận thông tin qua lại với nhau, vì vậy một Distributed Object Application cần phải giải quyết được việc định vị các Remote Object nhằm phục vụ cho việc truyền nhận thông tin như đã nói. Vì vậy, Non-Remote Object là một tham số nó sẽ được Copy từ một Object có sẵn và bên nhận sẽ khôi phục lại Object đó từ chuỗi các Byte, còn nếu Non-Remote Object là giá trị trả về nó sẽ được tạo mới và truyền đi.

VIMột số đặc điểm nổi bật của Java RMI

Chi tiết về việc truyền nhận như thế nào thì RMI đã làm, đối với người sử dụng thì việc truyền thông với Remote Object giống như là việc truyền thông với những Object bình thường khác. Bởi vì RMI cho phép truyền nhận các Object, mà các Object này “Serialize” được, vì vậy một Distributed Object Application cũng phải giải quyết việc lấy ByteCodes về để có thể thực thi tiếp công việc nào đó.

1Ví dụ về Load Class động

Với ClassNameB là một Class tương đương với ClassNameA nghĩa là những gì ClassNameA làm được thì ClassNameB cũng làm được hay về mặt lý luận trên thực tế một số nguyên cũng có thể xem là một số thực, do đó theo lý luận trên ta có thể truyền một số int thay cho một số float. Điều này gây ảnh hưởng về tính uyển chuyển của việc lập trình và chạy chương trình bởi vì dễ thấy rằng nếu muốn truyền các giá trị trả về hay các tham số cho một hàm từ xa nào đó, mà các giá trị này thuộc kiểu dữ liệu khác với khai báo hàm thì ta phải thực hiện biên dịch lại chương trình tại Server.

2Load Class động là gì ?

Chú ý là chỉ đối với những Object mới được thực hiện điều này, với kiểu dữ liệu nguyên thủy (ví dụ: kiểu int, float …) thì do Java không hỗ trợ việc tự động chuyển đổi kiểu nên RMI cũng không hỗ trợ việc chuyển đổi kiểu trong việc gọi hàm từ xa. Điều này có nghĩa là khi có một khai báo hàm tại Server và hàm này có các giá trị trả về hay các tham số là Object của một Class A nào đó, thì khi gọi hàm hay khi trả kết quả về thì ta có thể thay Object thuộc chính xác Class A đó bằng một Object thuộc Class B, với điều kiện là Class A và Class B là hai Class tương đương nhau.

3Lợi điểm của việc Load Class động

Java RMI cũng cho phép việc Load Class động, nghĩa là trong các gói dữ liệu truyền qua lại giữa Client và Server có một vùng thông tin để chứa lại thông tin đặc tả Class A nào đó mà Object của A đó được truyền đi trong gói dữ liệu tương ứng. Điều này giúp Java có thể xác định xem có cần phải đi Load Bytecode để phục vụ cho mục đích tạo lại Object từ dữ liệu nhận được hay không ?.

4Ứng dụng cụ thể của Load Class động

Ta cũng có thể hiểu rằng điều này có được là do cách Java truyền những gói dữ liệu giữa Client và Server.

VIIISerialization

Vấn đề Serialization cũng được đặt ra khi truyền một Object từ JVM này đến JVM khác, đó là do khi truyền một Object ta phải truyền thành một chuỗi các Byte, rồi sau đó ta cũng phải khôi phục lại Object đó dựa trên các Byte này. Đối với những Java Object, cách Serialized một Object là phải xác định và những định nghĩa lớp cho Object phải được kiểm tra bởi Java, để từ đó nội dung của Object được store một cách chính xác và việc restore nội dung thành một instance mới được thực hiện một cách chính xác.

IXMultiThread

Đối với lớp hiện thực Interface Serializable, việc Object Serialization có thể tự động save và restore những field của mỗi class của một object và tự động quản lý những lớp bằng cách thêm vào những field hay supertypes. Một lớp Serializable cũng có thể khai báo những field của nó là transient (nghĩa là không cần lưu trữ lại và không cần làm thao tác phục hồi khi phục hồi Object đối với field đó).

1Khái niệm MultiThread

Đối với lớp Externalizable , Object Serialization giao cho những lớp toàn quyền điều khiển qua external format và trạng thái của supertype được save và restore như thế vào. Những Thread trong một chương trình MultiThread được thực thi trên cùng một vùng dữ liệu chung, chính là vùng dữ liệu của hệ thống cấp cho Process.

2Lập trình Multithread trong Java

Nếu có một biến global nào đó thay đổi trong một Thread nào đó thì tất cả các Thread khác cũng bị thay đổi. Vì lý do đó mà các ngôn ngữ lập trình hiện đại đều có hỗ trợ Multithread, Java cũng vậy.

3Các trạng thái của Thread

Nói tóm lại, các Thread dùng chung tài nguyên và cuứng khoõng gian ủũa chổ. • Thread mất ít thời gian để tạo và loại bỏ so với việc tạo và loại bỏ Process.

2Classpath

• Tạo lập một biến môi trường để có thể dùng cho cả phiên làm việc. Với Unix ta cũng có các cách set Classpath tương tự như trên nhưng với cú pháp khác đi.

3URL

Đây là một loại URL dùng để chỉ tới một resource có cùng thư mục, cùng tên máy với một resource đã có sẵn. Vậy thì lúc này chúng ta có thể dùng partial URL, hay relative URL để chỉ tới một file khác trong cùng một thư mục, cùng một máy với file tên là “afile.html” như trên.

4Codebase

Với RMI, khi một Client muốn gọi một Method của một Remote Object nào đó thì bắt buộc Client phải có một tham khảo tới Remote Object đó, để có một tham khảo tới Remote Object thì Client phải có một Intance thuộc Class gọi là Stub Class, class này được tạo ra bởi chương trình RMIC. Và cũng vì mục đích để cho JVM có thể tự động tìm Bytecode mà người ta định nghĩa và sử dụng các biến môi trường như CLASSPATH và các Property như java.rmi.server.codebase với những cách sử dụng và cơ chế hoạt động như đã nêu ở trên.

Hình 13. Nguyên tắc làm việc của cơ chế RMI có dùng codebase.
Hình 13. Nguyên tắc làm việc của cơ chế RMI có dùng codebase.

XIMoâ hình Java Security

Tóm lại, trong Java để các ứng dụng có thể hoạt động một cách uyển chuyển hơn, người ta hỗ trợ cơ chế Load Class động, là cơ chế cho phép JVM tự động tìm và tạo một Instance thuộc một Class mà JVM chưa có Bytecode. Verifier có nhiệm vụ làm thế nào để ngăn chặn bytecode thực hiện các thao tác không hợp lệ chẳng hạn các vấn đề trong việc truy cập bộ nhớ, hay các hoạt động không được phép khác.

2Moâ hình Sandbox nguyeân thuûy

Cuối cùng, việc truy cập đến những tài nguyên hệ thống quan trọng thì phải thông qua JVM làm trung gian, việc truy cập đó cũng được kiểm tra bởi một lớp Security , lớp nầy giới hạn những hoạt động của những code không đáng tin cậy. Khái niệm này như sau : khi một bytecode được load về, thì nếu JVM tại Local nhận ra bytecode này có một khóa mà nó đã quy định trước thì bytecode này sẽ được đối xử như một bytecode tại JVM Local.

3Phát triển mô hình Sandbox

Cũng mô hình trên,với JDK 1.1 thì nó đã được phát triển lên một mức cao hơn, đó là việc JDK 1.1 giới thiệu khái niệm về “signed applet”. Thay vào đó, những code cục bộ (trừ code hệ thống, những packege ứng dụng được install trên hệ thống file cục bộ) đều được đưa vào chiến lược security giống như applet hay bất cứ bytecode nào lấy được từ mạng.

XIIActivation

• Cho phép kiểm tra security đối với tất cả các chương trình Java, ứng dụng cũng nhử applet. Với mô hình này thì không có khái niệm tất cả code cục bộ đều là code tin cậy.

2Khái niệm chung

Thực chất, khi một Activatable Object A đăng ký với Registry thì một Instance của Stub Class của A sẽ được tạo ra và tồn tại mãi, chú ý là Instance này không bị giải phóng mà Instance này được quản lý bởi Registry. Khi Remote Object A này chưa Active thì tham khảo này có giá trị là null, nhưng khi Remote Object A này đã đang ở trạng thái Active thì tham khảo này có giá trị là tham khảo tới Remote Object thực sự.

Hình 20. Faulting Remote Reference.
Hình 20. Faulting Remote Reference.

3Nguyên tắc hoạt động

Thông thường trên mỗi JVM có một Activation group, Activation group là một thực thể đóng vai trò nhận yêu cầu Activate một Object trên Local JVM và trả về tham khảo tới Object thực sự cho Activator.

Toồng keỏt phaàn lyự thuyeỏt

♦RMI còn là một mô hình muti-threaded, nó cho phép các Server khai thác tính chất thread của Java, điều này làm Server có thể thực hiện tốt hơn cho việc xử lý đồng thời các yêu cầu của các Client. Giúp cho cơ chế RMI trở nên mạnh hơn, cụ thể hơn là giúp cho RMI có thể hỗ trợ việc cho việc cho phép Client Object có thể gửi lên cho Remote Object một Object và nhờ Remote Object thực thi hộ một trong các Method của Object được gửi lên đó.

XVYêu cầu đối với hệ thống

♦Phải có tính mở về dịch vụ, nghĩa là hệ thống cho phép thêm dịch vụ một cách dễ dàng và bất cứ ai cũng có thể viết dịch vụ khi có format dịch vụ. ♦Phải có tính mở về giao tiếp, nghĩa là hệ thống phải cho phép các Object tạo ra từ các ngôn ngữ khác kết nối vào một cách dễ dàng.

XVICác giả thiết đối với hệ thống

♦Người quản trị mạng dễ dàng kiểm soát các hoạt động của hệ thống, dễ dàng thống kê được các thông tin cần thiết về hệ thống. ♦Có tính kháng lỗi nghĩa là hệ thống phải khắc phục được các lỗi có thể xảy ra trong quá trình vận hành.

XVIICác vấn đề chính yếu

2Giải thích mô hình

Ngoài mục đích trên, việc hệ thống có nhiều Agent cũng nhằm mục đích chuyên môn hóa các dịch vụ (nghĩa là một Agent quản lý một số dịch vụ mang tính chất gần giống nhau) , cũng chính điều này sẽ giải quyết phần nào vấn đề thắt nút cổ chai cho hệ thống. Nghĩa là Service A có thể cần tới kết quả của Service B và ngược lại thì ta nên bố trí các Service trên sao cho chúng cùng thuộc một Server, điều này có thể làm giảm thời gian Communicate, nhằm giúp hệ thống hoạt động hiệu quả hơn.

3Các phần tử của hệ thống

• Mô hình này đòi hỏi việc liên lạc qua lại trong hệ thống xảy ra nhiều hơn, nó có thể tốn nhiều thời gian Communicate, chẳng hạn Agent A nhờ Agent B, Agent B phân phối công việc , nhận kết quả, rồi trả kết quả về lại cho Agent A. • Client : là chương trình do người sử dụng phát triển, chương trình này làm nhiệm vụ trung gian giúp User của hệ thống có thể sử dụng các Service của hệ thống.

4Các vấn đề cần giải quyết

• Server : thực chất trong hệ thống này Server là một Remote Object, Server là một chương trình quản lý các Service tại máy có Server Object. Chương trình này chịu sự điều khiển của chương trình Agent, nghĩa là nó sẽ nhận yêu cầu từ phía Agent và thực hiện các yêu cầu đó.

2Hoạt động của từng phần tử hệ thống

    Vì yêu cầu của đề tài là xây dựng một môi trường hỗ trợ tính toán song song và phân bố nên việc thêm bớt hay sửa chữa dịch vụ nào đó vào hệ thống cũng phải thực hiện được. Chương trình này được kích khởi bởi người quản trị hệ thống (chương trình Admin.). ♦Lấy tên Server mà Agent đó quản lý từ một Database đã có sẵn từ trước. ♦Lấy thông tin từ Server mà nó phải quản lý. Cụ thể hơn là các thông tin như :. • Các dịch vụ mà Server đang quản lý. • Các thông tin về tải của Server. • Server nào còn hoạt động và Server nào bị fail. ♦Lấy thông tin từ Agent khác. Cụ thể là các thông tin như :. • Tên dịch vụ mà Agent đó quản lý. • Agent nào bị Fail, Agent nào còn hoạt động. ♦Chờ nhận kết nối từ Client. ♦Nhận yêu cầu về dịch vụ. ♦Sinh ra một Thread mới thực hiện phân chia công việc. Thread cũ vẫn chờ nhận yêu cầu. Số Thread sinh ra phải có một giới hạn nào đó. ♦Sau đó Thread này sẽ thi hành công việc đó luôn. Và khi kết thúc và trả về kết quả cho Client. ♦Trong Thread này còn phải làm các công việc như tổng hợp kết quả từ Server để trả veà cho Client. ♦Khi Client gửi yêu cầu xong nó gửi một tín hiệu Shutdown và Server dựa vào đó để đóng cầu nối khi trả xong kết quả. ♦Nếu Agent A không có dịch vụ mà Agent B có thì Agent A sẽ nhờ Agent B thực hiện công việc đó rồi nhận kết quả trả về và thực hiện việc trả về cho Client. ♦Vấn đề quảng cáo : khi Client kết nối với một Agent nếu Client yêu cầu thì Agent sẽ gửi những thông tin về dịch vụ mà nó có được và các Agent khác có được về cho Client. Việc này đòi hỏi nó phải cập nhật lại thông tin về dịch vụ sau một khoảng thời gian nào đó. ♦Trong một khoảng thời gian nào đó Agent sẽ kiểm tra xem các Server có bị fail và dịch vụ nào bị phá hoại, dịch vụ nào chạy tốt. ♦Nhận yêu cầu về kết nối từ phía chương trình Admin. Thực hiện các thao tác quản trị hệ thống do chương trình Admin gửi yêu cầu tới. Keỏt thuực chửụng trỡnh :. ♦Kết thúc việc chờ nhận yêu cầu từ Client. ♦Chờ cho hoàn thành các yêu cầu của Client. ♦Gửi yêu cầu Shutdown các Server và chờ nhận trả lời. ♦Lưu thông tin về Server, về Client, về dịch vụ và các thông tin cần thiết cho lần chạy sau. • Chương trình Server khác. Do Administrator kích khởi. Kích khởi các dịch vụ ban đầu dựa vào Database có sẵn trước đó. Chương trình Server đứng chờ gọi hàm từ xa từ Agent. Thực thi dịch vụ có tính quản lý Service tại host đó, trả kết quả về cho Agent. Lưu lại môi trường làm việc. Chương trình này do User chạy trên một máy bình thường. Không thực hiện công việc khởi tạo đặc biệt nào. Kết nối với Agent. Yêu cầu dịch vụ. Đối với Client hệ thống cung cấp hai loại hình dịch vụ đó là : + Dịch vụ của hệ thống sẵn có. + Dịch vụ do Client tự động gửi lên. Với loại hình này, dịch vụ này sẽ bị biến mất sau khi nó được thực thi xong. Nhận kết qủa trả về từ Agent. 5) Administrator (Người quản trị mạng).

    XXCác chức năng của hệ thống

    ♦Chức năng Activate một dịch vụ hay shutdown tạm thời các dịch vụ của hệ thống : chức năng này cung cấp cho người quản trị hệ thống nhằm giúp cho người quản trị hệ thống điều hành hệ thống hoạt động với hiệu quả của hệ thống có thể kiểm soát được. ♦Cung cấp giúp đỡ cho một Service trong hệ thống : chức năng này chỉ được cung cấp cho chương trình Admin, chức năng này nhằm mục đích cung cấp các thông tin cần thiết về cách sử dụng một Service của hệ thống.

    XXIGiải quyết các vấn đề trong hệ thống

    • Cung cấp toàn bộ tên các Server đang tồn tại trong hệ thống và toàn bộ tên các Service trên Server đó.

    1Thaột nuựt coồ chai (Bottle Neck)

    Tuy nhiên, đây là hệ thống Concurent, mỗi khi một yêu cầu đến, sau khi được chấp nhận, sẽ có một thread được sinh ra để thực hiện các công việc tiếp theo để phục vụ yêu cầu dịch vụ đó. Tức là Agent đếm thứ tự các yêu cầu đến, nếu số yêu cầu vượt quá con số quy định này, Agent sẽ sinh ra một Agent mới, sau đó Agent này sẽ trả địa chỉ của Agent mới cho Client để Client nếu muốn có thể kết nối đến Agent đó.

    2Vấn đề phân chia công việc

    Sau khi đã lấy thông tin của các host (trừ các host bị TIMEOUT ) truyền cho một hàm có tên là Separator để hàm này làm công việc phân chia khối lượng công việc ra thành nhiều khối lượng công việc nhỏ hơn. Do đó, Agent có thể thực hiện được việc phân chia này thì người phát triển dịch vụ khi muốn thêm vào hệ thống một dịch vụ nào đó, phải cung cấp cho hệ thống bytecode của một Object tên là Separator Object để nó đảm nhận việc phân chia này.

    3Fault-Tolerance

      Sau khi đã lấy thông tin của các host (trừ các host bị TIMEOUT ) truyền cho một hàm có tên là Separator để hàm này làm công việc phân chia khối lượng công việc ra thành nhiều khối lượng công việc nhỏ hơn. Hàm này là một Remote Method của Remote Object Service. Do đó, Agent có thể thực hiện được việc phân chia này thì người phát triển dịch vụ khi muốn thêm vào hệ thống một dịch vụ nào đó, phải cung cấp cho hệ thống bytecode của một Object tên là Separator Object để nó đảm nhận việc phân chia này. Object này phải là Object của một Class mà Class này Implement một Interface tên là Lvtn.agent.separator.Segment. Interface này do người phát triển hệ thống cung cấp. Phần này sẽ trình bày một số phương án để giải quyết các lỗi xảy ra với Agent, Server, RMIRegistry và cả với Service. Chú ý là ngay cả RMIRegistry cũng có thể chết, mà RMIRegistry đóng vai trò là một NameServer trong hệ thống RMI, do đó khi RMIRegistry bị chết ta cũng phải giải quyết. 1) Fault -Tolerance cho Agent. Có nhiều giải thuật để bầu chọn một Server trong hệ thống để làm nhiệm vụ của một Agent, nhưng giải thuật đơn giản và dễ dùng là giải thuật Bully của Garcia-Molina(1982)[4]. Nội dung giải thuật như sau:. • Các Server được đánh số theo chỉ số tăng dần và duy nhất. • Khi một Server phát hiện Agent chết nó sẽ khởi động việc bầu cử và nó sẽ gửi một message ứng cử tới cho các Server khác trong hệ thống. • Nếu có Server nào có chỉ số cao hơn nó sẽ trả lời cho Server đó, và lúc này ưu tiên ứng cử dành cho Server có chỉ số cao hơn. • Về phía Server ban đầu, nếu không thấy ai trả lời sẽ tự bầu nó làm Agent. Giải thuật trên có thể biểu diễn theo sơ đồ khối như sau : Start. Kieồm tra theo ủũnh kyứ. Gửi Message ứng cử. Có Server trả lời?. Start Agent mới. Lưu đồ cho cơ chế bầu cử. Để lựa chọn cơ chếcho việc hiện thực Agent của hệ thống, cần xét qua đặc tính của Agent của hệ thống. Agent của hệ thống có đặc tính là người quản lý là chính yếu, do đó một khi có sự kiện ảnh hưởng đến việc quản lý thì ta đã lưu sự ảnh hưởng của sự kiện đó xuống File Database. Do đó, cơ chế thích hợp cho việc khắc phục lỗi là cơ chế “CheckPoint and Recovery” như đã nêu ở trên. Tóm lại, giải pháp cho việc hiện thực khắc phục cho sự kiện Agent chết là theo cơ chế “CheckPoint and Recovery”. 2) Vấn đề Faul-tolerance đối với Server:. Server cũng có khả năng bị fail như Agent. Cũng có thể sử dụng các phương án như đã nêu trên để giải quyết vấn đề này. Ngoài ra có một phương án khác đó là Restart Server. Cô cheá “ReStart Server” :. Hoạt động của cơ chế này hoàn toàn đơn giản, đó là khởi tạo lại từ đầu một Server mới hoàn toàn. Đơn giản là một ưu điểm quan trọng nhất đối với cơ chế này, nhưng ngược lại cơ chế này lại là một cơ chế khắc phục lỗi không hiệu quả do không lưu lại được bất cứ dữ liệu gì của Server trước đó. Có thể nói ngắn gọn lại là khi phát hiện có một Server trong hệ thống bị Fail, Agent tự động Start lại một Server mới với các Database trên JVM đó và dùng nó giải quyết yêu cầu của Client lại từ đầu. Với phương án này thì nó dựa trên luận cứ là nếu làm không được thì làm lại từ đầu. Do đó tính đơn giản trong giải thuật rất cao do không cần phải khắc phục một điều gì từ hệ thống trước đó. Do đó có thể nói ta chỉ khắc phục tình trạng Fail của một chương trình với phương án này. Cơ chế này đơn giản, dễ sử dụng, dễ hiện thực. Đặt biệt là với cơ chế này hoàn toàn không mất thời gian trung gian trong việc chuẩn bị cho việc Fail của Agent. Tuy nhiên, độ mất mát thông tin của hệ thống là khá cao. Restart Server làphương án được lựa chọn cho hệ thống đang xây dựng. Để lựa chọn một phương án cho chương trình Server thì ta phải xem xét tính chất của chương trình Server. Vị trí và vai trò của Server trong hệ thống có thể được trình bày như sau :. Server Server Java Virtual Machine. Vai trò của Server Object trong hệ thống. Về thực chất thì Server cũng là một dịch vụ đặt biệt, nó sẽ nhận vào bytecode, lưu bytecode đó xuống phương tiện lưu trữ, tạo một Instance từ định nghĩa class là bytecode đó, và coi nó là một dịch vụ, nghĩa là đăng ký Instance đó với một RMIRegistry để cho các JVM khác có thể thấy được và sử dụng được theo cơ chế RMI. Do đó, có thể nói là chương trình Server không có trạng thái quan trọng nào cần lưu trữ, bởi vì nếu Server bị Fail thì thông tin bị mất chỉ là tên của các Service tại Local Machine mà thôi, mà tên của các Service này thì đã được lưu trong File Database của Server rồi, do đó khi Start lại chỉ cần làm công việc khởi tạo lại lần nữa là đã có thể hoạt động như cũ. Mặt khác , đây là hệ thống nhiều Server nên nếu dùng phương án khác như Back up thì rất hao tốn tài nguyên cho hệ thống. Tóm lại việc sử dụng phương án Restart lại Server vừa đáp ứng được cả hai mục đích : có thể giải quyết vấn đề server fail tương đối tốt và lại khá đơn giản thích hợp với việc phát triển hệ thống trong một khoảng thời gian không nhieàu. 3) Vấn đề Fault-Tolerance đối với Service. Một vấn đề đặt ra nữa là trường hợp những service bị fail thì làm sao hệthống biết được và cách giải quyết như thế nào?. Những Service trong hệ thống này thật ra là những Remote Object. Do đó, sau một khoảng thời gian nào đó Server sẽ đi kiểm tra chúng để biết những Service nào còn hoạt động, những service nào gặp vấn đề. Khi Agent phát hiện Service nào đó bị Fail, thì Agent sẽ lựa chọn các những cách giải quyeát sau:. • Agent yêu cầu Server Start lại Service với bytecode mà Server đang nắm giữ. • Agent yêu cầu Server Start lại Service với Bytecode mà Agent sẽ cung cấp để bytecode này sẽ thực hiện Recovery đối với từng trường hợp cụ thể. Với trường hợp thứ nhất thì ta không quan tâm giải quyết vấn đề khôi phục trạng thái Service trước đó, do đó không có vấn đề để giải thích. Với trường hợp thứ hai thì Service bị fail trước đó đã có lưu lại các trạng thái vào một log File, và ngay chính bản thân nó không làm được việc Recovery, do đó khi Start lại với bytecode đó thì có thể nó chưa giải quyết được việc khôi phục lại trạng thái Sevice trước đo. Do đó, đòi hỏi Agent phải gửi cho Server bytecode mà có giải quyết vấn đề Recovery. 4) Vấn đề RMIRegistry chết.

      XXIIVấn đề Data trong chương trình

      Tùy vào tính chất từng hệ thống sẽ có những phương án thích hợp để giải quyết vấn đề này. Cũng nói thêm rằng nếu một hệ thống được xây dựng có tính ổn định khá cao thì việc các phần tử trong hệ thống bị fail không phải xảy ra thường xuyên.

      1Sự không đồng nhất trong biểu diễn Data

      Trong trưởng hợp này ta khú cú thể xỏc định rừ ràng cỏch giải quyết nào là tốt nhất. Việc đưa ra những phương án đẻ giải quyết không phải lúc nào cũng thành công.

      2Các Dòng Dữ liệu

      Tóm lại, với dòng dữ liệu này hầu hết công việc cần làm là thiết kế nội dung các gói dữ liệu sao cho không những chúng đầy đủ thông tin mà cấu trúc dữ liệu phải hợp lý để có thể tăng hiệu quả của việc truyền dữ liệu và phục vụ tốt nhất cho các giao thức giao tiếp giữa các Object trong hệ thống. Tuy nhiên, với cách hoạt động như vậy cũng làm cho Agent phải đảm nhận công việc nhiều hơn, điều đó có nghĩa là tình trạng thắt nút cổ chai sẽ dễ dàng xảy ra cho Agent hơn do lượng công việc cho mỗi yêu cầu tăng lên cao.

      3Mã hóa dữ liệu

      Hơn thế nữa, do dữ liệu được truyền đi phải thông qua Agent do đó thời gian để truyền dữ liệu đi cần nhiều hơn, điều này làm hiệu quả của hệ thống giảm đi do thời gian Overhead cho việc truyền nhận dữ liệu bị tăng cao. Để lựa chọn phương pháp để truyền dữ liệu dùng trong một hệ thống, cần phải xem xét lại đặc tính của từng hệ thống và từng loại dịch vụ trên đó mà có phương pháp truyền dữ liệu thích hợp.

      Password authentication

      Nếu password được lưu hay truyền đi dưới dạng plaintext thì việc password bị đánh cắp có thể xảy ra. Vấn đề mã hóa dữ liệu làm cho hệ thống được đảm bảo an toàn hơn, tránh việc những User không có quyền đột nhập vào hệ thống khi lấy được những dữ liệu chưa được mã hóa.

      XXIIITrang bị phần cứng cho hệ thống

      XXVGiải thuật cho chương trình

      Việc nhận yêu cầu và phục vụ yêu cầu chúng ta hoàn toàn không cần quan tâm vì RMI đã làm cho ta chuyện đó. Nhiệm vụ chính của chúng ta chỉ là viết những hàm đó như thế nào để đạt được mục đích đề ra để thỏa yêu cầu phần thiết kế.

      1Database và tổ chức

      • Codebase Port : Port của chương trình giả lập Web Server, chương trình này sẽ cung cấp bytecode của Stub và Skeleton cho chương trình Client nào cần đến Stub và Skeleton thông qua codebase. Về các thông tin cho một Service ta tổ chức thành các File database dưới dạng text, file này gồm 3 field, filed 1 là tên Service, field 2 là tên file Class, field 3 là password.

      3Thiết lập CODEBASE

      Chỉ có một điều cần phải chú ý ở đây là tên máy (địa chỉ) và Port dùng để thiết lập CODEBASE là tên của máy có Stub (Skeleton) và đồng thời trên máy đó phải tồn tại ít nhất một chương trình tương tự như ClassFileServer đang chạy như vừa trình bày ở phần trên, Port dùng để thiết lập codebase là Port mà chương trình đó ra đứng chờ và nhận yêu cầu truy cập file từ một máy tính từ xa. Đến đây, việc thiết lập codebase cùng với việc chạy chương trình giả lập Web Server, chúng ta đã có thể chạy được chương trình RMI một cách bình thường, nghĩa là việc giao tiếp giữa những phần khác nhau trên các Host khác nhau trong hệ thống của chúng ta đã có thể giao tiếp với nhau một cách dễ dàng.

      4Đọc các file Database

      Kết quả của đoạn chương trình trên là một Instance mới được tạo ra, Instance này là Object của class có bytecode chứa trong file có tên là fileName. Tóm lại, chúng ta đã giải quyết được việc đọc dữ liệu từ các File database dưới dạng Text, sau đó sử dụng dữ liệu này để tìm các file class tương ứng với dữ liệu và tạo mới các Instance của các Class này, sau đó dùng hàm Naming.bind để đăng ký chúng với RMIRegistry.

      5Hàm AddService

      Lấy bytecode ghi xuống dĩa: dùng FileOutputStream do Java cung cấp để tạo một File mới tương ứng với dữ liệu trong tham số đã truyền cho hàm AddService. Thêm thông tin quản lý vào công cụ quản lý của chương trình : dùng class Vector do Java cung cấp để làm công cụ quản lý thông tin của chương trình, do đó ta cũng sẽ dùng các hàm của Class Vector này để thực hiện thao tác thêm này.

      6Hàm DeleteService

      Lấy tham khảo đến Remote Object : dùng tên Remote Object có được từ trong tham số truyền cho hàm DeleteService và sử dụng hàm Naming.lookup() để có thể lấy được tham khảo đến Remote Object Service cần thiết. Thêm thông tin quản lý vào công cụ quản lý của chương trình : dùng class Vector do Java cung cấp để làm công cụ quản lý thông tin của chương trình, do đó ta cũng sẽ dùng các hàm của Class Vector này để thực hiện thao tác cập nhật này.

      Hình 37. Thuật toán cho hàmDeleteService
      Hình 37. Thuật toán cho hàmDeleteService

      7Hàm ReplaceService

      Nếu đã được cho phép, công việc xóa Service đã có thể bắt đầu : dùng hàm Naming.unbind(Remote Object) để xóa sự xuất hiện của tên Service trong hệ thống. Khai báo của Class này là nhằm mục đích cung cấp thông tin một cách đầy đủ nhất cho hoạt động của hàm ReplaceService.

      Hình 38. Lưu đồ thuật giải của hàm ReplaceService của Class Server.
      Hình 38. Lưu đồ thuật giải của hàm ReplaceService của Class Server.

      8Hàm GetServerInfor

      Chú ý là tên máy này bao gồm luôn cả port của RMIRegistry chạy trên máy này, vì biến này là để nhằm mục đích Agent có thể tìm kiếm Server một cách dễ dàng. Giải thuật của hàm này hoàn toàn phụ thuộc vào các công cụ quản lý mà chương trình dùng, nhưng về thực chất chỉ là thao tác lấy thông tin từ các Vector.

      XXVIIIKết luận

      XXIXYêu cầu đối với chương trình Agent

      Với yêu cầu như trên, để giải quyết bằng RMI chúng ta chỉ cần quan tâm đến việc viết các hàm cho phép gọi từ xa giải quyết từng vấn đề cho Client và hệ thống. Do đó, phần sau đây sẽ nêu ra từng hàm và việc làm tương ứng của chúng.

      XXXICác hàm của Agent Object

      Nhưng để có thể trình bày chúng ta sẽ xem xét các hàm trong các nhóm.

      1Nhóm thao tác trên Service

      • GetServiceHelp : Lấy thông tin về Service tồn tại trong hệ thống Server do Agent hiện tại đang quản lý. Kết quả trả về là một Vector chứa các chuỗi là các String, là văn bản giúp đỡ sử dụng của Service.

      2Nhóm hàm liên quan đến User

      • Get ServiceName : Lấy tên của tất cả các Service trên Server do Agent hiện tại quản lý. Kết quả trả về là một chuỗi chứa tất cả tên của các Service, các tên này cách nhau bởi dấu “:”.

      3Nhóm lệnh phục vụ người Administrator

      • getError : nếu có lỗi xảy ra Admin có thể dùng hàm này để biết đã có lỗi gì xảy ra đối với hệ thống.

      1Hàm AddService

      Chú ý là khi thêm một Service vào thì tên của nó không được có dấu “:”. Laáy bytecode trong tham số ghi xuống thư mục tạm Tính toán và lấy tên Server thích hợp Tạo mới một Object thuộc class AddServerInfor chứa các thông tin thích hợp.

      Hình 49. Giải thuật cho hàm AddService trên Agent.
      Hình 49. Giải thuật cho hàm AddService trên Agent.

      XXXIIIKết luận

      2Chức năng cho phép

      Thực chất chương trình Admin khi thực hiện một chức năng nào đó là thực hiện việc gọi hàm từ xa của Agent Remote Object. Phần phân tích một cách cụ thể cách chương trình Admin thực hiện một số chức năng quan trọng của mình sẽ được trình bày ở phần sau.

      3Hoạt động của chương trình Admin

      Agent bằng cách nào đó thực hiện công việc rồi trả kết quả về cho Admin.

      3Theâm User

      Để gọi được hàm AddUser ta chỉ cần tạo được một Object thuộc Class UserInfor để có thể gọi được hàm AddUser trên Agent.

      XXXVIIKết luận

      1Authentication

      Tham số cho hàm Naming.lookup này là một biến kiểu String, biến này có ý nghĩa là một tên của một Remote Object, ta tạm đặt tên của biến này là “Name”. Với tên máy Agent và Port là hai giá trị do nhà cung cấp dịch vụ cho biết trước đó khi User đăng ký sử dụng dịch vụ.

      2Gọi hàm Connect

      Giỏ trị trả về của hàm này sẽ là một tham khảo tới Remote Object cú Interface tờn làứ Authentication. Interface này được nhà cung cấp dịch vụ cung cấp khi User đăng ký sử dụng dũch vuù.

      XLKết luận

      XLIICách viết dịch vụ

      Vì vậy trong khi hiện thực một dịch vụ mới ta cũng cần phải hiện thực một hàm là getAttribute để trả về thuộc tính của Service để có thể được dùng vào lúc hệ thống cần xóa một dịch vụ. Hơn thế nữa, theo lý luận thiết kế hệ thống thì có thể có nhiều Admin tham gia quản lý do có nhiều Agent trong hệ thống, do đó khi phát triển dịch vụ thì mỗi dịch vụ của chúng ta cần phải cómột Password để việc xóa sửa của Admin này không ảnh hưởng đến hoạt động của nhiệm vụ quản lý của Admin khác.

      XLIIIKết luận

      Hướng dẫn sử dụng Chửụng trỡnh Admin

      • About User: Xem thông tin về User hiện tại đang kết nối với hệ thống và danh dasch các User đăn ký để được truy cập vao môi trường này. √ Service Password : Mỗi dịch vụ có một Password nhằm mục đích thống nhất sự quản lý của một người quản trị hệ thống đối với dịch vụ đó, nghĩa là người nào thêm dịch vụ thì người đó mới có thể được phép xoá hay sửa dịch vụ đó.

      1Lvtn.agent.interfaces.Authentication

      Giá trị trả về là một String, trong đó tên của các Service được gắn vào cùng một chuỗi và giữa các tên này cách nhau bởi dấu “:”. Với các Service hiện thực Interface này thì chúng bắt buộc phải có một hàm tên là execute() để hệ thống coi đó là điểm nhập của quá trình thực thi Service mới của Client gửi lệ cho hệ thoáng.