Apache Thrift: giới thiệu và cài đặt

Chào mừng các bạn đã quay trở lại với thachleblog. Quay lại chủ đề software framework hôm nay, mình sẽ giới thiệu về Apache Thift – một framework được sử dụng khá rộng rãi trong các hệ thống backend. Theo mình nghĩ thì sẽ có nhiều bạn gặp khó khăn khi bắt đầu làm quen với Thrift, vì documents chính thức hơi khó hiểu (đối với mình, hehe). Do đó, hy vọng bài viết này của mình sẽ giúp các bạn mới làm quen với Thift tiết kiệm được thời gian trong bước đầu tìm hiểu. Tất nhiên, các bạn không làm backend thì cũng đọc cho biết ^.^. Nào, chúng ta cùng bắt đầu nhé.

Giới thiệu

Thrift là một IDL (interface definition language), tương tự như protobuf. Thrift còn cung cấp chuẩn RPC (memote proceduce call) dùng để giao tiếp cho các service thông qua network (socket). Thrift ban đầu được phát triển bởi facebook, và hiện tại là mã nguồn mở thuộc Apache project.

Kiến trúc

Giống như protobuf, Thrift sẽ cho phép chúng ta định nghĩa một service bằng ngôn ngữ Thrift (source file định dạng .thrift). Source file này được hiểu như là một interface trong Java. Sau đó, Thrift compiler sẽ build source file này thành các file class. Hiện tại Thrift hỗ trợ các ngôn ngữ bao gồm C++, Java, PHP, Python và Ruby.

Ởserver, chúng ta sẽ implement method từ file class Thrift, project client có thể “gọi” method mà server cung cấp thông qua file class Thrift.

Hình minh họa Kiến trúc Thrift

Có thể hiểu hiểu là nếu project A là server, các project B, C là client có thể gọi method a từ A. Ngoài ra, B, C cũng có thể là server cung cấp các method b, c để project D có thể gọi… Tóm lại, Thrift cung cấp chuẩn để các service có thể “giao tiếp” với nhau.

Đặc điểm

Chuẩn giao tiếp của Thrift là socket, do đó, tốc độ truyền dữ liệu sẽ nhanh hơn so với giao thức HTTP (vì không có header). Do đó, sử dụng Thrift sẽ đặc biệt hiểu quả trong các dự án microservice. Các project có thể giao tiếp với nhau thông qua giao thức do  Thrift cung cấp.

Thrift compiler

Chúng ta sử dụng Thrift compiler để build .thrift file thành các class file tương ứng. Bài viết hôm nay mình sẽ hướng dẫn cách cài đặt Thrift compiler trên ubuntu.

  • Đầu tiên, chúng ta cần cài đặt ant để có thể build Thrift
    sudo apt-get install ant
  • Tiếp theo, chúng ta cần cài đặt libs cần thiết để build Thrift
    sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libboost-filesystem-dev libboost-thread-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev
    
  • Sau đó, chúng ta có thể tải Thrift compiler từ trang chủ, giải nén và chạy lệnh config để kiểm tra:
    ./configure

Kết quả: (các dòng cuối sau khi chạy command)

thrift 0.9.3

Building C++ Library ......... : yes
Building C (GLib) Library .... : no
Building Java Library ........ : yes
Building C# Library .......... : no
Building Python Library ...... : yes
Building Ruby Library ........ : no
Building Haskell Library ..... : no
Building Perl Library ........ : no
Building PHP Library ......... : no
Building Erlang Library ...... : no
Building Go Library .......... : no
Building D Library ........... : no

C++ Library:
   Build TZlibTransport ...... : yes
   Build TNonblockingServer .. : yes
   Build TQTcpServer (Qt) .... : no

Java Library:
   Using javac ............... : javac
   Using java ................ : java
   Using ant ................. : /usr/bin/ant

Python Library:
   Using Python .............. : /usr/bin/python
  • Mọi thứ đã sẵn sàng, chúng ta sẽ dùng lệnh make để build
    sudo make
  • Buid xong thì có thể chạy lệnh check để kiểm tra quá trình build có thiếu thư viện gì không, nếu [Pass] hết thì đã thành công
    sudo make check
  • Bước cuối cùng, chạy lệnh install để cài đặt
    sudo make install
  • Kiểm tra version bằng lệnh
    thrift -version
    

    Vì mình tải về phiên bản 0.9.3 nên kết quả sẽ là:

    Thrift version 0.9.3

Tới bước này thì chúc mừng các bạn, các bạn đã cài đặt Thrift compiler thành công. Giờ thì các bạn có thể sử dụng Thrift compiler để build một source file đơn giản (calculator). Sau đó có thể follow theo ví dụ để tạo 2 project Server và Client.

