资讯详情

Dubbo学习笔记

Dubbo


Dubbo学习笔记

  • Dubbo
    • 一. Dubbo概述
    • 二. Dubbo背景
      • 1. 单应用框架
      • 2. 垂直应用框架
      • 3. 分布式应用架构(RPC)
      • 4. 流动计算架构(SOA)
      • 5. 架构演变详解
        • 1. 单一应用架构
        • 2. 垂直应用架构
        • 3. 分布式服务架构
        • 4. 流动计算架构
      • 6. RPC的简介
        • RPC需要解决的问题
    • 三. Dubbo作用
      • 1. 为什么使用Dubbo
      • 2. Dubbo能做什么
    • 四. Dubbo 和 Spring Cloud区别
    • 五. Dubbo技术架构
    • 六. Dubbo案例
      • 1. 服务端
      • 2. 消费端
    • 七. 加入zookeeper注册中心
      • 1. 服务端
      • 2. 消费端
    • 八. 配置方式多种多样
      • 1. API配置方式
      • 2. 注明配置模式
    • 九. 常用场景
      • 1. 启动时检查
      • 2. 集群容错
      • 3. 负载均衡
      • 4. 直连提供者
      • 5.多协议机制
      • 6.多注册中心
      • 7. 多版本
      • 8. 日志管理


一. Dubbo概述

Dubbo基于阿里巴巴的开源 Java 的高性能RPC(远程调用) 致力于提供高性能、透明度的分布式服务框架RPC远程服务调用方案和SOA服务治理方案。

每天为2000多项服务提供超过30亿次的访问支持,并广泛应用于阿里巴巴集团的成员网站和其他公司的业务。

简单的说,Dubbo它是一个服务框架。如果没有分布式需求,就不需要使用。只有在分布式时才有Dubbo需要这样的分布式服务框架。

本质上是远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在Dubbo上注册)

其核心部分包括:

1.远程通信:基于长连接提供多种类型的远程通信NIO框架抽象包装,包括各种线程模型、序列化和请求响应模式。 2、集群容错:提供基于接口方法的透明远程过程呼叫,包括多协议支持、软负荷平衡、失败容错、地址路由、动态配置等集群支持。 3、自动发现:基于注册中心目录服务,服务消费者可以动态找到服务提供商,使地址透明,使服务提供商能够平稳增加或减少机器

二. Dubbo背景

Dubbo从电子商务系统开始,所以从电子商务系统的演变开始。

1. 单应用框架

在这里插入图片描述

当网站流量非常小时时,只需要一个应用程序就可以部署以下所有功能,以降低部署节点和成本。

缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,而且随着流量的增加越来越难以维护。

2. 垂直应用框架

垂直应用架构解决了单个应用架构面临的扩展问题,流量可分散到各子系统,系统体积可控,在一定程度上降低了开发人员之间的协调和维护成本,提高了开发效率。

缺点:但同一逻辑代码在垂直架构中需要不断复制,不能重用。

3. 分布式应用架构(RPC)

当垂直应用程序越来越多时,应用程序之间的互动是不可避免的。核心业务作为独立服务,逐步形成稳定的服务中心。

4. 流动计算架构(SOA)

随着服务的进一步发展,服务越来越多,服务之间的呼叫和依赖越来越复杂,面向服务的架构体系诞生了(SOA),因此,一系列相应的技术,如服务提供、服务呼叫、连接处理、通信协议、序列化、服务发现、服务路由、日志输出等。

5. 结构演变详解

从电子商务系统的演变可以看出架构演变的过程:

一、单应用单服务器; 2.单个应用程序分为多个应用程序并部署到多个服务器中; 3.单应用分为多个应用,实现分布式部署; 4.流动计算框架(资源调度和治理中心用于提高机器利用率)

1. 单一应用架构

当网站流量非常小时时只需要一个应用程序来部署所有功能,以降低部署节点和成本。 此时,用于简化增删改查工作量 数据访问框架(ORM) 是关键。

2. 垂直应用架构

当访问量逐渐增加时,单个应用程序会增加机器带来的加速度,并将应用程序分为几个不相关的应用程序,以提高效率。此时,用于加速前端页面的开发 Web框架(MVC) 是关键。

3. 分布式服务架构

当垂直应用程序越来越多时,应用程序之间的互动是不可避免的。提取核心业务作为独立服务,逐步形成稳定的服务中心,使前端应用程序能够更快地响应可变的市场需求。此时,用于改进业务的再利用和集成 分布式服务框架(RPC) 是关键。

4. 流动计算架构

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

6. RPC的简介

RPC(Remote Procedure Call Protocol):远程过程调用

两台服务器A、B,分别部署不同的应用程序a,b。当A服务器想要B服务器上调用B提供的函数或方法时,需要通过网络表达调用的语义来传达调用的数据,因为它不在内存空间中,不能直接调用。 说白了,就是你在你的机器上写了一个程序,我这边是无法直接调用的,这个时候就出现了一个远程服务调用的概念。

