国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Dubbo 一篇文章就夠了:從入門到實(shí)戰(zhàn)

tomener / 3438人閱讀

摘要:啟動容器,加載,運(yùn)行服務(wù)提供者。服務(wù)提供者在啟動時(shí),在注冊中心發(fā)布注冊自己提供的服務(wù)。注冊中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費(fèi)者。

一 為什么需要 dubbo

很多時(shí)候,其實(shí)我們使用這個(gè)技術(shù)的時(shí)候,可能都是因?yàn)轫?xiàng)目需要,所以,我們就用了,但是,至于為什么我們需要用到這個(gè)技術(shù),可能自身并不是很了解的,但是,其實(shí)了解技術(shù)的來由及背景知識,對于理解一項(xiàng)技術(shù)還是有幫助的,那么,dubbo是怎么被提上日程的呢?

在互聯(lián)網(wǎng)的發(fā)展過程中,在以前,我們只需要一個(gè)服務(wù)器,將程序全部打包好就可以,但是,隨著流量的增大,常規(guī)的垂直應(yīng)用架構(gòu)已無法應(yīng)對,所以,架構(gòu)就發(fā)生了演變。

1 單一應(yīng)用架構(gòu)

2 應(yīng)用和數(shù)據(jù)庫多帶帶部署

3 應(yīng)用和數(shù)據(jù)庫集群部署

4 數(shù)據(jù)庫壓力變大,讀寫分離

5 使用緩存技術(shù)加快速度

6 數(shù)據(jù)庫分庫分表

7 應(yīng)用分為不同的類型拆分

發(fā)展到這個(gè)階段的時(shí)候,我們發(fā)現(xiàn),應(yīng)用與應(yīng)用之間的關(guān)系已經(jīng)十分的復(fù)雜了,就會出現(xiàn)以下幾個(gè)問題(以下摘錄于官網(wǎng)):

① 當(dāng)服務(wù)越來越多時(shí),服務(wù) URL 配置管理變得非常困難,F(xiàn)5 硬件負(fù)載均衡器的單點(diǎn)壓力也越來越大。
② 當(dāng)進(jìn)一步發(fā)展,服務(wù)間依賴關(guān)系變得錯(cuò)蹤復(fù)雜,甚至分不清哪個(gè)應(yīng)用要在哪個(gè)應(yīng)用之前啟動,架構(gòu)師都不能完整的描述應(yīng)用的架構(gòu)關(guān)系。
③ 接著,服務(wù)的調(diào)用量越來越大,服務(wù)的容量問題就暴露出來,這個(gè)服務(wù)需要多少機(jī)器支撐?什么時(shí)候該加機(jī)器?

為了解決這由于架構(gòu)的演變所產(chǎn)生的問題幾個(gè)問題,于是,dubbo 產(chǎn)生了。當(dāng)然,解決這個(gè)問題的技術(shù)不止 dubbo 。

從上面 Dubbo 的服務(wù)治理圖我們就可以看到,Duboo 很好了解決了上面所出現(xiàn)的一些問題。

所以,當(dāng)你的系統(tǒng)架構(gòu)發(fā)展到了這種階段的時(shí)候,就需要考慮使用 Dubbo 了。

二 Dubbo 技術(shù)架構(gòu)

我們已經(jīng)非常清楚的知道為什么在我們的系統(tǒng)中需要 Dubbo 這項(xiàng)技術(shù)了,下面,我們接著嘮叨嘮叨 Dubbo 的架構(gòu)。

首先,上一張圖(摘自官網(wǎng))。

看到圖之后,可能你對上面的幾個(gè)概念還是一臉懵逼,無從下手,下面,帶你看看這幾個(gè)角色到底是什么意思?

節(jié)點(diǎn)角色說明

節(jié)點(diǎn) 角色說明
Provider 暴露服務(wù)的服務(wù)提供方
Consumer 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方
Registry 服務(wù)注冊與發(fā)現(xiàn)的注冊中心
Monitor 統(tǒng)計(jì)服務(wù)的調(diào)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心
Container 服務(wù)運(yùn)行容器

看了這幾個(gè)概念后似乎發(fā)現(xiàn),其實(shí) Dubbo 的架構(gòu)也是很簡單的(其實(shí)現(xiàn)細(xì)節(jié)是復(fù)雜的),為什么這么說呢,有沒有發(fā)現(xiàn),其實(shí)很像生產(chǎn)者-消費(fèi)者模型。只是在這種模型上,加上了注冊中心和監(jiān)控中心,用于管理提供方提供的url,以及管理整個(gè)過程。

那么,整個(gè)發(fā)布-訂閱的過程就非常的簡單了。

啟動容器,加載,運(yùn)行服務(wù)提供者

服務(wù)提供者在啟動時(shí),在注冊中心發(fā)布注冊自己提供的服務(wù)

