融合spring cloud與dubbo 無縫替換spring cloud微服務間調用協(xié)議

項目地址:https://github.com/SpringCloud/spring-cloud-dubbo 歡迎star财搁、fork

spring-cloud-dubbo

spring/spring cloud的設計理念是integrate everything泥技。充分利用現有開源組件陪拘,在他們之上設計一套統(tǒng)一規(guī)范/接口使他們能夠接入spring cloud體系并且能夠無縫切換底層實現裳涛,使他們能夠集成到一起良好運作咐吼。最典型的例子就是DiscoveryClient,只要實現DiscoveryClient相關接口咳蔚,spring cloud的底層注冊中心可以隨意更換豪嚎,dubbo的注冊中心也有SPI規(guī)范進行替換。

本項目的目標是將dubbo融入到spring cloud生態(tài)中谈火,使微服務之間的調用同時具備restful和dubbo調用的能力侈询。做到對業(yè)務代碼無侵入,無感知:引入jar包則微服務間調用使用dubbo糯耍,去掉jar包則使用默認的restful扔字。

設計思路

之前因為工作需要增強過feign,feign的設計思路就是提供一套API温技,底層契約隨意更換啦租,參照feign的SpringMvcContract類。與項目理念非常相似荒揣,所以我們也使用feign作為統(tǒng)一接口篷角,spring cloud下feign默認使用restful方式調用,我們只需要擴展feign系任,提供dubbo方式調用就行了恳蹲。

服務提供方

服務提供方提供service(restful服務)和api(sdk開發(fā)工具)虐块。服務消費方使用api來調用服務(方便提供方升級增加服務提供方可控性)。

api中定義FeignClient接口(spring-cloud-dubbo-demo-provider-api):

@FeignClient("provider")
public interface ProviderService {
    @GetMapping("/hello")
    String hello();
}

service中實現該接口(spring-cloud-dubbo-demo-provider-service):

@RestController
public class ProviderServiceImpl implements ProviderService {
    @Override
    public String hello() {
        return "Hello " + System.currentTimeMillis();
    }
}

上述代碼是一個典型的spring cloud restful api嘉蕾。在服務提供方我們要做的就是:引入dubbo贺奠,掃描含有@FeignClient注解的類并且提供dubbo訪問即可(FeignClientToDubboProviderBeanPostProcessor)。關鍵代碼片段:

private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
        ...
        scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class, true, true));
        for (String packageToScan : packagesToScan) {
            // Registers @Service Bean first
            scanner.scan(packageToScan);
         ...
}

服務消費方

引入spring-cloud-dubbo-demo-provider-api依賴错忱,并直接使用@Autowire使用相關api:

@RestController
public class TestService {
    @Autowired
    private ProviderService providerService;

    @GetMapping("/test")
    public String test() {
        return "Test " + providerService.hello();
    }
}

上述代碼是一個典型的spring cloud feign使用儡率。我們只需要替換feign的實現:產生ProviderService接口proxy bean時,使用dubbo產生的bean替換默認的feign產生的restful調用的bean即可(DubboFeignBuilder)以清。關鍵代碼片段:

