Mục lục
Phần 1:Lời Mở đầu ............................................................................................................................... 2
Phần 2: Giới thiệu về APACHE THRIPT ............................................................................................ 2
1.
RPC là gì? .................................................................................................................................. 2
2.
Luồng RPC ................................................................................................................................. 3
3.
Apache Thrift ............................................................................................................................. 4
4.
a.
Giới thiệu ................................................................................................................................ 4
b.
Thrift protocol stack .............................................................................................................. 4
c.
Protocol Layer ........................................................................................................................ 6
d.
Transport Layer ..................................................................................................................... 6
e.
Processor ................................................................................................................................ 7
Hệ thống kiểu dữ liệu của Thrift ............................................................................................... 7
1
Phần 1:Lời Mở đầu
Việc thiết kế APIs đang thay đổi từng ngày. Trong khi phần lớn các APIs hiện
nay đều thiết kế theo kiểu monolith, tức là kiểu thiết kế cung cấp tất cả các dịch vụ
thông qua một ứng dụng to, cồng kềnh, thì những kiểu kiến trúc phát triển API gần
đây đã dần chuyển hướng sang microservices. Không giống như các hệ thống
monolith, Microservices phân tán chức năng ra nhiều ứng dụng và processes, và
cung cấp chức năng thông qua nhiều servers khi cần thiết
Microservice phát triển, đồng nghĩa với việc cần thêm những thiết kế kiến trúc
đa dạng và có tính mở rộng cao hơn. Một RPC framework là Apache Thrift để biết
thêm về một trong những xu hướng thiết kế APIs mới hiện nay.
Phần 2: Giới thiệu về APACHE THRIPT
1. RPC là gì?
Trước khi đi vào tìm hiểu về Apache Thrift – một RPC Framework, thì cần
phải biết định nghĩa RPC là gì và thế nào là một RPC Framework:
Theo định nghĩa của wiki: Trong hệ thống phân phối tính tốn (Distributed
computing), một RPC – viết tắt của Remote Procedure Call là khi một chương trình
máy tính tạo nên một procedure thực thi trên một dải địa chỉ riêng (thường là máy
tính khác trong cùng một mạng) như là gọi đến một normal (local) procedure, mà
người lập trình viên khơng trực tiếp lập trình chi tiết cho giao tiếp từ xa đó – điều
mà thơng thương lập trình viên phải viết code để thực thi trên môi trường local hoặc
remote.
RPC là một giao thức request-response. Một RPC được khởi tạo khi client gửi
request message tới một remote server biết trước để thực thi một procedure với
những parameters đã được cung cấp trước. Remote server gửi một response đến
client, và chương trình tiếp tục process của nó khi server xử lý lời gọi, client bị block
(nó sẽ đợi đến khi server hoàn thành trước khi chạy tiếp luồng của nó), trừ phi client
gửi một request bất đồng bộ với server (XMLHttpRequest). Có rất nhiều cách để
implement giao thức này, dẫn đến việc có nhiều giao thức RPC đa dạng và khơng
tương thích với nhau.
2
Một điểm khác biệt quan trọng giữa RPCs và local calls là remote call có thể
xảy ra lỗi bởi các vẫn đề về network khơng lường trước được. cũng vì thế mà caller
phải xử lý được các trường hợp lỗi mà khơng biết remote procedure có được thực
thi hay khơng.
2. Luồng RPC
Hình 1: Luồng điều khiển từ xa
B1: client gọi đến client stub (là một đoạn code giúp convert parameters
truyền giữa client và server trong một RPC). Lời gọi này là một local
procedure call, với parameters được đẩy vào stack một cách bình thường.
B2: client stub đóng gói parameters vào một message và gọi một lời gọi hệ
thống (system call) để gửi đi message
B3: OS của client gửi message từ client machine đến server machine.
B4: OS của server truyền gói tin đến server stub.
B5: server stub tháo gỡ gói tin nhận được parameter.
B6: cuối cùng server stub gọi đến server procedure
3
Quá trình gửi lại kết quả như quá trình thực hiện lời gọi đến server
3. Apache Thrift
a. Giới thiệu
Apache thrift là một stack software nhẹ, độc lập với ngôn ngữ lập trình với
một cơ chế sinh code tự động có liên kết cho RPC. Thift cung cấp một lớp trừu tượng
cho việc truyền dữ liệu, serialize dữ liệu và cho việc thực thi mức ứng dụng. Thrift
được phát triển bởi Facebook và được công bố dưới một project open source của
Apache Software Foundation.
Apache Thrift là một tập hợp công cụ sinh code tự động cho phép developer
xây dựng RPC client và server bằng cách chỉ việc định nghĩa kiểu dữ liệu và service
interface trong một file định nghĩa đơn giản. Đưa file đó là đầu vào, code sẽ được
sinh tự động để xây dựng RPC client và server có thể giao tiếp một cách dễ dàng
giữa tất cả các ngôn ngữ.
Thrift định nghĩa ra Thift IDL (Interface Definition Language – ngôn ngữ định
nghĩa giao tiếp) để cung cấp các service đa nền tảng. source code của client và server
được sinh ra từ chính IDL – là ngơn ngữ để viết file định nghĩa ở trên.
Thrift hỗ trợ rất nhiều ngôn ngữ lập trình: ActionScript, C, C++, C#,
cappuccino, Cocoa, Delphi, Erlang, Go, Haskell, java, node.js, Objective-C, OCaml,
Perl, PHP, Python, Ruby và smalltalk.
Thrift hỗ trợ rất nhiều kiểu chuyển tiếp (Socket, Unix Domain Sockets,
Framed, File, Memory, …) và giao thức (binary, compact, dense, Json, …)
b. Thrift protocol stack
Thrift bao gồm một stack hoàn chỉnh cho việc tạo server và client. Sơ đồ dưới
đây miêu tả Thrift Stack:
4
Phần trên cùng của stack là code được sinh ra từ file định nghĩa Thrift
Thrift service bao gồm client và code xử lý (Processor Code) được sinh ra, nó
chính là phần màu nâu trong sơ đồ trên.
Các cấu trúc dữ liệu được gửi đi (khác với các kiểu built-in) cũng nằm trong
code được Thrift generate ra, hiển thị ở phần màu đỏ của sơ đồ cấu trúc.
Phần giao thức (protocol) và giao vận (transport) là các phần trong runtime
library của Thrift.
Vì vậy với Thrift, bạn có thể định nghĩa service, và tự do thay đổi giao thức
và giao vận mà không phải sinh code.
5
Thrift cũng bao gồm hạ tầng server (server infrastructure) để kết nối giao thức
và giao vận với nhau. có single, multithreaded khả dụng để có thể lựa chọn.
Phần giao tiếp I/O cơ bản trong stack khác nhau dựa trên sự khác nhau giữa
ngôn ngữ được sử dụng. Đối với network I/O của Java và Python, các thư viện tích
hợp (built-in libraies) được tận dụng bởi Thrift, trong khi đó với C++ thì sử dụng
custom implementation.
Thrift cho phép bạn lựa chọn một cách độc lập giữa giao thức, giao vận và
máy chủ. Thrift được phép phát triển ban đầu bởi C++, Thrift có sự đa dạng nhất khi
implement với C++.
c. Protocol Layer
Tầng giao thức cung cấp tư cách serialize và deserialize dữ liệu. Thrift hỗ trợ
cả giao thức văn bản (text) và nhị phân (binary). Giao thức nhị phân vượt trội hơn
so với giao thức văn bản, nhưng cũng có những lúc giao thức văn bản có thể hữu ích
hơn. Một vài giao thức mà Thrift hỗ trợ:
TBinaryProtocol – Một dạng encoding các giá trị số dưới dạng nhị phân
mà khơng phải là convert nó thành dạng văn bản.
TCompactProtocol – rất hiệu quả, mã hóa dữ liệu dày đặc.
TDenseProtocol – Giống với loại trên nhưng tháo bỏ phần thông tin meta
khỏi phần dữ liệu được truyền đi, và thêm nó vào lại khi nhận lại dữ liệu
trả về. TDenseProtocol vẫn đang trong quá trình thử nghiệm và chưa khả
dụng khi implement với ngôn ngữ java
TJSONProtocol - Một giao thức write-only (chỉ ghi) sử dụng JSON. Thích
hợp cho các ngôn ngữ scripting parsing dữ liệu.
TDebugProtocol – giao thức sử dụng văn bản hỗ trợ debugging
d. Transport Layer
Trong khi tầng giao thức mơ tả “cái gì” được truyền đi, thì tầng giao vận lại
mơ tả dữ liệu được truyền đi “như thế nào”, có nghĩa là tầng giao vận chịu trách
nhiệm đọc và ghi. Dưới đây là một số kiểu giao vận hỗ trợ bởi Thrift:
TSocket – sử dụng bloking socket I/O để vận chuyển.
6
TFramedTransport – truyền dữ liệu theo từng khung (frame), mỗi khung
được đi trước bởi một độ dài. Kiểu vận chuyển này đòi hỏi kiểu server nonblocking.
TFileTransport – kiểu vận chuyển này ghi dữ liệu ra file. Kiểu dữ liệu này
chưa được implement với java.
e. Processor
Bộ xử lý nhận vào thao số là giao thứu đầu vào và đầu ra. Đọc dữ liệu từ đầu
vào, xử lý dữ liệu thơng qua Handler định nghĩa bởi người dung, sau đó khi dữ liệu
trả về vào đầu ra.
Một server sẽ lắng nghe các kết nối thông qua một cổng và sẽ truyền dữ liệu nó nhận
được đến bộ xử lý (Processor). Các loại server được hỗ trợ:
TSimpleServer – SingleThreaded server sử dụng std blocking I/O. Sử dụng
với mục đích testing
TThreadPoolServer- MultiThreaded server sử dụng std blocking I/O.
TNonblockingServer-MultiThreaded server sử dụng non-blocking I/O.
Tầng giao vận phải sử dụng TMemoryTransport với kiểu server này.
4. Hệ thống kiểu dữ liệu của Thrift
Kiểu dữ liệu của Thrift bao gồm những kiểu cơ bản như Bool, byte, double,
string và integer nhưng cũng có các kiểu đặc biệt như binary và Thrift cũng hỗ trợ
struct (giống như các classes nhưng khơng có tính kế thừa) và có cả kiểu containers
như list, set, map tương ứng với các interface thường có sẵn trong các ngơn ngữ lập
trình.
Hệ thống kiểu dữ liệu của Thrift tập trung chủ yếu vào các kiểu phổ biến trong
tất cả các ngơn ngữ lập trình và bỏ qua các kiểu dữ liệu đặc thù với một số loại ngơn
ngữ.
Ngồi ra Thrift cịn cho phép định nghĩa kiểu dữ liệu mới thơng qua Thrift
interface description language (IDL).
Các kiểu dữ liệu cơ bản
- Bool: giá trị logic (true, false)
7
-
Byte: một giá trị nguyên 8-bit có dấu.
I16, i32, i64: tương ứng là một giá trị nguyên 16-bit, 32-bit, 64-bit.
Double: một giá trị số phẩy động 64-bit.
String: Giá trị chuỗi văn bản sử dụng UTF-8 encoding.
Kiểu dữ liệu đặc biệt
- Binary: một chuỗi các byte khơng được mã hóa.
- Structs: một struct có một tập các trường có kiểu cơ bản, mỗi trường được
định danh bằng một tên duy nhât. Struct rất giống với kiểu struct trong ngôn
ngữ C.
Containers
- List (Interface này tương thích với C++ STL vector, java ArrayList, …)
- Set (Interface này tương thích với STL set, Java HashSet etc, …)
o PHP khơng hỗ trợ set- vì thế nó được coi như tương đương với một list
- Map (tương ứng với STL map, Java HashMap, …)
Tất cả những thiết lập trên đều là mặc định nhưng có thể tùy chỉnh tương ứng với
từng kiểu khác nhau của bất kỳ ngơn ngũ nào. Vì lý do này mà những đoạn code chỉ
thị đã được thêm vào.
Exception
Nó được kế thừa từ các base class exception tương ứng với từng loại ngơn ngữ lập
trình.
Service
8
Một service bao gồm một tập các hàm, mỗi hàm có một tập các tham số và một kiểu
trả về. việc định nghĩa một service cơ bản là việc định nghĩa một interface hoặc một
virtual abstract class.
9