服務(wù)消費(fèi)者在啟動時(shí),在注冊中心訂閱自己所需的服務(wù)

如果考慮失敗或變更的情況,就需要考慮下面的過程。

注冊中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費(fèi)者。

服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺調(diào)用。

服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。

通過這番講解,我相信 Dubbo 的架構(gòu)我們也輕車熟路了,那就直接入手,開車吧。

三 Dubbo 開始入門

終于走到這一步了,寫到這里停了大概一周的時(shí)間,主要原因還是最近項(xiàng)目太忙,趕著交差呢,今天希望能一鼓作氣,完完整整的寫完 dubbo 的基礎(chǔ)篇!

3.1 服務(wù)端

首先,我們先把服務(wù)端的接口寫好,因?yàn)槠鋵?shí) dubbo 的作用簡單來說就是給消費(fèi)端提供接口。

接口定義
/**
 * xml方式服務(wù)提供者接口
 */
public interface ProviderService {

    String SayHello(String word);
}

這個(gè)接口非常簡單,只是包含一個(gè) SayHello 的方法。

接著,定義它的實(shí)現(xiàn)類。

/**
 * xml方式服務(wù)提供者實(shí)現(xiàn)類
 */
public class ProviderServiceImpl implements ProviderService{

    public String SayHello(String word) {
        return word;
    }
}

這樣我們就把我們的接口寫好了,那么我們應(yīng)該怎么將我們的服務(wù)暴露出去呢?

導(dǎo)入 maven 依賴


    4.0.0

    com.ouyangsihai
    dubbo-provider
    1.0-SNAPSHOT

    
        
            junit
            junit
            3.8.1
            test
        
        
        
            com.alibaba
            dubbo
            2.6.6
        
        
            org.apache.zookeeper
            zookeeper
            3.4.10
        
        
            com.101tec
            zkclient
            0.5
        
        
            io.netty
            netty-all
            4.1.32.Final
        
        
            org.apache.curator
            curator-framework
            2.8.0
        
        
            org.apache.curator
            curator-recipes
            2.8.0
        

    

這里使用的 dubbo 的版本是 2.6.6 ,需要注意的是,如果你只導(dǎo)入 dubbo 的包的時(shí)候是會報(bào)錯(cuò)的,找不到 netty 和 curator 的依賴,所以,在這里我們需要把這兩個(gè)的依賴加上,就不會報(bào)錯(cuò)了。

另外,這里我們使用 zookeeper 作為注冊中心。

到目前為止,dubbo 需要的環(huán)境就已經(jīng)可以了,下面,我們就把上面剛剛定義的接口暴露出去。

暴露接口(xml 配置方法)

首先,我們在我們項(xiàng)目的 resource 目錄下創(chuàng)建 META-INF.spring 包,然后再創(chuàng)建 provider.xml 文件,名字可以任取哦,如下圖。




    
    
        
        
        
    

    

    
    
    

    
    

    
    

    
    

① 上面的文件其實(shí)就是類似 spring 的配置文件,而且,dubbo 底層就是 spring。
節(jié)點(diǎn):dubbo:application
就是整個(gè)項(xiàng)目在分布式架構(gòu)中的唯一名稱,可以在 name 屬性中配置,另外還可以配置 owner 字段,表示屬于誰。
下面的參數(shù)是可以不配置的,這里配置是因?yàn)槌霈F(xiàn)了端口的沖突,所以配置。
節(jié)點(diǎn):dubbo:monitor
監(jiān)控中心配置, 用于配置連接監(jiān)控中心相關(guān)信息,可以不配置,不是必須的參數(shù)。
節(jié)點(diǎn):dubbo:registry
配置注冊中心的信息,比如,這里我們可以配置 zookeeper 作為我們的注冊中心。address 是注冊中心的地址,這里我們配置的是 N/A 表示由 dubbo 自動分配地址。或者說是一種直連的方式,不通過注冊中心。
節(jié)點(diǎn):dubbo:protocol
服務(wù)發(fā)布的時(shí)候 dubbo 依賴什么協(xié)議,可以配置 dubbo、webserovice、Thrift、Hessain、http等協(xié)議。
節(jié)點(diǎn):dubbo:service
這個(gè)節(jié)點(diǎn)就是我們的重點(diǎn)了,當(dāng)我們服務(wù)發(fā)布的時(shí)候,我們就是通過這個(gè)配置將我們的服務(wù)發(fā)布出去的。interface 是接口的包路徑,ref 是第 ⑦ 點(diǎn)配置的接口的 bean。
⑦ 最后,我們需要像配置 spring 的接口一樣,配置接口的 bean。

到這一步,關(guān)于服務(wù)端的配置就完成了,下面我們通過 main 方法將接口發(fā)布出去。

發(fā)布接口
package com.sihai.dubbo.provider;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.alibaba.dubbo.container.Main;
import com.sihai.dubbo.provider.service.ProviderService;
import com.sihai.dubbo.provider.service.ProviderServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * xml方式啟動
 *
 */
