如何在Java生態圈選擇一個輕量級的RESTful框架?

在微服務流行的今天,咱們會從縱向和橫向分解代碼的邏輯,將一些獨立的無狀態的代碼單元實現爲微服務,能夠將它們發佈到一些分佈式計算單元或者Docker中,並在性能須要的時候及時地建立更多的服務單元。
微服務是一個概念,並無規定服務的格式,可是不少廠商和框架都不約而同的採用RESTful的架構,儘管也有一些其它的性能很好的RPC框架。
如何在Java生態圈選擇一個輕量級的RESTful框架?
就我我的而言,我選擇框架的理由很簡單:java

  • 簡單,輕量級
  • 性能好
  • 穩定,可靠
  • 易於開發和維護

我會首選遵循Java規範(JSR339)的框架,輕量級,便於發佈到Docker容器中。 因此我不會選擇Spring boot, Spring MVC, CXF等比較重的框架,也不會選擇純netty這樣的太過底層,還得實現路由等基本功能框架。
由於追求輕量級,便於發佈到docker容器中,我也不會考察JBOSS, Tomcat這樣的JEE容器, 而是選用jetty, undertow這樣的嵌入式容器。git

因此,這裏我挑選了幾個候選者:github

  1. Jersey + Grizzly
  2. Jersey + Jetty
  3. Dropwizard
  4. RESTEasy + Netty
  5. RESTEasy + Undertow

我增長了更多的 RESTful 框架,有些不是Jax-RS的實現,可是也有很活躍的社區。spring

  1. Jersey + Jetty4
  2. Spring Boot
  3. 純Netty
  4. Vert.x
    你會發現一些有趣的測試結果。

Jersey 是Jax-RS的官方參考實現,能夠很好的和其它JEE容器集成。RESTEasy是JBoss出品的框架,也很容易的和其它容器集成。Dropwizard實際上集成了Jersey, Jetty以及其它的第三方庫好比它的Metrics,提供了一站式的開發,略微有些厚重。docker

測試相關的代碼已經放在了GITHUB上: 代碼
瀏覽器

編譯代碼

測試代碼是一個多模塊的Maven項目, 你直接運行maven clean package就能夠生成各個jar,並且這些jar包含了所依賴的類,執行起來至關簡單。
你也能夠在每一個模塊下運行mvn exec:java啓動服務,而後在瀏覽器中訪問 http://localhost:8080/rest/hello (對於Jersey + Jetty,地址是http://localhost:8080/hello)springboot

測試環境

服務器
AWS C3.2xlarge服務器

  • 8 cores (E5-2666 v3 @ 2.90GHz)
  • memory: 16G (服務只分配了4G內存)

Java
1.8.0_51架構

測試工具
wrk
測試命令如: wrk -t16 -c1000 -d30s http://127.0.0.1:8080/rest/hello.
針對每一個case, 我使用16個線程,以及100/200/500/1000併發進行測試。併發

服務啓動命令

1
2
3
4
5
6
7
8
9
java -Xmx4g -Xms4g -jar jersey-grizzly2-1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar jersey-jetty- 1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar dropwizard- 1.0-SNAPSHOT.jar hello.yml
java -Xmx4g -Xms4g -jar resteasy-netty- 1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar resteasy-undertow- 1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar springboot- 1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar resteasy-netty4- 1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar nativenetty- 1.0-SNAPSHOT.jar
java -Xmx4g -Xms4g -jar vertx-verticles- 1.0-SNAPSHOT.jar -instances 20

測試結果

測試結果數據能夠查看這裏: 測試數據,
延遲基本在幾毫秒到10幾毫秒之間。

圖形化測試結果(y軸爲Requests/sec, x軸爲併發量):

結論

從結果看,

    • RESTEasy的性能要好於 Jersey,不管哪一種嵌入式JEE容器。
    • Jersey+Grizzly2和Jersey+Jetty, dropwizard性能差異不大
    • dropwizard底層實際是Jersey+Jetty,性能結果也和Jersey+Jetty同樣
    • RESTEasy+netty (netty3)的結果並無優於RESTEasy+undertow.這出乎個人意料,可能CPU和Memory佔用上會好一些
    • RESTEasy+netty4的性能遠遠低於RESTEasy+netty3,這出乎個人意料。或許由於Netty線程池的改變。
    • 純netty的性能遠遠高於其它框架,一方面是因爲沒有http router的邏輯,另外一方面也顯示了Netty框架的優秀。若是不是實現很複雜的路由和不少的Service,不妨使用純Netty實現高性能。
    • Spring Boot太厚重了,使用Spring MVC的語法,性能只有Jersey的一半。
相關文章
相關標籤/搜索