Project client có thể gọi các method từ project server thông qua Thrift. Mình cũng chỉ mới tới bước này. Tiếp đến cần debug và đọc document để hiểu hơn.

Kết

Hy vọng đọc tới đoạn này các bạn đã hiểu được cơ chế của Thrift và đã có thể build được source file .thrift. Mọi thắc mắc hay vấn đề gì các bạn có thể comment bên dưới, mình sẽ follow. Hẹn gặp lại các bạn ở các bài viết sau.

Tham khảo thêm:

Ước chung lớn nhất và bội số chung nhỏ nhất của mảng số nguyên

Chào mừng các bạn đã quay trở lại với thachleblog. Để “đổi gió” cho blog, thỉnh thoảng mình sẽ có những bài code challenge về các giải thuật đơn giản. Để bắt đầu cho phần giải thuật này, bài viết hôm nay mình sẽ trình bày giải thuật tìm ước chung lớn nhất và bội số chung nhỏ nhất cho mảng các số nguyên.

Yêu cầu

Tìm ước số chung lớn nhất và bội số chung nhỏ nhất của mảng các số nguyên.

– Ước chung lớn nhất: gcd (greatest common divisor) là số nguyên x lớn nhất sao cho các phần tử của mảng đều chia hết cho x

– Bội số chung nhỏ nhất: lcm (least common multiple) là số nguyên x nhỏ nhất sao cho x chia hết cho tất cả các phần tử của mảng

Input

a[] = {12, 8, 16}

Output

gcd(a): 4

lcm(a): 48

Giải thuật

– Tìm gcd

+ Đầu tiên mình sẽ tìm a[i] là phần tử nhỏ nhất mảng

+ Tiếp theo thực hiện kiểm tra các phần tử trong mảng có chia hết cho a[i] hay không, nếu chia hết thì a[i] là phần tử cần tìm

+ Nếu không, mình sẽ cho a[i] giảm dần về 1, nếu có giá trị nào mà tất cả phần tử trong mảng đều chia hết thì đó là giá trị cần tìm

– Tìm lcm

+ Đầu tiên mình sẽ tìm a[i] là phần tử lớn nhất nhất mảng

+ Tiếp theo thực hiện kiểm tra a[i] có chia hết cho các phần tử trong mảng không, nếu chia hết thì a[i] là phần tử cần tìm

+ Nếu không, mình sẽ cho a[i] tăng dần đến cấp số cộng, nếu có giá trị nào mà tất cả phần tử trong mảng đều chia hết thì đó là giá trị cần tìm

Code minh họa

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
 
public class Solution {
 
    static int max(int[] a) {
        int max = a[0];
        for (int i = 1; i < a.length; i++) {
            if (a[i] > max) {
                max = a[i];
            }
        }
        return max;
    }
 
    static int min(int[] a) {
        int min = a[0];
        for (int i = 1; i < a.length; i++) {
            if (a[i] < min) {
                min = a[i];
            }
        }
        return min;
    }
 
    static int lcm(int[] a) {
        int max = max(a);
        int result = max(a);
        int k = 1;
        boolean flag = true;
        int length = a.length;
        do {
            for (int i = 0; i < a.length; i++) {
                if (result % a[i] != 0) {
                    k++;
                    result = max * k;
                } else if (i == length - 1) {
                    flag = false;
                    break;
                }
            }
        } while (flag);
 
        return result;
    }
 
    static int gcd(int[] a) {
        int result = min(a);
        int length = a.length;
        boolean flag = true;
        do {
            for (int i = 0; i < length; i++) {
                if (a[i] % result != 0) {
                    result--;
                } else if (i == length - 1) {
                    flag = false;
                    break;
                }
            }
        } while (flag);
        return result;
    }

 

Kết

Giải thuật tìm ước chung lớn nhất và bội số chung nhỏ nhất của mảng các số nguyên là 1 phần của bài Between Two Sets trên hackerrank, nếu có hứng thú, các bạn có thể làm tiếp tục để hoàn thành. Sẽ có các test case để đánh giá giải thuật của bạn. Hiện tại thì mình đang luyện để tăng khả năng phản xạ cho giải thuật, hehe.

Đó là phần trình bày của mình về cách ước số chung lớn nhất và bội số chung nhỏ nhất của mảng các số nguyên. Các bạn có giải thuật nào hay hơn, độ phức tạp nhỏ hơn hay có góp ý cho bài của mình thì chia sẻ để chúng ta cùng trao đổi nhé.

Hẹn gặp lại các bạn ở các bài sau. Thanks.