SOA with Thrift and Finagle

Post on 15-Jan-2015

7,698 views 5 download

Tags:

description

 

transcript

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?