文章目錄
- 理解分布式系統
- 一、Dubbo背景和簡介
- 1、架構的演進:
- (1)單一應用架構
- (2)垂直應用架構
- (3)分布式服務架構
- (4)流動計算架構
- 2、認識RPC
- 3、Dubbo
- 3.1、簡介
- 3.2 設計架構
- 二、Dubbo環境搭建
- 1、搭建Zookeeper注冊中心
- 2、dubbo-admin管理控制臺安裝
- 3、Dubbo測驗案例
- 3.1、Dubbo服務提供者介面搭建
- (1)創建Maven專案:service-user-provider 服務提供者
- (2)創建Maven專案:order-service-consumer 服務消費者(訂單系統)
- (3)interface用于存放共通的服務介面
- 3.2、服務提供者配置及測驗
- 3.3、服務消費者配置及測驗
- 4、dubbo-monitor-simple簡易監控中心
- 三、Dubbo和SpringBoot整合
- 1、boot-user-service-provider 服務提供者
- 2、boot-order-service-consumer 服務消費者
理解分布式系統
分布式系統是若干個獨立計算機的集合,計算機之間通過網路進行通信,為了完成共同的任務而協調作業從而組成的系統,簡單來說就是利用更多的機器來處理更多的資料,
一、Dubbo背景和簡介
1、架構的演進:
(1)單一應用架構
當網站流量很小時,只需要一個應用,將所有功能代碼打成一個包部署在一個服務器上,以減少部署節點和成本,
缺點:
- 性能擴展比較難;
- 協同開發問題;
- 不利于升級和維護;

(2)垂直應用架構
當訪問量逐漸增大,將應用拆成互不相干的幾個應用,以提升效率,

通過切分業務來實作各模塊獨立部署,降低了維護和部署的難度,性能擴展也更加方便,更具針對性,
缺點:公共模塊無法重復利用,開放性的浪費,
(3)分布式服務架構

當垂直應用越來越多,應用之間的互動不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使得前端應用能夠快速的回應多變的市場需求,,此時,用于提高業務復用及整合分布式服務框架RPC是關鍵,
舉例理解:
- 如果要修改界面,只需將界面單獨修改后重啟界面的服務器,其相關的核心業務邏輯還在其他服務器上,
- 比如訂單web前端需要訂單資訊、用戶資訊、商品資訊,那就直接去調這幾個服務器的業務就行,包括業務之間也需要互相呼叫,
(4)流動計算架構
當服務器越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需要增加一個調度中心基于訪問壓力實時管理集群容量,提高集群利用率,此時,用于提高機器利用率的資源調度和治理中心是關鍵,

2、認識RPC
RPC:遠程程序呼叫,它是一種技術的思想
是一種行程之間通信的方式,它允許程式呼叫另一個地址空間(通常是共享網路的另一臺機器上)的程序或函式,而不是程式員顯示撰寫這個遠程呼叫的細節,即程式員無論是呼叫本地還是遠程函式,本質撰寫的呼叫代碼基本相同(類似使用Mybatis后,僅需要通過呼叫自己寫的mapper映射的介面實作crud),
RPC的用途
兩臺服務器A、B,一個應用部署在A服務器上,想要呼叫B服務器上的應用提供的函式(方法),由于兩個應用不在一個記憶體空間,不能直接呼叫,而需要網路來表達呼叫的語意和傳達呼叫的資料,為什么要用RPC呢?就是無法在一個行程內,甚至一個計算機內通過本地呼叫的方式完成的需求,比如不同的系統間的通訊,甚至不同的組織間的通訊,由于計算能力需要橫向擴展,需要在多臺機器組成的集群上部署應用,RPC就是要像呼叫本地的函式一樣去調遠程函式;
基本原理

步驟決議:

RPC需要解決的問題:
- 通訊問題
- 尋址問題
- 序列化/反序列化
3、Dubbo
3.1、簡介
是一款高性能、輕量級的開源Java RPC框架,
它提供了三大核心能力:
- 面向介面的遠程方法呼叫;
2.智能容錯和負載均衡;
3.服務自動注冊和發現,

3.2 設計架構

Provider:暴露服務的服務提供方;
Consumer:呼叫遠程服務的服務消費方;
Register:服務注冊與發現的注冊中心;
Monitor:統計服務的呼叫次數和呼叫時間的控制中心,
呼叫流程
0:服務器容器負責啟動、加載、運行服務提供者;
1:服務提供者在啟動時,向注冊中心注冊自己提供的服務;
2:服務消費者在啟動時,向注冊中心訂閱自己所需的服務;
3:注冊中心回傳服務提供者地址串列給消費者,如有變更,注冊中心將基于長連接推送變更資料給消費者;
4:服務消費者,從提供者地址串列中,基于軟負載均衡演算法,選一臺提供者進行呼叫,如果呼叫失敗,再選一臺呼叫,
5:服務消費者和提供者,在記憶體中積累呼叫次數和呼叫時間,定時每分鐘發送一次統計資料到監控中心,
二、Dubbo環境搭建
1、搭建Zookeeper注冊中心
zookeeper
1.將conf檔案夾下面的zoo_sample.cfg復制一份改名為zoo.cfg即可;
2.修改zoo.cfg中的dataDir路徑(新建一個data檔案,將路徑設定成此檔案夾,注意目錄使用“\”);
3.使用zkCli.cmd測驗:
(因為zookeeper是一個樹型的目錄服務)
ls /:列出zookeeper根下保存的所有節點
create –e /duanxinwei 123456:創建一個duanxinwei節點,值為123456
get /duanxinwei:獲取/duanxinwei節點的值

