1.需求
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;
我们现在 需要创建两个服务模块进行测试
模块 | 功能 |
订单服务web模块 | 创建订单等 |
用户服务service模块 | 查询用户地址等 |
测试预期结果:
订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。
2.工程架构
根据 dubbo《服务化最佳实践》
2.1分包
建议将服务接口,服务模型,服务异常等均放在 API 包中,因为服务模型及异常也是 API 的一部分,同时,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。
如果需要,也可以考虑在 API 包中放置一份 spring 的引用配置,这样使用方,只需在 spring 加载过程中引用此配置即可,配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml。
2.2粒度
服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。
不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。
文件结构如下:
3.创建dubbo-interface
3.1pom.xml
<properties>
<lombok.version>1.18.10</lombok.version>
</properties>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
3.2创建UserAddress
package com.dubbointerface.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAddress implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String userAddress;
private String userId;
}
3.3 创建UserService
package com.dubbointerface.service;
import com.dubbointerface.domain.UserAddress;
import java.util.List;
public interface UserService {
/**
* 查询用户所有的地址
*/
public List<UserAddress> queryAllAddress(String userId);
}
3.4OrderService
package com.dubbointerface.service;
import com.dubbointerface.domain.UserAddress;
import java.util.List;
public interface OrderService {
public List<UserAddress> initOrder(String userId);
}
4.创建dubbo-provider
4.1pom.xml文件
<dependency>
<groupId>com.dubbointerface</groupId>
<artifactId>dubbo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
4.2创建UserServiceImpl
package com.dubbo.provider.service.impl;
import com.dubbointerface.domain.UserAddress;
import com.dubbointerface.service.UserService;
import java.util.ArrayList;
import java.util.List;
public class UserServiceImpl implements UserService {
public static List<UserAddress> address = new ArrayList<>();
static {
address.add(new UserAddress(1, "湖北省武汉市东湖高新区金融港B22栋11楼", "whsxt"));
address.add(new UserAddress(2, "北京市海淀区西三旗街道建材城西路中腾建华商务大厦东侧二层尚学堂", "bjsxt"));
}
@Override
public List<UserAddress> queryAllAddress(String userId) {
System.out.println("20881");
return address;
}
}
4.3创建applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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">
<!-- 声明应用程序的名称 -->
<dubbo:application name="dubbo-user-service-provider"></dubbo:application>
<!--指定注册中心的地址 -->
<dubbo:registry
address="zookeeper://127.0.0.1:2181"></dubbo:registry>
<!--使用dubbo协议,将服务暴露在20880端口 -->
<dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
<!-- 声明要暴露的实现类的对象 -->
<bean id="userService"
class="com.dubbo.provider.service.impl.UserServiceImpl"></bean>
<!-- 进行服务暴露 -->
<dubbo:service interface="com.dubbointerface.service.UserService"
ref="userService"></dubbo:service>
</beans>
4.4创建测试类
package com.dubbo.provider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class TestProvider {
public static void main(String[] args) throws IOException {
ApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("服务提供者启动成功");
System.in.read();
}
}
5.创建dubbo-consumer
5.1修改pom.xml
<dependency>
<groupId>com.dubbointerface</groupId>
<artifactId>dubbo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
5.2创建OrderServiceImpl
package com.dubbo.consumer.service.impl;
import com.dubbointerface.domain.UserAddress;
import com.dubbointerface.service.OrderService;
import com.dubbointerface.service.UserService;
import java.util.List;
public class OrderServiceImpl implements OrderService {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public List<UserAddress> initOrder(String userId) {
return userService.queryAllAddress(userId);
}
}
5.3创建applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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">
<!-- 声明应用程序的名称 -->
<dubbo:application name="dubbo-order-service-consumer"></dubbo:application>
<!--指定注册中心的地址 -->
<dubbo:registry
address="zookeeper://127.0.0.1:2181"></dubbo:registry>
<!-- 生成远程调用对象 -->
<dubbo:reference id="userService" interface="com.dubbointerface.service.UserService"></dubbo:reference>
<!-- 创建订单对象 -->
<bean id="orderService" class="com.dubbo.consumer.service.impl.OrderServiceImpl">
<property name="userService" ref="userService"></property>
</bean>
</beans>
5.4创建测试类
package com.dubbo.consumer.test;
import com.dubbointerface.domain.UserAddress;
import com.dubbointerface.service.OrderService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.List;
public class TestConsumer {
public static void main(String[] args) throws IOException {
ApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
//从IOC里面得到OrderServiceImpl
OrderService orderService = context.getBean(OrderService.class);
List<UserAddress> list = orderService.initOrder("张三01");
for (UserAddress userAddress : list) {
System.out.println(userAddress.getUserId()+" "+userAddress.getUserAddress());
}
System.in.read();
}
}
6.测试项目
确保zookeeper,Dubbo已启动
6.1启动dubbo-provider项目
查看dubbo注册中心,服务已经注册
6.2启动dubbo-consumer项目
查看dubbo注册中心