1. 程式人生 > >使用Ratpack與Spring Boot構建高效能JVM微服務

使用Ratpack與Spring Boot構建高效能JVM微服務

在微服務天堂中Ratpack和Spring Boot是天造地設的一對。它們都是以開發者為中心的運行於JVM之上的web框架,側重於生產率、效率以及輕量級部署。他們在服務程式的開發中帶來了各自的好處。Ratpack通過一個高吞吐量、非阻塞式的web層提供了一個反應式程式設計模型,而且對應用程式結構的定義和HTTP請求過程提供了一個便利的處理程式鏈;Spring Boot集成了整個Spring生態系統,為應用程式提供了一種簡單的方式來配置和啟用元件。Ratpack和Spring Boot是構建原生支援計算雲的基於資料驅動的微服務的不二選擇。

Ratpack並不關心應用程式底層使用了什麼樣的依賴注入框架。相反,應用程式可以通過Ratpack提供的DI抽象(被稱為Registry)訪問服務層元件。Ratpack的Registry是構成其基礎設施的一部分,其提供了一個介面,DI提供者可以使用註冊器回撥(registry backing)機制來參與到元件解決方案序列中。

Ratpack直接為Guice和Spring Boot提供了註冊器回撥機制,開發人員可以為應用程式靈活選擇使用的依賴注入框架。

在本文中我們將演示使用Ratpack和Spring Boot構建一個RESTful風格的基於資料驅動的微服務,背後使用了Spring Data用於操作資料。

開始構建Ratpack專案的最佳方式是建立Gradle指令碼以及標準的Java專案結構。Gradle是Ratpack原生支援的構建系統,其實由於Ratpack只是一組簡單的JVM庫,所以其實它適用於任何構建系統(不管你的需求有多特別)。如果你還未安裝Gradle,那麼安裝它最佳方式是通過Groovy enVironment Manager工具

。示例專案的構建指令碼如列表1所示。

列表1


buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'io.ratpack:ratpack-gradle:0.9.18'
  }
}

apply plugin: 'io.ratpack.ratpack-java'
apply plugin: 'idea'
apply plugin: 'eclipse'

repositories {
  jcenter()
}