public class App 
{
    public static void main( String[] args ) throws IOException {
        //加載xml配置文件啟動
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml");
        context.start();
        System.in.read(); // 按任意鍵退出
    }
}

發(fā)布接口非常簡單,因?yàn)?dubbo 底層就是依賴 spring 的,所以,我們只需要通過 ClassPathXmlApplicationContext 拿到我們剛剛配置好的 xml ,然后調(diào)用 context.start() 方法就啟動了。

看到下面的截圖,就算是啟動成功了,接口也就發(fā)布出去了。

你以為到這里就結(jié)束了了,并不是的,我們拿到 dubbo 暴露出去的 url分析分析。

dubbo 暴露的 url

dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService?anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider×tamp=1562077289380

分析

① 首先,在形式上我們發(fā)現(xiàn),其實(shí)這么牛逼的 dubbo 也是用類似于 http 的協(xié)議發(fā)布自己的服務(wù)的,只是這里我們用的是 dubbo 協(xié)議
dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService
上面這段鏈接就是 ? 之前的鏈接,構(gòu)成:協(xié)議://ip:端口/接口。發(fā)現(xiàn)是不是也沒有什么神秘的。
anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider×tamp=1562077289380
? 之后的字符串,分析后你發(fā)現(xiàn),這些都是剛剛在 provider.xml 中配置的字段,然后通過 & 拼接而成的,聞到了 http 的香味了嗎?

終于,dubbo 服務(wù)端入門了。下面我們看看拿到了 url 后,怎么消費(fèi)呢?

3.2 消費(fèi)端

上面提到,我們在服務(wù)端提供的只是點(diǎn)對點(diǎn)的方式提供服務(wù),并沒有使用注冊中心,所以,下面的配置也是會有一些不一樣的。

消費(fèi)端環(huán)境配置

首先,我們在消費(fèi)端的 resource 下建立配置文件 consumer.xml




    
    

    
    
    
    

    
    
    

    

分析

① 發(fā)現(xiàn)這里的 dubbo:applicationdubbo:registry 是一致的。
dubbo:reference :我們這里采用點(diǎn)對點(diǎn)的方式,所以,需要配置在服務(wù)端暴露的 url 。

maven 依賴

和服務(wù)端一樣



    4.0.0

    com.ouyangsihai
    dubbo-consumer
    1.0-SNAPSHOT

    
        
            com.ouyangsihai
            dubbo-provider
            1.0-SNAPSHOT
        
        
            junit
            junit
            3.8.1
            test
        
        
        
            com.alibaba
            dubbo
            2.6.6
        
        
            org.apache.zookeeper
            zookeeper
            3.4.10
        
        
            com.101tec
            zkclient
            0.5
        
        
            io.netty
            netty-all
            4.1.32.Final
        
        
            org.apache.curator
            curator-framework
            2.8.0
        
        
            org.apache.curator
            curator-recipes
            2.8.0
        
    
調(diào)用服務(wù)
package com.sihai.dubbo.consumer;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.sihai.dubbo.provider.service.ProviderService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * xml的方式調(diào)用
 *
 */
public class App 
{
    public static void main( String[] args ) throws IOException {

        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");
        context.start();
        ProviderService providerService = (ProviderService) context.getBean("providerService");
        String str = providerService.SayHello("hello");
        System.out.println(str);
        System.in.read();

    }
}

這里和服務(wù)端的發(fā)布如出一轍。


如此,我們就成功調(diào)用接口了。

四 加入 zookeeper 作為注冊中心

在前面的案例中,我們沒有使用任何的注冊中心,而是用一種直連的方式進(jìn)行的。但是,實(shí)際上很多時(shí)候,我們都是使用 dubbo + zookeeper 的方式,使用 zookeeper 作為注冊中心,這里,我們就介紹一下 zookeeper 作為注冊中心的使用方法。

這里,我們在前面的入門實(shí)例中進(jìn)行改造。

4.1 服務(wù)端

在服務(wù)端中,我們只需要修改 provider.xml 即可。




    
    
        
        
        
    

    

    
    
    

    
    

    
    

    
    

重點(diǎn)關(guān)注這句話

在 address 中,使用我們的 zookeeper 的地址。

如果是 zookeeper 集群的話,使用下面的方式。

服務(wù)端的配置就好了,其他的跟 入門案例 一樣。

4.2 消費(fèi)端

跟服務(wù)端一樣,在消費(fèi)端,我們也只需要修改 consumer.xml 即可。




    
    

    
    
    
    

    
    
    

    

① 注冊中心配置跟服務(wù)端一樣。

② dubbo:reference
由于我們這里使用 zookeeper 作為注冊中心,所以,跟點(diǎn)對點(diǎn)的方式是不一樣的,這里不再需要 dubbo 服務(wù)端提供的 url 了,只需要直接引用服務(wù)端提供的接口即可。

