Thrift - framework usług siecowych
8 October 2009
Comments
thrift to framework skalowalnych usług sieciowych stworzony przez programistów Facebooka. Za jego pomocą można generować szkielet API RPC klient-serwer dla różnych języków: C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk i OCaml. Charakterystyka frameworka w punktach:
- Serializacja danych pomiędzy różnymi językami z małym narzutem spadku wydajności w porównaniu np. do SOAP
- Prosta i czysta biblioteka, bez konfiguracji itd.
- Brak zależności, brak mieszanki różnych licencji
- Wydany na otwartej licencji i przyjęty do programu Apache Incubator
- Oprócz Facebooka używane przez m.in. reCaptha, czy last.fm
- Brak dobrej i pełnej dokumentacji
- Przeznaczony do tworzenia bardzo dużych, rozbudowanych usług sieciowych (jak np. w Facebooku), choć jego zaletą jest możliwość wystawienia API operującego złożonymi strykturami dla wielu języków programistycznych (gdzie np. REST HTTP byłby mniej poręczny).
Instalacja
- Niektóre dystrybucje mogą zawierać gotowy pakiet z biblioteką - wtedy wystarczy go zainstalować i gotowe
- Jeżeli nie dysponujemy gotowym pakietem to pobieramy źródła i kompilujemy/instalujemy standardowo:
./configure --prefix=/usr make make install
Wykorzystanie
Wykorzystanie Thrifta polega na stworzeniu pliku .thrift zawierającego definicję usług i wykorzystywanych w nich struktur. Dla przykładu wykorzystam przykład opublikowany przez Abhi Yerra na jego blogu. Plik thrift wygląda tak:namespace rb MyAuth
namespace py myauth
struct User {
1: string username,
2: string password
}
enum LoginStatus {
SUCCESS,
FAIL
}
service Authentication {
string say_hello(),
LoginStatus login(1:User cred)
}
Mając gotowy plik możemy wygenerować szkielet dla Pythona i Ruby za pomocą:
thrift --gen rb --gen py plik.thrift
Po ich wygenerowaniu można je wykorzystać tworząc serwer w Ruby:
require 'thrift'
$:.push('gen-rb')
require 'Authentication'
require 'myauth_constants'
class AuthenticationHandler
def say_hello
puts "thrift client connected"
"hello thrift client"
end
def login cred
if cred.username == 'hello' && cred.password == 'world'
puts "logged in"
return MyAuth::LoginStatus::SUCCESS
end
puts "great pie of fail"
MyAuth::LoginStatus::FAIL
end
end
handler = AuthenticationHandler.new
processor = MyAuth::Authentication::Processor.new(handler)
transport = Thrift::ServerSocket.new(9090)
transportFactory = Thrift::BufferedTransportFactory.new()
server = Thrift::SimpleServer.new(processor, transport, transportFactory)
puts "Starting the server..."
server.serve()
puts "done."
import sys
sys.path.append('gen-py')
from myauth import Authentication
from myauth.constants import *
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
auth = Authentication.Client(protocol)
transport.open()
print auth.say_hello()
user = User()
user.username = 'hello'
user.password = 'world'
print "Login: %s" % auth.login(user)
user2 = User()
user2.username = 'failed'
user2.password = 'world'
print "Login: %s" % auth.login(user2)
RkBlog
Comment article