Slide 1

Slide 1 text

@armeria_project line/armeria Trustin Lee, Databricks Apr 2022 Introducing Armeria … or Three Principles of a Good Framework

Slide 2

Slide 2 text

@armeria_project line/armeria

Slide 3

Slide 3 text

@armeria_project line/armeria

Slide 4

Slide 4 text

@armeria_project line/armeria Start small Server server = Server.builder() .http(8080) .service("/hello/:name", (ctx, req) -> HttpResponse.of("Hello, %s!", ctx.pathParam("name"))) .build();

Slide 5

Slide 5 text

@armeria_project line/armeria Grow Server server = Server.builder() .http(8080) .service("/hello/:name", …) .decorator(LoggingService.newDecorator()) .build();

Slide 6

Slide 6 text

@armeria_project line/armeria … grow … Server server = Server.builder() .http(8080) .service("/api/v1/...", …) .service("/internal/metrics", PrometheusExpositionService.of(…)) .service("/internal/health-check", HealthCheckService.of()) .decorator(LoggingService.newDecorator()) .decorator(MetricCollectingService.newDecorator(…)) .build();

Slide 7

Slide 7 text

@armeria_project line/armeria … and grow! ● Security – Authn/z, CORS, SAML ● Rate-limiting ● Distributed tracing ● Debugging & management ●

Slide 8

Slide 8 text

@armeria_project line/armeria Principle #1: Well-paced ● Build services on top of simple core concepts – Easy to learn & easy to master ● Let users start simple and grow bit by bit – Grown code should still look simple.

Slide 9

Slide 9 text

@armeria_project line/armeria

Slide 10

Slide 10 text

@armeria_project line/armeria Server server = Server.builder() .http(8080) .service(GrpcService.builder() .addService(new GrpcHelloService()) .build()) .build(); class GrpcHelloService extends HelloServiceGrpc.HelloServiceImplBase { ... } ● Full example: https://github.com/line/armeria-examples/tree/master/grpc-service

Slide 11

Slide 11 text

@armeria_project line/armeria Thrift Server server = Server.builder() .http(8080) .service("/hello", THttpService.of(new ThriftHelloService())) .build(); class ThriftHelloService implements HelloService.AsyncIface { ... } ● Full example: https://github.com/line/armeria-examples/tree/master/thrift

Slide 12

Slide 12 text

@armeria_project line/armeria Mix & Match! Server server = Server.builder() .http(8080) .service("/hello/rest", (ctx, req) -> HttpResponse.of("Hello, world!")) .service("/hello/thrift", THttpService.of(new ThriftHelloService())) .service(GrpcService.builder() .addService(new GrpcHelloService()) .build()) .build();

Slide 13

Slide 13 text

@armeria_project line/armeria Armeria integrates with … ● Languages ● Frameworks ● Protocols ● Discovery ● Tracing ● Legacy Dropwizard Thrift DNS Eureka

Slide 14

Slide 14 text

@armeria_project line/armeria Principle #2: Unopinionated (integration) ● No side effect between integrations ● No complex mandatory dependencies ● All built on top of simple core constructs – Know how to add decorators or services? It’s likely you already know how to integrate with .

Slide 15

Slide 15 text

@armeria_project line/armeria 2-phase migration (Thrift gRPC) → 1) Run THttpService and GrpcService in a single Armeria server. 2) Remove THttpService from the Armeria server. 3) Profit! ● Much less operational complexity – No reverse proxy such as Envoy & NGINX – No 2 ports or 2 server instances

Slide 16

Slide 16 text

@armeria_project line/armeria It’s more than migration ● Multi-protocol is the new normal. – gRPC + REST + GraphQL – Load balancer health checks – WebSocket (coming soon) – Static resources ● One service, one port, one JVM – Operational complexity – Code and build complexity

Slide 17

Slide 17 text

@armeria_project line/armeria Different core, different capability ● Netty-based reactive HTTP runtime built from the ground up enables unsurpassably powerful integration. ● All kinds of endpoints in the same port with minimal overhead – gRPC, Thrift, GraphQL, REST, … ● Even Tomcat, Jetty and WebFlux ● Decorators work for all endpoints – Metrics, Tracing, Rate-limiting, … ● Even if it’s not implemented in the upstream

Slide 18

Slide 18 text

@armeria_project line/armeria Different core, different capability ● Structured logging – Programmatic access to everything about the request – Ingested by machines for analytics – ELK, Kafka, … ● Abstraction layer with both HTTP/1 and 2 in mind – Your gRPC service suddenly starts to talk HTTP/1. – Your old Tomcat, Jetty and Thrift service suddenly start to talk HTTP/2. ● HAPROXY, SOCKS, Protocol auto-detection, …

Slide 19

Slide 19 text

@armeria_project line/armeria

Slide 20

Slide 20 text

@armeria_project line/armeria Principle #3: Community-friendly ● It’s all about building a virtuous cycle a.Well-designed API that adheres to its principles b.Great developer experience c.More users and contributors w/ ideas d.Close collaboration with them e.(Repeat)

Slide 21

Slide 21 text

@armeria_project line/armeria Ingredients that fuel virtuous cycle ● Friendly yet honest atmosphere ● Less hassles to contribute ● Consistency – being true to the project goal ● Applies to every aspect of the cycle: – Questions – Feedback – Code reviews

Slide 22

Slide 22 text

@armeria_project line/armeria Our community ● 150+ contributors ● Serving production workloads in different companies

Slide 23

Slide 23 text

@armeria_project line/armeria Recap ● Well-paced – Easy to learn & easy to master ● Unopinionated integration – Powered by custom reactive HTTP runtime ● Community-friendly – Building a virtuous cycle to make an impact

Slide 24

Slide 24 text

@armeria_project line/armeria Future work You’re the contributor!

Slide 25

Slide 25 text

@armeria_project line/armeria Currently on our radar ● Web-based dashboard ● Richer route expressions ● HTTP/3 ● WebSocket / Socket.io ● Dynamic reconfiguration ● LiveReload / HotSwap ● xDS protocol support ● OpenAPI interoperability ● UNIX domain sockets ● Kotlin / Scala DSL ● GraalVM native images ● Command-line interface

Slide 26

Slide 26 text

@armeria_project line/armeria Meet us at ARMERIA.dev Star our repo if you enjoyed this talk!