好了,消費(fèi)端也配置好了,這樣就可以使用修改的入門案例,重新啟動運(yùn)行了。

同樣成功了。

這時(shí)候的區(qū)別在于,將 dubbo 發(fā)布的 url 注冊到了 zookeeper,消費(fèi)端從 zookeeper 消費(fèi),zookeeper 相當(dāng)于一個(gè)中介,給消費(fèi)者提供服務(wù)。

你以為這就完了?不,好戲才剛剛開始呢。

五 多種配置方式

入門實(shí)例的時(shí)候,我們使用的是 xml 配置的方式,對 dubbo 的環(huán)境進(jìn)行了配置,但是,官方還提供了其他的配置方式,這里我們也一一分解。

5.1 API配置方式

這種方式其實(shí)官方是不太推薦的,官方推薦使用 xml 配置的方式,但是,在有的時(shí)候測試的時(shí)候,還是可以用的到的,另外,為了保證完整性,這些內(nèi)容還是有必要講講的。

首先還是回到服務(wù)端工程。

服務(wù)端

這里我們使用 api 的方式配置,所以,provider.xml 這個(gè)配置文件就暫時(shí)不需要了,我們只需要在上面的 AppApi 這個(gè)類中的 main 方法中用 api配置及啟動即可。

package com.sihai.dubbo.provider;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.sihai.dubbo.provider.service.ProviderService;
import com.sihai.dubbo.provider.service.ProviderServiceImpl;

import java.io.IOException;

/**
 * Api方式啟動
 * api的方式調(diào)用不需要其他的配置,只需要下面的代碼即可。
 * 但是需要注意,官方建議:
 * Api方式用于測試用例使用,推薦xml的方式
 */
public class AppApi
{
    public static void main( String[] args ) throws IOException {

        // 服務(wù)實(shí)現(xiàn)
        ProviderService providerService = new ProviderServiceImpl();

        // 當(dāng)前應(yīng)用配置
        ApplicationConfig application = new ApplicationConfig();
        application.setName("provider");
        application.setOwner("sihai");

        // 連接注冊中心配置
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress("zookeeper://localhost:2181");
//        registry.setUsername("aaa");
//        registry.setPassword("bbb");

        // 服務(wù)提供者協(xié)議配置
        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("dubbo");
        protocol.setPort(20880);
        //protocol.setThreads(200);

        // 注意:ServiceConfig為重對象,內(nèi)部封裝了與注冊中心的連接,以及開啟服務(wù)端口

        // 服務(wù)提供者暴露服務(wù)配置
        ServiceConfig service = new ServiceConfig(); // 此實(shí)例很重,封裝了與注冊中心的連接,請自行緩存,否則可能造成內(nèi)存和連接泄漏
        service.setApplication(application);
        service.setRegistry(registry); // 多個(gè)注冊中心可以用setRegistries()
        service.setProtocol(protocol); // 多個(gè)協(xié)議可以用setProtocols()
        service.setInterface(ProviderService.class);
        service.setRef(providerService);
        service.setVersion("1.0.0");

        // 暴露及注冊服務(wù)
        service.export();
    }
}

分析

看到上面的代碼是不是云里霧里,不要慌,我們通過對照 xml 的方式分析一下。

registry  的 xml 方式
API 的方式
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://localhost:2181");

dubbo:registry節(jié)點(diǎn)對應(yīng)RegistryConfig ,xml 的屬性對應(yīng) API 方式用 set 方法就可以了。對比之下,你就會發(fā)現(xiàn),如果 API 的方式不熟悉,可以對照 xml 配置方式就可以。

其他 API

org.apache.dubbo.config.ServiceConfig
org.apache.dubbo.config.ReferenceConfig
org.apache.dubbo.config.ProtocolConfig
org.apache.dubbo.config.RegistryConfig
org.apache.dubbo.config.MonitorConfig
org.apache.dubbo.config.ApplicationConfig
org.apache.dubbo.config.ModuleConfig
org.apache.dubbo.config.ProviderConfig
org.apache.dubbo.config.ConsumerConfig
org.apache.dubbo.config.MethodConfig
org.apache.dubbo.config.ArgumentConfig

更詳細(xì)的可以查看官方文檔:
http://dubbo.apache.org/zh-cn...

我們再看看我配置的消費(fèi)端的 Api 方式。

消費(fèi)端

同樣,我們不需要 consumer.xml 配置文件了,只需要在 main 方法中啟動即可。

package com.sihai.dubbo.consumer;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.sihai.dubbo.provider.service.ProviderService;

/**
 * api的方式調(diào)用
 * api的方式調(diào)用不需要其他的配置,只需要下面的代碼即可。
 * 但是需要注意,官方建議:
 * Api方式用于測試用例使用,推薦xml的方式
 */
