文 | 平哥 日期 | 20201013java
具體代碼詳見GitHub倉庫:點我跳轉git
此項目爲本身學習Dubbo+Zookeeper,搭建的第一個項目,主要架構就是一個父項目、三個子Module:dubbo_provider、 dubbo_consumer 和 dubbo_api,三個子Module分別繼承父項目。github
Dubbo的遠程訪問是基於接口的。Consumer和Provider使用同一個接口,能夠實現遠程訪問。web
p.s. 此項目重點是練習Dubbo+Zookeeper,故沒有寫鏈接數據庫的內容,只是模擬了訪問數據庫。spring
用IDEA建立項目,建立完項目目錄以下:數據庫
直接上代碼:apache
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.gcp</groupId> <artifactId>dubbo_pro01</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>dubbo_provider</module> <module>dubbo_consumer</module> <module>dubbo_api</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent> <dependencies> <!--springboot 啓動器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!--lombok依賴--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--dubbo springboot啓動器--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.8</version> </dependency> <!--curator依賴--> <!--Curator提供了一套Java類庫, 能夠更容易的使用ZooKeeper。 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>5.1.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>5.1.0</version> </dependency> </dependencies> </project>
package com.gcp.pojo; import lombok.Data; @Data public class User { private Long id; private String name; private String password; }
package com.gcp.service; import com.gcp.pojo.User; /** * 用戶服務接口 */ public interface UserService { void register(User user); User getUserById(Long id); }
在pom.xml文件中添加依賴:api
<dependencies> <dependency> <groupId>com.gcp</groupId> <artifactId>dubbo_api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
UserMapper接口:瀏覽器
import com.gcp.pojo.User; /** * 模擬數據庫訪問 */ public interface UserMapper { void insert(User user); User selectById(Long id); }
UserMapperImpl實現類:springboot
@Repository public class UserMapperImpl implements UserMapper { @Override public void insert(User user) { System.out.println("數據庫訪問:新增用戶 - " + user); } @Override public User selectById(Long id) { User user = new User(); user.setId(id); user.setName("name" + id); user.setPassword("password" + id); System.out.println("數據庫訪問:主鍵查詢用戶 - " + user); return user; } }
@DubboService(loadbalance = "roundrobin")
, 其中 loadbalance = "roundrobin"
意思是若是此服務有集羣將採用輪詢的方式進行負載均衡訪問,
默認是 random
:隨機
@DubboService(loadbalance = "roundrobin") public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public void register(User user) { System.out.println("UserService 實現類中:註冊用戶"); userMapper.insert(user); } @Override public User getUserById(Long id) { System.out.println("UserService 實現類中:根據id查詢用戶"); return userMapper.selectById(id); } }
說明:
在 resources 文件夾下建立application.yml:
dubbo: # dubbo配置根節點 registry: # 配置dubbo的註冊中心 registry address: zookeeper://192.168.40.170:2181 # 提供註冊中心的訪問地址。 application: # 配置本dubbo應用信息 name: gcp-dubbo-first-provider # 配置本dubbo的應用名稱,名稱組成是:字母,數字,'-',字母開頭 protocol: # 協議,協議自定義配置的時候,全部的默認值失效。 name: dubbo # 協議名 port: 20880 # 端口,默認20880
如何安裝Zookeeper能夠詳見我另外一篇文章
*
在 com.gcp
包下建立SpringBoot啓動類:
@SpringBootApplication @EnableDubbo // @EnableDubboConfig public class DbProviderApplication { public static void main(String[] args) { SpringApplication.run(DbProviderApplication.class,args); } }
此時可啓動,測試看Zookeeper中是否成功註冊上服務,訪問Linux服務器,利用Zookeeper客戶端工具查看:
在pom.xml文件中添加依賴:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.gcp</groupId> <artifactId>dubbo_api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
有人可能會疑惑,Zookeeper註冊中心中已經有提供的Service服務了,怎麼本地還須要Service?
說明: 其實,dubbo遠程服務調用,是爲了 封裝通用規則,但各個子項目有本身的個性邏輯
如:用戶的註冊邏輯,在一個企業中是統一的。提供一個Provider實現註冊邏輯;
對於consumer來講,是不一樣的,能夠提供若干入口。如騰訊的用戶註冊,能夠經過QQ、QQ音樂、QQ空間等實現註冊或登陸。底層的用戶是相同的。
LocalUserService接口:
package com.gcp.service; import com.gcp.pojo.User; /** * consumer子Module的本地Service */ public interface LocalUserService { void register(User user); User getById(Long id); }
LocalUserServiceImpl實現類:
@Service public class LocalUserServiceImpl implements LocalUserService { /** * 遠程服務的接口。經過註解@DubboReference實現動態代理建立 * 規則: * 一、 通知Dubbo框架,根據配置找註冊中心,發現服務的地址。 * 拿接口名稱做爲zookeeper中節點的命名規則,獲取地址。 * 二、 通知Spring,根據Dubbo框架的特性,建立接口的動態代理對象,並維護 * 在Spring容器中。 * 三、 相似@Autowired,把代理對象注入到當前的變量中。 */ @DubboReference private UserService userService; @Override public void register(User user) { System.out.println("準備調用遠程服務,服務對象類型是:" + userService.getClass().getName()); System.out.println("註冊的用戶是: " + user); userService.register(user); } @Override public User getById(Long id) { System.out.println("根據主鍵查詢用戶,主鍵是: " + id); return userService.getUserById(id); } }
UserController類:
@RestController public class UserController { @Autowired private LocalUserService localUserService; @RequestMapping("findUser") public User findUser(Long id){ return localUserService.getById(id); } @RequestMapping("registerUser") public String register(User user){ localUserService.register(user); return "註冊用戶成功"; } }
在 resources 文件夾下建立 application.yml:
dubbo: registry: address: zookeeper://192.168.40.170:2181
在 com.gcp 包下建立 DbConsumerApplication:
@SpringBootApplication @EnableDubbo public class DbConsumerApplication { public static void main(String[] args) { SpringApplication.run(DbConsumerApplication.class,args); } }
啓動consumer的啓動類,查看Zookeeper註冊中心是否註冊成功:
打開瀏覽器,輸入consumer訪問地址,測試是否能夠正常訪問:
後臺輸出:
consumer 子 Module:
provider 子 Module:
至此,項目搭建建立成功,你們能夠本身多複製幾個provider和consumer子Module的啓動類,把端口都改爲不同試試集羣輪詢、隨機訪問的效果。
具體代碼詳見GitHub倉庫:點我跳轉