@Override
public <T> T target(Target<T> target) {
    ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder
            .create(defaultReference, target.getClass().getClassLoader(), applicationContext)
            .interfaceClass(target.type());
    try {
        T object = (T) beanBuilder.build().getObject();
        return object;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

如何使用

參考spring-cloud-dubbo-demo

先建立一組標準的spring cloud restful工程儿普,注意feign client接口由服務提供方提供。然后接入spring-cloud-dubbo給項目提供dubbo調用能力掷倔。
引入依賴:

<dependency>
    <groupId>cn.springcloud.dubbo</groupId>
    <artifactId>spring-cloud-dubbo-starter</artifactId>
</dependency>

使用 https://github.com/apache/incubator-dubbo-spring-boot-project 0.2.0版本眉孩,目前還未發(fā)布maven中央倉庫,需要本地編譯安裝勒葱,spring-boot與dubbo集成和配置均安裝此項目說明文檔

服務提供方配置:

dubbo.application.name=provider
dubbo.registry.address=eureka://127.0.0.1:8761
dubbo.scan.basePackages=cn.springcloud.dubbo.demo.provider.service

為了減少依賴浪汪,快速體驗,并且作為將dubbo完全融入spring cloud后續(xù)計劃的POC凛虽。我們按照dubbo SPI擴展規(guī)范 http://dubbo.apache.org/books/dubbo-dev-book/impls/registry.html 死遭,提供了一個實驗性質的dubbo eureka注冊中心(dubbo eureka配置中心的ip和端口可以隨便填,我們并不會用到這里的配置凯旋,我們用的是spring cloud的配置殃姓,dubbo擴展規(guī)范要求 eureka:// 后面必須要跟ip和端口而已)。如果要在生產環(huán)境使用瓦阐,目前還是建議采用dubbo自帶的zookeeper注冊中心,只需將上面注冊中心配置改為:

dubbo.registry.address=zookeeper://127.0.0.1:2181

服務消費方配置:

dubbo.application.name=consumer
dubbo.registry.address=eureka://127.0.0.1:8761
dubbo.scan.basePackages=cn.springcloud.dubbo.demo.consumer.service

開啟eureka

開啟provider

開啟consumer

訪問 view-source:http://localhost:8761/eureka/apps/CONSUMER metadata確認含有如下dubbo注冊信息:

<metadata>
    <providers>["dubbo://172.24.223.241:30880/cn.springcloud.dubbo.demo.consumer.service.BarService?anyhost=true&amp;application=consumer&amp;dubbo=2.6.2&amp;generic=false&amp;interface=cn.springcloud.dubbo.demo.consumer.service.BarService&amp;methods=bar&amp;pid=9268&amp;side=provider&amp;timestamp=1528524172162"]</providers>
    <consumers>["consumer://172.24.223.241/cn.springcloud.dubbo.demo.provider.service.FooService?application=consumer&amp;category=consumers&amp;check=false&amp;dubbo=2.6.2&amp;interface=cn.springcloud.dubbo.demo.provider.service.FooService&amp;methods=foo&amp;pid=9268&amp;qos.enable=false&amp;side=consumer&amp;timestamp=1528524172906","consumer://172.24.223.241/cn.springcloud.dubbo.demo.provider.service.ProviderService?application=consumer&amp;category=consumers&amp;check=false&amp;dubbo=2.6.2&amp;interface=cn.springcloud.dubbo.demo.provider.service.ProviderService&amp;methods=hello&amp;pid=9268&amp;qos.enable=false&amp;side=consumer&amp;timestamp=1528524172823"]</consumers>
</metadata>

在服務消費方TestService打上斷點篷牌,訪問 http://localhost:28080/test 可以看到ProviderService的實現類proxy為dubbo睡蟋,采用dubbo進行服務間調用

服務消費方使用restful調用,只需將dubbo相關依賴排除即可:

<dependency>
    <groupId>cn.springcloud.dubbo</groupId>
    <artifactId>spring-cloud-dubbo-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </exclusion>
    </exclusions>
</dependency>

在服務消費方TestService打上斷點枷颊,訪問 http://localhost:28080/test 可以看到ProviderService的實現類proxy為feign戳杀,采用restful進行服務間調用

FAQ

如何使用更加細致的dubbo配置?

我們的工程融合了spring cloud和dubbo夭苗,只是將feign底層實現替換為dubbo而已信卡,因此所有dubbo標準用法均支持。服務提供方可以使用標準dubbo @Service注解進行細致配置:

@Service(group = "testGroup")
@RestController
public class ProviderServiceImpl implements ProviderService {
}

服務消費方可以使用標準dubbo @Reference注解進行細致配置:

// @Autowired
@Reference(group = "testGroup")
private ProviderService providerService;

作者:Charles_He
鏈接:http://www.reibang.com/p/0368dc1e9357
來源:簡書

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末题造,一起剝皮案震驚了整個濱河市傍菇,隨后出現的幾起案子,更是在濱河造成了極大的恐慌界赔,老刑警劉巖丢习,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牵触,死亡現場離奇詭異,居然都是意外死亡咐低,警方通過查閱死者的電腦和手機揽思,發(fā)現死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來见擦,“玉大人钉汗,你說我怎么就攤上這事±鹇牛” “怎么了损痰?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長执俩。 經常有香客問我徐钠,道長,這世上最難降的妖魔是什么役首? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任尝丐,我火速辦了婚禮,結果婚禮上衡奥,老公的妹妹穿的比我還像新娘爹袁。我一直安慰自己,他們只是感情好矮固,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布失息。 她就那樣靜靜地躺著,像睡著了一般档址。 火紅的嫁衣襯著肌膚如雪盹兢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天守伸,我揣著相機與錄音绎秒,去河邊找鬼。 笑死尼摹,一個胖子當著我的面吹牛见芹,可吹牛的內容都是我干的。 我是一名探鬼主播蠢涝,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼玄呛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了和二?” 一聲冷哼從身側響起徘铝,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后庭砍,有當地人在樹林里發(fā)現了一具尸體场晶,經...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年怠缸,在試婚紗的時候發(fā)現自己被綠了诗轻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡揭北,死狀恐怖扳炬,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情搔体,我是刑警寧澤恨樟,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站疚俱,受9級特大地震影響劝术,放射性物質發(fā)生泄漏。R本人自食惡果不足惜呆奕,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一养晋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梁钾,春花似錦绳泉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拇勃,卻和暖如春四苇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背方咆。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工月腋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人峻呛。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像辜窑,于是被迫代替她去往敵國和親钩述。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內容