概述
Dubbo是阿里巴巴SOA服務化治理方案的核心框架,每天爲2,000+個服務提供3,000,000,000+次訪問量支持,並被廣泛應用於阿里巴巴集團的各成員站點,自開源後,已有不少非阿里系公司在使用Dubbo,所以我也得學習學習。
那麼,Dubbo是什麼?
隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用框架已無法應對,分佈式服務框架以及流動計算架構勢在必行。
單一應用架構
● 當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。
● 此時,用於簡化增刪改查工作量的 數據訪問框架(ORM) 是關鍵。
垂直應用架構
● 當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。
● 此時,用於加速前端頁面開發的 Web框架(MVC) 是關鍵。
分佈式服務架構
● 當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務 中心,使前端應用能更快速的響應多變的市場需求。
● 此時,用於提高業務複用及整合的 分佈式服務框架(RPC) 是關鍵。
流動計算架構
● 當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實 時管理集羣容量,提高集羣利用率。
● 此時,用於提高機器利用率的 資源調度和治理中心(SOA) 是關鍵。
Dubbo |ˈdʌbəʊ| 是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。 其核心部分包含:
● 遠程通訊: 提供對多種基於長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。
● 集羣容錯: 提供基於接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集羣支持
● 自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
Dubbo能做什麼?
● 透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
● 軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
● 服務自動註冊與發現,不再需要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的IP地址,並且能夠平滑添加或刪除服務提供者。
Dubbo Hello World
概述是照抄官網,代碼當然也是官網的了,照着官方提供的 dubbo-demo 敲了一遍(https://github.com/alibaba/dubbo)
準備工作:idea+maven+jdk
1.創建maven項目(父項目)
添加依賴 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>dubbo-hello-server</module>
<module>dubbo-hello-consumer</module>
<module>dubbo-hello-provider</module>
</modules>
<groupId>priv.starfish</groupId>
<artifactId>testDubbo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>testDubbo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
</dependencies>
<build>
<finalName>testDubbo</finalName>
</build>
</project>
2.創建子項目(模塊)
(和創建普通的maven項目一樣一樣的,
dubbo-hello-server:中間件,遠程服務接口,也可以寫到生產者模塊中;
dubbo-hello-provider:生產者,provider發佈遠程服務到註冊中心;
dubbo-hello-consumer:消費者,consumer自動發現遠程服務並完成服務調用)
項目的層次結構是介個樣子的
3.開始附代碼:
dubbo-hello-server模塊:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>testDubbo</artifactId>
<groupId>priv.starfish</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>dubbo-hello-server</artifactId>
<!-- 這是幹嘛的 不懂-->
<properties>
<skip_maven_deploy>true</skip_maven_deploy>
</properties>
</project>
HelloService(定義服務接口)
package priv.starfish.dubbo.hello;
/**
* Created by starfish on 2017/9/5.
*/
public interface HelloService {
String sayHello(String name);
}
dubbo-hello-provider模塊:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>testDubbo</artifactId>
<groupId>priv.starfish</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-hello-provider</artifactId>
<dependencies>
<dependency>
<groupId>priv.starfish</groupId>
<artifactId>dubbo-hello-server</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
HelloServiceImpl(在服務提供方實現接口)
package priv.starfish.dubbo.hello;
/**
* Created by starfish on 2017/9/5.
*/
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
System.out.println("Hello Provider-----"+name);
name = "starfish begin dubbo hello"+name;
return name;
}
}
Provider(加載Spring配置)
package priv.starfish.dubbo.hello;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by starfish on 2017/7/31.
*/
public class Provider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-hello-provider.xml"});
context.start();
System.in.read(); // 按任意鍵退出
}
}
dubbo-hello-provider.xml(用 Spring 配置聲明暴露服務)
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方應用信息,用於計算依賴關係 -->
<dubbo:application name="dubbo-hello-provider"/>
<!-- 使用multicast廣播註冊中心暴露服務地址 -->
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<!-- zookeeper註冊中心 -->
<!-- <dubbo:registry address="zookeeper://127.0.0.1:2181" />-->
<!-- 用dubbo協議在20880端口暴露服務 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- 聲明需要暴露的服務接口 -->
<bean id="helloService" class="priv.starfish.dubbo.hello.HelloServiceImpl"/>
<!-- 和本地bean一樣實現服務 -->
<dubbo:service interface="priv.starfish.dubbo.hello.HelloService" ref="helloService"/>
</beans>
dubbo-hello-consumer模塊:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>testDubbo</artifactId>
<groupId>priv.starfish</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-hello-consumer</artifactId>
<dependencies>
<dependency>
<groupId>priv.starfish</groupId>
<artifactId>dubbo-hello-server</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Consumer(加載Spring配置,並調用遠程服務,可以用IOC注入)
package priv.starfish.dubbo.hello;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by starfish on 2017/9/5.
*/
public class Consumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-hello-consumer.xml"});
context.start();
HelloService helloService = (HelloService) context.getBean("helloService"); // 獲取遠程服務代理
String hello = helloService.sayHello("world"); // 執行遠程方法
System.out.println(hello); // 顯示調用結果
}
}
dubbo-hello-consumer.xml(通過Spring配置引用遠程服務)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方一樣 -->
<dubbo:application name="dubbo-hello-consumer"/>
<!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<!-- 使用 zookeeper 廣播註冊中心暴露發現服務地址 -->
<!--<dubbo:registry address="zookeeper://127.0.0.1:2181" />-->
<!-- 生成遠程服務代理,可以和本地bean一樣使用helloService -->
<dubbo:reference id="helloService" check="false" interface="priv.starfish.dubbo.hello.HelloService"/>
</beans>
4.運行:
先啓動生產方,再啓動消費方(運行provider的main方法後,再運行consumer的main方法,哦了)