原文鏈接:http://www.2cto.com/kf/201606/515503.html
隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大弄唧,常規(guī)的垂直應(yīng)用架構(gòu)已無法應(yīng)對,分布式服務(wù)架構(gòu)以及流動計算架構(gòu)勢在必行,亟需一個治理系統(tǒng)確保架構(gòu)有條不紊的演進(jìn)疙教。其中阿里的dubbo就是一款分布式服務(wù)框架,致力于提供高性能和透明化的RPC遠(yuǎn)程服務(wù)調(diào)用方案。
一伞租、Dubbo簡介
1.1 背景與需求
隨著互聯(lián)網(wǎng)的發(fā)展贞谓,上網(wǎng)的人越來越多。加之移動互聯(lián)的普及葵诈,更加快了互聯(lián)網(wǎng)的腳步裸弦。隨之而來的,便是對網(wǎng)站應(yīng)用的強(qiáng)大挑戰(zhàn)作喘,和飛速的成長理疙。下面我們就簡單總結(jié)一下網(wǎng)站系統(tǒng)的成長史。
單一應(yīng)用框架
當(dāng)網(wǎng)站流量很小時泞坦,只需一個應(yīng)用窖贤,將所有的功能都不熟在一起,以減少不熟節(jié)點和成本贰锁。 此時主之,用于監(jiān)護(hù)增刪改查工作量的數(shù)據(jù)訪問框架(ORM)是關(guān)鍵。 垂直應(yīng)用框架
當(dāng)訪問量逐漸增大李根,單一應(yīng)用增加機(jī)器帶來的加速度越來越小槽奕,將應(yīng)用拆成互不相干的幾個應(yīng)用,以提升效率房轿。 此時粤攒,用于加速前端頁面開發(fā)的 Web框架(MVC) 是關(guān)鍵所森。 分布式服務(wù)架構(gòu)
當(dāng)垂直應(yīng)用越來越多,應(yīng)用之間交互不可避免夯接,將核心業(yè)務(wù)抽取出來焕济,作為獨立的服務(wù),逐漸形成穩(wěn)定的服務(wù)中心盔几,使前端應(yīng)用能更快速的響應(yīng)多變的市場需求晴弃。 此時,用于提高業(yè)務(wù)復(fù)用及整合的 分布式服務(wù)框架(RPC) 是關(guān)鍵逊拍。 流動計算架構(gòu)
當(dāng)服務(wù)越來越多上鞠,容量的評估,小服務(wù)資源的浪費等問題逐漸顯現(xiàn)芯丧,此時需增加一個調(diào)度中心基于訪問壓力實時管理集群容量芍阎,提高集群利用率。 此時缨恒,用于提高機(jī)器利用率的 資源調(diào)度和治理中心(SOA) 是關(guān)鍵谴咸。
1.2 什么是Dubbo
Dubbo是阿里巴巴公司開源的一個高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過高性能的 RPC 實現(xiàn)服務(wù)的輸出和輸入功能骗露,可以和 Spring框架無縫集成岭佳。
主要核心部件有:
1. Remoting: 網(wǎng)絡(luò)通信框架,實現(xiàn)了 sync-over-async 和 request-response 消息機(jī)制.
2. RPC: 一個遠(yuǎn)程過程調(diào)用的抽象萧锉,支持負(fù)載均衡珊随、容災(zāi)和集群功能
3. Registry: 服務(wù)目錄框架用于服務(wù)的注冊和服務(wù)事件發(fā)布和訂閱.
1.3 Dubbo架構(gòu)
節(jié)點角色說明:
Provider: 暴露服務(wù)的服務(wù)提供方。 Consumer:調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費方驹暑。 Registry:服務(wù)注冊與發(fā)現(xiàn)的注冊中心。 Monitor:統(tǒng)計服務(wù)的調(diào)用次調(diào)和調(diào)用時間的監(jiān)控中心辨赐。 Container:服務(wù)運(yùn)行容器优俘。
調(diào)用關(guān)系說明:
服務(wù)容器負(fù)責(zé)啟動,加載掀序,運(yùn)行服務(wù)提供者帆焕。 服務(wù)提供者在啟動時,向注冊中心注冊自己提供的服務(wù)不恭。 服務(wù)消費者在啟動時叶雹,向注冊中心訂閱自己所需的服務(wù)。 注冊中心返回服務(wù)提供者地址列表給消費者换吧,如果有變更折晦,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者。 服務(wù)消費者沾瓦,從提供者地址列表中满着,基于軟負(fù)載均衡算法谦炒,選一臺提供者進(jìn)行調(diào)用,如果調(diào)用失敗风喇,再選另一臺調(diào)用宁改。 服務(wù)消費者和提供者,在內(nèi)存中累計調(diào)用次數(shù)和調(diào)用時間魂莫,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心还蹲。
二、Dubbo的簡單使用
2.1 準(zhǔn)備工作
使用maven配置dubbo
1
2
3
4
5
<code
class
=
"hljs xml"
><dependency>
????
<groupid>com.alibaba</groupid>?
????
dubbo</artifactid>
????
<version>
2.4
.
10
</version>
</dependency></code>
2.1 服務(wù)提供端(provider)
第一步:配置provider.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code
class
=
"hljs xml"
><!--?xml version=
"1.0"
encoding=
"UTF-8"
?-->
<beans xmlns=
"http://www.springframework.org/schema/beans"
xsi:schemalocation=
"http://www.springframework.org/schema/beans???????
??? http://www.springframework.org/schema/beans/spring-beans.xsd???????
??? http://code.alibabatech.com/schema/dubbo???????
??? http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=
"http://code.alibabatech.com/schema/dubbo"
>
????
<!-- 提供方應(yīng)用信息耙考,用于計算依賴關(guān)系 -->
????
<dubbo:application name=
"hello-world-app"
>
????
<!-- 使用multicast廣播注冊中心暴露服務(wù)地址 -->
????
<!-- 用dubbo協(xié)議在
20880
端口暴露服務(wù) -->
????
<dubbo:protocol name=
"dubbo"
port=
"20880"
>
????
<!-- 聲明需要暴露的服務(wù)接口 -->
????
<dubbo:service ref=
"demoService"
interface
=
"com.xiaocao.mydubbo.DemoService"
>
????
<!-- 和本地bean一樣實現(xiàn)服務(wù) -->
????
<bean
class
=
"com.xiaocao.mydubbo.impl.DemoServiceImpl"
id=
"demoService"
>
</bean></dubbo:service></dubbo:protocol></dubbo:registry></dubbo:application></beans></code>
第二步:設(shè)計接口與實現(xiàn)類
接口:
1
2
3
4
<code
class
=
"hljs cs"
>
package
com.xiaocao.mydubbo;
public
interface
DemoService {
????
public
String sayHello(String name);
}</code>
實現(xiàn)類:
<code
class
=
"hljs java"
>
package
com.xiaocao.mydubbo.impl;
import
com.xiaocao.mydubbo.DemoService;
public
class
DemoServiceImpl
implements
DemoService{
????
@Override
????
public
String sayHello(String name) {
????????
return
"hello"
+ name;
????
}
}
</code>
2.2 服務(wù)使用端(consumer)
第一步:配置consumer.xml
<code
class
=
"hljs xml"
><!--?xml version=
"1.0"
encoding=
"UTF-8"
?-->
<beans xmlns=
"http://www.springframework.org/schema/beans"
xsi:schemalocation=
"http://www.springframework.org/schema/beans???????
??? http://www.springframework.org/schema/beans/spring-beans.xsd???????
??? http://code.alibabatech.com/schema/dubbo???????
??? http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=
"http://code.alibabatech.com/schema/dubbo"
>
?????
<!-- 消費方應(yīng)用名谜喊,用于計算依賴關(guān)系,不是匹配條件琳骡,不要與提供方一樣 -->
????
<dubbo:application name=
"consumer-of-helloworld-app"
>
????
<!-- 使用multicast廣播注冊中心暴露發(fā)現(xiàn)服務(wù)地址 -->
????
<!-- 生成遠(yuǎn)程服務(wù)代理锅论,可以和本地bean一樣使用demoService -->
????
<dubbo:reference id=
"demoService"
interface
=
"com.xiaocao.mydubbo.DemoService"
>
</dubbo:reference></dubbo:registry></dubbo:application></beans></code>
第二步:將provider的接口生成jar包引入,或者之際拷貝到consumer項目(包名必須一樣)
2.3 測試
privider端:
<code
class
=
"hljs java"
>
package
com.xiaocao.mydubbo.main;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public
class
Provider {
????
public
static
void
main(String[] args)
throws
Exception {
????????
ClassPathXmlApplicationContext context =
new
ClassPathXmlApplicationContext(
new
String[] {
"provider.xml"
});
????????
context.start();
????????
System.in.read();
// 按任意鍵退出
????
}
}</code>
consumer端:
<code
class
=
"hljs avrasm"
>
package
com.xiaocao.mydubbo.main;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import
com.xiaocao.mydubbo.DemoService;
public
class
Consumer {
????
public
static
void
main(String[] args)
throws
Exception {
????????
ClassPathXmlApplicationContext context =
new
ClassPathXmlApplicationContext(
new
String[] {
"consumer.xml"
});
????????
context.start();
????????
DemoService demoService = (DemoService)context.getBean(
"demoService"
);
// 獲取遠(yuǎn)程服務(wù)代理
????????
String hello = demoService.sayHello(
"? dubbo "
);
// 執(zhí)行遠(yuǎn)程方法
????????
context.close();
????????
System.out.println(hello);
????
}
}</code>
結(jié)果:
三楣号、Dubbo與SSM框架整合實現(xiàn)分布式系統(tǒng)
整合的話需要注意兩個問題:
1. 使用spring的時候最易,他總是加載不了dubbo下的xsd文件,而是去http://code.alibabatech.com/schema/dubbo/dubbo.xsd下載炫狱。而阿里的網(wǎng)站已經(jīng)停了好幾個月了藻懒,所以命名空間不能使用,需要手動配置视译。
解決辦法:取下載好的dubbo的jar包META-INF下的xsd文件嬉荆,配置到eclipse的xml配置中
2. Dubbo缺省依賴以下三方庫:
我們在使用mybatis與spring整合的時候,使用spring至少是3.0版本酷含。而Dubbo引用的是2.*版本鄙早。會引起版本沖突。
解決辦法:修改pom文件中的dubbo<?喎?"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjwvYmxvY2txdW90ZT4NCjxwcmUgY2xhc3M9"brush:java;">com.alibaba???? dubbo???? ${dubbo.version}???? org.springframework???????????? spring???????????? 4.1.2???????? ????
整合步驟一:在web.xml配置加載provider.xml
使用spring容器加載寫好的provider.xml文件
12345678<code
class
=
"hljs xml"
><!-- 初始化spring容器 -->
????
<context-param>
????????
<param-name>contextConfigLocation</param-name>
????????
<param-value>classpath:spring/applicationContext-*.xml</param-value>
????
</context-param>
????
<listener>
????????
<listener-
class
>org.springframework.web.context.ContextLoaderListener</listener-
class
>
????
</listener></code>
注:我的provider配置文件命名的是applicationContext-privider.xml
整合步驟二:共享接口文件
整合步驟三:在consumer端使用Ioc注解椅亚,像本地一樣調(diào)用即可
四限番、感想
dubbo其實是使用配置文件的方式包裝了RPC遠(yuǎn)程過程調(diào)用,而RPC的底層實現(xiàn)呀舔,其實是使用了動態(tài)代理和Socket通信弥虐。所以乍一看dubbo的功能很神奇,可以讓使用本地方法一樣實現(xiàn)遠(yuǎn)程調(diào)用媚赖,其實內(nèi)在的機(jī)制只是簡單的技術(shù)進(jìn)行組合霜瘪。
總結(jié):我們在學(xué)習(xí)的過程中,總是會聽到前輩們給我們強(qiáng)調(diào)基礎(chǔ)的重要性惧磺。這確實是很簡單但是很重要的真理颖对。技術(shù)不斷的推陳出新,我們只是學(xué)習(xí)使用技術(shù)是永遠(yuǎn)趕不上的磨隘,更別說有所創(chuàng)新和發(fā)展了惜互。其實新技術(shù)的產(chǎn)生布讹,往往都是一些你我都知道的技術(shù)經(jīng)過重新組合而產(chǎn)生的,只要我們能理解了基本的技術(shù)和知識训堆,應(yīng)對任何新技術(shù)的產(chǎn)生都能很快的理解和應(yīng)用描验。
再說一遍我之前博客說過的話吧:技術(shù)其實就在那里,多不多少不少坑鱼,只要我們思維足夠開闊膘流,就能夠把一些簡單的技術(shù)組合成一種讓人耳目一新的技術(shù)。而在中國其實從不缺乏技術(shù)人才鲁沥,而是缺乏技術(shù)的想象力呼股,只有我們將已有的技術(shù)進(jìn)行大膽的想象和組合,就能讓我們的技術(shù)流行起來画恰,讓別人追趕我們的思維彭谁,而不是我們一直再用雙手追趕別人的思維,這樣是永遠(yuǎn)趕不上的允扇。