public class AppApi {

    public static void main(String[] args) {
        // 當(dāng)前應(yīng)用配置
        ApplicationConfig application = new ApplicationConfig();
        application.setName("consumer");
        application.setOwner("sihai");

        // 連接注冊中心配置
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress("zookeeper://localhost:2181");

        // 注意:ReferenceConfig為重對象,內(nèi)部封裝了與注冊中心的連接,以及與服務(wù)提供方的連接

        // 引用遠(yuǎn)程服務(wù)
        ReferenceConfig reference = new ReferenceConfig(); // 此實(shí)例很重,封裝了與注冊中心的連接以及與提供者的連接,請自行緩存,否則可能造成內(nèi)存和連接泄漏
        reference.setApplication(application);
        reference.setRegistry(registry); // 多個(gè)注冊中心可以用setRegistries()
        reference.setInterface(ProviderService.class);

        // 和本地bean一樣使用xxxService
        ProviderService providerService = reference.get(); // 注意:此代理對象內(nèi)部封裝了所有通訊細(xì)節(jié),對象較重,請緩存復(fù)用
        providerService.SayHello("hello dubbo! I am sihai!");
    }
}

這部分的 API 配置的方式就到這了,注意:官方推薦 xml 的配置方法

5.2 注解配置方式

注解配置方式還是需要了解一下的,現(xiàn)在微服務(wù)都傾向于這種方式,這也是以后發(fā)展的趨勢,0 配置應(yīng)該是這幾年的趨勢。

那么如何對 dubbo 使用注解的方式呢?我們先看服務(wù)端。

服務(wù)端

第一步:定義接口及實(shí)現(xiàn)類,在上面的截圖中的 annotation 包下

package com.sihai.dubbo.provider.service.annotation;

/**
 * 注解方式接口
 */
public interface ProviderServiceAnnotation {
    String SayHelloAnnotation(String word);
}
package com.sihai.dubbo.provider.service.annotation;

import com.alibaba.dubbo.config.annotation.Service;

/**
 * 注解方式實(shí)現(xiàn)類
 */
@Service(timeout = 5000)
public class ProviderServiceImplAnnotation implements ProviderServiceAnnotation{

    public String SayHelloAnnotation(String word) {
        return word;
    }
}

@Service

@Service 用來配置 Dubbo 的服務(wù)提供方。

第二步:組裝服務(wù)提供方。通過 Spring 中 Java Config 的技術(shù)(@Configuration)和 annotation 掃描(@EnableDubbo)來發(fā)現(xiàn)、組裝、并向外提供 Dubbo 的服務(wù)。

package com.sihai.dubbo.provider.configuration;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 注解方式配置
 */
@Configuration
@EnableDubbo(scanBasePackages = "com.sihai.dubbo.provider.service.annotation")
public class DubboConfiguration {

    @Bean // #1 服務(wù)提供者信息配置
    public ProviderConfig providerConfig() {
        ProviderConfig providerConfig = new ProviderConfig();
        providerConfig.setTimeout(1000);
        return providerConfig;
    }

    @Bean // #2 分布式應(yīng)用信息配置
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-annotation-provider");
        return applicationConfig;
    }

    @Bean // #3 注冊中心信息配置
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("localhost");
        registryConfig.setPort(2181);
        return registryConfig;
    }

    @Bean // #4 使用協(xié)議配置,這里使用 dubbo
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        return protocolConfig;
    }
}

分析

通過 @EnableDubbo 指定在com.sihai.dubbo.provider.service.annotation 下掃描所有標(biāo)注有 @Service 的類

通過 @ConfigurationDubboConfiguration 中所有的 @Bean 通過 Java Config 的方式組裝出來并注入給 Dubbo 服務(wù),也就是標(biāo)注有 @Service 的類。這其中就包括了:

ProviderConfig:服務(wù)提供方配置

ApplicationConfig:應(yīng)用配置

RegistryConfig:注冊中心配置

ProtocolConfig:協(xié)議配置

看起來很復(fù)雜,其實(shí)。。。

第三步:啟動服務(wù)

package com.sihai.dubbo.provider;

import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
import com.sihai.dubbo.provider.configuration.DubboConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import sun.applet.Main;

import java.io.IOException;

/**
 * 注解啟動方式
 */
public class AppAnnotation {

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DubboConfiguration.class); 
        context.start();
        System.in.read(); 
    }
}

發(fā)現(xiàn)輸出下面信息就表示 success 了。

消費(fèi)端

同樣我們下看看消費(fèi)端的工程,有一個(gè)感性認(rèn)識。

第一步:引用服務(wù)

package com.sihai.dubbo.consumer.Annotation;

import com.alibaba.dubbo.config.annotation.Reference;
import com.sihai.dubbo.provider.service.annotation.ProviderServiceAnnotation;
import org.springframework.stereotype.Component;

/**
 * 注解方式的service
 */
