SlideShare a Scribd company logo
1 of 41
Download to read offline
Using Armeria to write your
RPC
koji lin
Armeria
● 非同步 RPC library
● LINE 的開放原始碼專案
○ Trustin Lee
● Java 8 
● HTTP/1・2 
● Thrift/gRPC 
● 尤其適合在 Microservices 架構
Synchronous? Asynchrnous?
● 在同步下,如果一個處理需要等待,thread 必須等
待完成才能繼續執行
● 同步處理在大量存取下不易 scale up
○ Concurrent requests 受限於 max threads 
○ CPU 花費成本在 contention & context switch 
○ 較快或優先程度較高的存取會被較慢的存取拖累
Armeria is Asynchronous
● 建立於 Netty 之上
● Max concurrent requests >>> max threads
● 較慢的存取不會阻礙到其他存取
● 程式庫內部也非同步化
○ DNS 查詢
○ Connection pool
● 0.20.x reactive stream 化
Why HTTP/2 ?
● 一個連線上可以同時來往多個 request / response
● 不需要一個存取就建一個連線
from https://www.nginx.com/blog/7-tips-for-faster-http2-performance/
Why HTTP/2 ? (cont'd)
● 解決了 HTTP/1 的許多問題
○ Binary header compression
○ 更少的連線
● 比較容易從 HTTP/1 轉換
● 可以利用各種現存的工具
○ cURL,瀏覽器,Wireshark
Netty 夠穩定嗎?
● HTTP/1
○ Twitter
○ Apple
● HTTP/2
○ gRPC
○ LINE internal use
Thrift
● 跨平台跟語言的服務開發框架
○ 透過 compiler 自動生成程式,支援 C++, Java,
Python, Ruby, Perl, C#, Go, Javascript ...等等
○ 支援各種傳輸格式/協定
● 原本是 Facebook 開發,現為 Apache Thrift 開源
● 定義好 service method 就可以快速開發 RPC
client 和 server
○ .thrift 本身就是良好的文件
● 比 text-based 格式更有效率
Thrift hello world on Armeria
● 撰寫 .thrift 定義 service method
1. namespace java idv.koji.example.service
2. service HelloService {
3. string hello(1:string name)
4. }
Thrift hello world on Armeria (cont’d)
● 使用 thrift compiler 產生好 client/server 溝通部分
● 實作邏輯
1. public class Foo implements
HelloService.AsyncIface {
2. public void hello(String name,
AsyncMethodCallback cb) {
3. cb.onComplete(name + ", hello world!");
4. }
5. }
● 利用 Armeria 建立 Server
1. ServerBuilder sb = new ServerBuilder();
2. sb.port(8080, SessionProtocol.HTTP);
3. sb.serviceAt(
4. "/hello",
5. ThriftService.of(fooHandler,
6. SerializationFormat.THRIFT_BINARY)
7. .decorate(LoggingService::new));
8. sb.build().start();
Thrift hello world on Armeria (cont’d)
● 利用 Armeria 建立 Client
1. HelloService.Iface helloService =
2. Clients.newClient(
3. "tbinary+http://127.0.0.1:8080/hello",
4. HelloService.AsyncIface.class);
5.
6. helloService.hello("Armeria",
7. new AsyncMethodCallback<String>() {
8. ...
9. });
Thrift hello world on Armeria (cont’d)
● 跟 Swagger 類似
1. ServerBuilder sb = new ServerBuilder();
2. sb.serviceAt("/foo/", THttpService.of(...))
3. .serviceAt("/bar/", THttpService.of(...))
4. .serviceUnder("/docs/", new
5. DocService());
文件產生器
和 legacy webapp 共存
● 將 legacy 的程式透過 Tomcat Servlet Engine 執行
● Tomcat 不需綁定 port,還可以透過 armeria 得到
HTTP/2 的好處
1. ServerBuilder sb = new ServerBuilder();
2. sb.serviceUnder("/legacy/",
3. TomcatService.forFileSystem(
4. "/var/example.war"));
靜態頁面
1. ServerBuilder sb = new ServerBuilder();
2. sb.serviceUnder("/images/",
3. HttpFileService.forFileSystem(
4. "/var/lib/www/images"));
HTTP Server
1. ServerBuilder sb = new ServerBuilder();
2. sb.port(8080, SessionProtocol.HTTP);
3. builder.serviceAt("/http",
4. new AbstractHttpService() {
5. @Override protected void
6. doPost(ServiceRequestContext ctx,
7. HttpRequest req,
8. HttpResponseWriter res)... {
9. res.respond(HttpStatus.OK,
10. MediaType.PLAIN_TEXT_UTF_8,
11. "test");
12. }
13. }).build().start();
HTTP Client
1. HttpClient httpClient = Clients.newClient(
2. "none+http://example.com/",
3. HttpClient.class);
4. AggregatedHttpMessage textResponse =
5. httpClient
6. .get("/foo/bar.txt") // Publisher
7. .aggregate() // CompletableFuture
8. .join();
Client side load balancing
● Armeria 使用單一 HTTP/2 連線,所以在某些狀況
如 L4 下,需要自己的 LB 機制
1. EndpointGroupRegistry.register(
2. "myGroup",
3. new StaticEndpointGroup(
4. Endpoint.of("1.2.3.4", 8080), ...),
5. EndpointSelectionStrategy.
6. WEIGHTED_ROUND_ROBIN);
7. Clients.newClient(
8. "none+http://group:myGroup/foo/bar",
9. SimpleHttpClient.class);
Metrics
● Dropwizard Metrics
● 使用 DropwizardMetricCollectingService decorate
1. builder.serviceAt(
2. "/hello",
3. THttpService.of(new HelloHandler())
4. .decorate(
5. DropwizardMetricCollectingService
6. .newDecorator(metricRegistry,
7. "hello-service")));
Zipkin 整合
● Twitter 的開放源碼專案
● 分散式服務追蹤系統,追蹤跨網路存取的一連串
API 呼叫過程
● 在存取產生時放入一些資訊在 request 中,送到後
台可視化
Zipkin 整合 (cont’d)
1. Brave brave = new
2. Brave.Builder("HelloService")
3. .spanCollector(
4. new ScribeSpanCollector("127.0.0.1",
5. 9410))
6. .traceSampler(Sampler.create(1f))
7. .build();
8. server.serviceAt("/hello",
9. ThriftService.of(new HelloService())
10. .decorate(HttpTracingService
11. .decorator(brave));
Circuit Breaker
● 有多個遠端呼叫的系統最怕超時的服務所造成的連
鎖反應
● http://martinfowler.com/bliki/CircuitBreaker.html
http://developers.linecorp.com/blog/ja/?p=3684
Circuit Breaker (cont’d)
1. decorator =
2. CircuitBreakerClient.newDecorator(
3. new CircuitBreakerBuilder("hello")
4. .failureRateThreshold(0.1).build());
5.
6. new ClientBuilder("tbinary+http://...")
7. .decorator(ThriftCall.class,
8. ThriftReply.class,
9. decorator)
10. .build(HelloService.Iface.class);
Circuit Breaker (cont’d)
● Circuit Breaker 開啟時會丟出 FailFastException
● 可以針對 host, method 等級去做設定
○ newPerMethodDecorator
○ newPerHostDecorator
○ newPerHostAndMethodDecorator
gRPC support
● https://github.com/line/armeria/pull/247
1. ServerBuilder sb = new ServerBuilder();
2. sb.port(8080, SessionProtocol.HTTP);
3. GrpcService grpcService = new
4. GrpcServiceBuilder()
5. .addService(new HiService())
6. .build();
7. sb.serviceUnder("/", grpcService);
8. sb.build().start();
● 理應可以支援 HTTP/1,但現在沒有 HTTP/1 client
● 尚未支援文件產生器 DocService
● 尚未支援 json 格式
○ 類似 gRPC gateway
gRPC support (cont’d)
Retrofit with armeria client
● https://github.com/line/armeria/pull/297
1. HttpClient httpClient =
2. Clients.newClient(ClientFactory.DEFAULT,
3. "none+http://localhost:8080",
4. HttpClient.class);
5. Retrofit retrofit =
6. ArmeriaRetrofit.builder(httpClient)
7. .addConverterFactory(...)
8. .build();
9. MyApi api = retrofit.create(MyApi.class);
Armeria 之於應用程式開發者
● 良好的抽象設計
○ 一樣的方式模式建立 http/thrift client 和 server
● 方便的 decorator 模式
○ 預設已提供 logging, metrics, tracing, circuit
breaker…
○ 依需求可以用同模式實作各種功能 例如: ACL,
rate-limiting...等等
Is Armeria production ready?
Shop architecture using armeria
● 內部與外部都從 thrift socket client/server 實作切
換到 armeria
○ 內部都是 HTTP/2
○ 外部則 HTTP/2 & HTTP/1 都有
● 與 Spring MVC 共存
● Circuit breaker
● Metrics + Zipkin tracing
# of backend requests
但是...
● 非同步化不只是更換框架/程式庫就完成
○ 非同步化的程式不易撰寫跟維護
○ 我們使用 Dagger Producers 去實作非同步的相依
流程
● server/client 都使用 armeria,記得不要使用 client
的 future#get 之類的阻塞方法
○ event loop 下造成同 thread 等待跑在同個 thread
下的 task, 造成永遠阻塞
但是... (cont’d)
● 非同步出錯時,exception 的 stack trace 資訊不足
更多資訊
● http://line.github.io/armeria/
● https://github.com/line/armeria
● 歡迎直接到 issue 提出建議跟需求
Q&A

More Related Content

What's hot

Serverless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolongServerless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolongStreamNative
 
独爽不如众乐
独爽不如众乐独爽不如众乐
独爽不如众乐Zheng Biao
 
Http cache 的優化
Http cache 的優化Http cache 的優化
Http cache 的優化振揚 陳
 
Rpc原理与实现
Rpc原理与实现Rpc原理与实现
Rpc原理与实现wavefly
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用琛琳 饶
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析Justin Lin
 
基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送OpenRestyCon
 
JCConf2015: groovy to gradle
 JCConf2015: groovy to gradle JCConf2015: groovy to gradle
JCConf2015: groovy to gradleChing Yi Chan
 
20081128 http caching_in_php
20081128 http caching_in_php20081128 http caching_in_php
20081128 http caching_in_phpHunter Wu
 
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化Mu Chun Wang
 
DNS协议与应用简介
DNS协议与应用简介DNS协议与应用简介
DNS协议与应用简介琛琳 饶
 
微软Bot framework简介
微软Bot framework简介微软Bot framework简介
微软Bot framework简介Zhichao Liang
 
區塊鏈創新基地 - 區塊鏈
區塊鏈創新基地 - 區塊鏈區塊鏈創新基地 - 區塊鏈
區塊鏈創新基地 - 區塊鏈Hu Kenneth
 
Res tful api design tw-2.0
Res tful api design tw-2.0Res tful api design tw-2.0
Res tful api design tw-2.0昀陞 李
 
深入浅出Netty l.t
深入浅出Netty   l.t深入浅出Netty   l.t
深入浅出Netty l.toleone
 
Linux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflowLinux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflowAngel Boy
 
Introduction of netty
Introduction of nettyIntroduction of netty
Introduction of nettyBing Luo
 
以太坊智能合約撰寫簡單教學
以太坊智能合約撰寫簡單教學以太坊智能合約撰寫簡單教學
以太坊智能合約撰寫簡單教學Nicholas Lin
 
使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能
使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能
使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能Mu Chun Wang
 

What's hot (20)

Serverless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolongServerless Event Streaming with Pulsar Functions-xiaolong
Serverless Event Streaming with Pulsar Functions-xiaolong
 
独爽不如众乐
独爽不如众乐独爽不如众乐
独爽不如众乐
 
Http cache 的優化
Http cache 的優化Http cache 的優化
Http cache 的優化
 
RESTful API Design
RESTful API DesignRESTful API Design
RESTful API Design
 
Rpc原理与实现
Rpc原理与实现Rpc原理与实现
Rpc原理与实现
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析
 
基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送
 
JCConf2015: groovy to gradle
 JCConf2015: groovy to gradle JCConf2015: groovy to gradle
JCConf2015: groovy to gradle
 
20081128 http caching_in_php
20081128 http caching_in_php20081128 http caching_in_php
20081128 http caching_in_php
 
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化
 
DNS协议与应用简介
DNS协议与应用简介DNS协议与应用简介
DNS协议与应用简介
 
微软Bot framework简介
微软Bot framework简介微软Bot framework简介
微软Bot framework简介
 
區塊鏈創新基地 - 區塊鏈
區塊鏈創新基地 - 區塊鏈區塊鏈創新基地 - 區塊鏈
區塊鏈創新基地 - 區塊鏈
 
Res tful api design tw-2.0
Res tful api design tw-2.0Res tful api design tw-2.0
Res tful api design tw-2.0
 
深入浅出Netty l.t
深入浅出Netty   l.t深入浅出Netty   l.t
深入浅出Netty l.t
 
Linux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflowLinux Binary Exploitation - Stack buffer overflow
Linux Binary Exploitation - Stack buffer overflow
 
Introduction of netty
Introduction of nettyIntroduction of netty
Introduction of netty
 
以太坊智能合約撰寫簡單教學
以太坊智能合約撰寫簡單教學以太坊智能合約撰寫簡單教學
以太坊智能合約撰寫簡單教學
 
使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能
使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能
使用 PostgreSQL 及 MongoDB 從零開始建置社群必備的按讚追蹤功能
 

Viewers also liked

使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise APIkoji lin
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuturekoji lin
 
TensorFlow 深度學習快速上手班--電腦視覺應用
TensorFlow 深度學習快速上手班--電腦視覺應用TensorFlow 深度學習快速上手班--電腦視覺應用
TensorFlow 深度學習快速上手班--電腦視覺應用Mark Chang
 
TensorFlow 深度學習快速上手班--深度學習
 TensorFlow 深度學習快速上手班--深度學習 TensorFlow 深度學習快速上手班--深度學習
TensorFlow 深度學習快速上手班--深度學習Mark Chang
 
TensorFlow 深度學習快速上手班--機器學習
TensorFlow 深度學習快速上手班--機器學習TensorFlow 深度學習快速上手班--機器學習
TensorFlow 深度學習快速上手班--機器學習Mark Chang
 
TensorFlow 深度學習講座
TensorFlow 深度學習講座TensorFlow 深度學習講座
TensorFlow 深度學習講座Mark Chang
 

Viewers also liked (8)

使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise API
 
Ionic2
Ionic2Ionic2
Ionic2
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuture
 
TensorFlow 深度學習快速上手班--電腦視覺應用
TensorFlow 深度學習快速上手班--電腦視覺應用TensorFlow 深度學習快速上手班--電腦視覺應用
TensorFlow 深度學習快速上手班--電腦視覺應用
 
TensorFlow 深度學習快速上手班--深度學習
 TensorFlow 深度學習快速上手班--深度學習 TensorFlow 深度學習快速上手班--深度學習
TensorFlow 深度學習快速上手班--深度學習
 
TensorFlow 深度學習快速上手班--機器學習
TensorFlow 深度學習快速上手班--機器學習TensorFlow 深度學習快速上手班--機器學習
TensorFlow 深度學習快速上手班--機器學習
 
TensorFlow 深度學習講座
TensorFlow 深度學習講座TensorFlow 深度學習講座
TensorFlow 深度學習講座
 
TENSORFLOW深度學習講座講義(很硬的課程)
TENSORFLOW深度學習講座講義(很硬的課程)TENSORFLOW深度學習講座講義(很硬的課程)
TENSORFLOW深度學習講座講義(很硬的課程)
 

Similar to Using armeria to write your RPC

构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接 构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接 Renaun Erickson
 
Node.js长连接开发实践
Node.js长连接开发实践Node.js长连接开发实践
Node.js长连接开发实践longhao
 
Real time web实时信息流推送
Real time web实时信息流推送Real time web实时信息流推送
Real time web实时信息流推送yongboy
 
Real-Time Web实时信息流推送
Real-Time Web实时信息流推送Real-Time Web实时信息流推送
Real-Time Web实时信息流推送yongboy
 
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geekJohnson Gau
 
Nginx+常见应用技术指南
Nginx+常见应用技术指南Nginx+常见应用技术指南
Nginx+常见应用技术指南andy54321
 
高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕ideawu
 
Node.js在淘宝的应用实践
Node.js在淘宝的应用实践Node.js在淘宝的应用实践
Node.js在淘宝的应用实践taobao.com
 
Jetty服务器架构及调优.v2 2011-5
Jetty服务器架构及调优.v2 2011-5Jetty服务器架构及调优.v2 2011-5
Jetty服务器架构及调优.v2 2011-5lovingprince58
 
Php Webservers
Php WebserversPhp Webservers
Php Webserverssamon127
 
twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC
 
D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版Jackson Tian
 
NodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiNodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiJackson Tian
 
Apache trafficserver
Apache trafficserverApache trafficserver
Apache trafficserverDin Dindin
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开longxibendi
 
使用Nginx轻松实现开源负载均衡
使用Nginx轻松实现开源负载均衡使用Nginx轻松实现开源负载均衡
使用Nginx轻松实现开源负载均衡cachowu
 
Golang 高性能实战
Golang 高性能实战Golang 高性能实战
Golang 高性能实战rfyiamcool
 

Similar to Using armeria to write your RPC (20)

构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接 构建ActionScript游戏服务器,支持超过15000并发连接
构建ActionScript游戏服务器,支持超过15000并发连接
 
Node.js长连接开发实践
Node.js长连接开发实践Node.js长连接开发实践
Node.js长连接开发实践
 
Real time web实时信息流推送
Real time web实时信息流推送Real time web实时信息流推送
Real time web实时信息流推送
 
Real-Time Web实时信息流推送
Real-Time Web实时信息流推送Real-Time Web实时信息流推送
Real-Time Web实时信息流推送
 
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek
 
Nginx+常见应用技术指南
Nginx+常见应用技术指南Nginx+常见应用技术指南
Nginx+常见应用技术指南
 
高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕高性能并发Web服务器实现核心内幕
高性能并发Web服务器实现核心内幕
 
Node.js在淘宝的应用实践
Node.js在淘宝的应用实践Node.js在淘宝的应用实践
Node.js在淘宝的应用实践
 
Jetty服务器架构及调优.v2 2011-5
Jetty服务器架构及调优.v2 2011-5Jetty服务器架构及调优.v2 2011-5
Jetty服务器架构及调优.v2 2011-5
 
Php Webservers
Php WebserversPhp Webservers
Php Webservers
 
Php Webservers
Php WebserversPhp Webservers
Php Webservers
 
twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧
 
D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版D2_node在淘宝的应用实践_pdf版
D2_node在淘宝的应用实践_pdf版
 
Html5
Html5Html5
Html5
 
NodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 ShanghaiNodeJS快速服务端开发 朝沐金风 Shanghai
NodeJS快速服务端开发 朝沐金风 Shanghai
 
Apache trafficserver
Apache trafficserverApache trafficserver
Apache trafficserver
 
Showinnodbstatus公开
Showinnodbstatus公开Showinnodbstatus公开
Showinnodbstatus公开
 
摘星
摘星摘星
摘星
 
使用Nginx轻松实现开源负载均衡
使用Nginx轻松实现开源负载均衡使用Nginx轻松实现开源负载均衡
使用Nginx轻松实现开源负载均衡
 
Golang 高性能实战
Golang 高性能实战Golang 高性能实战
Golang 高性能实战
 

More from koji lin

サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよkoji lin
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code genkoji lin
 
Use Lambdas in Android
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Androidkoji lin
 
docker intro
docker introdocker intro
docker introkoji lin
 
Java8 time
Java8 timeJava8 time
Java8 timekoji lin
 
Java8 stream
Java8 streamJava8 stream
Java8 streamkoji lin
 
Java8 lambda
Java8 lambdaJava8 lambda
Java8 lambdakoji lin
 
Raspberry Pi with Java
Raspberry Pi with JavaRaspberry Pi with Java
Raspberry Pi with Javakoji lin
 
Services you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appServices you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appkoji lin
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Javakoji lin
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發koji lin
 
Android Location-based應用開發分享
Android Location-based應用開發分享Android Location-based應用開發分享
Android Location-based應用開發分享koji lin
 

More from koji lin (16)

サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
G1GC
G1GCG1GC
G1GC
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Jcconf
JcconfJcconf
Jcconf
 
Use Lambdas in Android
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Android
 
docker intro
docker introdocker intro
docker intro
 
Java8 time
Java8 timeJava8 time
Java8 time
 
Java8 stream
Java8 streamJava8 stream
Java8 stream
 
Java8 lambda
Java8 lambdaJava8 lambda
Java8 lambda
 
Idea13
Idea13Idea13
Idea13
 
Raspberry Pi with Java
Raspberry Pi with JavaRaspberry Pi with Java
Raspberry Pi with Java
 
Services you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appServices you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile app
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Java
 
JQuery
JQueryJQuery
JQuery
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發
 
Android Location-based應用開發分享
Android Location-based應用開發分享Android Location-based應用開發分享
Android Location-based應用開發分享
 

Using armeria to write your RPC

  • 1. Using Armeria to write your RPC koji lin
  • 2. Armeria ● 非同步 RPC library ● LINE 的開放原始碼專案 ○ Trustin Lee ● Java 8  ● HTTP/1・2  ● Thrift/gRPC  ● 尤其適合在 Microservices 架構
  • 3. Synchronous? Asynchrnous? ● 在同步下,如果一個處理需要等待,thread 必須等 待完成才能繼續執行 ● 同步處理在大量存取下不易 scale up ○ Concurrent requests 受限於 max threads  ○ CPU 花費成本在 contention & context switch  ○ 較快或優先程度較高的存取會被較慢的存取拖累
  • 4. Armeria is Asynchronous ● 建立於 Netty 之上 ● Max concurrent requests >>> max threads ● 較慢的存取不會阻礙到其他存取 ● 程式庫內部也非同步化 ○ DNS 查詢 ○ Connection pool ● 0.20.x reactive stream 化
  • 5. Why HTTP/2 ? ● 一個連線上可以同時來往多個 request / response ● 不需要一個存取就建一個連線 from https://www.nginx.com/blog/7-tips-for-faster-http2-performance/
  • 6. Why HTTP/2 ? (cont'd) ● 解決了 HTTP/1 的許多問題 ○ Binary header compression ○ 更少的連線 ● 比較容易從 HTTP/1 轉換 ● 可以利用各種現存的工具 ○ cURL,瀏覽器,Wireshark
  • 7. Netty 夠穩定嗎? ● HTTP/1 ○ Twitter ○ Apple ● HTTP/2 ○ gRPC ○ LINE internal use
  • 8. Thrift ● 跨平台跟語言的服務開發框架 ○ 透過 compiler 自動生成程式,支援 C++, Java, Python, Ruby, Perl, C#, Go, Javascript ...等等 ○ 支援各種傳輸格式/協定 ● 原本是 Facebook 開發,現為 Apache Thrift 開源 ● 定義好 service method 就可以快速開發 RPC client 和 server ○ .thrift 本身就是良好的文件 ● 比 text-based 格式更有效率
  • 9. Thrift hello world on Armeria ● 撰寫 .thrift 定義 service method 1. namespace java idv.koji.example.service 2. service HelloService { 3. string hello(1:string name) 4. }
  • 10. Thrift hello world on Armeria (cont’d) ● 使用 thrift compiler 產生好 client/server 溝通部分 ● 實作邏輯 1. public class Foo implements HelloService.AsyncIface { 2. public void hello(String name, AsyncMethodCallback cb) { 3. cb.onComplete(name + ", hello world!"); 4. } 5. }
  • 11. ● 利用 Armeria 建立 Server 1. ServerBuilder sb = new ServerBuilder(); 2. sb.port(8080, SessionProtocol.HTTP); 3. sb.serviceAt( 4. "/hello", 5. ThriftService.of(fooHandler, 6. SerializationFormat.THRIFT_BINARY) 7. .decorate(LoggingService::new)); 8. sb.build().start(); Thrift hello world on Armeria (cont’d)
  • 12. ● 利用 Armeria 建立 Client 1. HelloService.Iface helloService = 2. Clients.newClient( 3. "tbinary+http://127.0.0.1:8080/hello", 4. HelloService.AsyncIface.class); 5. 6. helloService.hello("Armeria", 7. new AsyncMethodCallback<String>() { 8. ... 9. }); Thrift hello world on Armeria (cont’d)
  • 13. ● 跟 Swagger 類似 1. ServerBuilder sb = new ServerBuilder(); 2. sb.serviceAt("/foo/", THttpService.of(...)) 3. .serviceAt("/bar/", THttpService.of(...)) 4. .serviceUnder("/docs/", new 5. DocService()); 文件產生器
  • 14. 和 legacy webapp 共存 ● 將 legacy 的程式透過 Tomcat Servlet Engine 執行 ● Tomcat 不需綁定 port,還可以透過 armeria 得到 HTTP/2 的好處 1. ServerBuilder sb = new ServerBuilder(); 2. sb.serviceUnder("/legacy/", 3. TomcatService.forFileSystem( 4. "/var/example.war"));
  • 15. 靜態頁面 1. ServerBuilder sb = new ServerBuilder(); 2. sb.serviceUnder("/images/", 3. HttpFileService.forFileSystem( 4. "/var/lib/www/images"));
  • 16. HTTP Server 1. ServerBuilder sb = new ServerBuilder(); 2. sb.port(8080, SessionProtocol.HTTP); 3. builder.serviceAt("/http", 4. new AbstractHttpService() { 5. @Override protected void 6. doPost(ServiceRequestContext ctx, 7. HttpRequest req, 8. HttpResponseWriter res)... { 9. res.respond(HttpStatus.OK, 10. MediaType.PLAIN_TEXT_UTF_8, 11. "test"); 12. } 13. }).build().start();
  • 17. HTTP Client 1. HttpClient httpClient = Clients.newClient( 2. "none+http://example.com/", 3. HttpClient.class); 4. AggregatedHttpMessage textResponse = 5. httpClient 6. .get("/foo/bar.txt") // Publisher 7. .aggregate() // CompletableFuture 8. .join();
  • 18. Client side load balancing ● Armeria 使用單一 HTTP/2 連線,所以在某些狀況 如 L4 下,需要自己的 LB 機制 1. EndpointGroupRegistry.register( 2. "myGroup", 3. new StaticEndpointGroup( 4. Endpoint.of("1.2.3.4", 8080), ...), 5. EndpointSelectionStrategy. 6. WEIGHTED_ROUND_ROBIN); 7. Clients.newClient( 8. "none+http://group:myGroup/foo/bar", 9. SimpleHttpClient.class);
  • 19. Metrics ● Dropwizard Metrics ● 使用 DropwizardMetricCollectingService decorate 1. builder.serviceAt( 2. "/hello", 3. THttpService.of(new HelloHandler()) 4. .decorate( 5. DropwizardMetricCollectingService 6. .newDecorator(metricRegistry, 7. "hello-service")));
  • 20. Zipkin 整合 ● Twitter 的開放源碼專案 ● 分散式服務追蹤系統,追蹤跨網路存取的一連串 API 呼叫過程 ● 在存取產生時放入一些資訊在 request 中,送到後 台可視化
  • 21. Zipkin 整合 (cont’d) 1. Brave brave = new 2. Brave.Builder("HelloService") 3. .spanCollector( 4. new ScribeSpanCollector("127.0.0.1", 5. 9410)) 6. .traceSampler(Sampler.create(1f)) 7. .build(); 8. server.serviceAt("/hello", 9. ThriftService.of(new HelloService()) 10. .decorate(HttpTracingService 11. .decorator(brave));
  • 22. Circuit Breaker ● 有多個遠端呼叫的系統最怕超時的服務所造成的連 鎖反應 ● http://martinfowler.com/bliki/CircuitBreaker.html http://developers.linecorp.com/blog/ja/?p=3684
  • 23. Circuit Breaker (cont’d) 1. decorator = 2. CircuitBreakerClient.newDecorator( 3. new CircuitBreakerBuilder("hello") 4. .failureRateThreshold(0.1).build()); 5. 6. new ClientBuilder("tbinary+http://...") 7. .decorator(ThriftCall.class, 8. ThriftReply.class, 9. decorator) 10. .build(HelloService.Iface.class);
  • 24. Circuit Breaker (cont’d) ● Circuit Breaker 開啟時會丟出 FailFastException ● 可以針對 host, method 等級去做設定 ○ newPerMethodDecorator ○ newPerHostDecorator ○ newPerHostAndMethodDecorator
  • 25. gRPC support ● https://github.com/line/armeria/pull/247 1. ServerBuilder sb = new ServerBuilder(); 2. sb.port(8080, SessionProtocol.HTTP); 3. GrpcService grpcService = new 4. GrpcServiceBuilder() 5. .addService(new HiService()) 6. .build(); 7. sb.serviceUnder("/", grpcService); 8. sb.build().start();
  • 26. ● 理應可以支援 HTTP/1,但現在沒有 HTTP/1 client ● 尚未支援文件產生器 DocService ● 尚未支援 json 格式 ○ 類似 gRPC gateway gRPC support (cont’d)
  • 27. Retrofit with armeria client ● https://github.com/line/armeria/pull/297 1. HttpClient httpClient = 2. Clients.newClient(ClientFactory.DEFAULT, 3. "none+http://localhost:8080", 4. HttpClient.class); 5. Retrofit retrofit = 6. ArmeriaRetrofit.builder(httpClient) 7. .addConverterFactory(...) 8. .build(); 9. MyApi api = retrofit.create(MyApi.class);
  • 28. Armeria 之於應用程式開發者 ● 良好的抽象設計 ○ 一樣的方式模式建立 http/thrift client 和 server ● 方便的 decorator 模式 ○ 預設已提供 logging, metrics, tracing, circuit breaker… ○ 依需求可以用同模式實作各種功能 例如: ACL, rate-limiting...等等
  • 30.
  • 32. ● 內部與外部都從 thrift socket client/server 實作切 換到 armeria ○ 內部都是 HTTP/2 ○ 外部則 HTTP/2 & HTTP/1 都有 ● 與 Spring MVC 共存 ● Circuit breaker ● Metrics + Zipkin tracing
  • 33. # of backend requests
  • 34.
  • 35.
  • 36.
  • 37.
  • 38. 但是... ● 非同步化不只是更換框架/程式庫就完成 ○ 非同步化的程式不易撰寫跟維護 ○ 我們使用 Dagger Producers 去實作非同步的相依 流程 ● server/client 都使用 armeria,記得不要使用 client 的 future#get 之類的阻塞方法 ○ event loop 下造成同 thread 等待跑在同個 thread 下的 task, 造成永遠阻塞
  • 41. Q&A