一胁澳、前言
最近接到公司的項目, 其中技術用到了springboot、 dubbo米者、 zookeeper韭畸、 activiti、 kafka等, 有些東西是比較熟悉, 有些只是稍微看過, 還不是很懂; 個人認為做一個項目就要去了解該項目用的所有技術, 知己知彼方能百戰(zhàn)不殆嘛; 后面我也會陸續(xù)更新相關技術棧的搭建~然后慢慢的深入的去了解;
可以先下載demo看一看~~~~
Dubbo_Github_Demo
二蔓搞、Dubbo
Dubbo官網(wǎng)
上面有詳細的Dubb文檔, 但是在創(chuàng)建Dubbo項目時讓我一頭霧水, 網(wǎng)上也找了相關的視頻看, 也是很懵逼; 這里官網(wǎng)給的文檔, 跟alibaba的github上面的案例又不一樣; 下面我講寫一個我自己搭成功的案例
1. Dubbo是什么
Dubbo是阿里巴巴公司開源的一個高性能優(yōu)秀的服務框架胰丁,使得應用可通過高性能的 RPC 實現(xiàn)服務的輸出和輸入功能,可以和 Spring框架無縫集成喂分。
Dubbo是一款高性能隘马、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用妻顶,智能容錯和負載均衡酸员,以及服務自動注冊和發(fā)現(xiàn)。
Dubbo和SpringCloud一樣, 是一個分布式框架, 如果對SpringCloud有興趣的可以:
1. SrpingCloud之Eureka--服務治理
2. SrpingCloud使用過Eureka怎么進行服務間相互訪問--Feign
3. SrpingCloud調用方法異常怎么辦--Hystrix使用講解
4. SrpingCloud服務之間的負載均衡
2. Dubbo的架構
執(zhí)行流程:
- Provider:服務的提供者讳嘱,負責對外提供服務幔嗦,提供者在啟動的時候,需要向Registry注冊自己能夠提供
的服務- Consumer:服務的消費者沥潭,消費者在啟動的時候邀泉,需要向Registry訂閱自己需要的服務
- Registry:注冊中心,授受注冊和訂閱钝鸽,會異步的通知訂閱者汇恤,向消費者提供服務列表
- 當消費者需要執(zhí)行遠程過程調用時,會從Registry獲取到服務地址列表(基于負載均衡算法)進行調用拔恰,
如果調用失敗會重新選擇新的提供者再次調用- Monitor:監(jiān)控中心因谎,統(tǒng)計服務的調用次數(shù)和調用時間,服務消費者和提供者會在內(nèi)存中累計調用次數(shù)和
調用時間颜懊,定時每分鐘向監(jiān)控中心發(fā)送一次統(tǒng)計數(shù)據(jù)
3. Dubbo創(chuàng)建三部曲
3.1 創(chuàng)建一個接口
這里說接口, 我個人認為可以將一些公用的類放在一個工程里面, 通過jar包形式使項目之間相互引用, 這里我只放了實體類, 定義的接口(service接口)
使用到的jar:
<!-- 簡化開發(fā)的工具, 這里只用到在實體類上@Data注解,
減少get/set方法生成, 使用時在ide添加插件, 不會自行百度 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
創(chuàng)建的類:
這里強調下,~返回對象一定要實現(xiàn)Serializable接口, 不然會序列化失敗;
package com.example.pojo;
import lombok.Data;
import java.io.Serializable;
/**
* 用戶
*/
@Data
//這里注意下, 一定要實現(xiàn)Serializable接口~, 不然消費者調用返回json時候會序列化失敗
public class User implements Serializable{
private Integer id;
private String name;
private Integer age;
}
定義的接口:
package com.example.service;
import com.example.pojo.User;
/**
* 該地方只定義接口, 一般為公用接口
* 可以定義許多接口; 這里為了演示, 只定義一個
*/
public interface UserService {
User getUserById(int id);
}
說明, 方便演示這里直接用的jar的方式被生產(chǎn)者和消費者應用, 實際項目中是打成jar包的形式給生產(chǎn)者/消費者使用;
3.2 創(chuàng)建生產(chǎn)者
創(chuàng)建一個springboot項目; 然后編寫接口的實現(xiàn)類
使用到的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我們定義的接口, 這里進行引用-->
<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ù)庫數(shù)據(jù)源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
編寫的類:
- myabtis的配置類, 這里不貼了, 不是關鍵代碼; 需要去看github上的demo
- 數(shù)據(jù)從數(shù)據(jù)庫里面拿的, dao + mapper這里也不貼了, 就是簡單的根據(jù)用戶id查詢用戶數(shù)據(jù)
重點, 實現(xiàn)類
@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的注解, 將接口暴露在外, 可以供調用, 這里就是放在了注冊中心
//@org.springframework.stereotype.Service spring自己的注解, 為了區(qū)分, 使用了@Component
@Component //讓spring掃描該類, 用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的注冊的服務名, 唯一性
registry:
address: zookeeper://127.0.0.1:2181 #注冊zookeeper的地址
啟動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 //啟動dubbo的配置
public class DubboProducerApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProducerApplication.class, args);
}
}
3.3 創(chuàng)建消費者
創(chuàng)建的方法和生產(chǎn)者類似, 這里為了讓大家更好的看明白使用;
使用的jar:
這里直接調用生產(chǎn)者的服務, 沒有其他的交互, 這里就沒有引用數(shù)據(jù)庫的工具
<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>
使用的類:
創(chuàng)建controller, 完成調用消費者;
@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)者注冊到Dubbo映射到該對象上, 這里完成了服務之間的調用
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 #應為我這里是將服務起在一臺電腦, 和生產(chǎn)者的tomcat端口區(qū)分以免沖突
如果消費者也有服務要注冊到Dubbo中, 也在啟動類上添加注解@EnbaleDubbo
3.4 測試
- 啟動生產(chǎn)者
- 啟動消費者
兩者都沒有報錯, 并看到tomcat端口時, 說明啟動成功; -
測試接口
測試成功.jpg - 查看zookeeper中注冊的服務
zookeeper中注冊的服務.jpg
UserService 就是我們注冊在zookeeper中的服務