Upgrade to Pro — share decks privately, control downloads, hide ads and more …

High Performance RPC with Finagle

Sam Bessalah
November 10, 2015

High Performance RPC with Finagle

Devoxx Belgium Antwerp 2015

Sam Bessalah

November 10, 2015
Tweet

More Decks by Sam Bessalah

Other Decks in Programming

Transcript

  1. @samklr
    #devoxx #finagle #scala
    High Performance RPC with
    Sam BESSALAH
    @samklr

    View Slide

  2. @samklr
    #devoxx #finagle #scala
    RPC Redux
    • Control of clients and servers
    • Need for predictable performance
    • Communication between different languages
    • Isolated computations
    • Fan out, Fan In distributed systems
    • ...

    View Slide

  3. @samklr
    #devoxx #finagle #scala

    View Slide

  4. @samklr
    #devoxx #finagle #scala
    Open sourced by Twitter in 2011 to solve this :

    View Slide

  5. @samklr
    #devoxx #finagle #scala

    View Slide

  6. @samklr
    #devoxx #finagle #scala
    Asynchronous
    Non-Blocking
    Protocol Agnostic
    Full Stack RPC
    built on top of

    View Slide

  7. @samklr
    #devoxx #finagle #scala
    http://monkey.org/~marius/funsrv.pdf

    View Slide

  8. @samklr
    #devoxx #finagle #scala
    Load Balancing : Heap Balancer
    Client Backoff Strategy
    BackPressure
    Failure Detection
    Failover/Retry
    Connection Pooling
    Tracing (via ZipKin)
    ...
    Production ready distributed toolbox

    View Slide

  9. @samklr
    #devoxx #finagle #scala
    • Box
    • Foursquare
    • Nest
    • Uber
    • Pinterest
    • NY Times
    • Rdio
    • PagerDuty
    • Soundcloud
    • Strava
    • StumbleUpon
    • ...
    Known Users ...

    View Slide

  10. @samklr
    #devoxx #finagle #scala
    @nivdul

    View Slide

  11. @samklr
    #devoxx #finagle #scala
    Networking Layer
    @nivdul

    View Slide

  12. @samklr
    #devoxx #finagle #scala
    Building Blocks
    Futures
    Services
    Filters

    View Slide

  13. @samklr
    #devoxx #finagle #scala
    Futures
    • Concurrency primitive in Finagle
    • Different from scala.concurrent.Future and java.util.concurrent.
    Future
    • Less context-switching, easier cancelability
    • From com.twitter.util.Future
    • Composables
    • Error and Exception Handling

    View Slide

  14. @samklr
    #devoxx #finagle #scala
    Futures Combinators
    • Can be composed with map, flatMap, handle and rescue
    • Exception handling via:

    View Slide

  15. @samklr
    #devoxx #finagle #scala
    Service

    View Slide

  16. @samklr
    #devoxx #finagle #scala
    Services
    class DummyService extends Service[httpx.Request, httpx.Response]
    {
    def apply(req: httpx.Request): Future[httpx.Response] = {
    val response = req.response
    response.setStatusCode(200)
    response.setContentTypeJson()
    response.write(requestHandler(req.getContentString()))
    Future.value(response)
    }

    View Slide

  17. @samklr
    #devoxx #finagle #scala
    Filters
    class Filter[-ReqIn, +RepOut, +ReqOut, -RepIn] extends
    ((ReqIn, Service[ReqOut, RepIn]) => Future[RepOut])
    or
    type Filter[Req, Rep] =
    (Req, Service[Req, Rep]) => Future[Rep]

    View Slide

  18. @samklr
    #devoxx #finagle #scala
    Filters

    Wrap services to modify inputs or outputs (or both) …

    Protocol and Network agnostic

    Composable

    View Slide

  19. @samklr
    #devoxx #finagle #scala
    Filters
    val myTimeoutFilter =
    new TimeoutFilter[String,Int](1.second,DefaultTimer.twitter)

    View Slide

  20. @samklr
    #devoxx #finagle #scala
    Filters
    val myTimeoutFilter =
    new TimeoutFilter[String, Int](1.second,DefaultTimer.twitter)
    val myService = new DummyService

    View Slide

  21. @samklr
    #devoxx #finagle #scala
    Filters
    val myTimeoutFilter =
    new TimeoutFilter[String, Int](1.second,DefaultTimer.twitter)
    val myService = new DummyService
    val server = myTimeOutFilter andThen myService

    View Slide

  22. @samklr
    #devoxx #finagle #scala
    Filters
    val myTimeoutFilter =
    new TimeoutFilter[String,Int](
    1.second, DefaultTimer.twitter)
    val myService = new DummyService
    val service = myService andThen myTimeOutFilter
    val server = Httpx.serve( “:8080”, service)
    Await.ready(server)

    View Slide

  23. @samklr
    #devoxx #finagle #scala
    Filters
    Can be used for:
    • Retries
    • Logging
    • Serialization
    • Authentication
    • Retries
    • Timeouts
    • ...

    View Slide

  24. @samklr
    #devoxx #finagle #scala
    Clients

    View Slide

  25. @samklr
    #devoxx #finagle #scala
    Clients
    Finagle client are just full stack services
    val myClient: Service[Request, Response] =
    Httpx.newService("rtb-bidder.com:8081")
    val bidder = Httpx.serve(":8080", myClient)

    View Slide

  26. @samklr
    #devoxx #finagle #scala
    Finagle in a nutshell

    View Slide

  27. @samklr
    #devoxx #finagle #scala
    Protocols
    • Thrift
    • Memcache
    • Redis
    • HTTP
    • SMTP
    • MySQL
    • Zookeeper
    • Mux
    Protocol.newService( … )

    View Slide

  28. @samklr
    #devoxx #finagle #scala
    Finagle Mux
    • RPC Protocol Multiplexing
    • One network connection per client-server session
    • Maximization of available bandwidth without incurring the cost of
    opening additional sockets
    • Elimination of head-of-line blocking
    • Explicit queue management
    • Pure session layer (OSI )

    View Slide

  29. @samklr
    #devoxx #finagle #scala
    Finagle Serial

    View Slide

  30. @samklr
    #devoxx #finagle #scala
    Finagle Serial
    Use binary format. Scodec, Protobuf, Thrift, Avro, etc.

    View Slide

  31. @samklr
    #devoxx #finagle #scala
    Service discovery

    Finagle ServerSets via ”Names”

    Uses Zookeeper as Name server
    val client = Http.newService(
    “zk!myzkhost.home.com:2181!/my/zk/path” )

    View Slide

  32. @samklr
    #devoxx #finagle #scala
    Twitter-Server
    • Template for servers at Twitter built on top of Finagle
    • Flags for configuration
    • Logging and Metrics
    • Admin HTTP UI
    • Lifecycle management endpoints, handy for Docker and/or Mesos
    • Tracing via ZipKin

    View Slide

  33. @samklr
    #devoxx #finagle #scala
    Finagle Java
    Service service = new Service() {
    public Future apply(Request request) {
    Response response = Response.apply();
    response.setContent(ChannelBuffers.wrappedBuffer("yo".getBytes()));
    Future future = Future.value(response);
    return future;
    }};
    ServerBuilder.safeBuild(
    service,
    ServerBuilder.get()
    .codec(Http.get())
    .bindTo(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0))
    .name("HttpServer"));
    }

    View Slide

  34. @samklr
    #devoxx #finagle #scala
    Finatra
    • Library to easily build API Services on top of the Twitter Stack (Finagle,
    Twitter-Server, Twitter-util, etc.)
    • Supports Http and Thrift services
    • Brings Sinatra like Style to Finagle for Rest Services

    View Slide

  35. @samklr
    #devoxx #finagle #scala
    Finatra
    class HelloWorldController extends Controller {
    get("/hi") { request: Request =>
    "Hello " + request.params.getOrElse("name", "unnamed")
    }
    post("/hi") { hiRequest: HiRequest =>
    "Hello " + hiRequest.name + " with id " + hiRequest.id
    }
    }

    View Slide

  36. @samklr
    #devoxx #finagle #scala
    Finatra
    object HelloWorldServerMain extends HelloWorldServer
    class HelloWorldServer extends HttpServer {
    override def modules = Seq(Slf4jBridgeModule)
    override def configureHttp(router: HttpRouter) {
    router
    .filter[LoggingMDCFilter[Request, Response]]
    .filter[TraceIdMDCFilter[Request, Response]]
    .filter[CommonFilters]
    .add[HelloWorldController]
    }
    }

    View Slide

  37. @samklr
    #devoxx #finagle #scala
    ● Thin layer of purely functional basic blocks, to build
    composable REST APIs.
    ● Built on top of Finagle
    ● Functional wrapper of Finagle-http
    ● Performance close to Bare Metal Finagle
    http://github.com/finagle/finch

    View Slide

  38. @samklr
    #devoxx #finagle #scala
    Zipkin
    • Zipkin is a distributed tracing system that helps us gather timing data
    for all the disparate services at Twitter. It manages both the collection
    and lookup of this data through a Collector and a Query service.
    • Implementation of Google’s Dapper paper
    • Moved to OpenZipkin

    View Slide

  39. @samklr
    #devoxx #finagle #scala
    ZipKin - Open ZipKin

    View Slide

  40. @samklr
    #devoxx #finagle #scala
    Finagle : Cons
    • Stuck to old versions of Netty. Currently Netty 3 and now moving to 4
    • API Changes since 6.x. No more Netty API Leaking through Finagle’s
    • Mismatch between scala.concurrent.Future and com.twitter.util.Future
    • Slow to update
    • Documentation not exhaustive. Thanks for gitter.im and the Mailing List
    • Can be painful to plug to other Metrics and Monitoring systems. Hopefully
    it’s changing

    View Slide

  41. @samklr
    #devoxx #finagle #scala
    Quick Demo

    View Slide

  42. @samklr
    #devoxx #finagle #scala
    Conclusion

    View Slide