dependencies {
  compile ratpack.dependency
('spring-boot') (1) } mainClassName = "springpack.Main" (2) eclipse { classpath { containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' } }

在(1)部分中,構建指令碼通過呼叫Ratpack Gradle外掛的ratpack.dependency(..)方法引入了Ratpack和Spring Boot的整合。根據構建指令碼和當前專案結構,我們可以建立一個“主類”(main class),其作為可執行的類來啟動和執行應用程式。注意(2)中我們指定了主類的名稱,所以使用命令列工具時會更簡練。這意味著實際的主類名必須與之一致,所以需要在本專案的src/main/java目錄中建立一個名為springpack.Main的類。

在主類中,我們通過工廠方法構造了RatpackServer的一個例項,在start方法中提供了對應用程式的定義。該定義中我們編寫了RESTful API處理器鏈。請參見列表2中對Main類的演示。注意Ratpack要求的編譯環境為Java 8

列表2


package springpack;

import ratpack.server.RatpackServer;

public class Main {

  public static void main(String[] args) throws Exception {
    RatpackServer.start(spec -> spec
      .handlers(chain -> chain (1)
          .prefix("api", pchain -> pchain (2)
            .all(ctx -> ctx (3)
              .byMethod(method -> method (4)
                .get(() -> ctx.render("Received GET request"))
                .post(() -> ctx.render("Received POST request"))
                .put(() -> ctx.render("Received PUT request"))
                .delete(() -> ctx.render("Received DELETE request"))
              )
            )
          )
      )
    );
  }
}

如果我們仔細剖析主類中的應用程式定義,我們可以識別出一些關鍵知識點,對於不熟悉Ratpack的人來說,我們需要對這些知識點做進一步解釋。第一個值得注意的點在(1)中處理器區域定義了一個處理器鏈,該處理器鏈用於處理Ratpack流中的HTTP請求。通過鏈式定義的處理器描述了它們能夠處理的請求型別。特別在(2)中我們定義了一個字首處理器型別,指定它被繫結到“api”這個HTTP路由。字首處理器建立了一個新的處理器鏈,用來處理匹配”/api” 埠(endpoint)到來的請求。在(3)處我們使用了所有的處理器型別來指定所有到來的請求應該執行在我們提供的處理器中,在(4)處我們使用Ratpack的byMethod機制來將get,post,put和delete處理器繫結到到各自的HTTP方法中。

在專案根目錄下,我們可以通過命令列簡單使用gradle的“run”命令執行該應用程式。這會啟動web伺服器並繫結到埠5050。為了演示當前專案的功能,確保處理器結構工作正常,我們可以在命令列中通過curl執行一些測試:

可以看到,應用程式處理器鏈可以正確地路由請求,我們建立了RESTful API的結構。接下來需要改善這些API…

為了演示的緣故,讓我們儘量保持簡單,改造該微服務以便可以對一個User領域物件進行CRUD操作。通過REST介面,客戶可以做以下事情:

  • 通過一個GET請求來請求指定的使用者賬號,使用者名稱作為路徑變數(path variable);
  • GET請求中如果未指定使用者名稱,則列出所有的使用者;
  • 通過POST一個JSON格式的使用者物件來建立一個使用者;
  • 使用PUT請求,使用者名稱作為路徑變數來更新該使用者的郵件地址;
  • 使用DELETE請求,使用者名稱作為路徑變數來刪除該使用者。

在之前小節中我們定義的處理器已經包含了大多數處理這種需求的基礎設施。但根據需求我們還需要做細微調整。例如,我們現在需要繫結處理器接收使用者名稱作為路徑變數。列表3中是更新後的程式碼,主類中的處理器可以滿足現在的需求。

列表3


package springpack;

import ratpack.server.RatpackServer;

public class Main {

  public static void main(String[] args) throws Exception {
    RatpackServer.start(spec -> spec
      .handlers(chain -> chain
        .prefix("api/users", pchain -> pchain (1)
          .prefix(":username", uchain -> uchain (2)
            .all(ctx -> { (3)
              String username = ctx.getPathTokens().get("username");
              ctx.byMethod(method -> method (4)
                .get(() -> ctx.render("Received request for user: " + username))
                                              .put(() -> {
                  String json = ctx.getRequest().getBody().getText();
                  ctx.render("Received update request for user: " + username + ", JSON: " + json);
                })
                .delete(() -> ctx.render("Received delete request for user: " + username))
              );
            })
          )
          .all(ctx -> ctx (5)
            .byMethod(method -> method
              .post(() -> { (6)
                String json = ctx.getRequest().getBody().getText();
                ctx.render("Received request to create a new user with JSON: " + json);
              })
              .get(() -> ctx.render("Received request to list all users")) (7)
            )
          )
        )
      )
    );
  }
}

重新構造後的API遵循了面向資源的模式,圍繞著user領域物件為中心。以下是一些修改點:

  • 在(1)中我們修改了入口級字首為/api/users;
  • 在(2)中我們綁定了一個新的字首處理器到:username路徑變數上。任何到來的請求路徑中的值會被轉換,並且Ratpack處理器可以通過ctx.getPathTokens()中的表來訪問該值。
  • 在(3)中我們為所有匹配/api/users/:username URI模式的請求繫結一個處理器;
  • 在(4)中我們使用byMethod機制來為HTTP GET,PUT和DELETE方法繫結處理器。通過這些處理器我們可以瞭解客戶端對指定使用者的操作意圖。在PUT處理器中,我們呼叫ctx.getRequest().getBody().getText()方法來捕獲到來的請求中的JSON資料;
  • 在(5)中我們附加一個處理器來匹配所有從/api/users埠到來的請求;
  • 在(6)中我們對/api/users處理器使用byMethod機制來附加一個POST處理器,當建立新使用者時該POST處理器會被呼叫。這裡又一次從到來的請求中取出JSON資料;
  • 最後在(7)中,我們附加了一個GET處理器,當客戶端需要所有使用者的列表時可以呼叫它。

再次啟動該應用程式並進行一系列curl命令列呼叫,來測試這些埠操作是否符合預期:

現在我們擁有了滿足需求的API的基礎框架,但仍需使其更加有用。我們可以開始設定服務層的依賴。在本例中,我們將使用Spring Data JPA元件作為資料訪問物件;列表4展示了對構建指令碼的修改。

列表4


buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'io.ratpack:ratpack-gradle:0.9.18'
  }
}

