一、前言
最近接到公司的項(xiàng)目, 其中技術(shù)用到了springboot、 dubbo、 zookeeper、 activiti、 kafka等, 有些東西是比較熟悉, 有些只是稍微看過(guò), 還不是很懂; 個(gè)人認(rèn)為做一個(gè)項(xiàng)目就要去了解該項(xiàng)目用的所有技術(shù), 知己知彼方能百戰(zhàn)不殆嘛; 后面我也會(huì)陸續(xù)更新相關(guān)技術(shù)棧的搭建~然后慢慢的深入的去了解;
可以先下載demo看一看~~~~
Dubbo_Github_Demo
二、Dubbo
Dubbo官網(wǎng)
上面有詳細(xì)的Dubb文檔, 但是在創(chuàng)建Dubbo項(xiàng)目時(shí)讓我一頭霧水, 網(wǎng)上也找了相關(guān)的視頻看, 也是很懵逼; 這里官網(wǎng)給的文檔, 跟alibaba的github上面的案例又不一樣; 下面我講寫(xiě)一個(gè)我自己搭成功的案例
1. Dubbo是什么
Dubbo是阿里巴巴公司開(kāi)源的一個(gè)高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過(guò)高性能的 RPC 實(shí)現(xiàn)服務(wù)的輸出和輸入功能,可以和 Spring框架無(wú)縫集成。
Dubbo是一款高性能、輕量級(jí)的開(kāi)源Java RPC框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。
Dubbo和SpringCloud一樣, 是一個(gè)分布式框架, 如果對(duì)SpringCloud有興趣的可以:
1. SrpingCloud之Eureka--服務(wù)治理
2. SrpingCloud使用過(guò)Eureka怎么進(jìn)行服務(wù)間相互訪問(wèn)--Feign
3. SrpingCloud調(diào)用方法異常怎么辦--Hystrix使用講解
4. SrpingCloud服務(wù)之間的負(fù)載均衡
2. Dubbo的架構(gòu)

