SERVICE ORIENTED ARCHITECTURE WITH THRIFT AND FINAGLE
Luka Zakrajšek
@bancek
First Scala meetup in Ljubljana
May 23, 2013
HII'm Luka. I work at Koofr,
Slovenian startup of the year
DISTRIBUTED SYSTEMSredundancymodularityflexibilityneeds to be simple
IT ENDS UP LIKE THIS
COMPONENTS MUST TALKSOAPXML-RPCRESTGoogle Protocol BuffersApache Thrift
EXAMPLE
APACHE THRIFTframework, for scalable cross-languageservices development
code generation engine
C++, Java, Python, PHP, Ruby, Erlang,Perl, Haskell, C#, Cocoa, JavaScript,Node.js, Smalltalk, OCaml, Delphi, ...
Developed by Facebook,opensourced in April 2007
APACHE THRIFTType systemTransport layerProtocol layerProcessorsServer
TWITTER FINAGLEextensible asynchronous (reactive)RPC system for the JVMuniform client and server APIsfor several protocolshigh performance and concurrency
written in Scalaprovides both Scala and Java idiomatic APIs
TWITTER FINAGLEAsynchronous client/server for multiple protocols:
HTTPMemcachedRedisProtobufThriftMySQLmDNS ...
THRIFT IDLping.thrift
namespace java com.example.pingtypedef string UUIDtypedef i64 DateTime
struct Message { 1: required UUID id; 2: required string body; 3: optional DateTime sent;}
service Ping {
Message ping(1:Message msg)
}
SCALA SERVER/CLIENTFinagle for server/client
Scrooge for code generation
sbt-scrooge for SBT plugin https://github.com/bancek/sbt-scrooge
SCALA SERVERimport com.twitter.util.Future
import com.example.ping._
class PingImpl extends Ping.FutureIface {
def ping(message: Message): Future[Message] = { val returnMessage = message.copy(message="pong")
Future.value(returnMessage) } }
SCALA SERVERimport java.net.InetSocketAddressimport org.apache.thrift.protocol.TBinaryProtocolimport com.twitter.finagle.thrift.ThriftServerFramedCodecimport com.twitter.finagle.builder.ServerBuilder
val port = 1234
val processor = new PingImpl()
val service = new Ping.FinagledService(processor, new TBinaryProtocol.Factory())
ServerBuilder() .bindTo(new InetSocketAddress(port)) .codec(ThriftServerFramedCodec()) .name("ping") .build(service)
SCALA CLIENTimport java.net.InetSocketAddressimport org.apache.thrift.protocol.TBinaryProtocolimport com.twitter.finagle.Serviceimport com.twitter.finagle.CodecFactoryimport com.twitter.finagle.thrift.{ThriftClientFramedCodec,ThriftClientRequest}import com.twitter.finagle.builder.ClientBuilder
import com.example.ping._
val serviceCodec = ThriftClientFramedCodec()
val service: Service[ThriftClientRequest, Array[Byte]] = ClientBuilder() .hosts(new InetSocketAddress(host, port)) .codec(serviceCodec) .build()
SCALA CLIENTval message = Message( id = "12341234-1234-1234-1234-123412341234", body = "ping", sent = 1369315198125)
val pongFuture = client.ping(message)
pongFuture.onSuccess { pong => println(pong.message)}
PYTHON CLIENTThrift code generator:
Thrift library dependency:
thrift --gen py:new_style,utf8strings ping.thrift
pip install thrift
PYTHON CLIENTfrom thrift.transport import TSocket, TTransportfrom thrift.protocol import TBinaryProtocol
from ping import Pingfrom ping.ttypes import Message
transport = TSocket.TSocket('localhost', 1234)transport = TTransport.TFramedTransport(transport)protocol = TBinaryProtocol.TBinaryProtocol(transport)transport.open()
PYTHON CLIENTclient = Ping.Client(protocol)
message = Message( id='12341234-1234-1234-1234-123412341234', body='ping', sent=1369315198125)
pong = client.ping(message)
print pong.message
QUESTIONS?
Top Related