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 RPC Redux • Control of clients

    and servers • Need for predictable performance • Communication between different languages • Isolated computations • Fan out, Fan In distributed systems • ...
  2. @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
  3. @samklr #devoxx #finagle #scala • Box • Foursquare • Nest

    • Uber • Pinterest • NY Times • Rdio • PagerDuty • Soundcloud • Strava • StumbleUpon • ... Known Users ...
  4. @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
  5. @samklr #devoxx #finagle #scala Futures Combinators • Can be composed

    with map, flatMap, handle and rescue • Exception handling via:
  6. @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) }
  7. @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]
  8. @samklr #devoxx #finagle #scala Filters • Wrap services to modify

    inputs or outputs (or both) … • Protocol and Network agnostic • Composable
  9. @samklr #devoxx #finagle #scala Filters val myTimeoutFilter = new TimeoutFilter[String,

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

    Int](1.second,DefaultTimer.twitter) val myService = new DummyService val server = myTimeOutFilter andThen myService
  11. @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)
  12. @samklr #devoxx #finagle #scala Filters Can be used for: •

    Retries • Logging • Serialization • Authentication • Retries • Timeouts • ...
  13. @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)
  14. @samklr #devoxx #finagle #scala Protocols • Thrift • Memcache •

    Redis • HTTP • SMTP • MySQL • Zookeeper • Mux Protocol.newService( … )
  15. @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 )
  16. @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” )
  17. @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
  18. @samklr #devoxx #finagle #scala Finagle Java Service<Request, Response> service =

    new Service<Request, Response>() { public Future<Response> apply(Request request) { Response response = Response.apply(); response.setContent(ChannelBuffers.wrappedBuffer("yo".getBytes())); Future<Response> future = Future.value(response); return future; }}; ServerBuilder.safeBuild( service, ServerBuilder.get() .codec(Http.get()) .bindTo(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) .name("HttpServer")); }
  19. @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
  20. @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 } }
  21. @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] } }
  22. @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
  23. @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
  24. @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