redis作爲註冊中心

下載dubbo源碼

dubbo可以讓redis作爲註冊中心。

從github上下載dubbo源碼。

找到dubbo-registry模塊下的dubbo-registry-redis。裏面的RedisRegistry類是redis作爲註冊中心的核心邏輯:

     //獲得Redis主節點名稱
        String masterName = url.getParameter(REDIS_MASTER_NAME_KEY);
        if (StringUtils.isEmpty(masterName)) {
            //單機版redis
            for (String address : addresses) {
                int i = address.indexOf(':');
                String host;
                int port;
                if (i > 0) {
                    host = address.substring(0, i);
                    port = Integer.parseInt(address.substring(i + 1));
                } else {
                    host = address;
                    port = DEFAULT_REDIS_PORT;
                }
                this.jedisPools.put(address, new JedisPool(config, host, port,
                        url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), StringUtils.isEmpty(url.getPassword()) ? null : url.getPassword(),
                        url.getParameter("db.index", 0)));
            }
        } 

它默認的端口號就是6379。

修改demo

我們找到dubbo-demo下的dubbo-demo-xml

它默認是用zookeeper作爲註冊中心的。

我們將dubbo-provider.xml修改爲:

  <dubbo:application metadata-type="remote" name="demo-provider"/>

    <dubbo:metadata-report address="redis://localhost:6379"/>


    <dubbo:registry protocol="redis" address="localhost:6379" />

    <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>

    <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>

此時的協議是redis協議。

同樣的,把dubbo-consumer.xml修改爲:

 <dubbo:application name="demo-consumer"/>
    <dubbo:metadata-report address="redis://localhost:6379"/>

    <dubbo:registry protocol="redis" address="localhost:6379" />

    <dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.demo.DemoService"/>

並且在上面consumer和provider兩個子模塊的pom文件中都導入:

    <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-metadata-report-redis</artifactId>
        </dependency>

源碼默認是沒有redis註冊中心依賴和redis數據元依賴的。

導進來後要reimport項目,否則不能生效。


運行

運行provider。

此時redis中就有provider了:

它的元數據:

{
    "parameters":{
        "side":"provider",
        "release":"",
        "methods":"sayHello,sayHelloAsync",
        "deprecated":"false",
        "qos.port":"22222",
        "dubbo":"2.0.2",
        "interface":"org.apache.dubbo.demo.DemoService",
        "generic":"false",
        "default":"true",
        "metadata-type":"remote",
        "application":"demo-provider",
        "dynamic":"true",
        "anyhost":"true"
    },
    "canonicalName":"org.apache.dubbo.demo.DemoService",
    "codeSource":"file:/Users/aruyi/IdeaProjects/dubbo-master/dubbo-demo/dubbo-demo-interface/target/classes/",
    "methods":[
        {
            "name":"sayHello",
            "parameterTypes":[
                "java.lang.String"
            ],
            "returnType":"java.lang.String"
        },
        {
            "name":"sayHelloAsync",
            "parameterTypes":[
                "java.lang.String"
            ],
            "returnType":"java.util.concurrent.CompletableFuture"
        }
    ],
    "types":[
        {
            "type":"int",
            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
        },
        {
            "type":"java.lang.Object",
            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
        },
        {
            "type":"byte",
            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
        },
        {
            "type":"java.util.concurrent.CompletableFuture$Completion",
            "properties":{
                "next":{
                    "type":"java.util.concurrent.CompletableFuture$Completion",
                    "$ref":"java.util.concurrent.CompletableFuture$Completion",
                    "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
                },
                "status":{
                    "type":"int",
                    "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
                }
            },
            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
        },
        {
            "type":"java.lang.String",
            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
        },
        {
            "type":"java.util.concurrent.CompletableFuture",
            "properties":{
                "result":{
                    "type":"java.lang.Object",
                    "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
                },
                "stack":{
                    "type":"java.util.concurrent.CompletableFuture$Completion",
                    "properties":{
                        "next":{
                            "type":"java.util.concurrent.CompletableFuture$Completion",
                            "$ref":"java.util.concurrent.CompletableFuture$Completion",
                            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
                        },
                        "status":{
                            "type":"int",
                            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
                        }
                    },
                    "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
                }
            },
            "typeBuilderName":"org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder"
        }
    ]
}

運行consumer:

public class Application {
    /**
     * In order to make sure multicast registry works, need to specify '-Djava.net.preferIPv4Stack=true' before
     * launch the application
     */
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
        context.start();
        DemoService demoService = context.getBean("demoService", DemoService.class);
        System.err.println(demoService.sayHello("ocean"));
        CompletableFuture<String> hello = demoService.sayHelloAsync("world");
        System.err.println("result: " + hello.get());
    }
}

控制檯上,它成功調用了遠程的方法:

在這裏插入圖片描述

我們也可以看到redis中有consumer的註冊。

它的元數據:

{
    "init":"false",
    "side":"consumer",
    "metadatatype":"remote",
    "application":"demo-consumer",
    "release":"",
    "methods":"sayHello,sayHelloAsync",
    "qos.port":"33333",
    "sticky":"false",
    "dubbo":"2.0.2",
    "check":"false",
    "interface":"org.apache.dubbo.demo.DemoService"
}

原理

這是官網的截圖。

可以看到,它是基於redis的事件發佈和訂閱的。monitor用於監視各種事件的變化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章