2、dubbo-admin管理控制臺安裝
- dubbo-admin 下載地址(最好用此版本,官網已經更新了新的版本)
- 將原始碼下載下來,可以使用 git clone 或者下載壓縮包都可以
- 修改/dubbo-admin-master/dubbo-admin/src/main/resources檔案夾下的application.properties中的admin的port和注冊中心地址(zookeeper埠)

- 進入dubbo-admin目錄下打jar包dubbo-admin
mvn clean package -Dmaven.test.skip=true
用cmd打jar包我總是報錯,所以我用的idea中的maven打的jar包
- 將打好的jar包復制到dubbo-admin目錄下面,cmd運行此jar包(注意:提前將zookeeper跑起來)
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
此時控制臺服務就已經跑起來了,通過locahost:7001,訪問到注冊中心,輸入賬號密碼:root

3、Dubbo測驗案例
基于下圖實作服務提供者、消費者

3.1、Dubbo服務提供者介面搭建
(1)創建Maven專案:service-user-provider 服務提供者

提供的服務是:通過userId查詢用戶地址
UserService:
//用戶服務
public interface UserService {
/**
* 按照用戶id回傳所有的識訓地址
* @param userId
* @return
*/
public List<UserAddress> getUserAddressList(String userId);
}
UserServiceImpl:
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
// // 模擬從資料庫中獲取的該userId對應的地址
UserAddress address1 = new UserAddress(1, "河南省鄭州鞏義市宋陵大廈2F", "1", "安然", "150360313x", "Y");
UserAddress address2 = new UserAddress(2, "北京市昌平區沙河鎮沙陽路", "1", "情話", "1766666395x", "N");
return Arrays.asList(address1,address2);
}
}
物體類
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserAddress implements Serializable {
private Integer id;
private String userAddress; //用戶地址
private String userId; //用戶id
private String consignee; //識訓人
private String phoneNum; //電話號碼
private String isDefault; //是否為默認地址 Y-是 N-否
//get set
//有參構造 無參構造
}
(2)創建Maven專案:order-service-consumer 服務消費者(訂單系統)
OrderService
public interface OrderService {
/**
* 初始化訂單
* @param userID
*/
public void initOrder(String userID);
}
OrderServiceImpl
public class OrderServiceImpl implements OrderService {
public UserService userService;
public void initOrder(String userID) {
//查詢用戶的識訓地址
List<UserAddress> userAddressList = userService.getUserAddressList(userID);
System.out.println(userAddressList);
}
}
因為服務消費者要拿到提供者的方法
得將服務提供者中的物體類UserAddress和UserService復制到消費者的檔案中,這樣消費者代碼才不會報錯,
但是這樣復制代碼會使得重復代碼太多,可以直接將重用的代碼(物體類,service方法)放在單獨的專案下,打成jar包,
在服務提供者和消費者專案中引入這個jar包的依賴,這樣就會省略大量代碼,
(3)interface用于存放共通的服務介面

<dependency>
<groupId>com.duan</groupId>
<artifactId>duan-interface</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>..路徑../duan-interface-1.0-SNAPSHOT.jar</systemPath>
</dependency>
3.2、服務提供者配置及測驗
在service-user-provider中引入依賴
<!--dubbo-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!--注冊中心是 zookeeper,引入zookeeper客戶端-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
在resrouce檔案中創建provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--1、指定當前服務/應用的名字(同樣的服務名字相同,不要和別的服務同名)-->
<dubbo:application name="service-user-provider"></dubbo:application>
<!--2、指定注冊中心的位置-->
<!--<dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>-->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
<!--3、指定通信規則(通信協議? 服務埠)-->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<!--4、暴露服務 讓別人呼叫 ref指向服務的真正實作物件-->
<dubbo:service interface="com.duan.service.UserService" ref="userServiceImpl"></dubbo:service>
<!--服務的實作, 上面ref指向此bean物件-->
<bean id="userServiceImpl" class="com.duan.service.impl.UserServiceImpl"></bean>
</beans>
撰寫一個ProviderApplication啟動類程式,運行測驗配置
public class MailApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext= new ClassPathXmlApplicationContext("provider.xml");
applicationContext.start();
System.in.read();
}
}
(保證此時zoopkeeper和dubbo-admin運行時,在dubbo控制首頁查看提供者資訊)



