Finagle : Controlling the Future Of RPC systems


logo

In this blog we’ll use Finagle to build a very simple HTTP server that is also an HTTP client — an HTTP proxy.

So Let’s Begin With Some Introduction to the Finagle.

Finagle is an extensible Remote Procedure Call (RPC system) for the JVM, used to construct high-concurrency servers.

Twitter Finagle is a great framework to write distributed applications in Scala or Java. It is written in Scala, but provides both Scala and Java idiomatic APIs.
It implements uniform client and server APIs for several protocols, and is designed for high performance and concurrency.

 

Finagle uses a clean, simple, and safe concurrent programming model, based on Futures. This leads to safe and modular programs that are also simple to reason about.

Finagle provides a robust implementation of:

  • connection pools, with throttling to avoid TCP connection churn;
  • failure detectors, to identify slow or crashed hosts;
  • failover strategies, to direct traffic away from unhealthy hosts;
  • load-balancers, including “least-connections” and other strategies; and
  • back-pressure techniques, to defend servers against abusive clients and dogpiling.

Finagle At Twitter

Today, Finagle is deployed in production at Twitter in several front- and back-end serving systems, including our URL crawler and HTTP Proxy.

 

finagle

Finagle Futures

Finagle uses futures to encapsulate and compose concurrent operations such as network RPCs. Futures are directly analogous to threads — they provide independent and overlapping threads of control — and can be thought of as featherweight threads. They are cheap in construction, so the economies of traditional threads do not apply. It is no problem to maintain millions of outstanding concurrent operations when they are represented by futures.

Futures also decouple Finagle from the operating system and runtime thread schedulers. This is used in important ways; for example, Finagle uses thread biasing to reduce context switching costs.

Getting Started

Let’s Begin.

Step 1: Create a New SBT project

 

Using Intellij Idea , Create a new Sbt Project in order to Start Building The Application from Scratch.

Step 2: Adding required dependencies to build.sbt

Add the Following to Your build.sbt :

libraryDependencies += "com.twitter" %% "finagle-http" % "6.44.0"

Note : scala 2.10 Version no longer supported.

Step 3 : A minimal HTTP server

We’ll need to import a few things into our Server Class :

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

Service is the interface used to represent a server or a client . Http is Finagle’s HTTP client and server.

Next, we’ll define a Service to serve our HTTP requests:

val service = new Service[http.Request, http.Response] {
  def apply(req: http.Request): Future[http.Response] =
    Future.value(
      http.Response(req.version, http.Status.Ok)
    )
}

The complete server:

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

object Server extends App {
  val service = new Service[http.Request, http.Response] {
    def apply(req: http.Request): Future[http.Response] =
      Future.value(
        http.Response(req.version, http.Status.Ok)
      )
  }
  val server = Http.serve(":8080", service)
  Await.ready(server)
}

The serve method takes a bind target (which port to expose the server) and the service itself. The server is responsible for listening for incoming connections, translating the HTTP wire protocol into com.twitter.finagle.http.Request objects, and translating our com.twitter.finagle.http.Response object back into its wire format, sending replies back to the client.

 

Running The Client from the terminal  :

sbt 'run-main Server'

Checking the Connection :

curl -D - localhost:8080
HTTP/1.1 200 OK

Step 4 : Using HTTP clients

 

In our server example, we define a Service to respond to requests. Clients work the other way around: we’re given a Service to use.

Client is a Service to which we can dispatch an http.Request and in return receive a Future[http.Response] — the promise of an http.Response (or an error) some time in the future.

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

object Client extends App {
  val client: Service[http.Request, http.Response] = Http.newService("www.scala-lang.org:80")
  val request = http.Request(http.Method.Get, "/")
  request.host = "www.scala-lang.org"
  val response: Future[http.Response] = client(request)
  Await.result(response.onSuccess { rep: http.Response =>
    println("GET success: " + rep)
  })

}

Running The Client from the terminal  :

sbt 'run-main Client'

Step 5 : Integrating The Client And Server

Now we’re ready to create an HTTP proxy! Notice the symmetry above: servers provide a Service, while a client uses it.

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Request, Response}
import com.twitter.util.Await

object Proxy extends App {
  val client: Service[Request, Response] =
    Http.newService("twitter.com:80")

  val server = Http.serve(":8080", client)
  Await.ready(server)
}

Note :  Be sure to shutdown the Server example from earlier as Both use the Same port.

 

Running The Proxy from the terminal  :

$sbt 'run-main Proxy'
$curl --dump-header - --header "Host: twitter.com" localhost:8080

Result :

HTTP/1.1 301 Moved Permanently
content-length: 0
date: Thu, 15 Jun 2017 12:49:31 GMT
location: https://twitter.com/
server: tsa_k
.....

 

To Explore More About Finagle Refer  :  Finagle


KNOLDUS-advt-sticker

Advertisements
This entry was posted in Java, Scala and tagged , , , , , , . Bookmark the permalink.

One Response to Finagle : Controlling the Future Of RPC systems

  1. anmolsarna09 says:

    Reblogged this on Anmol Sarna and commented:
    Finagle : Controlling the Future Of RPC systems

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s