Ob1k is a new open source RPC container. it belongs to a new breed of frameworks that tries to improve on the classic J2EE 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.
4. Before OB1K...
● Hard to troubleshoot performance issues
● Hard to fine tune JVMs
● Shared configuration
5. Before OB1K...
● Deployments means start / stop for several
modules
● Sub optimal for CD environment...
6. Before OB1K...
● The container (Tomcat) was installed by
Chef, and had a different life cycle then the
web-modules
● Container upgrades were a nightmare
33. Jetty Server
public 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");
}}
34. 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();
}
35. OB1K Service
public 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);
}}
36. OB1K client
new ClientBuilder<>(IOb1kService.class).
setProtocol(ContentType.JSON).
setRequestTimeout(requestTimeout).
setRetries(retries).
addEndpoint("http://somehost:8080/Ob1kApp/Ob1kService").
build();
39. 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)
40. Why Streams ?
● Time to serve is limited, better to serve results as
they come
● A stream of results is, well… a stream
● Request/response model is not a good fit for all
scenarios, thing twitter streaming API
● Streams can be combined in all sorts of wonderful
ways
● Implementation uses RxJava
● Ask netflix :)
41. 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