dubbo是阿里巴巴開源的一套rpc方案,以為理念很契合微服務,這幾年很火,用戶里面不凡京東,當當,去哪兒等大公司。
rpc場景
dubbo架構
官網也提供了一個很簡單實用的demo來演示dubbo協議的使用,用起來的確很簡單強大。
dubbo demo
可參考 http://dubbo.io/ 首頁的例子已經很好了。
基於telnet的簡單調試接口
任何一個dubbo服務都支持一個簡單的telent交互。比如
telnet localhost 20880
>ls -l > ls -l DemoService > invoke DemoSerivce.sayHello("seveniruby")
這種方式只能用來簡單驗證接口的可用
傳統的基於xml配置的dubbo的測試方法
首先創建一個xml文件放到resources下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="demo-consumer"/> <dubbo:registry address="dubbo://127.0.0.1:9090"/> <dubbo:reference id="demoService" interface="com.testerhome.tapi.dubbo.DemoService"/> </beans>
通過使用一份xml配置文件進行測試
test("dubbo use registy xml"){ val context = new ClassPathXmlApplicationContext("dubbo/consumer.xml") context.start() val demoService = context.getBean("demoService").asInstanceOf[DemoService] println(demoService.sayHello("seveniruby")) val req=new RequestModel() req.setName("james") req.getChild.setName("lily") println(TData.toJson(demoService.reqModel(req))) }
基於api的dubbo測試方法
其實除了xml配置之外,官方也提供了一份直接通過api進行配置的方式,這個方式無疑是可編程比較靈活的
test("dubbo use registry"){ // 當前應用配置 val application = new ApplicationConfig application.setName("yyy") // 注意:ReferenceConfig為重對象,內部封裝了與注冊中心的連接,以及與服務提供方的連接 // 引用遠程服務 val reference = new ReferenceConfig[DemoService] // 此實例很重,封裝了與注冊中心的連接以及與提供者的連接,請自行緩存,否則可能造成內存和連接泄漏 reference.setApplication(application) reference.setRegistry(registry); // 多個注冊中心可以用setRegistries() reference.setInterface(classOf[DemoService]) //reference.setUrl("dubbo://127.0.0.1:20881") reference.setTimeout(5000) // 和本地bean一樣使用DemoService val DemoService = reference.get // 注意:此代理對象內部封裝了所有通訊細節,對象較重,請緩存復用 System.out.println(DemoService.sayHello("seveniruby")) val req=new RequestModel() req.setName("james") req.getChild.setName("lily") System.out.println(TData.toJson(DemoService.reqModel(req))) }
泛化調用
官方原話是
泛化接口調用方式主要用於客戶端沒有 API 接口及模型類元的情況,參數及返回值中的所有 POJO 均用 Map 表示,通常用於框架集成,比如:實現一個通用的服務測試框架,可通過 GenericService 調用所有服務實現。
這種情況適合自己打造接口測試框架使用。以上2個方式都需要依賴研發提供的dubbo接口的jar包,這無疑會增加項目的負擔。
使用泛化可以不依賴任何研發提供的jar包,不過缺點也明顯,仍然需要jar包或者其他的文檔去分析dubbo接口的調用參數信息。
例子
test("泛化調用 by provider conf use map"){ var reference = new ReferenceConfig[GenericService]() // 該實例很重量,里面封裝了所有與注冊中心及服務提供方連接,請緩存 reference.setGeneric(true) // 聲明為泛化接口 reference.setApplication(new ApplicationConfig("generic-provider")) //reference.setRegistry(registry) reference.setInterface("com.testerhome.tapi.dubbo.DemoService") // 弱類型接口名 reference.setTimeout(5000) reference.setUrl(s"dubbo://127.0.0.1:20881") val genericService = reference.get val result = genericService.$invoke("sayHello", Array("java.lang.String"), Array("xxxx".asInstanceOf[AnyRef])) log.info(result) val childMap= mutable.Map[String, AnyRef]() childMap.put("name", "children") val map= mutable.Map[String, AnyRef]() map.put("name", "aaa") map.put("id", "11") map.put("child", childMap.asJava) val resModel=genericService.$invoke( "reqModel", Array("com.testerhome.tapi.dubbo.RequestModel"), Array(map.asJava.asInstanceOf[AnyRef])) log.info(resModel) log.info(TData.toJson(resModel)) }
雖然看起來還是依賴jar包,不過這個依賴就挺小了。如果你技術稍微“猥瑣”點,就應該可以想到,只需要借助asm之類的字節碼分析框架即可自動生成接口測試用例模板了。
dubbo測試的技術關注點
- dubbo支持很多的協議,如果用的是http或者hessian協議,他們本身是文本的,可以直接使用restassured框架進行接口測試
- dubbo的registry保存了dubbo各種服務的注冊信息,測試的時候可以直接用registry,而不是直接連接到提供服務的provider上

