# 基于Dubbo Protocol的Demo實現指南
## 前言
Dubbo作為一款高性能Java RPC框架,在分布式服務治理領域占據重要地位。本文將詳細介紹如何基于Dubbo協議實現一個完整的服務調用Demo,涵蓋環境搭建、接口定義、服務暴露與調用等核心環節。
## 一、環境準備
### 1.1 基礎環境要求
- JDK 1.8+
- Maven 3.5+
- Zookeeper 3.4+(注冊中心)
- IDE(IntelliJ IDEA或Eclipse)
### 1.2 Maven依賴配置
```xml
<!-- Dubbo核心依賴 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.0.7</version>
</dependency>
<!-- Zookeeper客戶端 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<!-- 序列化支持 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-kryo</artifactId>
<version>3.0.7</version>
</dependency>
建議將服務接口單獨作為模塊,供服務提供者和消費者共同依賴。
// UserService.java
public interface UserService {
User getUserById(Long id);
List<User> findUsersByCondition(UserQuery query);
}
// User.java
public class User implements Serializable {
private Long id;
private String name;
private Integer age;
// getters/setters...
}
// UserQuery.java
public class UserQuery implements Serializable {
private String namePrefix;
private Integer minAge;
// getters/setters...
}
public class UserServiceImpl implements UserService {
private final Map<Long, User> userStore = new ConcurrentHashMap<>();
@Override
public User getUserById(Long id) {
return userStore.get(id);
}
@Override
public List<User> findUsersByCondition(UserQuery query) {
return userStore.values().stream()
.filter(u -> query.getNamePrefix() == null ||
u.getName().startsWith(query.getNamePrefix()))
.filter(u -> query.getMinAge() == null ||
u.getAge() >= query.getMinAge())
.collect(Collectors.toList());
}
}
<!-- provider.xml -->
<dubbo:application name="user-service-provider"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:protocol name="dubbo" port="20880"/>
<bean id="userService" class="com.example.UserServiceImpl"/>
<dubbo:service interface="com.example.UserService" ref="userService"/>
@Configuration
@EnableDubbo(scanBasePackages = "com.example")
public class ProviderConfig {
@Bean
public RegistryConfig registryConfig() {
RegistryConfig config = new RegistryConfig();
config.setAddress("zookeeper://127.0.0.1:2181");
return config;
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig config = new ProtocolConfig();
config.setName("dubbo");
config.setPort(20880);
return config;
}
}
public class ProviderBootstrap {
public static void main(String[] args) throws Exception {
// XML方式
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("provider.xml");
context.start();
System.in.read(); // 阻塞等待
}
}
<!-- consumer.xml -->
<dubbo:application name="user-service-consumer"/>
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<dubbo:reference id="userService" interface="com.example.UserService"/>
@Configuration
@EnableDubbo(scanBasePackages = "com.example")
public class ConsumerConfig {
@Bean
public RegistryConfig registryConfig() {
RegistryConfig config = new RegistryConfig();
config.setAddress("zookeeper://127.0.0.1:2181");
return config;
}
}
@Service
public class UserAction {
@Reference
private UserService userService;
public void doInvoke() {
User user = userService.getUserById(1L);
System.out.println(user);
}
}
public class ConsumerBootstrap {
public static void main(String[] args) {
// XML方式
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("consumer.xml");
UserService userService = (UserService)context.getBean("userService");
// 調用示例
User user = userService.getUserById(1L);
System.out.println("查詢結果:" + user);
// 復雜查詢
UserQuery query = new UserQuery();
query.setNamePrefix("張");
query.setMinAge(18);
List<User> users = userService.findUsersByCondition(query);
System.out.println("條件查詢結果:" + users);
}
}
<dubbo:protocol name="dubbo"
port="20880"
dispatcher="all"
threadpool="fixed"
threads="200"
queues="0"
iothreads="4"
payload="8388608"/>
參數說明:
- dispatcher
: 消息派發策略
- threadpool
: 線程池類型(fixed/cached)
- payload
: 最大請求數據大?。?MB)
<dubbo:service interface="com.example.UserService"
ref="userService"
version="1.0.0"
timeout="3000"
retries="2"
loadbalance="random"/>
<dubbo:service interface="com.example.UserService" ref="userService">
<dubbo:method name="getUserById" timeout="1000" retries="0"/>
<dubbo:method name="findUsersByCondition" timeout="5000"/>
</dubbo:service>
<!-- 提供方 -->
<dubbo:service group="production" version="2.0.0" .../>
<!-- 消費方 -->
<dubbo:reference group="production" version="2.0.0" .../>
// 本地存根實現
public class UserServiceStub implements UserService {
private final UserService userService;
public UserServiceStub(UserService userService) {
this.userService = userService;
}
@Override
public User getUserById(Long id) {
try {
return userService.getUserById(id);
} catch (Exception e) {
// 降級邏輯
return new User(id, "默認用戶", 0);
}
}
}
配置方式:
<dubbo:reference stub="com.example.UserServiceStub" .../>
// 消費者端設置
RpcContext.getContext().setAttachment("token", "123456");
// 提供者端獲取
String token = RpcContext.getContext().getAttachment("token");
# log4j.properties
log4j.logger.org.apache.dubbo=DEBUG
log4j.logger.com.alibaba.dubbo=DEBUG
telnet 127.0.0.1 20880
> status
> ls
> invoke UserService.getUserById(1)
dubbo-demo/
├── dubbo-api/ # 接口定義
│ └── src/main/java/com/example/UserService.java
├── dubbo-provider/ # 服務提供者
│ ├── src/main/resources/provider.xml
│ └── src/main/java/com/example/UserServiceImpl.java
└── dubbo-consumer/ # 服務消費者
├── src/main/resources/consumer.xml
└── src/main/java/com/example/UserAction.java
通過本文的實踐,我們完成了基于Dubbo協議的完整服務調用Demo。在實際生產環境中,還需要考慮以下方面:
Dubbo的強大功能需要結合具體業務場景進行深度定制,建議參考官方文檔持續深入學習。
注意:本文基于Dubbo 3.x版本實現,部分配置與2.x版本存在差異 “`
該文檔共約3650字,采用標準的Markdown格式編寫,包含: 1. 多級標題結構 2. 代碼塊與語法高亮 3. 表格與參數說明 4. 項目結構樹形圖 5. 配置示例與最佳實踐 6. 版本兼容性說明
可根據實際需求調整具體實現細節,建議配合Dubbo官方文檔使用以獲得最佳效果。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。