飞道的博客

分布式服务之间的通讯-RPC实战

413人阅读  评论(0)

前提:在会议发布后,需要提供依据会议id查询发布该会议的员工信息

  • provider:员工信息模块

  • consumer:会议模块

注意:由于是两个模块的进程间通信,所以必须实现Serializable

依据服务最佳实践

http://dubbo.apache.org/zh-cn/docs/user/best-practice.html

分包

建议将服务接口、服务模型、服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。

如果需要,也可以考虑在 API 包中放置一份 Spring 的引用配置,这样使用方只需在 Spring 加载过程中引用此配置即可。配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml

粒度

服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。

服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。

不建议使用过于抽象的通用接口,如:

Map query(Map)

这样的接口没有明确语义,会给后期维护带来不便。

序列化

……

按照普通类定义好这两个类后,需要启动注册中心:zookeeper和monitor

此时,将provider服务注册到注册中心——使用spring配置声明暴露服务

然后,让consumer订阅注册中心即可。

实现步骤

一、 定义两个服务模块

直接选择新建工程-maven项目,建立两个普通maven项目

导入微服务依赖:

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>${dubbo.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-dependencies-zookeeper</artifactId>
    <version>${dubbo.version}</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>

lombok插件为自动生成get和set方法,需要在pojo类上注解@Data

二、提取共同的api模块

此处api模块为:服务接口、服务模型、服务异常

(注意:由于每个类都可以作为provider也可以作为consumer,此处为了简化,只将user模块的pojo和service提取出来了,也可以将有可能的全部提取出来)

api模块目录结构:meeting-interface-api:

三、编写各自的业务实现类

实现类中在需要调用RPC方法时,需要使用spring的自动注入功能,然后引用api包:

  1. 将本类标志为@Service,将需要注入的变量标志为@Autowired
  2. pom.xml文件中引入api的jar包
<dependency>
    <groupId>com.pp</groupId>
    <artifactId>meeting-interface-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

下图是生产者和消费者的目录结构:

生产者类:

消费者类:

四、编写各自的注册订阅配置

建议放在resources资源目录下

生产者:provider.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:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans               http://www.springframework.org/schema/beans/spring-beans-4.3.xsd               http://dubbo.apache.org/schema/dubbo               http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    <!-- 提供方应用信息,用于计算依赖关系 最好和服务应用名称一样!且唯一-->
    <dubbo:application name="user-service-provider" /> <!-- 使用zookeeper广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.pp.service.UserService" ref="userServiceImpl" /> <!-- 和本地bean一样实现服务 -->
    <bean id="userServiceImpl" class="com.pp.service.impl.UserServiceImpl" />
</beans>

消费者:consumer.xml

消费者由于引用了api包中的类,需要使用spring注入该类,需要配置自动注入功能

<?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://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd       http://dubbo.apache.org/schema/dubbo       http://dubbo.apache.org/schema/dubbo/dubbo.xsd              http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="com.pp" /> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="meeting-service-consumer" /> <!-- 使用zookeeper广播注册中心暴露发现服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="userService" interface="com.pp.service.UserService" />
</beans>

五、启动服务

提供者启动类:

public static void main( String[] args ) throws IOException {    
    ClassPathXmlApplicationContext context =            
    new ClassPathXmlApplicationContext(                    
        new String[] {"classpath:provider.xml"}
    );    
    context.start();    
    System.in.read(); // 按任意键退出 
}

消费者启动类:

public static void main( String[] args ) throws IOException {    
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"classpath:consumer.xml"});    
    context.start();    
    MeetingPubService meetingPubService = context.getBean(MeetingPubService.class);     
    MeetingPub meetingPub = meetingPubService.selectByPcode("999");    
    System.out.println( meetingPub ); // 显示调用结果    
    System.in.read(); 
}

转载:https://blog.csdn.net/xiapi3/article/details/106901532
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场