服務提供者的配置和測驗完成,
3.3、服務消費者配置及測驗
在service-order-consumer服務消費者專案中引入依賴
<!--dubbo-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!--注冊中心是 zookeeper,引入zookeeper客戶端-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
創建consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
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-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--包掃描-->
<context:component-scan base-package="com.duan.service.impl"/>
<!--指定當前服務/應用的名字(同樣的服務名字相同,不要和別的服務同名)-->
<dubbo:application name="service-order-consumer"></dubbo:application>
<!--指定注冊中心的位置-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry>
<!--呼叫遠程暴露的服務,生成遠程服務代理,呼叫的介面和提供者暴漏的介面相同-->
<dubbo:reference interface="com.duan.service.UserService" id="userService"></dubbo:reference>
</beans>
把當前OrderServiceImpl實作類中加上注解(使用spring的注解)
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
public UserService userService;
public void initOrder(String userID) {
//查詢用戶的識訓地址
List<UserAddress> userAddressList = userService.getUserAddressList(userID);
//為了直觀看到得到的資料
System.out.println("當前接收到的userId=> "+userID);
System.out.println("**********");
System.out.println("查詢到的所有地址為:");
for (UserAddress userAddress : userAddressList) {
//列印遠程服務地址的資訊
System.out.println(userAddress.getUserAddress());
}
}
}
撰寫一個ConsumerApplication啟動類程式,運行測驗配置
public class ConsumerApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml");
OrderService orderService = (OrderService)applicationContext.getBean(OrderService.class);
//呼叫方法查詢出資料
orderService.initOrder("1");
System.out.println("呼叫完成...");
System.in.read();
}
}
結果:

管理控制臺:


此時可以看到一個提供者,一個消費者的資訊監控資訊,
4、dubbo-monitor-simple簡易監控中心
dubbo-monitor-simple目錄下cmd輸入命令mvn clean package,打出jar包

將target目錄下的dubbo-monitor-simple-2.0.0-assembly.tar.gz 壓縮包解壓至當前檔案夾,復制到dubbo主目錄下

進入在config檔案查看properties的配置是否是本地的zookeeper,
打開解壓后的 assembly.bin 檔案,start.bat 啟動dubbo-monitor-simple監控中心(記住要先開啟zookeeper服務)

localhost:8080 ,可以看到一個監控中心,
在服務提供者和消費者的xml中配置以下內容,再次啟動服務提供和消費者啟動類,

<!--dubbo-monitor-simple監控中心發現的配置-->
<dubbo:monitor protocol="registry"></dubbo:monitor>
<!--<dubbo:monitor address="127.0.0.1:7070"></dubbo:monitor>-->
啟動服務提供者和服務消費者后,監視結果:

三、Dubbo和SpringBoot整合
注意整合版本適配:

1、boot-user-service-provider 服務提供者
創建spring專案后,匯入依賴:
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
配置 application.properties
dubbo.application.name=boot-user-service-provider
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#連接監控中心
dubbo.monitor.protocol=registry
把user-service-provider中的service拿到此專案中,將將此方法的回傳型別改為List
@Service//dubbo的服務暴露
@Component
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
UserAddress address1 = new UserAddress(1, "河南省鄭州鞏義市宋陵大廈2F", "1", "安然", "150360313x", "Y");
UserAddress address2 = new UserAddress(2, "北京市昌平區沙河鎮沙陽路", "1", "情話", "1766666395x", "N");
return Arrays.asList(address1,address2);
}
}
BootProviderApplication 啟動類配置
@EnableDubbo //開啟基于注解的dubbo功能
@SpringBootApplication
public class BootProviderApplication {
public static void main(String[] args) {
SpringApplication.run(BootProviderApplication.class, args);
}
}
啟動注冊中心,啟動當前服務提供者,可以在瀏覽器看到一個服務提供者,
2、boot-order-service-consumer 服務消費者
- 匯入dubbo-spring-boot-starter依賴
- 把order-service-consumer專案中的service復制到當前專案,
- 創建application.properties 配置
server.port=8081
dubbo.application.name=boot-order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
#連接監控中心 注冊中心協議
dubbo.monitor.protocol=registry
- 把order-service-consumer專案中的service復制到當前專案,
@Service
public class OrderServiceImpl implements OrderService {
@Reference//參考遠程提供者服務
UserService userService;
public List<UserAddress> initOrder(String userID) {
//查詢用戶的識訓地址
List<UserAddress> userAddressList = userService.getUserAddressList(userID);
System.out.println("當前接收到的userId=> "+userID);
System.out.println("**********");
System.out.println("查詢到的所有地址為:");
for (UserAddress userAddress : userAddressList) {
//列印遠程服務地址的資訊
System.out.println(userAddress.getUserAddress());
}
return userAddressList;
}
}
- 創建 OrderController 控制器
@Controller
public class OrderController {
@Autowired
OrderService orderService;
@RequestMapping("/initOrder")
@ResponseBody
public List<UserAddress> initOrder(@RequestParam("uid")String userId) {
return orderService.initOrder(userId);
}
}
- BootConsumerApplication 啟動類創建
配置完畢,此時啟動zookeeper注冊中心及監控,
啟動springboot配置的服務提供者和消費者
在瀏覽器輸入 localhost:7001 查看結果

查詢地址資訊

duboo的springboot整合配置完成,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/435455.html
標籤:其他
下一篇:Hadoop