apply plugin: 'io.ratpack.ratpack-java'
apply plugin: 'idea'
apply plugin: 'eclipse'

repositories {
  jcenter()
}

dependencies {
  compile ratpack.dependency
            
           

相關推薦

使用RatpackSpring Boot構建高效能JVM服務

在微服務天堂中Ratpack和Spring Boot是天造地設的一對。它們都是以開發者為中心的運行於JVM之上的web框架,側重於生產率、效率以及輕量級部署。他們在服務程式的開發中帶來了各自的好處。Ratpack通過一個高吞吐量、非阻塞式的web層提供了一個反應式程式

Spring Cloud + Spring Boot + Mybatis + shiro + RestFul + 服務 技術分享

trap 企業 緩存 瓶頸 定位 spa comm 功能 中心 1. 介紹 Commonservice-system是一個大型分布式、微服務、面向企業的JavaEE體系快速研發平臺,基於模塊化、服務化、原子化、熱插拔的設計思想,使用成熟領先的無商業限制的主流開源技術構建

企業分布式微服務雲架構技術分享 Spring Cloud + Spring Boot + Mybatis + shiro + RestFul + 服務

行數 進行 互聯網產品 strong 日誌管理 平臺 bootstra work oot 1. 介紹 Commonservice-system是一個大型分布式、微服務、面向企業的JavaEE體系快速研發平臺,基於模塊化、服務化、原子化、熱插拔的設計思想,使用成熟領先的無

Spring Boot構建RESTful API單元測試實戰

一 點睛 1 相關注解 @Controller:修飾class,用來建立處理http請求的物件 @RestController:Spring4之後加入的註解,原來在@Controller中返回json需要@ResponseBody來配合,如果直接用@

Spring Boot 入門篇 (二) Spring Boot構建RESTful API單元測試

http://blog.didispace.com/springbootrestfulapi/ 首先,回顧並詳細說明一下在快速入門中使用的@Controller、@RestController、@RequestMapping註解。如果您對Spring MVC不熟悉並且還沒有嘗試過快速入門案例,建

spring boot構建服務-通過maven構建專案HelloWorld

1.訪問如下地址來構建基礎專案 地址:http://start.spring.io/ 2.具體操作選項如下 a.Generate a:建立一個什麼樣的工程,這裡選擇Maven Project b.with:通過什麼語言,這裡選擇Java c.and Spring Boot:這個是選擇sp

從實踐出發:服務佈道師告訴你Spring CloudSpring Boot他如何選擇

背景 隨著公司業務量的飛速發展,平臺面臨的挑戰已經遠遠大於業務,需求量不斷增加,技術人員數量增加,面臨的複雜度也大大增加。在這個背景下,平臺的技術架構也完成了從傳統的單體應用到微服務化的演進。 系統架構的演進過程 單一應用架構(第一代架構) 這是平臺最開始

Spring Boot構建RESTful API單元測試

@Controller:修飾class,用來建立處理http請求的物件@RestController:Spring4之後加入的註解,原來在@Controller中返回json需要@ResponseBody來配合,如果直接用@RestController替代@Controlle

爬蟲框架webmagicspring boot的結合使用--轉

odi oid reat 簡單 ots factor per 爬蟲框架 ddp 原文地址:http://www.jianshu.com/p/c3fc3129407d 1. 爬蟲框架webmagic WebMagic是一個簡單靈活的爬蟲框架。基於WebMagi

rabbitMqspring boot搭配實現監聽

address app caching prefix 前段時間 ever 不用 理解 its   在我前面有一篇博客說到了rabbitMq實現與zk類似的watch功能,但是那一篇博客沒有代碼實例,後面自己補了一個demo,便於理解。demo中主要利用spring boot

kotlin web開發教程【一】從零搭建kotlinspring boot開發環境

1.8 jre cond utf8 erro 2.0 .com 就會 一個tomcat IDEA中文輸入法的智能提示框不會跟隨光標的問題我用的開發工具是IDEA這個版本的IDEA有一個問題;就是中文輸入法的智能提示框不會跟隨光標解決這個問題的辦法很簡單,只有在安裝目錄下把J

漫談spring cloud spring boot 基礎架構

大牛 jquer frame 協作平臺 微信點餐系統 工作 高效 kotlin 彩票 詳情請交流 QQ 709639943 01、漫談spring cloud 與 spring boot 基礎架構 02、漫談spring cloud分布式服務架構 03、Node.

QuartzSpring Boot集成使用

ack innodb edr iba sta hid support getprop eat 上次自己搭建Quartz已經是幾年前的事了,這次項目中需要定時任務,需要支持集群部署,想到比較輕量級的定時任務框架就是Quartz,於是來一波。 版本說明 通過搜索引擎很容易找到其

基於Spring Boot構建應用開發規範

SpringBoot 項目規範 1.規範的意義和作用 編碼規範可以最大限度的提高團隊開發的合作效率 編碼規範可以盡可能的減少一個軟件的維護成本 , 並且幾乎沒有任何一個軟件,在其整個生命周期中,均由最初的開發人員來維護 編碼規範可以改善軟件的可讀性,可以讓開發人員盡快而徹底地理解新的代碼 規範性編碼

springcloud Spring Boot mybatis分布式微服務雲架構(三):服務提供調用

客戶端 生產 pat 簡單的 第一次 his 流程 如何 localhost 上一篇文章我們介紹了eureka服務註冊中心的搭建,這篇文章介紹一下如何使用eureka服務註冊中心,搭建一個簡單的服務端註冊服務,客戶端去調用服務使用的案例。 案例中有三個角色:服務註冊中心、服

Spring-Boot構建多模塊項目

基本 引入 一個 創建 右鍵 簡單的 strong mod style Spring-Boot構建多模塊項目 功能模塊單獨項目開發,可以將一個龐大的項目分解成多個小項目,便於細分開發 Maven多模塊項目不能獨立存在,必須有一個介質來包含。 1.創建一個Maven 項目

Spring Cloud Spring Boot mybatis分布式微服務雲架構(二)使用Intellij中的Spring Initializr來快速構建Spring Boot/Cloud工程

follow 體驗 alt initial ali roo 進行 依賴管理 img 在之前的所有Spring Boot和Spring Cloud相關博文中,都會涉及Spring Boot工程的創建。而創建的方式多種多樣,我們可以通過Maven來手工構建或是通過腳手架等方式快

spring boot項目之信支付功能實現詳細介紹

tab 流程 invalid body 正方形 無法 數據 fmt -s 對接微信支付功能主要有以下幾個步驟, 而其第一個關鍵點就是獲取OpenID,在這裏介紹兩種獲取方式: 一、微信授權 微信網頁授權 如果用戶在微信客戶端中訪問第三方網頁,公

ajaxspring boot web聯調

click port ria button 應用 emp name form oot aajax.html <!DOCTYPE html> <html> <head> <meta charset="ut

Spring Boot構建REST

controller package com.example.demo.controller; import com.example.demo.pojo.User; import com.example.demo.utils.ResultUtil; import org.springf