執(zhí)行流程:
- Provider:服務(wù)的提供者,負(fù)責(zé)對(duì)外提供服務(wù),提供者在啟動(dòng)的時(shí)候,需要向Registry注冊(cè)自己能夠提供
的服務(wù)- Consumer:服務(wù)的消費(fèi)者,消費(fèi)者在啟動(dòng)的時(shí)候,需要向Registry訂閱自己需要的服務(wù)
- Registry:注冊(cè)中心,授受注冊(cè)和訂閱,會(huì)異步的通知訂閱者,向消費(fèi)者提供服務(wù)列表
- 當(dāng)消費(fèi)者需要執(zhí)行遠(yuǎn)程過(guò)程調(diào)用時(shí),會(huì)從Registry獲取到服務(wù)地址列表(基于負(fù)載均衡算法)進(jìn)行調(diào)用,
如果調(diào)用失敗會(huì)重新選擇新的提供者再次調(diào)用- Monitor:監(jiān)控中心,統(tǒng)計(jì)服務(wù)的調(diào)用次數(shù)和調(diào)用時(shí)間,服務(wù)消費(fèi)者和提供者會(huì)在內(nèi)存中累計(jì)調(diào)用次數(shù)和
調(diào)用時(shí)間,定時(shí)每分鐘向監(jiān)控中心發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)
3. Dubbo創(chuàng)建三部曲
3.1 創(chuàng)建一個(gè)接口
這里說(shuō)接口, 我個(gè)人認(rèn)為可以將一些公用的類(lèi)放在一個(gè)工程里面, 通過(guò)jar包形式使項(xiàng)目之間相互引用, 這里我只放了實(shí)體類(lèi), 定義的接口(service接口)
使用到的jar:
<!-- 簡(jiǎn)化開(kāi)發(fā)的工具, 這里只用到在實(shí)體類(lèi)上@Data注解,
減少get/set方法生成, 使用時(shí)在ide添加插件, 不會(huì)自行百度 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
創(chuàng)建的類(lèi):
這里強(qiáng)調(diào)下,~返回對(duì)象一定要實(shí)現(xiàn)Serializable接口, 不然會(huì)序列化失敗;
package com.example.pojo;
import lombok.Data;
import java.io.Serializable;
/**
* 用戶
*/
@Data
//這里注意下, 一定要實(shí)現(xiàn)Serializable接口~, 不然消費(fèi)者調(diào)用返回json時(shí)候會(huì)序列化失敗
public class User implements Serializable{
private Integer id;
private String name;
private Integer age;
}
定義的接口:
package com.example.service;
import com.example.pojo.User;
/**
* 該地方只定義接口, 一般為公用接口
* 可以定義許多接口; 這里為了演示, 只定義一個(gè)
*/
public interface UserService {
User getUserById(int id);
}
說(shuō)明, 方便演示這里直接用的jar的方式被生產(chǎn)者和消費(fèi)者應(yīng)用, 實(shí)際項(xiàng)目中是打成jar包的形式給生產(chǎn)者/消費(fèi)者使用;
3.2 創(chuàng)建生產(chǎn)者
創(chuàng)建一個(gè)springboot項(xiàng)目; 然后編寫(xiě)接口的實(shí)現(xiàn)類(lèi)
使用到的jar:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--接口, 3.1我們定義的接口, 這里進(jìn)行引用-->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- dubbo starter 這里已經(jīng)集成了zookeeper的客戶端jar -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<!--myabtis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<!-- 使用阿里的數(shù)據(jù)庫(kù)數(shù)據(jù)源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
編寫(xiě)的類(lèi):
- myabtis的配置類(lèi), 這里不貼了, 不是關(guān)鍵代碼; 需要去看github上的demo
- 數(shù)據(jù)從數(shù)據(jù)庫(kù)里面拿的, dao + mapper這里也不貼了, 就是簡(jiǎn)單的根據(jù)用戶id查詢用戶數(shù)據(jù)
重點(diǎn), 實(shí)現(xiàn)類(lèi)
@Service 注解 import com.alibaba.dubbo.config.annotation.Service;
package com.example.dubboproducer.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.example.dubboproducer.dao.UserDao;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Service //這里是dubbo的注解, 將接口暴露在外, 可以供調(diào)用, 這里就是放在了注冊(cè)中心
//@org.springframework.stereotype.Service spring自己的注解, 為了區(qū)分, 使用了@Component
@Component //讓spring掃描該類(lèi), 用spring的 @Service也行
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public User getUserById(int id) {
return userDao.selectUserById(id);
}
}
yml配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/dubbo?useUnicode=true&characterEncoding=utf-8
username: root
password: root
mybatis-plus:
type-aliases-package: com.example.pojo
mapper-locations: classpath:mapper/*.xml
global-config:
db-config:
id-type: auto
#*****************分割線, 上面我就不解釋了, 下面是dubbo的配置************************
dubbo:
application:
name: dubbo-producer #dubbo的注冊(cè)的服務(wù)名, 唯一性
registry:
address: zookeeper://127.0.0.1:2181 #注冊(cè)zookeeper的地址
啟動(dòng)Dubbo配置:
@EnableDubbo 注解
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
package com.example.dubboproducer;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo //啟動(dòng)dubbo的配置
public class DubboProducerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProducerApplication.class, args);
}
}
3.3 創(chuàng)建消費(fèi)者
創(chuàng)建的方法和生產(chǎn)者類(lèi)似, 這里為了讓大家更好的看明白使用;
使用的jar:
這里直接調(diào)用生產(chǎn)者的服務(wù), 沒(méi)有其他的交互, 這里就沒(méi)有引用數(shù)據(jù)庫(kù)的工具
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<!-- 使用3.1的創(chuàng)建的接口 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
使用的類(lèi):
創(chuàng)建controller, 完成調(diào)用消費(fèi)者;
@Reference 注解 import com.alibaba.dubbo.config.annotation.Reference;
package com.example.dubboconsumer.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.example.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Reference //將生產(chǎn)者注冊(cè)到Dubbo映射到該對(duì)象上, 這里完成了服務(wù)之間的調(diào)用
private UserService userService;
@RequestMapping("/getUserById")
public Object getUserById (int id){
return userService.getUserById(id);
}
}
yml配置:
dubbo:
application:
name: dubbo-consumer
registry:
address: zookeeper://127.0.0.1:2181
server:
port: 8081 #應(yīng)為我這里是將服務(wù)起在一臺(tái)電腦, 和生產(chǎn)者的tomcat端口區(qū)分以免沖突
如果消費(fèi)者也有服務(wù)要注冊(cè)到Dubbo中, 也在啟動(dòng)類(lèi)上添加注解@EnbaleDubbo
3.4 測(cè)試
- 啟動(dòng)生產(chǎn)者
- 啟動(dòng)消費(fèi)者
兩者都沒(méi)有報(bào)錯(cuò), 并看到tomcat端口時(shí), 說(shuō)明啟動(dòng)成功; -
測(cè)試接口
測(cè)試成功.jpg - 查看zookeeper中注冊(cè)的服務(wù)
zookeeper中注冊(cè)的服務(wù).jpg
UserService 就是我們注冊(cè)在zookeeper中的服務(wù)

