一、架构

 

节点角色说明:

  • Provider: 暴露服务的服务提供方
  • Consumer: 调用远程服务的服务消费方
  • Registry: 服务注册与发现的注册中心
  • Monitor: 统计服务的调用次数和调用时间的监控中心
  • Container: 服务运行容器

调用关系说明:

  • 0. 服务容器负责启动,加载,运行服务提供者
  • 1. 服务提供者在启动时,向注册中心注册自己提供的服务
  • 2. 服务消费者在启动时,向注册中心订阅自己所需的服务
  • 3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
  • 4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
  • 5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

说明:

  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

用法示例:

首先,定义服务接口,该接口需单独打包,在服务方和消费方共享,通常将其称为api层。

 1 package com.patty.dubbo.api.service;
 2 
 3 import com.patty.dubbo.api.domain.UserVo;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  * Version: 3.0
 9  * Author: pattywgm
10  * Time: 17/5/23 下午5:25
11  * Desc: 用户服务公共接口
12  */
13 
14 public interface UserService {
15     // 查询所有用户
16     public List<UserVo> findAllUsers();
17 
18     // 根据id获取指定用户
19     public UserVo findUserById(String id);
20 }

 然后,在服务提供方实现UserService接口,如下:

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserBaseService userBaseService;

    public UserServiceImpl(){

    }

    @Override
    public List<UserVo> findAllUsers() {
// 去数据库查询所有用户
return userBaseService.findAllUsers(); } @Override public UserVo findUserById(String id) {
// 去数据库查询指定ID的用户
return userBaseService.findUserById(id); } }

UserBaseService是用户查询逻辑的的具体实现,涉及跟数据库,缓存的交互。

接下来,服务提供方要暴露自己的服务给消费者,我们采用springboot配置的方式实现。

<?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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="${dubbo.application.name}"/>
    <!-- 注册中心暴露服务地址 -->
    <dubbo:registry protocol="${dubbo.registry.protocol}" address="${dubbo.registry.address}"/>
    <!-- 暴露服务 -->
    <dubbo:protocol name="${dubbo.protocol.name}" port="${dubbo.protocol.port}"/>

    <dubbo:service ref="userService" interface="com.patty.dubbo.api.service.UserService"/>

</beans>
dubbo.properties文件
#应用名称 dubbo.application.name=dubbo-demo-provider #注册中心协议类型 dubbo.registry.protocol=zookeeper #注册中心地址 dubbo.registry.address=127.0.0.1:2181 #暴露服务方式,采用dubbo协议 dubbo.protocol.name=dubbo #暴露服务端口 dubbo.protocol.port=20880

启动provider,加载配置

@SpringBootApplication
@EntityScan("com.patty.dubbo.provider.model")
@MapperScan("com.patty.dubbo.provider.dao")
public class ProviderServer {
    public static void main(String[] args) throws IOException{
        SpringApplication.run(ProviderServer.class, args);

        System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟
    }
}

在消费方通过spring配置调用远程UserService服务,完成消费方的业务逻辑。

<?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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="${dubbo.application.name}"/>
    <!-- 注册中心暴露服务地址 -->
    <dubbo:registry protocol="${dubbo.registry.protocol}" address="${dubbo.registry.address}" check="false"/>

    <dubbo:reference id="userService" interface="com.patty.dubbo.api.service.UserService"
                     timeout="10000" retries="3"/>

</beans>
// 实现消费端的远程RPC调用
@RestController @RequestMapping(
"/users") public class UserController { @Resource private UserService userService; @RequestMapping(value = "/all", method = RequestMethod.GET) @ResponseBody public List<UserVo> getAllUsers() { return userService.findAllUsers(); } @RequestMapping(value = "/{userId}",method = RequestMethod.GET) @ResponseBody public UserVo getUser(@PathVariable("userId") String userId) { return userService.findUserById(userId); } }
// 启动消费方服务,加载spring配置,获取远程服务地址列表,供Controller中的业务逻辑调用
@SpringBootApplication
public class ConsumerServer { public static void main(String[] args) { SpringApplication.run(ConsumerServer.class, args); } }

 具体实现参见:https://github.com/pattywgm/dubbo-demo

posted on 2017-06-27 14:48  pattywgm  阅读(294)  评论(0编辑  收藏  举报