high performance microservices with ratpack and spring boot
TRANSCRIPT
SUPPORT YOUR COMMUNITY.
ALL ROYALTIES FOR LEARNING RATPACK GO DIRECTLY TO GR8LADIES
HTTP://GR8LADIES.ORG
ROUGH AGENDA
> Brief overview> Execution model
> Registries> Registries + Spring
> Microservice example> Performance numbers
@Grab('io.ratpack:ratpack-groovy:1.4.0-rc-2')
import static ratpack.groovy.Groovy.ratpack
ratpack { handlers { get { render "Hello World!" } }}
package app;
import ratpack.server.RatpackServer
public class Main { public static void main(String args[]) throws Exception { RatpackServer.start(spec -> spec .handlers(chain -> chain .get(ctx -> ctx.render("Hello World!")) ) ); }}
Traditionally there is a temporal disconnect between calling an async function and getting its response.
public void asyncDbCall(Long productId, Consumer callback) { Product product = ... async db call + future + wait for future callback.apply(product);}
Bad things happen!final List products = new ArrayList();
Long productId = request.pathTokens.productId;db.asyncDbCall(productId, product -> products.add(product));
Long nextProductId = productId+1;db.asyncDbCall(nextProductId, product -> products.add(product));
response.send(products);
There is no guarantee as to what order async calls will be executed!
final List products = new ArrayList();
String productId = request.pathTokens.productId;db.asyncDbCall(productId, product -> products.add(product)); // call may return first, maybe not!
String nextProductId = productId+1;db.asyncDbCall(nextProductId, product -> products.add(product)); // call may return second, may not!
response.send(products); // what even is the value of `products` here!
While an execution segment is processing, its thread is able to handle other processing and requests
Can quickly prototype without any DI system public static void main(String[] args) throws Exception { RatpackServer.start(spec -> spec .registryOf(r -> r.add(new MyAsyncDbService())) // bind my service in the registry .handlers(chain -> chain .get(ctx -> { MyAsyncDbService db = ctx.get(MyAsyncDbService.class); // retrieve it later // ... }) ) ); }
Integrate with Spring Boot when you're ready!@SpringBootApplication // Spring Boot!!public class Main {
@Bean public MyAsyncDbService myAsyncDbService() { // bind it as a bean! return new MyAsyncDbService(); }
public static void main(String[] args) { // turn Spring Boot into a Ratpack registry! Registry registry = ratpack.spring.Spring.spring(Main.class);
RatpackServer.start(spec -> spec .registry(registry) .handlers(chain -> chain .get(ctx -> { MyAsyncDbService db = ctx.get(MyAsyncDbService.class); // retrieve your service! // ... }) ) ) }}
Architect your application using all the helpful aspects of Spring Boot, while using Ratpack under the hood for
high throughput, reactive, async, non-blocking processing
Unrealistic.Modern performance testing needs to be about how much
burst traffic can be sustained, without your service falling over, before you can horizontally scale it.