Dubbo基础

1、背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

单一应用架构

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。

垂直应用架构

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。

分布式服务架构

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。

流动计算架构

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。

2、Dubbo简介

Dubbo (开源分布式服务框架) Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。Dubbo是一个RPC(RPC是远程过程调用(Remote Procedure Call)的缩写形式)框架,

RPC主要解决的问题:

1、解决分布式系统中,服务之间的调用问题

2、远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。

架构

dubbo-architecture.jpg

如上图所示,这个架构图中有5个节点:

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

3、注册中心(Registry)

Dubbo支持五种注册中心:Multicast注册中心、Zookeeper注册中心、Nacos注册中心、Redis注册中心、Simple注册中心,官方推荐使用Zookeeper。

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

Zookeeper 是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。

Zookeeper可以去官网下载,下载后解压,打开conf目录,复制zoo_sample.cfg并重命名为zoo.cfg。之后回到上级目录运行bin目录下的zkServer.sh(Linux)或zkSercer.cmd(Windosws)。默认运行在2181端口。

4、监控中心(Monitor)

dubbo admin是一个图形化的管理界面,安装时需要指定注册中心地址,即可从注册中心获取所有的提供者、消费者配置管理。可以去这个网址下载:https://github.com/apache/dubbo-admin/tree/master。

下载之后解压进入dubbo-admin目录,打开cmd窗口运行mvn clean package,命令执行完成后,会在dubbo-admin-master\dubbo-admin\target 当前目录下 创建target文件夹。点击会出现:
dubbo-admin-0.0.1-SNAPSHOT.jar。这个项目是一个SpringBoot项目,打开cmd窗口运行java -jar dubbo-admin-0.0.1-SNAPSHOT.jar。然后打开浏览器访问http://localhost:7001,用户名密码都是root,登录之后就可以看到当前的消费者与生产者。需要注意,这时要保证ZooKeeper已经开启了。

5、一个Demo

创建一个maven项目名为429dubbo,下面有三个子模块:meeting-interface-api、meeting-service-consumer、user-service-provider。在meeting-interface-api这个模块中定义了两个POJO:User与MeetingPub,还有两个接口:UserService与MeetingPub,现在的目的是根据某次会议的id查询这次会议的主持人的信息,两个service的实现类在不同模块中,此时user-service是生产者,将被调用,meeting-service是消费者,需要调用UserService的getUserById(int id)这个方法。所以必须在meeting-service模块中获得UserService这个Bean。

pom.xml(429dubbo)



    4.0.0

    com.qianfeng
    429dubbo
    1.0-SNAPSHOT
    
        user-service-provider
        meeting-service-consumer
        meeting-interface-api
    

    pom

    
        2.7.6
    
    
        
            
                junit
                junit
                4.12
                test
            
            
                org.projectlombok
                lombok
                1.18.12
                provided
            
            
                org.apache.dubbo
                dubbo
                ${dubbo.version}
            
            
                org.apache.dubbo
                dubbo-dependencies-zookeeper
                ${dubbo.version}
                pom
            
        
    

除了junit与lombok之外,添加了两个依赖:dubbo与dubbo-dependencies-zookeeper。两个service模块都需要使用这些依赖,所以就定义在父项目中,可以很方便的继承。

pom.xml(user与meeting)



    
        429dubbo
        com.qianfeng
        1.0-SNAPSHOT
    
    4.0.0

    user-service-provider

    
        
            org.apache.dubbo
            dubbo
        
        
            org.apache.dubbo
            dubbo-dependencies-zookeeper
            pom
        
        
            org.projectlombok
            lombok
        
        
            com.qianfeng
            meeting-interface-api
            1.0-SNAPSHOT
        
    

这个依赖文件将meeting-interface-api模块作为一个依赖引进来,因为要使用POJO与接口,定义实现类。

provider.xml




    
    

    
    

    
    

    
    

    
    

这个provider.xml文件定义在user-service模块的resources下,因为是一个生产者所以就命名为provider.xml。定义了需要暴露的服务接口,并指向实现类。还定义了应用的名字和注册中心与协议端口。

consumer.xml




    
    

    
    

    
    

consumer.xml位于meeting-service模块下,定义了应用名字、注册中心的地址和端口,最重要的是定义了一个引用。

Provider.java

package com.qianfeng;

import org.springframework.context.support.ClassPathXmlApplicationContext;

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

这个类位于user-service模块下,读取provider.xml文件并向外界提供服务。System.in.read()的作用是让程序阻塞知道我们手动停止运行。

Consumer.java

package com.qianfeng;

import com.qianfeng.entity.User;
import com.qianfeng.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Consumer {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"classpath:consumer.xml"});
        context.start();
        UserService userService = (UserService)context.getBean("userService"); // 获取远程服务代理
        User user = userService.getUserByUid("19061555");// 执行远程方法
        System.out.println( user ); // 显示调用结果
        System.in.read();
    }
}

这个类位于meeting-service模块下,读取consumer.xml文件并获取服务,读取配置文件获得Bean运行方法。

你可能感兴趣的:(Dubbo基础)