柚子快報邀請碼778899分享:Java經(jīng)典框架之Dubbo
柚子快報邀請碼778899分享:Java經(jīng)典框架之Dubbo
Dubbo
Java 是第一大編程語言和開發(fā)平臺。它有助于企業(yè)降低成本、縮短開發(fā)周期、推動創(chuàng)新以及改善應(yīng)用服務(wù)。如今全球有數(shù)百萬開發(fā)人員運行著超過 51 億個 Java 虛擬機,Java 仍是企業(yè)和開發(fā)人員的首選開發(fā)平臺。
??
課程內(nèi)容的介紹
1. Dubbo概述
2. Dubbo基本應(yīng)用
3. Dubbo實戰(zhàn)案例
? ? ?
一、Dubbo概述
1、Dubbo及架構(gòu)變化
1.1 Dubbo 介紹
Dubbo 是阿里巴巴公司開源的一個高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過高性能的RPC 實現(xiàn)服務(wù)的輸出和輸入功能,可以和 Spring 框架無縫集成。Dubbo 框架,是基于容器運行的.。容器是 Spring。
官方網(wǎng)站 : http://dubbo.apache.org/
阿里巴巴已經(jīng)將 dubbo 框架捐獻給了 Apache 軟件基金會。
??
現(xiàn)在出去找工作如果不會點分布式和微服務(wù)相關(guān)的內(nèi)容,都不太好更面試官扯蛋。但這些架構(gòu)也不是突然就出現(xiàn)的,而是經(jīng)過不但演變才出現(xiàn)及流行起來的,本文就給大家來梳理下java項目架構(gòu)的演變歷程。
??系統(tǒng)架構(gòu)演化歷程 單體架構(gòu) ??大型網(wǎng)站都是從小型網(wǎng)站發(fā)展而來的,網(wǎng)站架構(gòu)也是一樣,是從小型網(wǎng)站架構(gòu)逐步演化而來的,小型網(wǎng)站最開始沒有太多人訪問,只需要一臺服務(wù)器就綽綽有余了,這時的架構(gòu)如下:
??
應(yīng)用程序、數(shù)據(jù)庫、文件等所有的資源都在一臺服務(wù)器上,通常服務(wù)器操作系統(tǒng)使用Linux、應(yīng)用程序使用java或者其他語句,然后部署在Apache或者Nginx上。數(shù)據(jù)庫使用MySQL,使用開源的技術(shù)實現(xiàn),然后部署在一臺廉價的服務(wù)器上就開始了網(wǎng)站的發(fā)展之路。
? ? ??
應(yīng)用服務(wù)和數(shù)據(jù)服務(wù)分離 ??好景不長,隨著公司業(yè)務(wù)的發(fā)展,一臺服務(wù)逐漸滿足不了需求,越來越多的用戶訪問導(dǎo)致性能越來越差,數(shù)據(jù)存儲空間開始不足,這時我們需要將應(yīng)用和數(shù)據(jù)分離,分離后開始使用三臺服務(wù)器:應(yīng)用服務(wù)器、文件服務(wù)器、數(shù)據(jù)庫服務(wù)器。如圖:
??
應(yīng)用和數(shù)據(jù)分離后,不同特性的服務(wù)器承擔(dān)著不同的服務(wù)角色,網(wǎng)站的并發(fā)處理能力和數(shù)據(jù)存儲空間都得到了很大的改善,支持網(wǎng)站業(yè)務(wù)進一步發(fā)展,但是隨著用戶逐漸增多,數(shù)據(jù)庫壓力越來越大,訪問延遲,進而影響整個網(wǎng)站的性能,此時需要進一步優(yōu)化。
緩存的使用 ??網(wǎng)站訪問有個著名的二八定律,即80%的業(yè)務(wù)集中訪問在20%的數(shù)據(jù)上,如果我們將這一小部分的數(shù)據(jù)緩存在內(nèi)存中,能夠很好的減少數(shù)據(jù)庫的訪問壓力,提高整個網(wǎng)站的數(shù)據(jù)訪問速度。
? ?
緩存常用的組件可以是Redis,ehcache等。
? ??集群的使用 ??緩存解決了數(shù)據(jù)庫訪問量比較大的問題,但是并不能解決隨著業(yè)務(wù)增多造成的服務(wù)器并發(fā)壓力大的問題,這時我們需要增加一臺應(yīng)用服務(wù)器來分擔(dān)原來服務(wù)器的訪問壓力和存儲壓力。如圖:
??
通過負載均衡調(diào)度服務(wù)器,可將來自用戶的訪問請求分發(fā)到應(yīng)用服務(wù)器中的任何一臺服務(wù)器中,這樣多臺服務(wù)器就分擔(dān)了原來一臺服務(wù)器的壓力,我們只需要注意會話的一致性就可以了。
??
數(shù)據(jù)庫讀寫分離 ??系統(tǒng)正常運行了一段時間后,雖然加的有緩存,使絕大多數(shù)的數(shù)據(jù)庫操作可以不通過數(shù)據(jù)庫就能完成,但是任然有一部分的操作(緩存訪問不命中,緩存過期)和全部的寫操作需要訪問數(shù)據(jù)庫,當(dāng)用戶達到一定規(guī)模后,數(shù)據(jù)庫因為負載壓力過大還是會成為系統(tǒng)的瓶頸, ??這時主流的數(shù)據(jù)庫都提供的有主從熱備份功能,通過配置兩臺數(shù)據(jù)庫實現(xiàn)主從關(guān)系,可以將一臺數(shù)據(jù)庫服務(wù)器的數(shù)據(jù)更新同步到另一臺服務(wù)器上。可以利用這一功能來實現(xiàn)數(shù)據(jù)庫讀寫分離。從而改善數(shù)據(jù)庫的負載壓力,如圖:
??
mysql的讀寫分離可以通過自身自帶的從主復(fù)制實現(xiàn),Oracle的話可以通過阿里巴巴的mycat組件來實現(xiàn)。
??
反向代理和CDN加速 ??為了應(yīng)付復(fù)雜的網(wǎng)絡(luò)環(huán)境和不同地區(qū)用戶的訪問,通過CDN和反向代理加快用戶訪問的速度,同時減輕后端服務(wù)器的負載壓力。CDN與反向代理的基本原理都是緩存。CDN部署在網(wǎng)絡(luò)提供商的機房。用戶請求到來的時候從距離自己最近的網(wǎng)絡(luò)提供商機房獲取數(shù)據(jù),而反向代理則部署在網(wǎng)站的中心機房中,請求帶來的時候先去反向代理服務(wù)器中查看請求資源,如果有則直接返回。如圖:
??
使用CDN和反向代理的目的都是盡早返回數(shù)據(jù)給用戶,一方面加快用戶的訪問速度,另一方面也減輕后端服務(wù)器的負載壓力。
??
分布式文件和分布式數(shù)據(jù)庫 ??任何強大的單一服務(wù)器都滿足不了大型網(wǎng)站持續(xù)增長的業(yè)務(wù)需求。數(shù)據(jù)庫經(jīng)過讀寫分離后,從一臺服務(wù)器拆分成兩天服務(wù)器,但是隨著業(yè)務(wù)的增長后面依然不能滿足需求,這時我們需要使用分布式數(shù)據(jù)庫,同時文件系統(tǒng)也一樣,需要使用分布式文件系統(tǒng)。 ??分布式數(shù)據(jù)庫是數(shù)據(jù)庫拆分的最后的手段,只有在表單數(shù)據(jù)規(guī)模非常龐大的時候才使用,不到不得已時,我們更常用的手段是業(yè)務(wù)分庫,將不同的業(yè)務(wù)數(shù)據(jù)部署在不同的物理服務(wù)器上。
??
NoSql和搜索引擎 ??隨著業(yè)務(wù)越來越復(fù)雜,對數(shù)據(jù)存儲和檢索的需求也越來越復(fù)雜,這時一些NoSQL(Reids,HBase,mongodb)數(shù)據(jù)庫技術(shù)和搜索引擎(Solr,Elasticsearch)的時候就顯得很有必要。如下圖:
? ? ?
NoSQL和搜索引擎對可伸縮的分布式特性具有更好的支持,應(yīng)用服務(wù)器通過一個統(tǒng)一的數(shù)據(jù)訪問模塊訪問各種數(shù)據(jù),減輕應(yīng)用程序管理諸多數(shù)據(jù)源的麻煩。
??
業(yè)務(wù)拆分 ??當(dāng)訪問量達到一定規(guī)模的時候我們可以通過分而治之的手段將整個系統(tǒng)的業(yè)務(wù)分成不同的產(chǎn)品線,例如我們將系統(tǒng)的首頁,商鋪,訂單,買家,賣家,支付,訂單等拆分成不同的產(chǎn)品線。 ??具體到技術(shù)實現(xiàn)上,也可以根據(jù)產(chǎn)品線劃分,將一個網(wǎng)站拆分成許多不同的應(yīng)用,每個應(yīng)用獨立部署維護,應(yīng)用之間通過RPC框架(dubbo,webService,httpClient…)建立連接,也可以通過消息隊列實現(xiàn)異步分發(fā)處理。來構(gòu)成一個完整的系統(tǒng),如下圖:
??
分布式服務(wù) 隨著業(yè)務(wù)拆分越來越小,存儲系統(tǒng)越來越龐大,應(yīng)用系統(tǒng)的整體復(fù)雜度呈指數(shù)級增加,部署維護越來越困難,由于所有應(yīng)用要和所有數(shù)據(jù)庫系統(tǒng)連接,最終導(dǎo)致數(shù)據(jù)庫連接資源不足,拒絕服務(wù)。
1.當(dāng)服務(wù)越來越多時,服務(wù)URL配置管理變得非常困難,F(xiàn)5硬件負載均衡器的單點壓力也越來越大。 2.當(dāng)進一步發(fā)展,服務(wù)間依賴關(guān)系變得錯蹤復(fù)雜,甚至分不清哪個應(yīng)用要在哪個應(yīng)用之前啟動,架構(gòu)師都不能完整的描述應(yīng)用的架構(gòu)關(guān)系。 3.接著,服務(wù)的調(diào)用量越來越大,服務(wù)的容量問題就暴露出來,這個服務(wù)需要多少機器支撐?什么時候該加機器? 4.服務(wù)多了,溝通成本也開始上升,調(diào)某個服務(wù)失敗該找誰?服務(wù)的參數(shù)都有什么約定? 5.一個服務(wù)有多個業(yè)務(wù)消費者,如何確保服務(wù)質(zhì)量? 6.隨著服務(wù)的不停升級,總有些意想不到的事發(fā)生,比如cache寫錯了導(dǎo)致內(nèi)存溢出,故障不可避免,每次核心服務(wù)一掛,影響一大片,人心慌慌,如何控制故障的影響面?服務(wù)是否可以功能降級?或者資源劣化?
? ? 解決方案:公共的應(yīng)用模塊被提取出來,部署在分布式服務(wù)器上供應(yīng)用服務(wù)器調(diào)用。也就是我們將的分布式服務(wù)或者微服務(wù)。
??
1.2 單體架構(gòu)
單體架構(gòu)也稱之為單體系統(tǒng)或者是單體應(yīng)用。就是一種把系統(tǒng)中所有的功能、模塊耦合在一個應(yīng)用中的架構(gòu)方式。其優(yōu)點為:項目易于管理、部署簡單。缺點:測試成本高、可伸縮性差、可靠性差、迭代困難、跨語言程度差、團隊協(xié)作難。
??
1.3 SOA 架構(gòu):
面向服務(wù)的架構(gòu)(SOA- Service-Oriented Architecture)是一個組件模型,它將應(yīng)用程序拆分成不同功能單元(稱為服務(wù))通過這些服務(wù)之間定義良好的接口和契約聯(lián)系起來。接口是采用中立的方式進行定義的,它應(yīng)該獨立于實現(xiàn)服務(wù)的硬件平臺、操作系統(tǒng)和編程語言。這使得構(gòu)建在各種各樣的系統(tǒng)中的服務(wù)可以以一種統(tǒng)一和通用的方式進行交互。
??
1.4 RPC 遠程過程調(diào)用
遠程過程調(diào)用協(xié)議( Remote Procedure Call Protocol),它是一種通過網(wǎng)絡(luò)從遠程計算機程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。RPC 協(xié)議假定某些傳輸協(xié)議的存在,如 TCP 或 UDP,為通信程序之間攜帶信息數(shù)據(jù)。在 OSI 網(wǎng)絡(luò)通信模型中,RPC 跨越了傳輸層和應(yīng)用層。RPC 使得開發(fā)包括網(wǎng)絡(luò)分布式多程序在內(nèi)的應(yīng)用程序更加容易。
??
2、Dubbo 框架結(jié)構(gòu)圖
2.1 Dubbo 角色介紹
??
registry
注冊中心是用于發(fā)布和訂閱服務(wù)的一個平臺.用于替代 SOA 結(jié)構(gòu)體系框架中的 ESB 服務(wù)總線的。
??
發(fā)布
開發(fā)服務(wù)端代碼完畢后,將服務(wù)信息發(fā)布出去. 實現(xiàn)一個服務(wù)的公開。
?
訂閱
客戶端程序,從注冊中心下載服務(wù)內(nèi)容 這個過程是訂閱。
訂閱服務(wù)的時候,會將發(fā)布的服務(wù)所有信息,一次性下載到客戶端.客戶端也可以自定義,修改部分服務(wù)配置信息。如: 超時的時長, 調(diào)用的重試次數(shù)等。
? ?
consumer
服務(wù)的消費者, 就是服務(wù)的客戶端。
消費者必須使用 Dubbo 技術(shù)開發(fā)部分代碼. 基本上都是配置文件定義。
??
provider
服務(wù)的提供者, 就是服務(wù)端。
服務(wù)端必須使用 Dubbo 技術(shù)開發(fā)部分代碼. 以配置文件為主。
??
container
容器. Dubbo 技術(shù)的服務(wù)端(Provider), 在啟動執(zhí)行的時候, 必須依賴容器才能正常啟動。
默認(rèn)依賴的就是 Spring 容器. 且 Dubbo 技術(shù)不能脫離 Spring 框架。
在 2.5.3 版本的 dubbo 中, 默認(rèn)依賴的是 spring2.5 版本技術(shù). 可以選用 Spring4.5 以下版本。
在 2.5.7 版本的 dubbo 中, 默認(rèn)依賴的是 spring4.3.10 版本技術(shù). 可以選擇任意的 spring版本。
??
monitor
監(jiān)控中心,是 Dubbo 提供的一個jar工程。
主要功能是監(jiān)控服務(wù)端(Provider)和消費端(Consumer)的使用數(shù)據(jù)的。?如:服務(wù)端是什么,有多少接口,多少方法,調(diào)用次數(shù),壓力信息等。客戶端有多少,調(diào)用過哪些服務(wù)端,調(diào)用了多少次等。
? ?
2.2 Dubbo 執(zhí)行流程
start:啟動 Spring 容器時,自動啟動 Dubbo 的 Provider。
register:Dubbo 的 Provider 在啟動后自動會去注冊中心注冊內(nèi)容注冊的內(nèi)容包括:
1.1 Provider 的 IP。
1.2 Provider 的端口。
1.3 Provider 對外提供的接口列表,哪些方法,哪些接口類。
1.4 Dubbo 的版本。
1.5 訪問 Provider 的協(xié)議。
subscribe: 訂閱.當(dāng) Consumer 啟動時,自動去 Registry 獲取到所已注冊的服務(wù)的信息。
notify: 通知.當(dāng) Provider 的信息發(fā)生變化時,自動由 Registry 向 Consumer 推送通知。
invoke: 調(diào)用. Consumer 調(diào)用 Provider 中方法。
1.1 同步請求.消耗一定性能.但是必須是同步請求,因為需要接收調(diào)用方法后的結(jié)果。
count:次數(shù). 每隔 2 分鐘,provoider 和 consumer 自動向 Monitor 發(fā)送訪問次數(shù).Monitor進行統(tǒng)計。
??
3.Dubbo 支持的協(xié)議
3.1Dubbo 協(xié)議(官方推薦協(xié)議)
??
3.2RMI(Remote Method Invocation)協(xié)議
??
3.3Hessian 協(xié)議
??
4.Dubbo 支持的注冊中心
4.1Zookeeper(官方推薦)
1. 優(yōu)點:
支持分布式.很多周邊產(chǎn)品。
2. 缺點:
受限于 Zookeeper 軟件的穩(wěn)定性。Zookeeper 專門分布式輔助軟件,穩(wěn)定較優(yōu)。
??
4.2 Multicast
1. 優(yōu)點:
去中心化,不需要單獨安裝軟件。
2. 缺點:
Provider 和 Consumer 和 Registry 不能跨機房(路由)。
??
4.3Redis
1. 優(yōu)點:
支持集群,性能高。
??
2. 缺點:
要求服務(wù)器時間同步。否則可能出現(xiàn)集群失敗問題。
? ?
4.4Simple
1. 優(yōu)點:
標(biāo)準(zhǔn) RPC 服務(wù)。沒有兼容問題。
2. 缺點:
不支持集群。
??
二、Dubbo基本應(yīng)用
1. Dubbo基本案例
實現(xiàn)項目之間的調(diào)用。
??
1.1 項目結(jié)構(gòu)
??
1.2 公共模塊
在commons模塊中定義個service接口即可。
package com.bobo;
public interface UserService {
String sayHello(String name);
}
??
??
1.3 provider
創(chuàng)建服務(wù)提供者。
??
創(chuàng)建服務(wù)端提供的服務(wù)。
package com.bobo.service;
import com.bobo.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public String sayHello(String name) {
System.out.println("服務(wù)端執(zhí)行了: " + name);
return "HELLO:" + name + "[msg]";
}
}
??
添加Spring的配置文件。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181"/> group="dubbo" version="1.0.0" timeout="5000" />
??
為了看到日志效果,我們添加log4j.properties文件。
log4j.rootLogger=INFO,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
? ?
添加啟動文件。
package com.bobo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppStart {
public static void main(String[] args) throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 掛起當(dāng)前線程
Thread.currentThread().join();
}
}
??
啟動后效果。
??
我們在Zookeeper中可以看到提供者的相關(guān)的注冊信息。
??
1.4 consumer
服務(wù)消費者
引入相關(guān)的依賴(和provide中的依賴是一樣的)
??
創(chuàng)建Spring的配置文件。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181" /> group="dubbo" version="1.0.0" timeout="5000" />
??
添加對應(yīng)的日志文件。
創(chuàng)建測試的代碼
package com.bobo;
import com.bobo.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AppStart {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 獲取接口的代理對象
UserService userService = (UserService) ac.getBean("userService");
System.out.println(userService.sayHello("aaa"));
}
}
??
1.5 測試
先啟動服務(wù)端代碼。
??
啟動消費者程序。
??
獲取結(jié)果的輸出。
??
消費者消費后我們在Zookeeper的注冊中心中是可以看到新的注冊信息的。
??
2. Dubbo源碼下載和編譯
https://github.com/apache/incubator-dubbo/tree/2.5.x?utm_source=csdn_toolbar
??
解壓縮
??
進入dubbo-2.5.10目錄下執(zhí)行 mvn clean package -Dmaven.test.skip=true 會生成如下結(jié)果[注意:以管理員身份進入]
??
看到如下提示表示編譯成功。
??
核對我們需要的內(nèi)容。
??
? ??
3. 管理控制臺
開源的dubbo服務(wù)管理控制臺是阿里巴巴內(nèi)部裁剪的版本,開源的部分功能包括:路由規(guī)則,動態(tài)配置,服務(wù)降級,訪問控制,權(quán)重調(diào)整,負載均衡等管理功能。將生成的dubbo-admin-2.5.10.war拷貝到web容器中(此處使用tomcat8)
??
解壓縮后我們需要修改dubbo的屬性文件。
??
dubbo.registry.address=zookeeper://192.168.100.120:2181?
backup=192.168.100.121:2181,192.168.100.122:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
? ?
啟動Tomcat服務(wù)即可。
登錄的地址:http://localhost:8080/dubbo-admin-2.5.10/
默認(rèn)的賬號密碼是 root root
??
??
將頁面語音切換到中文。
??
4. 監(jiān)控平臺
Dubbo-Monitor主要是用來統(tǒng)計服務(wù)和調(diào)用次數(shù)和調(diào)用時間,服務(wù)消費者和提供者,在內(nèi)存中累計調(diào)用次數(shù)和調(diào)用時間,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心,監(jiān)控中心則使用數(shù)據(jù)繪制圖表來顯示。
??
4.1 開啟monitor服務(wù)
我們需要在消費者和服務(wù)提供者中都開啟monitor服務(wù),我們只需要在對應(yīng)的配置文件中添加如下信息即可。
??
??
4.2 修改配置
??
解壓縮后的結(jié)構(gòu)。
??
修改配置進入conf目錄中 添加Zookeeper注冊中心的信息。
# 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 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.
dubbo.container=log4j,spring,registry,jetty
dubbo.application.name=simple-monitor
dubbo.application.owner=
# zookeeper的配置信息
dubbo.registry.address=zookeeper://192.168.100.120:2181?
backup=192.168.100.121:2181,192.168.100.122:2181
#dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.protocol.port=7070
dubbo.jetty.port=8080
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${dubbo.jetty.directory}/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN
??
4.3 啟動監(jiān)控服務(wù)
啟動服務(wù)的程序在bin目錄下。
??
??
4.4 訪問服務(wù)
http://localhost:8084
訪問成功的頁面
??
三、Dubbo實戰(zhàn)案例
1、案例介紹
1.1 案例結(jié)構(gòu)圖
??
1.2 需求
完成對用戶表的CRUD操作。
??
1.3 技術(shù)選型
MySQL、Dubbo、Zookeeper、Maven、MyBatis、SpringMVC、Spring。
??
1.4 表結(jié)構(gòu)
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`userage` int(11) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
? ?
2、項目創(chuàng)建
2.1 項目設(shè)計
整個案例工程會通過Maven聚合工程來創(chuàng)建,先來設(shè)計Maven聚合工程的項目結(jié)構(gòu)。
dubbo-parent(POM)
|-- dubbo-pojo(jar)
|-- dubbo-mapper(jar)
|-- dubbo-user-provider(POM)
|-- dubbo-user-provider-interface(jar)
|-- dubbo-user-provider-service(jar)
|-- dubbo-user-consumer(POM)
|-- dubbo-user-consumer-web-service(jar)
|-- dubbo-user-consumer-web(war)
??
2.2 創(chuàng)建dubbo-parent
??
在對應(yīng)的pom文件中聲明如下信息。
??
2.2 創(chuàng)建dubbo-pojo
項目結(jié)構(gòu)
??
User實體對象
package com.bobo.pojo;
import java.io.Serializable;
public class User implements Serializable {
private Integer userid;
private String username;
private Integer userage;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getUserage() {
return userage;
}
public void setUserage(Integer userage) {
this.userage = userage;
}
public User() {
}
public User(Integer userid, String username, Integer userage) {
this.userid = userid;
this.username = username;
this.userage = userage;
}
@Override
public String toString() {
return "User{" +
"userid=" + userid +
", username='" + username + '\'' +
", userage=" + userage +
'}';
}
}
??
2.3 創(chuàng)建dubbo-mapper
持久層項目
??
創(chuàng)建UserMapper接口。
/**
* UserMapper接口
*/
public interface UserMapper {
}
? ?
創(chuàng)建UserMapper的映射文件。
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
??
修改POM文件,添加相關(guān)的依賴。
? ?
2.4 創(chuàng)建服務(wù)提供者
2.4.1 創(chuàng)建dubbo-user-provider
直接創(chuàng)建出來即可。
??
2.4.2 創(chuàng)建dubbo-user-provider-interface
? ?
添加dubbo-pojo的依賴。
??
2.4.3 創(chuàng)建dubbo-user-provider-service
??
修改POM文件,添加相關(guān)的依賴。
??
創(chuàng)建db.properties文件。
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shop?characterEncoding=utf-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
??
SqlMapperClient.xml MyBatis的配置文件。
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
??
applicationContext-service.xml Spring的基本你文件。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
??
applicationContext-trans.xml事務(wù)配置文件。
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
? ? ?
applicationContext-dao.xml 持久層。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
? ?
然后在classpath:/META-INF/spring目錄下創(chuàng)建dubbo的配置文件。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181"/> ref="addUserDubboServiceImpl" group="dubbo" version="1.0.0" timeout="5000"/> ref="selectUserDubboServiceImpl" group="dubbo" version="1.0.0" timeout="5000"/> ref="deleteUserDubboServiceImpl" group="dubbo" version="1.0.0" timeout="5000"/>
? ?
整個項目結(jié)構(gòu)。
??
然后將dubbo-parent 打包處理,然后添加主方法,測試。
package com.bobo.dubbo;
import com.alibaba.dubbo.container.Main;
public class Start {
public static void main(String[] args) throws Exception{
// Dubbo提供的啟動方法,默認(rèn)會去classpath:/META-INF/spring/*.xml 加載
Main.main(args);
}
}
??
??
Zookeeper中查看的注冊信息。
??
2.5 創(chuàng)建消費者
2.5.1 創(chuàng)建dubbo-user-consumer
??
2.5.2 創(chuàng)建service服務(wù)
??
修改pom文件。
??
2.5.3 創(chuàng)建web服務(wù)
??
修改pom文件
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
? ??
添加相關(guān)的配置文件 SpringMVC,Spring,web.xml,Dubbo。
applicationContext-dubbo.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181" /> id="addUserDubboService" group="dubbo" version="1.0.0" timeout="5000"/> id="selectUserDubboService" group="dubbo" version="1.0.0" timeout="5000"/> id="deleteUserDubboService" group="dubbo" version="1.0.0" timeout="5000"/>
??
applicationContext-service.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
??
springmvc.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> class="org.springframework.web.servlet.view.InternalResourceViewResolver">
? ?
web.xml
xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
??
? ?
測試web項目是否可以訪問。
??
訪問成功。
??
3. 業(yè)務(wù)實現(xiàn)
??
3.1 添加用戶信息
3.1.1 dubbo-mapper
package com.bobo.mapper;
import com.bobo.pojo.User;
/**
* UserMapper接口
*/
public interface UserMapper {
int insertUser(User user);
}
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
insert into users(username,userage)values(#{username},#{userage})
??
3.1.2 dubbo-user-service-interface
在dubbo-user-service-interface中聲明provider對外提供的功能。
package com.bobo.dubbo.service;
import com.bobo.pojo.User;
public interface AddUserDubboService {
void addUser(User user);
}
??
3.1.3 dubbo-user-service
依賴
??
實現(xiàn)provider對外提供的功能。
package com.bobo.dubbo.service.impl;
import com.bobo.dubbo.service.AddUserDubboService;
import com.bobo.mapper.UserMapper;
import com.bobo.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AddUserDubboServiceImpl implements AddUserDubboService {
@Autowired
private UserMapper userMapper;
@Override
public void addUser(User user) {
userMapper.insertUser(user);
}
}
??
添加了對外新增的功能,那么我們需要將這個功能注冊到Zookeeper的注冊中心中,所以我們需要修改Dubbo的配置文件。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
??
重啟服務(wù),然后去Zookeeper中查看相關(guān)的注冊信息。
??
3.1.4 dubbo-user-web-service
public interface UserService {
int addUser(User user);
}
??
創(chuàng)建接口的實現(xiàn)。
package com.bobo.service.impl;
import com.bobo.dubbo.service.AddUserDubboService;
import com.bobo.pojo.User;
import com.bobo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService{
/**
* 從Spring容器中獲取 provider中的接口的代理對象
*/
@Autowired
public AddUserDubboService addUserDubboService;
@Override
public int addUser(User user) {
addUserDubboService.addUser(user);
return 1;
}
}
? ?
3.1.5 dubbo-user-web
需要向dubbo訂閱對應(yīng)的服務(wù)。
id="addUserDubboService" group="dubbo" version="1.0.0" timeout="5000" /> ?? 添加新增用戶的界面。 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
??
??
測試報錯
??
pojo對象必須要實現(xiàn)序列化。
??
數(shù)據(jù)庫中查看信息。
??
3.2 查詢用戶信息
mapper添加相關(guān)的信息。
在provider的接口中聲明服務(wù)。
在provider中實現(xiàn)服務(wù),并注冊到注冊中心。
消費者訂閱服務(wù),調(diào)用服務(wù)。
??
3.3 刪除用戶信息
mapper添加相關(guān)的信息。
在provider的接口中聲明服務(wù)。
在provider中實現(xiàn)服務(wù),并注冊到注冊中心。
消費者訂閱服務(wù),調(diào)用服務(wù)。
柚子快報邀請碼778899分享:Java經(jīng)典框架之Dubbo
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。