36
Yotam Oron (@YotamOron2) Asy Ronen (A.K.A Async) Eran Harel (@eran_ha)

OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Embed Size (px)

DESCRIPTION

OB1K is a new RPC container. it belongs to a new breed of frameworks that tries to improve on the classic JEE model by embedding the server and reducing redundant bloatware. OB1K supports two modes of operations: sync and async, the async mode aims for maximum performance by adopting reactive principals like using non-blocking code and functional composition using futures. Ob1k also aims to be ops/devops friendly by being self contained and easily configured.

Citation preview

Page 1: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

⇨ Yotam Oron (@YotamOron2)⇨ Asy Ronen (A.K.A Async)⇨ Eran Harel (@eran_ha)

Page 2: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

What is OB1K?

Page 3: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Asynchronous IO based on Netty

Page 4: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Synchronous Modules based on Jetty 9

Page 5: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Drop-in replacement for Tomcat apps

Page 6: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Kick A$$ Performance :)

Page 7: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain
Page 8: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Self Contained

Page 9: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Isolated Services

● Own JVM● Own JVM settings● Own configuration● Own port● Own logs● Own log configuration

Page 10: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Full control over your module

● JVM options● Configuration properties● Logging● Ports● Compression● Threads● Etc

Page 11: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Seamless RPC

● Strongly Typed RPC Client

Page 12: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Seamless RPC

● No need to configure anything○ Except for more advanced cases…

Page 13: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Seamless RPC

● RPC complexity is transparent to the client

Page 14: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Seamless RPC

● Server implementation only worries about the business logic

Page 15: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Seamless RPC

● Configurable client behavior (e.g. retries)

Page 16: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Seamless RPC

● Built-In serialization support○ MsgPack○ JSON○ Compression

Page 17: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Free Standard API entry points

● /selftest● /version● /help (/)● /properties● /ping● /presence● /jmx

Page 18: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Free Service Monitoring

Page 19: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Free ZooKeeper Registration

Page 20: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Easier upgrades, easier deployment

Page 21: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Same execution path for Dev / Prod / JUnit

Page 22: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Maven Archetype Scaffolding$ mvn archetype:generate -DarchetypeGroupId=com.outbrain -DarchetypeArtifactId=outbrain-ob1k-archetype -DarchetypeVersion=1.0.13 -DinteractiveMode=false -Dversion=trunk -DgroupId=com.outbrain -Dpackage=com.outbrain.YOUR_PACKAGE_NAME -DartifactId=YOUR_SERVICE_NAME

Page 23: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

A set of asynchronous modules

● Async memcached client● Async RPC client● Async HTTP client● Async DB query execution● Async Event Stream support● Composable Futures infrastructure

Page 24: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain
Page 25: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

The main class

Page 26: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Jetty Serverpublic class GruffaloServer { private static final Logger logger = LoggerFactory.getLogger(GruffaloServer.class);

public static void main(String[] args) { new GruffaloServer().build().start(); logger.info("******** Gruffalo started ********"); }

public Server build() { return new JettyServerBuilder().useConfigurationPorts().setContextPath("/Gruffalo"); }}

Page 27: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Netty Server public static Server buildServer() { final String contextPath = "/Ob1kTemplate";

Context ctx = new SpringContextBuilder(contextPath). addInitParam("self-tests", "properties,zookeeper,url,valid-context"). setMainContext("main", "classpath:applicationContext-Ob1kTemplate-all.xml"). addSubContext("ops", "classpath:WEB-INF/spring/ops-services.xml"). addSubContext("service", "classpath:WEB-INF/spring/Ob1kTemplate-service.xml"). build();

ServerBuilder serverBuilder = new ServerBuilder(). setContextPath(contextPath). setContext(ctx). addStaticPath("/html"). addStaticPath("/css"). addBaseServices("ops"). addServiceFromContext("service", Ob1kService.class, "/api"). createServiceFromContext("service", Ob1kNamedService.class, "/names"). addEndpoint("handleFirstRequest", "/first/{id}"). addEndpoint("handleSecondRequest", "/second/{name}"). addEndpoint("handleThirdRequest", "/third/{state}/{city}"). addService().useConfigurationPorts();

return serverBuilder.build(); }

Page 28: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

OB1K Servicepublic class Ob1kService implements Service { private static final Logger log = LoggerFactory.getLogger(Ob1kService.class); private final String greetingMessage;

public Ob1kService(final String greetingMessage) { this.greetingMessage = greetingMessage; }

public ComposableFuture<String> echo(final String name) { return ComposableFutures.fromValue("hello " + name + ". " + greetingMessage); }}

Page 29: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

OB1K clientnew ClientBuilder<>(IOb1kService.class). setProtocol(ContentType.JSON). setRequestTimeout(requestTimeout). setRetries(retries). addEndpoint("http://somehost:8080/Ob1kApp/Ob1kService"). build();

Page 30: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

ComposableFuturepublic interface ComposableFuture<T> extends Future<T> { <R> ComposableFuture<R> continueWith(FutureResultHandler<T, R> handler); <R> ComposableFuture<R> continueWith(ResultHandler<T, R> handler);

<R> ComposableFuture<R> continueOnSuccess(FutureSuccessHandler<T, R> handler); ComposableFuture<T> continueOnError(FutureErrorHandler<T> handler);

ComposableFuture<T> withTimeout(long duration, final TimeUnit unit); void onResult(Handler<T> handler); <R> ComposableFuture<R> transform(final Function<? super T, ? extends R> function);

State getState(); Throwable getError();}

Page 31: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

ComposableFuture ExampleComposableFuture<Response> f1 = client.httpGet("http://www.google.co.il/search?q=term1");ComposableFuture<Response> f2 = client.httpGet("http://www.google.co.il/search?q=term2");ComposableFuture<Response> f3 = client.httpGet("http://www.google.co.il/search?q=term3");

ComposableFuture<List<Response>> combined = all(f1, f2, f3);ComposableFuture<String> res = combined.continueWith((result) -> { // prepare combined result.});

schedule(() -> { return trySomething().continueOnError((error) -> { return getFallback(); });}, 30, TimeUnit.SECONDS);

Page 32: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

how does it all works ?

● All IO is non blocking and done via Netty● Basically one thread per core, all working

unless there is nothing to do● Context switch is minimized● Transport is always HTTP, payload may vary● Adjusted Executor for blocking actions(if you

must)

Page 33: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

What is the catch?

● Blocking code is (almost)forbidden in the async mode

● Writing asynchronous code has a learning curve

● Libraries have to be adapted

Page 34: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Alternatives

FinagleDrop WizardVert.xPlay FrameworkRESTEasy Etc

Page 35: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

Future Features

● Client Side Load Balancing● Client Side Discovery (ZK based)● Aggregation● Scatter-Gather● Throttling● Session Tracing (a-la Zipkin)

Page 36: OB1K - New, Better, Faster, Devops Friendly Java container by Outbrain

* We’r

e rec

ruitin

g ;)