Spring Boot Dubbo 建構分布式服務
概述:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLi0zaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLwkzX39GZhh2csATMflHLwEzX4xSZz91ZsADMx8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PnVGcq5COiRjN2EzY1UTN4cTNjJTM5UTZwUzY5UWNmVmY3UGMk9CXxIzLcZDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL2M3Lc9CX6MHc0RHaiojIsJye.jpeg)
節點角色說明
節點 | 角色說明 |
---|---|
Provider | 暴露服務的服務提供方 |
Consumer | 調用遠端服務的服務消費方 |
Registry | 服務注冊與發現的注冊中心 |
Monitor | 統計服務的調用次數和調用時間的監控中心 |
Container | 服務運作的容器 |
調用關系說明
- 服務容器 Container 負責啟動,加載,運作服務提供者。
- 服務提供者 Provider 啟動的時候,向注冊中心 Registry 注冊自己提供的服務。
- 服務消費者 Consumer 在啟動的時候,向注冊中心 Registry 訂閱自己所需要的服務。
- 注冊中心 Registry 傳回服務提供者的位址清單給消費者,如果有變更注冊中心将基于長連接配接推送變更資料給消費者。
- 服務消費者從提供者位址清單中,基于軟負載均衡算法,選擇一台提供者進行進行調用,如果調用失敗再選擇另外一台。
- 服務消費者與提供者在記憶體中統計調用次數和調用時間,定時每分鐘發送一次統計資料到監控中心 Monitor 。
項目建構
開發環境主要涉及以下方面:
- Spring Boot
- JDK 8
- Dubbo 2.7.1
- Zookeeper
具體代碼可以檢視 github 的 dubbo 子產品:https://github.com/UniqueDong/springboot-study
Dubbo API
定義服務接口,打成 jar 包讓消費者依賴,服務者實作接口。該工程隻有接口定義以及 model 對象。@Data 屬于lombok 開源庫提供的特性,友善開發。
- model 對象定義:
-
@Data
-
public class User implements Serializable {
-
private Long id;
-
private String username;
-
}
- provider 接口定義:
-
public interface UserProvider {
-
List<User> listUser();
-
}
Provider 服務提供者
- pom依賴:
引入spring-boot-starter,dubbo-api 接口就是我們上面提到的 接口定義 jar ,dubbo-spring-boot-starter ,dubbo-dependencies-zookeeper。
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter</artifactId>
-
<exclusions>
-
<exclusion>
-
<artifactId>spring-boot-starter-logging</artifactId>
-
<groupId>org.springframework.boot</groupId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<dependency>
-
<groupId>zero.springboot.study</groupId>
-
<artifactId>dubbo-api</artifactId>
-
<version>1.0.0-SNAPSHOT</version>
-
</dependency>
-
<!--dubbo start-->
-
<dependency>
-
<groupId>org.apache.dubbo</groupId>
-
<artifactId>dubbo-spring-boot-starter</artifactId>
-
<version>2.7.1</version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.dubbo</groupId>
-
<artifactId>dubbo</artifactId>
-
<version>2.7.1</version>
-
</dependency>
-
<!-- Zookeeper dependencies -->
-
<dependency>
-
<groupId>org.apache.dubbo</groupId>
-
<artifactId>dubbo-dependencies-zookeeper</artifactId>
-
<version>2.7.1</version>
-
<type>pom</type>
-
<exclusions>
-
<exclusion>
-
<artifactId>log4j</artifactId>
-
<groupId>log4j</groupId>
-
</exclusion>
-
<exclusion>
-
<artifactId>slf4j-log4j12</artifactId>
-
<groupId>org.slf4j</groupId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<!--dubbo end-->
-
<dependency>
-
<groupId>com.alibaba</groupId>
-
<artifactId>fastjson</artifactId>
-
<version>1.2.57</version>
-
</dependency>
-
</dependencies>
- 配置檔案 yaml 定義:
-
spring:
-
application:
-
name: dubbo-provider
-
#自定義配置
-
embedded:
-
zookeeper:
-
# zookeeper 服務連接配接端口
-
port: 2181
-
# dubbo 配置
-
dubbo:
-
# 注冊中心配置
-
registry:
-
id: dubbo-provider
-
address: zookeeper://127.0.0.1:${embedded.zookeeper.port}
-
group: local
-
application:
-
name: dubbo-provider
-
id: dubbo-provider
-
logger: slf4j
-
qosEnable: true
-
qosPort: 22224
-
qosAcceptForeignIp: false
-
# dubbo 協定配置
-
protocol:
-
# -1 表示使用随機未被占用的端口
-
port: -1
-
name: dubbo
-
scan:
-
# dubbo 服務提供者實作類所在包
-
base-packages: com.zero.provider.impl
-
實作 api 定義的接口
注意 @Service 是 Dubbo 的,不要導入了 Spring 的。
-
import com.google.common.collect.Lists;
-
import com.zero.api.model.User;
-
import com.zero.api.provider.UserProvider;
-
import org.apache.dubbo.config.annotation.Service;
-
import java.util.List;
-
@Service(interfaceClass = UserProvider.class)
-
public class UserProviderImpl implements UserProvider {
-
@Override
-
public List<User> listUser() {
-
User user = new User();
-
user.setId(1L);
-
user.setUsername("青龍");
-
return Lists.newArrayList(user);
-
}
-
}
- Pom 定義:
我們要依賴 spring-boot-starter-web 提供http rest接口給前端調用。同時内部通過 Dubbo 實作 RPC調用服務提供者。
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-web</artifactId>
-
<exclusions>
-
<exclusion>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-logging</artifactId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<dependency>
-
<groupId>zero.springboot.study</groupId>
-
<artifactId>dubbo-api</artifactId>
-
<version>1.0.0-SNAPSHOT</version>
-
</dependency>
-
<!--dubbo start-->
-
<dependency>
-
<groupId>org.apache.dubbo</groupId>
-
<artifactId>dubbo-spring-boot-starter</artifactId>
-
<version>2.7.1</version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.dubbo</groupId>
-
<artifactId>dubbo</artifactId>
-
<version>2.7.1</version>
-
</dependency>
-
<!-- Zookeeper dependencies -->
-
<dependency>
-
<groupId>org.apache.dubbo</groupId>
-
<artifactId>dubbo-dependencies-zookeeper</artifactId>
-
<version>2.7.1</version>
-
<type>pom</type>
-
<exclusions>
-
<exclusion>
-
<artifactId>log4j</artifactId>
-
<groupId>log4j</groupId>
-
</exclusion>
-
<exclusion>
-
<artifactId>slf4j-log4j12</artifactId>
-
<groupId>org.slf4j</groupId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<!--dubbo end-->
-
<dependency>
-
<groupId>org.projectlombok</groupId>
-
<artifactId>lombok</artifactId>
-
<optional>true</optional>
-
</dependency>
-
</dependencies>
- yaml 定義:
-
server:
-
# web 日更年期端口
-
port: 9005
-
spring:
-
application:
-
name: dubbo-comsumer
-
#自定義配置
-
embedded:
-
zookeeper:
-
port: 2181
-
# dubbo 配置
-
dubbo:
-
registry:
-
id: dubbo-comsumer
-
address: zookeeper://127.0.0.1:${embedded.zookeeper.port}
-
group: local
-
application:
-
name: dubbo-comsumer
-
id: dubbo-comsumer
-
logger: slf4j
-
qosEnable: false
-
qosPort: 22223
-
qosAcceptForeignIp: false
-
protocol:
-
port: -1
-
name: dubbo
-
# 是否檢查服務提供者有效
-
consumer:
-
check: false
- 服務消費者調用服務生産者
-
import com.zero.api.model.User;
-
import com.zero.api.provider.UserProvider;
-
import org.apache.dubbo.config.annotation.Reference;
-
import org.springframework.stereotype.Service;
-
import java.util.List;
-
@Service
-
public class UserService {
-
@Reference
-
private UserProvider userProvider;
-
public List<User> listUser() {
-
return userProvider.listUser();
-
}
-
}
- 我們通過一個RESTfull接口,提供給前端調用。
-
@RestController
-
@RequestMapping("/users")
-
public class UserController {
-
@Autowired
-
private UserService userService;
-
@GetMapping
-
public Object listUser() {
-
List<User> list = userService.listUser();
-
return list;
-
}
-
}