1 dubbo-helloworld xml版
1)需求
某個電商系統,訂單服務需要調用用戶服務獲取某個用戶的所有地址;我們現在 需要創建兩個服務模塊進行測試
模塊 | 功能 |
---|---|
訂單服務web模塊 | 創建訂單等 |
用戶服務service模塊 | 查詢用戶地址等 |
測試預期結果:訂單服務web模塊在A服務器,用戶服務模塊在B服務器,A可以遠程調用B的功能。
2)工程架構
根據 dubbo《服務化最佳實踐》
(1)分包
建議將服務接口,服務模型,服務異常等均放在 API 包中,因爲服務模型及異常也是 API 的一部分,同時,這樣做也符合分包原則:重用發佈等價原則(REP),共同重用原則(CRP)。如果需要,也可以考慮在 API 包中放置一份 spring 的引用配置,這樣使用方,只需在 spring 加載過程中引用此配置即可,配置建議放在模塊的包目錄下,以免衝突,如:com/alibaba/china/xxx/dubbo-reference.xml。
(2)粒度
服務接口儘可能大粒度,每個服務方法應代表一個功能,而不是某功能的一個步驟,否則將面臨分佈式事務問題,Dubbo 暫未提供分佈式事務支持。服務接口建議以業務場景爲單位劃分,並對相近業務做抽象,防止接口數量爆炸。不建議使用過於抽象的通用接口,如:Map query(Map),這樣的接口沒有明確語義,會給後期維護帶來不便。
3)創建空工程,新建3個模塊
(1)新建一個empty project (maven)
新建3個moudle(maven)
order-service(具體實現)
user-service(具體實現)
common-interface(提取所有的接口和bean)
配置好maven環境變量
(2)user-service moudle
a)添加maven依賴
<dependencies>
<!-- 引入dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由於我們使用zookeeper作爲註冊中心,所以需要操作zookeeper
dubbo 2.6以前的版本引入zkclient操作zookeeper
dubbo 2.6及以後的版本引入curator操作zookeeper
下面兩個zk客戶端根據dubbo版本2選1即可
-->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>com.tang</groupId>
<artifactId>common-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
b )新建UserAddress Bean模型
public class UserAdress implements Serializable {
private Integer id;
private String userAddress;
private String userId;
private String consignee;
private String phoneNum;
private String isDefault;
public UserAdress(Integer id, String userAddress, String userId, String consignee, String phoneNum, String isDefault) {
this.id = id;
this.userAddress = userAddress;
this.userId = userId;
this.consignee = consignee;
this.phoneNum = phoneNum;
this.isDefault = isDefault;
}
}
c )編寫UserService接口以及UserServiceImpl實現類
public interface UserService {
public List<UserAdress> getUserAddressList(String userId);
}
public class UserServiceImpl implements UserService {
public List<UserAdress> getUserAddressList(String userId){
UserAdress u1=new UserAdress(1,"ezhou","123","","15168242649","y");
UserAdress u2=new UserAdress(1,"ezhou","123","","15168242649","y");
return Arrays.asList(u1,u2);
}
}
d)新建provider.xml配置文件(dubbo服務提供者配置),編輯文件
參考開發文檔:dubbo.apache.org/zh-cn/docs/user/quick-start.html
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 1、指定當前服務/應用的名字(同樣的服務名字相同,不要和別的服務同名) -->
<dubbo:application name="userserviceprovider"></dubbo:application>
<!-- 2、指定註冊中心的位置 -->
<!-- <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
<!-- 3、指定通信規則(通信協議?通信端口) -->
<dubbo:protocol name="dubbo" port="20882"></dubbo:protocol>
<!-- 4、暴露服務 ref:指向服務的真正的實現對象 -->
<dubbo:service interface="com.service.UserService"
ref="userService">
<!-- <dubbo:method name="getUserAddressList" timeout="1000"></dubbo:method> -->
</dubbo:service>
<!--統一設置服務提供方的規則 -->
<dubbo:provider timeout="1000"></dubbo:provider>
<!-- 服務的實現 -->
<bean id="userService" class="com.tang.service.impl.UserServiceImpl"></bean>
</beans>
e)編寫測試代碼UserApplication
新建 UserApplication
public class UserApplication {
public static void main(String[] args) throws IOException{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:provider.xml");
System.in.read();
}
}
f)啓動user-service 進行測試
查看dubbo服務管理界面是否有對應的服務提供者,具體參考https://mp.csdn.net/mdeditor/95346703#
在zk安裝bin目錄下 啓動zkServer腳本
java -jar 執行dubbo-admin的maven打包文件
localhost:7001訪問
(3) order-service moudle 訂單模塊(調用用戶模塊)
a ) 添加maven依賴
<?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.tang</groupId>
<artifactId>order-service</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.tang</groupId>
<artifactId>common-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
b)編寫OrderService接口以及OrderServiceImpl實現
public interface OrderService {
/**
* 初始化訂單,查詢用戶的所有地址並返回
* @param userId
* @return
*/
public List<UserAdress> initOrder(String userId);
}
@Service
public class OrderServiceImpl implements OrderService {
@Resource
UserService userService;
/**
* 初始化訂單,查詢用戶的所有地址並返回
* @param userId
* @return
*/
public List<UserAdress> initOrder(String userId){
return userService.getUserAddressList(userId);
}
}
c)編寫consumer.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<context:component-scan base-package=“com.service.impl”></context:component-scan>
<dubbo:application name=“orderserviceconsumer”></dubbo:application>
<!-- 2、指定註冊中心的位置 -->
<!-- <dubbo:registry address="zookeeper://127.0.0.1:2181"></dubbo:registry> -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181"></dubbo:registry>
<dubbo:reference id="userService" interface="com.service.UserService"></dubbo:reference>
d)編寫測試代碼
public class OrderApplication {
public static void main(String[] args) throws IOException{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:consumer.xml");
OrderService orderService =context.getBean(OrderService.class);
List<UserAdress> address=orderService.initOrder("1");
System.out.println(address.get(0).toString());
System.in.read();
}
}
e) 測試調用
訪問orderService的initOrder請求,會調用UserService獲取用戶地址;
調用成功。說明我們order已經可以調用遠程的UserService了;
目前無法調用,因爲UserAdress與UserService在用戶moudel工程中,需要將這些被第三方調用的接口和bean單獨提取出來作爲一個moudel工程爲其他調用者提供maven依賴
(4)common-interface modile 公共接口層(bean,service,exception…)
作用:定義公共接口,也可以導入公共依賴
a)將user-service moule中的接口和bean實體提取到common-interface modile
b)將order-service moule中的接口和bean實體提取到common-interface modile
c ) 將 common-interface modile 的maven 座標信息添加到 user-service moule和
order-service moule 的pom.xml文件中
(5)啓動 user-service,order-service
查看dubbo服務管理界面
2 註解版
與xml版基本相同,不同的地方如下
1)服務提供方
<dubbo:application name=“gmall-user”></dubbo:application>
<dubbo:registry address=“zookeeper://localhost:2181” />
<dubbo:protocol name=“dubbo” port=“20880” />
<dubbo:annotation package=“com.atguigu.gmall.user.impl”/>需要暴露的接口的包
import com.alibaba.dubbo.config.annotation.Service;
import com.atguigu.gmall.bean.UserAddress;
import com.atguigu.gmall.service.UserService;
import com.atguigu.gmall.user.mapper.UserAddressMapper;
@Service //使用dubbo提供的service註解,註冊暴露服務
public class UserServiceImpl implements UserService {
@Autowired
UserAddressMapper userAddressMapper;
2 ) 服務消費方
<dubbo:application name=“gmall-order-web”></dubbo:application>
<dubbo:registry address=“zookeeper://118.24.44.169:2181” />
<dubbo:annotation package=“com.atguigu.gmall.order.controller”/>需要調用的接口的包
@Controller
public class OrderController {
@Reference //使用dubbo提供的reference註解引用遠程服務
UserService userService;