Dubbo源码-从HelloWorld开始
Dubbo簡(jiǎn)介
Dubbo,相信做后端的同學(xué)應(yīng)該都用過(guò),或者有所耳聞。沒(méi)錯(cuò),我就是那個(gè)有所耳聞中的一員。
公司在好幾年前實(shí)現(xiàn)了一套自己的RPC框架,所以也就沒(méi)有機(jī)會(huì)使用市面上琳瑯滿目的RPC框架產(chǎn)品。
之所以想好好看看Dubbo,有以下幾個(gè)原因
公司內(nèi)部的框架一直在做迭代更新,配置越來(lái)越簡(jiǎn)潔,性能越來(lái)越好。但是作為使用者,它就像一個(gè)黑盒子,我們無(wú)法感知其內(nèi)部的改動(dòng)以及實(shí)現(xiàn)的原理
現(xiàn)在使用的框架,因?yàn)槭褂昧藅hrift,讓平時(shí)的開(kāi)發(fā)顯得格外的蹩腳,常常在各種model的轉(zhuǎn)換中迷失自我,耗盡了耐心
阿里團(tuán)隊(duì)從去年開(kāi)始重新維護(hù)Dubbo,并在春節(jié)之際進(jìn)入Apache孵化器,在開(kāi)源的道路上又猛跨一大步,其背后定然有我們值得學(xué)習(xí)借鑒的地方,更何況有阿里技術(shù)的背書
開(kāi)源項(xiàng)目是很好的學(xué)習(xí)素材,希望借助學(xué)習(xí)Dubbo代碼,了解序列化、分布式、網(wǎng)絡(luò)通訊等方面的知識(shí)
Dubbo是Alibaba開(kāi)源的分布式服務(wù)框架,它最大的特點(diǎn)是按照分層的方式來(lái)架構(gòu),使用這種方式可以使各個(gè)層之間解耦合(或者最大限度地松耦合)。
GitHub:https://github.com/apache/incubator-dubbo
官網(wǎng):http://dubbo.apache.org/
中文用戶手冊(cè):http://dubbo.io/books/dubbo-user-book/
HelloWorld之前的兩個(gè)小問(wèn)題
1.沒(méi)有Dubbo之前,我們是什么樣的工作方式
Dubbo代表的是一類RPC框架,類似的產(chǎn)品還有鼎鼎大名的gRPC。
沒(méi)有Dubbo之前是什么樣的,可以回想下我們學(xué)生時(shí)代做的項(xiàng)目。
一臺(tái)電腦既是服務(wù)器又是客戶端,估計(jì)當(dāng)時(shí)也沒(méi)有想過(guò)我調(diào)用的這個(gè)接口是哪臺(tái)電腦上,我是不是可以多部署幾臺(tái)電腦,怎么樣充分利用這幾臺(tái)電腦好讓調(diào)用的效率更高。
因?yàn)榧词瓜肓?#xff0c;也搞不了,因?yàn)闆](méi)錢!
即使我們?cè)谧约旱腜C上把項(xiàng)目做好了,需要部署到服務(wù)器上,那么我們只要記住那臺(tái)服務(wù)器的IP,使用Socket通訊,就很簡(jiǎn)單的實(shí)現(xiàn)了服務(wù)的調(diào)用和通訊了。
2.Dubbo有什么用
接著學(xué)生時(shí)代的項(xiàng)目說(shuō),那時(shí)候我們做個(gè)圖書管理系統(tǒng),學(xué)籍管理系統(tǒng),其訪問(wèn)量和并發(fā)量一般不會(huì)太高,準(zhǔn)確說(shuō),是非常低。
但是如果還是一個(gè)服務(wù)端,大量的用戶請(qǐng)求,達(dá)到高并發(fā)的場(chǎng)景,那么問(wèn)題就來(lái)了,一臺(tái)機(jī)子顯然承受不住,這時(shí)候需要考慮分布式。
Dubbo的產(chǎn)生于微服務(wù)聯(lián)系緊密,我們一方面想著借助微服務(wù)的思想,實(shí)現(xiàn)各個(gè)服務(wù)或者模塊之間的解耦。那么我們另一方面就不能忽視服務(wù)之間的通訊,這時(shí)候Dubbo一類的RPC框架就應(yīng)運(yùn)而生。
我們需要考慮擴(kuò)展性,比如為了防止訪問(wèn)過(guò)載,服務(wù)所在機(jī)器需要進(jìn)行水平擴(kuò)展,同時(shí)也要考慮不斷增加的服務(wù)調(diào)用方。
我們需要考慮負(fù)載均衡,怎么樣才能將服務(wù)集群的威力發(fā)揮到最大。
我們需要考慮如何自動(dòng)的注冊(cè)服務(wù)以及更新服務(wù),如果做好異常情況下,比如注冊(cè)中心宕機(jī)時(shí),服務(wù)方和調(diào)用方之間的服務(wù)調(diào)用。
如此種種,都是催生Dubbo的重要因素。
HelloWorld的準(zhǔn)備工作
打開(kāi)命令行,執(zhí)行git clone https://github.com/apache/incubator-dubbo.git命令,將遠(yuǎn)程項(xiàng)目拉到本地
導(dǎo)入項(xiàng)目進(jìn)IDE,使用mvn clean compile在項(xiàng)目目錄下編譯
- 下載安裝zookeeper,在命令行執(zhí)行brew install zookeeper
相應(yīng)的啟動(dòng)zk和關(guān)閉zk服務(wù)的命令分別是zkServer start和zkServer stop
運(yùn)行HelloWorld
導(dǎo)入Dubbo項(xiàng)目并且完成編譯后,可以看到Dubbo項(xiàng)目的目錄結(jié)構(gòu)如下
今天要介紹的是dubbo-demo,該子模塊包括
dubbo-demo-api(提取出公共接口)
dubbo-demo-consumer(服務(wù)調(diào)用方)
dubbo-demo-provider(服務(wù)提供方)
dubbo-demo-api
該模塊最核心的類就是DemoService接口,該接口只有一個(gè)方法sayHello
package com.alibaba.dubbo.demo;public interface DemoService {String sayHello(String name);}這個(gè)接口是聯(lián)系調(diào)用方和提供方的紐帶。
dubbo-demo-consumer
該模塊核心的類為Consumer,主要是一個(gè)main函數(shù)
public class Consumer {public static void main(String[] args) {//Prevent to get IPV6 address,this way only work in debug mode//But you can pass use -Djava.net.preferIPv4Stack=true,then it work well whether in debug mode or notSystem.setProperty("java.net.preferIPv4Stack", "true");ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});context.start();DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxywhile (true) {try {Thread.sleep(1000);String hello = demoService.sayHello("world"); // call remote methodSystem.out.println(hello); // get result} catch (Throwable throwable) {throwable.printStackTrace();}}} }其主要功能是加載配置文件,用于尋找服務(wù)提供方所在的位置,拿到DemoService接口的實(shí)現(xiàn)類DemoServiceImpl,并調(diào)用其方法實(shí)現(xiàn)sayHello
dubbo-demo-provider
該模塊包含了DemoService的實(shí)現(xiàn)類DemoServiceImpl,同時(shí)包含一個(gè)服務(wù)啟動(dòng)類Provider
public class Provider {public static void main(String[] args) throws Exception {//Prevent to get IPV6 address,this way only work in debug mode//But you can pass use -Djava.net.preferIPv4Stack=true,then it work well whether in debug mode or notSystem.setProperty("java.net.preferIPv4Stack", "true");ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});context.start();System.in.read(); // press any key to exit}}啟動(dòng)注冊(cè)中心
因?yàn)檎{(diào)用方和服務(wù)提供方需要靠注冊(cè)中心來(lái)聯(lián)系,提供方將自己的服務(wù)登記到注冊(cè)中心,調(diào)用方需要拉取可用的服務(wù)提供方的位置信息,比較常見(jiàn)的關(guān)系描述如下圖所示
調(diào)用關(guān)系說(shuō)明
服務(wù)容器負(fù)責(zé)啟動(dòng),加載,運(yùn)行服務(wù)提供者。
服務(wù)提供者在啟動(dòng)時(shí),向注冊(cè)中心注冊(cè)自己提供的服務(wù)。
服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊(cè)中心訂閱自己所需的服務(wù)。
注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者。
服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺(tái)調(diào)用。
服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。
鑒于Dubbo源碼中,配置文件中的默認(rèn)配置是multicast,但是我在運(yùn)行的時(shí)候總是出現(xiàn)can't assign address的情況,所以改用zookeeper。
相應(yīng)修改如下,在dubbo-demo-provider項(xiàng)目中,將dubbo-demo-provider.xml修改為
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You 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 athttp://www.apache.org/licenses/LICENSE-2.0Unless 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-4.3.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- provider's application name, used for tracing dependency relationship --><dubbo:application name="demo-provider"/><!-- use multicast registry center to export service --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- use dubbo protocol to export service on port 20880 --><dubbo:protocol name="dubbo" port="20880"/><!-- service implementation, as same as regular local bean --><bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/><!-- declare the service interface to be exported --><dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/></beans>將dubbo-demo-consumer項(xiàng)目中的dubbo-demo-consumer.xml修改為
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You 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 athttp://www.apache.org/licenses/LICENSE-2.0Unless 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-4.3.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- consumer's application name, used for tracing dependency relationship (not a matching criterion),don't set it same as provider --><dubbo:application name="demo-consumer"/><!-- use multicast registry center to discover service --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- generate proxy for the remote service, then demoService can be used in the same way as thelocal regular interface --><dubbo:reference id="demoService" check="false" interface="com.alibaba.dubbo.demo.DemoService"/></beans>同時(shí)在命令行輸入zkServer start啟動(dòng)zk
分別啟動(dòng)Proiver和Consumer
運(yùn)行Provider類,將自己的服務(wù)接口對(duì)外開(kāi)放
運(yùn)行Consumer類,尋找服務(wù)提供方,并調(diào)用其接口實(shí)現(xiàn)
至此,對(duì)于Dubbo有了一個(gè)初步的認(rèn)識(shí)并通過(guò)dubbo-demo項(xiàng)目了解Dubbo的運(yùn)作模式。
網(wǎng)上找了一份PDF版的源碼閱讀心得,如果有需要,下方留下你的郵箱
如果您覺(jué)得閱讀本文對(duì)您有幫助,請(qǐng)點(diǎn)一下“推薦”按鈕,您的“推薦”將是我最大的寫作動(dòng)力!如果您想持續(xù)關(guān)注我的文章,請(qǐng)掃描二維碼,關(guān)注JackieZheng的微信公眾號(hào),我會(huì)將我的文章推送給您,并和您一起分享我日常閱讀過(guò)的優(yōu)質(zhì)文章。
總結(jié)
以上是生活随笔為你收集整理的Dubbo源码-从HelloWorld开始的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。