下載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用於監視各種事件的變化。