RPC在不了解底层网络技术的情况下,通过网络从远程计算机程序要求服务。RPC假设某些传输协议存在,如协议TCP或UDP,将信息数据带到通信程序之间。OSI网络通信模型中,RPC跨越传输层和应用层。RPC更容易开发包括网络分布式多程序在内的应用程序。 RPC采用客户机/服务器模式。请求程序是客户机,服务提供程序是服务器。首先,客户机调用过程向服务过程发送具有过程参数的调用信息,然后等待响应信息。在服务器端,过程保持睡眠,直到信息到达。当一个呼叫信息到达时,服务器获程参数,计算结果,发送回复信息,然后等待下一个呼叫信息。最后,客户端呼叫流程接收回复信息,获取流程结果,然后呼叫执行继续进行。

RPC需要解决的问题

  • 通信问题:主要是在客户端和服务器之间建立TCP连接,远程过程调用的所有交换数据都在此连接中传输。连接可按需连接,调用后断开,或长连接,多个远程过程调用共享同一连接。
  • 寻址问题:A如何告诉底层服务器上的应用?RPC如何连接到B服务器(如主机或IP地址)和特定的端口,方法的名称是什么,以便完成调用。例如,基于Web服务协议栈RPC,提供一个endpoint URI,或者是从UDDI搜索服务。如果是RMI如果调用,还需要一个RMI Registry注册服务地址。
  • 序列化 与反序列化:当A服务器上的应用程序启动远程调用时,方法的参数需要通过底层网络协议,如TCP传递到服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。同理,B服务器接收参数要将参数反序列化。B服务器应用调用自己的方法处理后返回的结果也要序列化给A服务器,A服务器接收也要经过反序列化的过程。

三. Dubbo作用

我们一起来看一下Dubbo的服务治理图:

1. 为什么使用Dubbo

因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了Netty、Zookeeper,保证了高性能高可用性。

  • 使用Dubbo可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。
  • 分布式架构可以承受更大规模的并发流量。

2. Dubbo能做什么

1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。 2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。 3.、服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。

四. Dubbo 和 Spring Cloud区别

1、通信方式不同:Dubbo 使用的是 RPC 通信,而Spring Cloud 使用的是HTTP RESTFul方式。 2、组成不一样:

  • dubbo的服务注册中心为Zookeerper,服务监控中心为dubbo-monitor,无消息总线、服务跟踪、批量任务等组件;
  • Spring Cloud的服务注册中心为spring-cloud netflix enruka,服务监控中心为spring-boot admin,有消息总线、数据流、服务跟踪、批量任务等组件;

五. Dubbo技术架构

节点角色说明

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

看了这几个概念后似乎发现其实Dubbo 的架构也是很简单的(其实现细节是复杂),为什么这么说呢,有没有发现,其实很像生产者-消费者模型。只是在这种模型上,加上了注册中心和监控中心,用于管理提供方提供的url,以及管理整个过程。

调用关系说明

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


那么,整个发布-订阅的过程就非常的简单了:

  • 启动容器,加载,运行服务提供者。
  • 服务提供者在启动时,在注册中心发布注册自己提供的服务。
  • 服务消费者在启动时,在注册中心订阅自己所需的服务。

如果考虑失败或变更的情况,就需要考虑下面的过程:

  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

六. Dubbo案例

1. 服务端

首先,我们先把服务端的接口写好,因为其实dubbo的作用简单来说就是给消费端提供接口。

接口定义

/** * xml方式服务提供者接口 */
public interface ProviderService { 
        
    String SayHello(String word);
}

这个接口非常简单,只是包含一个 SayHello 的方法。

接着,定义它的实现类

/** * xml方式服务提供者实现类 */
public class ProviderServiceImpl implements ProviderService{ 
        
    public String SayHello(String word) { 
        
        return word;
    }
}

这样我们就把我们的接口写好了,那么我们应该怎么将我们的服务暴露出去呢?

导入 maven 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ouyangsihai</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.5</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.32.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>

    </dependencies>
</project>

这里使用的dubbo的版本是2.6.6,需要注意的是,如果你只导入dubbo的包的时候是会报错的,找不到netty和curator的依赖,所以,在这里我们需要把这两个的依赖加上,就不会报错了。

另外,这里我们使用 zookeeper作为注册中心。

到目前为止,dubbo 需要的环境就已经可以了,下面,我们就把上面刚刚定义的接口暴露出去。