@Component("annotatedConsumer")
public class ConsumerAnnotationService {

    @Reference
    private ProviderServiceAnnotation providerServiceAnnotation;

    public String doSayHello(String name) {
        return providerServiceAnnotation.SayHelloAnnotation(name);
    }
}

ConsumerAnnotationService 類中,通過 @Reference 引用服務(wù)端提供的類,然后通過方法調(diào)用這個(gè)類的方式,給消費(fèi)端提供接口。
注意:如果這里找不到 ProviderServiceAnnotation 類,請?jiān)诜?wù)端先把服務(wù)端工程用 Maven intall 一下,然后將服務(wù)端的依賴放到消費(fèi)端的 pom 中。如下:


          com.ouyangsihai
            dubbo-provider
            1.0-SNAPSHOT
        

第二步:組裝服務(wù)消費(fèi)者
這一步和服務(wù)端是類似的,這里就不在重復(fù)了。

package com.sihai.dubbo.consumer.configuration;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 注解配置類
 */
@Configuration
@EnableDubbo(scanBasePackages = "com.sihai.dubbo.consumer.Annotation")
@ComponentScan(value = {"com.sihai.dubbo.consumer.Annotation"})
public class ConsumerConfiguration {
    @Bean // 應(yīng)用配置
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-annotation-consumer");
        Map stringStringMap = new HashMap();
        stringStringMap.put("qos.enable","true");
        stringStringMap.put("qos.accept.foreign.ip","false");
        stringStringMap.put("qos.port","33333");
        applicationConfig.setParameters(stringStringMap);
        return applicationConfig;
    }

    @Bean // 服務(wù)消費(fèi)者配置
    public ConsumerConfig consumerConfig() {
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setTimeout(3000);
        return consumerConfig;
    }

    @Bean // 配置注冊中心
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("localhost");
        registryConfig.setPort(2181);
        return registryConfig;
    }
}

第三步:發(fā)起遠(yuǎn)程調(diào)用

main 方法中通過啟動一個(gè) Spring Context,從其中查找到組裝好的 Dubbo 的服務(wù)消費(fèi)者,并發(fā)起一次遠(yuǎn)程調(diào)用。

package com.sihai.dubbo.consumer;

import com.sihai.dubbo.consumer.Annotation.ConsumerAnnotationService;
import com.sihai.dubbo.consumer.configuration.ConsumerConfiguration;
import com.sihai.dubbo.provider.service.ProviderService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * 注解方式啟動
 *
 */
public class AppAnnotation
{
    public static void main( String[] args ) throws IOException {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); 
        context.start(); // 啟動
        ConsumerAnnotationService consumerAnnotationService = context.getBean(ConsumerAnnotationService.class); 
        String hello = consumerAnnotationService.doSayHello("annotation"); // 調(diào)用方法
        System.out.println("result: " + hello); // 輸出結(jié)果

    }
}

結(jié)果

六 常用場景

在下面的講解中,都會是以 xml 配置的方式來講解的,這也是 dubbo 官方比較推薦的方式。以下的操作都是在服務(wù)端的 xml 配置文件和消費(fèi)端的配置文件來講解的。

6.1 啟動時(shí)檢查

