Ī¼WURFL Case Study
This qualĀityĀ of beĀing able to store strain enĀergy and deĀļ¬ect elasĀtiĀcally unĀder a loadĀ withĀout breakĀing isĀ calledĀ āreĀsilienceā, and it is aĀ veryvaluĀableĀ charĀacĀterĀisĀtic in a strucĀture. ReĀsilience may be deĀļ¬ned asĀ āthe amountĀ of strain enĀergywhichĀ can be stored in a strucĀtureĀ withĀoutĀ causĀing perĀmaĀnent damĀage to itā.
ā GorĀdon, J.e.āStrucĀtures.ā
Ā
Results of asyncronousĀ operations are rapresented as composable futures, expressing the dependencies between operations
Systems boundaries are represented by asynchronous functions called services. Symmetric and uniform APIĀ represents both clients and servers
Application-agnostic concerns (e.g. timeouts, retries, authentication) are encapsulated by filters which compose to build services from multiple independent modules
Finagle is an extensible RPC system for the JVM, used to construct high-concurrency servers. Finagle implements uniform client and server APIs for several protocols, and is designed for high performance and concurrency. Most of Finagleās code is protocol agnostic, simplifying the implementation of new protocols.
Ā
val client = Http.newService("uwurfl.dev.williamhill.plc:10000")
or..
val client = Http.newService("uwurfl1.dev.wh.plc:10000,uwurfl2.dev.wh.plc:10000")
Await.ready(Httpx.serveAndAnnounce(":*", "zk!zk.dev.wh.plc:2181!/zktest!0", foo))
val client = Httpx.newService("zk2!localhost:2181!/zktest")
val req = RequestBuilder().url("http://foo").buildGet
(and they are always the same)
register any finagle client/server with zipkin
val zipkinTracer = ZipkinTracer.mk("zipkin.dev.wh.plc", port = 9410, sampleRate = 1f)
Distributed tracing application based on the Google Dapper paper
cs - client start
sr - server receive
ss - server send
cr - client receive
http://research.google.com/pubs/pub36356.html
http://www.slideshare.net/johanoskarsson/zipkin-strangeloop
https://blog.twitter.com/2013/observability-at-twitter
https://blog.twitter.com/2013/new-tweets-per-second-record-and-how
TwitterServer defines a template from which servers at Twitter are built. It provides common application components such as an administrative HTTP server, tracing, stats, etc. These features are wired in correctly for use in production at Twitter.
Ā
Fast, testable, Scala HTTP services
Ā
class Example extends Controller {
get("/") { request: Request =>
"hi"
}
}
http://foo.com/users?max=10&start_date=2014-05-30TZ&verbose=true
case class UsersRequest(
@Max(100) @QueryParam max: Int,
@PastDate @QueryParam startDate: Option[DateTime],
@QueryParam verbose: Boolean = false)
class MyController @Inject()(dao: GroupsDAO, service: FooService) extends Controller
class WurflWarmupHandler @Inject()(httpWarmup: HttpWarmup) extends Handler {
override def handle() = {
httpWarmup.send(
get("/v1/json"),
responseCallback = expectOkResponse(_)
)
}
}
class MyService @Inject()(
stats: StatsReceiver)
object MyModule1 extends TwitterModule {
val key = flag("key", "defaultkey", "The key to use.")
@Singleton
@Provides
def providesThirdPartyFoo: ThirdPartyFoo = {
new ThirdPartyFoo(key())
}
}
@Mustache("foo")
case class FooView(
name: String)
get("/foo") { request: Request =>
FooView("abc")
}
get("/foo") { request: Request =>
response.notFound(
FooView("abc"))
}
class Server extends HttpServer {
override configureHttp(router: HttpRouter) {
router.
filter[CommonFilters].
filter[LoggingMDCFilter].
filter[FinagleRequestScopeFilter].
filter[UserFilter].
add[MyController1].
add[MyController2]
}
}
class MyClass extends Logging {
def foo() = {
info("Calculating...")
"bar"
}
}
import com.google.inject.Stage
import com.twitter.finatra.http.test.EmbeddedHttpServer
import com.twitter.inject.server.FeatureTest
class MyServiceStartupTests extends FeatureTest {
val server = new EmbeddedHttpServer(
stage = Stage.PRODUCTION,
twitterServer = new SampleApiServer,
extraArgs = Seq(
"-com.twitter.server.resolverMap=myservice=nil!"))
"SampleApiServer" should {
"startup" in {
server.assertHealthy()
}
}
}
0:0:0:0:0:0:0:1 - - [16/Oct/2015:00:59:45 +0000] "GET /v1/json HTTP/1.1" 200 202 5 "curl/7.43.0" 3dad52fbec16da6a
0:0:0:0:0:0:0:1 - - [16/Oct/2015:00:59:46 +0000] "GET /v1/json HTTP/1.1" 200 202 1 "curl/7.43.0" 520d2b910eef9eea
2015-10-16 02:59:26,604 INFO HttpWarmup Warmup Request("GET /v1/json", from 0.0.0.0/0.0.0.0:0) complete with Status(200)
2015-10-16 02:59:27,138 INFO DefaultTracer$ Tracer: com.twitter.finagle.zipkin.thrift.SamplingTracer
2015-10-16 02:59:27,145 INFO WurflServerMain$ http server started on port: 8888
2015-10-16 02:59:27,146 INFO WurflServerMain$ Enabling health endpoint on port 9990
2015-10-16 02:59:27,146 INFO WurflServerMain$ App started.
2015-10-16 02:59:27,147 INFO WurflServerMain$ Startup complete, server ready.
2015-10-16 02:59:45,185 INFO 3dad52fbec16da6a WurflController Entering /v1/json with curl/7.43.0
2015-10-16 02:59:45,186 DEBUG 3dad52fbec16da6a WurflServiceImpl Looking up capabilities.
2015-10-16 02:59:45,187 INFO 3dad52fbec16da6a ScientiaWurflEngine capabilities=[generic_curl_based_crawler, match=conclusive]
2015-10-16 02:59:45,187 INFO 3dad52fbec16da6a WurflController Capabilities found DeviceCapabilities(Map(device_os -> , is_wireless_device -> false, physical_screen_height -> 400, is_mobile -> false, is_tablet -> false, device_os_version -> , physical_screen_width -> 400))
2015-10-16 02:59:46,024 INFO 520d2b910eef9eea WurflController Entering /v1/json with curl/7.43.0
2015-10-16 02:59:46,024 DEBUG 520d2b910eef9eea WurflServiceImpl Looking up capabilities.
2015-10-16 02:59:46,025 INFO 520d2b910eef9eea ScientiaWurflEngine capabilities=[generic_curl_based_crawler, match=cached]
2015-10-16 02:59:46,025 INFO 520d2b910eef9eea WurflController Capabilities found DeviceCapabilities(Map(device_os -> , is_wireless_device -> false, physical_screen_height -> 400, is_mobile -> false, is_tablet -> false, device_os_version -> , physical_screen_width -> 400))
2015-10-16 02:59:46,633 INFO aa0cbfd36849d955 WurflController Entering /v1/json with curl/7.43.0
2015-10-16 02:59:46,633 DEBUG aa0cbfd36849d955 WurflServiceImpl Looking up capabilities.
2015-10-16 02:59:46,633 INFO aa0cbfd36849d955 ScientiaWurflEngine capabilities=[generic_curl_based_crawler, match=cached]
2015-10-16 02:59:46,634 INFO aa0cbfd36849d955 WurflController Capabilities found DeviceCapabilities(Map(device_os -> , is_wireless_device -> false, physical_screen_height -> 400, is_mobile -> false, is_tablet -> false, device_os_version -> , ph
UNIFICATION OF LOGS
Bridged the Twitter Metrics to Dropwizard metrics and then exported to JMX in order to integrate with Wily
https://github.com/rlazoti/finagle-metrics
https://dropwizard.github.io/
Exported Dropwizard metrics to Graphite and then Graphana (free)
Ī¼WURFL
curl -H "user-agent: Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) Mobile/1A543a Safari/419.3" localhost:8888/v1/json
{
"timestamp" : 1445003791106,
"capabilities" : {
"is_mobile" : true,
"device_os" : "iOS",
"device_os_version" : 1,
"is_tablet" : false,
"is_wireless_device" : true,
"physical_screen_height" : 74,
"physical_screen_width" : 50
}
}