首先,我们在我们项目的resource目录下创建 META-INF.spring 包,然后再创建 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://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="provider" owner="sihai">
        <dubbo:parameter key="qos.enable" value="true"/>
        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
        <dubbo:parameter key="qos.port" value="55555"/>
    </dubbo:application>

    <dubbo:monitor protocol="registry"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <!--<dubbo:registry address="N/A"/>-->
    <dubbo:registry address="N/A" />

    <!--当前服务发布所依赖的协议;webservice、Thrift、Hessain、http-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!--服务发布的配置,需要暴露的服务接口-->
    <dubbo:service interface="com.sihai.dubbo.provider.service.ProviderService" ref="providerService"/>

    <!--Bean bean定义-->
    <bean id="providerService" class="com.sihai.dubbo.provider.service.ProviderServiceImpl"/>
</beans>

说明:

1、上面的文件其实就是类似 spring的配置文件,而且,dubbo 底层就是 spring。

2、节点:dubbo:application 就是整个项目在分布式架构中的唯一名称,可以在name属性中配置,另外还可以配置owner字段,表示属于谁。 下面的参数是可以不配置的,这里配置是因为出现了端口的冲突,所以配置。

3、节点:dubbo:monitor 监控中心配置, 用于配置连接监控中心相关信息,可以不配置,不是必须的参数。

4、节点:dubbo:registry 配置注册中心的信息,比如,这里我们可以配置 zookeeper 作为我们的注册中心。address 是注册中心的地址,这里我们配置的是 N/A 表示由 dubbo自动分配地址。或者说是一种直连的方式,不通过注册中心。

5、节点:dubbo:protocol 服务发布的时候 dubbo 依赖什么协议,可以配置dubbo、webservice、http等协议。

6、节点:dubbo:service 这个节点就是我们的重点了,当我们服务发布的时候,我们就是通过这个配置将我们的服务发布出去的。interface是接口的包路径,ref是第 ⑦ 点配置的接口的bean。

7、最后,我们需要像配置spring的接口一样,配置接口的 bean。 到这一步,关于服务端的配置就完成了,下面我们通过 main 方法将接口发布出去。

package com.sihai.dubbo.provider;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.alibaba.dubbo.container.Main;
import com.sihai.dubbo.provider.service.ProviderService;
import com.sihai.dubbo.provider.service.ProviderServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/** * xml方式启动 * */
public class App 
{ 
        
    public static void main( String[] args ) throws IOException { 
        
        //加载xml配置文件启动
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml");
        context.start();
        System.in.read(); // 按任意键退出
    }
}

发布接口非常简单,因为dubbo底层就是依赖 spring 的,所以,我们只需要通过 ClassPathXmlApplicationContext拿到我们刚刚配置好的 xml,然后调用 context.start()方法就启动了。

看到下面的截图,就算是启动成功了,接口也就发布出去了。

你以为到这里就结束了了,并不是的,我们拿到 dubbo 暴露出去的 url分析分析。

Dubbo 暴露的 URL

dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService?anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider&timestamp=1562077289380

分析如下:

1、首先,在形式上我们发现,其实这么牛逼的 dubbo也是用类似于 http 的协议发布自己的服务的,只是这里我们用的是dubbo协议。 2、dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService 上面这段链接就是 ?之前的链接,构成:协议://ip:端口/接口。发现是不是也没有什么神秘的。 3、anyhost=true&application=provider&bean.name=com.sihai.dubbo.provider.service.ProviderService&bind.ip=192.168.234.1&bind.port=20880&dubbo=2.0.2&generic=false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider&timestamp=1562077289380 ?之后的字符串,分析后你发现,这些都是刚刚在provider.xml中配置的字段,然后通过& 拼接而成的,闻到了 http 的香味了吗?

终于,dubbo 服务端入门了。下面我们看看拿到了 url后,怎么消费呢?

2. 消费端

上面提到,我们在服务端提供的只是点对点的方式提供服务,并没有使用注册中心,所以,下面的配置也是会有一些不一样的。

首先,我们在消费端的 resource下建立配置文件 consumer.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://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="consumer" owner="sihai"/>

    <!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
    <!--点对点的方式-->
    <dubbo:registry address="N/A" />
    <!--<dubbo:registry address="zookeeper://localhost:2181" check="false"/>-->

    <!--生成一个远程服务的调用代理-->
    <!--点对点方式-->
    <dubbo:reference id="providerService" interface="com.sihai.dubbo.provider.service.ProviderService" url="dubbo://192.168.234.1:20880/com.sihai.dubbo.provider.service.ProviderService"/>

    <!--<dubbo:reference id="providerService" interface="com.sihai.dubbo.provider.service.ProviderService"/>-->
</beans>

分析如下所示:

1、发现这里的 dubbo:application 和 dubbo:registry 是一致的 2、dubbo:reference :我们这里采用点对点的方式,所以,需要配置在服务端暴露的 url

和服务端一样

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ouyangsihai</groupId>
    <artifactId>dubbo-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.ouyangsihai</groupId>
            <artifactId>dubbo-provider</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.10</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.5</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            
        标签: 234变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台