Dubbo 缺省會在啟動時(shí)檢查依賴的服務(wù)是否可用,不可用時(shí)會拋出異常,阻止 Spring 初始化完成,以便上線時(shí),能及早發(fā)現(xiàn)問題,默認(rèn) `check="true"。

但是,有的時(shí)候,我們并不是都需要啟動時(shí)就檢查的,比如測試的時(shí)候,我們是需要更快速的啟動,所以,這種場景的時(shí)候,我們是需要關(guān)閉這個(gè)功能的。

下面,我們看看如何使用這個(gè)功能。

在服務(wù)端注冊的時(shí)候(客戶端注冊時(shí)同樣適用);

在客戶端引用服務(wù)端服務(wù)的時(shí)候;

就是這么簡單,就是這么強(qiáng)!

6.2 集群容錯(cuò)

dubbo 也是支持集群容錯(cuò)的,同時(shí)也有很多可選的方案,其中,默認(rèn)的方案是 failover,也就是重試機(jī)制。

首先,我們先把所有的容錯(cuò)機(jī)制都整理一遍,然后再看看使用。

集群模式 說明 使用方法
Failover Cluster 失敗自動切換,當(dāng)出現(xiàn)失敗,重試其它服務(wù)器。通常用于讀操作,但重試會帶來更長延遲。可通過 retries="2" 來設(shè)置重試次數(shù)(不含第一次)。 cluster="xxx" xxx:集群模式名稱 ,例如cluster="failover"
Failfast Cluster 快速失敗,只發(fā)起一次調(diào)用,失敗立即報(bào)錯(cuò)。通常用于非冪等性的寫操作,比如新增記錄。
Failsafe Cluster 失敗安全,出現(xiàn)異常時(shí),直接忽略。
Failback Cluster 失敗自動恢復(fù),后臺記錄失敗請求,定時(shí)重發(fā)。通常用于消息通知操作。
Forking Cluster 并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回。通常用于實(shí)時(shí)性要求較高的讀操作,但需要浪費(fèi)更多服務(wù)資源。可通過 forks="2" 來設(shè)置最大并行數(shù)。
Broadcast Cluster 廣播調(diào)用所有提供者,逐個(gè)調(diào)用,任意一臺報(bào)錯(cuò)則報(bào)錯(cuò)。通常用于通知所有提供者更新緩存或日志等本地資源信息。

使用實(shí)例
在發(fā)布服務(wù)或者引用服務(wù)的時(shí)候設(shè)置


    
6.3 負(fù)載均衡

負(fù)載均衡想必是一個(gè)再熟悉不過的概念了,所以,dubbo 支持也是再正常不過了,這里也總結(jié)一下 dubbo 支持的負(fù)載均衡的一些方案及使用方法。

負(fù)載均衡模式 說明 使用方法
Random LoadBalance 隨機(jī) 按權(quán)重設(shè)置隨機(jī)概率 xxx:負(fù)載均衡方法
RoundRobin LoadBalance 輪詢 按公約后的權(quán)重設(shè)置輪詢比率。
LeastActive LoadBalance 最少活躍調(diào)用數(shù) 相同活躍數(shù)的隨機(jī),活躍數(shù)指調(diào)用前后計(jì)數(shù)差。
ConsistentHash LoadBalance 一致性 Hash 相同參數(shù)的請求總是發(fā)到同一提供者。 當(dāng)某一臺提供者掛時(shí),原本發(fā)往該提供者的請求,基于虛擬節(jié)點(diǎn),平攤到其它提供者,不會引起劇烈變動。
6.4 直連提供者

在開發(fā)及測試環(huán)境下,經(jīng)常需要繞過注冊中心,只測試指定服務(wù)提供者,所以,這種情況下,我們只需要直接連接服務(wù)端的地即可,其實(shí),這種方法在前面的講解已經(jīng)使用到了,第一種講解的方式就是這種方式,因?yàn)檫@種方式簡單。

使用

說明:可以看到,只要在消費(fèi)端在 dubbo:reference 節(jié)點(diǎn)使用 url 給出服務(wù)端的方法即可。

6.5 只訂閱

只訂閱就是只能夠訂閱服務(wù)端的服務(wù),而不能夠注冊。

引用官方的使用場景如下:

為方便開發(fā)測試,經(jīng)常會在線下共用一個(gè)所有服務(wù)可用的注冊中心,這時(shí),如果一個(gè)正在開發(fā)中的服務(wù)提供者注冊,可能會影響消費(fèi)者不能正常運(yùn)行。
可以讓服務(wù)提供者開發(fā)方,只訂閱服務(wù)(開發(fā)的服務(wù)可能依賴其它服務(wù)),而不注冊正在開發(fā)的服務(wù),通過直連測試正在開發(fā)的服務(wù)。

① 使用只訂閱方式

當(dāng)在服務(wù)提供端使用 register="false" 的時(shí)候,我們使用下面的方式獲取服務(wù)端的服務(wù);

啟動信息

發(fā)現(xiàn),這時(shí)候并不是向注冊中心 zookeeper 注冊,而只是做了發(fā)布服務(wù)和啟動netty

② 不使用只訂閱方式

啟動信息

可以發(fā)現(xiàn),這里就向注冊中心 zookeeper 注冊了。

6.6 只注冊

只注冊正好跟前面的只訂閱相反,這個(gè)時(shí)候可以向注冊中心注冊,但是,消費(fèi)端卻不能夠讀到服務(wù)。

應(yīng)用場景

如果有兩個(gè)鏡像環(huán)境,兩個(gè)注冊中心,有一個(gè)服務(wù)只在其中一個(gè)注冊中心有部署,另一個(gè)注冊中心還沒來得及部署,而兩個(gè)注冊中心的其它應(yīng)用都需要依賴此服務(wù)。這個(gè)時(shí)候,可以讓服務(wù)提供者方只注冊服務(wù)到另一注冊中心,而不從另一注冊中心訂閱服務(wù)。

使用說明

在服務(wù)端的 dubbo:registry 節(jié)點(diǎn)下使用 subscribe="false" 來聲明這個(gè)服務(wù)是只注冊的服務(wù)。

這個(gè)時(shí)候消費(fèi)端調(diào)用的時(shí)候是不能調(diào)用的。

6.7 多協(xié)議機(jī)制

在前面我們使用的協(xié)議都是 dubbo 協(xié)議,但是 dubbo 除了支持這種協(xié)議外還支持其他的協(xié)議,比如,rmi、hessian等,另外,而且還可以用多種協(xié)議同時(shí)暴露一種服務(wù)。

使用方法

① 一種接口使用一種協(xié)議

先聲明多種協(xié)議

 
    
    

然后在發(fā)布接口的時(shí)候使用具體協(xié)議


    
    

在輸出日志中,就可以找到rmi發(fā)布的接口。

rmi://192.168.234.1:1099/com.sihai.dubbo.provider.service.ProviderService?anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&cluster=failover&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=796&retries=2&side=provider×tamp=1564281053185, dubbo version: 2.6.6, current host: 192.168.234.1

② 一種接口使用多種協(xié)議
聲明協(xié)議和上面的方式一樣,在發(fā)布接口的時(shí)候有一點(diǎn)不一樣。

說明:protocol屬性,可以用,隔開,使用多種協(xié)議。

6.8 多注冊中心

Dubbo 支持同一服務(wù)向多注冊中心同時(shí)注冊,或者不同服務(wù)分別注冊到不同的注冊中心上去,甚至可以同時(shí)引用注冊在不同注冊中心上的同名服務(wù)。

服務(wù)端多注冊中心發(fā)布服務(wù)

一個(gè)服務(wù)可以在不同的注冊中心注冊,當(dāng)一個(gè)注冊中心出現(xiàn)問題時(shí),可以用其他的注冊中心。

注冊


    
    
    

發(fā)布服務(wù)


    
    

說明:使用registry="reg2"指定該接口使用的注冊中心,同時(shí)也可以使用多個(gè),用隔開,例如,registry="reg1,,reg2"

消費(fèi)端多注冊中心引用服務(wù)

首先,先向不同注冊中心注冊;


    
    
    

其次,不同的消費(fèi)端服務(wù)引用使用不同的注冊中心;

!--不同的服務(wù)使用不同的注冊中心-->
    
    

說明:上面分別使用注冊中心1和注冊中心2。

6.9 多版本

不同的服務(wù)是有版本不同的,版本可以更新并且升級,同時(shí),不同的版本之間是不可以調(diào)用的。


    
    

加入了版本控制。

6.10 日志管理

dubbo 也可以將日志信息記錄或者保存到文件中的。

① 使用accesslog輸出到log4j


    

② 輸出到文件


    
七 總結(jié)

這篇文章就到這里了,主要講了一下幾個(gè)內(nèi)容
1、為什么需要dubbo
2、dubbo架構(gòu)簡析
3、dubbo入門
4、zookeeper注冊中心加入dubbo
5、dubbo多種配置方式(xml、api、注解)
6、常用場景介紹
下一篇文章,將講講源碼分析。

文章有不當(dāng)之處,歡迎指正,如果喜歡微信閱讀,你也可以關(guān)注我的微信公眾號好好學(xué)java,獲取優(yōu)質(zhì)學(xué)習(xí)資源。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/75620.html

相關(guān)文章

  • 入門機(jī)器學(xué)習(xí),看這些材料夠了

    摘要:作者微信號微信公眾號博客地址現(xiàn)在網(wǎng)上有很多的機(jī)器學(xué)習(xí)材料,讓人一下子看不過來。在我看來,多種類型的文件學(xué)習(xí)對自己是由幫助的。作者微信號博客地址是一個(gè)專注于算法實(shí)戰(zhàn)的平臺,從基礎(chǔ)的算法到人工智能算法都有設(shè)計(jì)。 作者:chen_h微信號 & QQ:862251340微信公眾號:coderpai博客地址:http://www.jianshu.com/p/5084... showImg(htt...

    whatsns 評論0 收藏0
  • 【推薦】最新200篇:技術(shù)文章整理

    摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語言和等其他語言的對比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語言和Java、python等其他語言的對比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...

    BicycleWarrior 評論0 收藏0
  • 【推薦】最新200篇:技術(shù)文章整理

    摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語言和等其他語言的對比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語言和Java、python等其他語言的對比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...

    tommego 評論0 收藏0
  • 份最中肯的Java學(xué)習(xí)路線+資源分享(拒絕傻逼式分享)

    摘要:因?yàn)槟承┰颍环奖阍谶@里直接發(fā)送百度鏈接,關(guān)注我的微信公眾號面試通關(guān)手冊回復(fù)資源分享第一波即可領(lǐng)取。然后大家還有什么問題的話,可以在我的微信公眾號后臺面試通關(guān)手冊給我說或者加我微信,我會根據(jù)自己的學(xué)習(xí)經(jīng)驗(yàn)給了說一下自己的看法。 這是一篇針對Java初學(xué)者,或者說在Java學(xué)習(xí)路線上出了一些問題(不知道該學(xué)什么、不知道整體的學(xué)習(xí)路線是什么樣的) 第一步:Java基礎(chǔ)(一個(gè)月左右) 推薦...

    hearaway 評論0 收藏0

發(fā)表評論

0條評論

tomener

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<