4.1)、提出需求
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;
我们现在 需要创建两个服务模块进行测试
| #模块# | 功能 |
| 订单服务web模块 | 创建订单等 |
| 用户服务service模块 | 查询用户地址等 |
测试预期结果:
订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。
4.2)、工程架构
根据 dubbo《服务化最佳实践》
1、分包
建议将服务接口,服务模型,服务异常等均放在 API 包中,因为服务模型及异常也是 API 的一部分,同时,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。
如果需要,也可以考虑在 API 包中放置一份 spring 的引用配置,这样使用方,只需在 spring 加载过程中引用此配置即可,配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml。
2、粒度
服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。
不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。

4.3)、创建模块
1、gmall-interface:公共接口层(model,service,exception…)
作用:定义公共接口,也可以导入公共依赖
1、Bean模型
public class UserAddress implements Serializable{
private Integer id;
private String userAddress;
private String userId;
private String consignee;
private String phoneNum;
private String isDefault;
}
3、Service接口
UserService
public List<UserAddress> getUserAddressList(String userId)

2、gmall-user:用户模块(对用户接口的实现)
1、pom.xml
<dependencies>
<dependency>
<groupId>com.atguigu.dubbo</groupId>
<artifactId><u>gmall</u>-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
2、Service
public class UserServiceImpl implements UserService {
@Override
public List<UserAddress> getUserAddressList(String userId) {
// **TODO** Auto-generated method stub
return userAddressDao.getUserAddressById(userId);
}
}
4、gmall-order-web:订单模块(调用用户模块)
1、pom.xml
<dependencies>
<dependency>
<groupId>com.atguigu.dubbo</groupId>
<artifactId>gmall-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
2、测试
public class OrderService {
UserService userService;
/**
* 初始化订单,查询用户的所有地址并返回
* @param userId
* @return
*/
public List<UserAddress> initOrder(String userId){
return userService.getUserAddressList(userId);
}
}
现在这样是无法进行调用的。我们gmall-order-web引入了gmall-interface,但是interface的实现是gmall-user,我们并没有引入,而且实际他可能还在别的服务器中。
4.4)、使用dubbo改造
1、改造gmall-user作为服务提供者
1、引入dubbo
<!-- 引入<u>dubbo</u> -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId><u>dubbo</u></artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由于我们使用<u>zookeeper</u>作为注册中心,所以需要操作zookeeper
dubbo 2.6以前的版本引入<u>zkclient</u>操作<u>zookeeper</u>
dubbo 2.6及以后的版本引入<u>curator操作</u><u>z</u><u>ookeeper</u>
<u>下面两个</u><u>z</u><u>k客户端根据</u><u>d</u><u>ubbo版本</u><u>2选1即可</u>
-->
<dependency>
<groupId><u>com</u>.101tec</groupId>
<artifactId><u>zkclient</u></artifactId>
<version>0.10</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId><u>curator</u>-framework</artifactId>
<version>2.12.0</version>
</dependency>
2、配置提供者
<!--当前应用的名字 -->
<dubbo:application name=*"gmall-user"*></dubbo:application>
<!--指定注册中心的地址 -->
<dubbo:registry address=*"zookeeper://118.24.44.169:2181"* />
<!--使用<u>dubbo</u>协议,将服务暴露在20880端口 -->
<dubbo:protocol name=*"dubbo"* port=*"20880"* />
<!-- 指定需要暴露的服务 -->
<dubbo:service interface=*"com.atguigu.gmall.service.UserService"* ref=*"userServiceImpl"* />
3、启动服务
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext <u>context</u> = new ClassPathXmlApplicationContext("classpath:spring-
beans.xml");
System.in.read();
}
2、改造gmall-order-web作为服务消费者
1、引入dubbo
<!-- 引入<u>dubbo</u> -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId><u>dubbo</u></artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由于我们使用<u>zookeeper</u>作为注册中心,所以需要引入<u>zkclient</u>和<u>curator</u>操作<u>zookeeper</u> -->
<dependency>
<groupId><u>com</u>.101tec</groupId>
<artifactId><u>zkclient</u></artifactId>
<version>0.10</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId><u>curator</u>-framework</artifactId>
<version>2.12.0</version>
</dependency>
2、配置消费者信息
<!-- 应用名 -->
<dubbo:application name=*"gmall-order-web"*></dubbo:application>
<!-- 指定注册中心地址 -->
<dubbo:registry address=*"zookeeper://118.24.44.169:2181"* />
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id=*"userService"* interface=*"com.atguigu.gmall.service.UserService"*></dubbo:reference>
3、测试调用
访问gmall-order-web的initOrder请求,会调用UserService获取用户地址;
调用成功。说明我们order已经可以调用远程的UserService了;
4、注解版
1、服务提供方
<dubbo:application name=*"gmall-user"*></dubbo:application>
<dubbo:registry address=*"zookeeper://118.24.44.169: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;
网友评论