什么是Dubbo

Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

什么是RPC

RPC全称(Remote Procedure Call)远程过程调用

过程指的是某个代码片段的执行,远程调用则意味着我们可以在其他进程,甚至其他机器上去调用这段代码,当然也能获取到其执行后的返回值,按照这个定义,我们请求某个http地址得到相应数据其实也算一次RPC,但是这样的方式太过麻烦,(数据要先打包成http请求格式,在调用相关的请求库,拿到的结果也是文本格式的需要在进行转换),执行效率,和开发效率相比RPC则低一些;

我们需要一种更简单的方式来完成分布式开发中的RPC环节,这也是Dubbo的核心所在,有多简单呢? 调用远程服务器上的某个服务时就像是调用本地的某个方法一样简单,就像下面这样

为什么需要rpc

RPC是用来实现分布式构架的基石,分布式构架将同一个系统中的不同模块拆分到不同的子系统中,而子系统又分布在不同的服务器上,这时就需要RPC在来完成子系统之间的相互访问;

可以这么说分布式少不了RPC,RPC也要在分布式系统中才能发挥其核心价值;

rpc的实现原理

毫无以为底层肯定是要通过socket来进行网络通讯的,但是如何能够直接调用另一个机器上的方法呢?

服务消费方(client)调用以本地调用方式调用服务;

2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;

3)client stub找到服务地址,并将消息发送到服务端;

4)server stub收到消息后进行解码;

5)server stub根据解码结果调用本地的服务;

6)本地服务执行并将结果返回给server stub;

7)server stub将返回结果打包成消息并发送至消费方;

8)client stub接收到消息,并进行解码;

9)服务消费方得到最终结果。

当然传递的参数或返回值是某个Java对象时则还需要对其进行序列化与反序列化

分布式与集群

集群:

集群构架是将相同的处理逻辑进行复制(复制一份源代码),创建出一组具备相同功能的服务集合,集群中每个服务都能够独立的完成用户的请求,它们之间基本上不需要互相通讯,也就用不上RPC了;

分布式:

分布式指的是将一个系统拆分为多个独立的子系统,部署在不同的机器上;

在处理任务时会将一个任务拆分成若干子任务,分发给不同的子系统处理,每个子系统仅能处理一部分任务,通常一个完整的任务包含多个处理步骤,例如用户要购买某个商品,需要先创建订单,然后修改库存,假设修改库存的服务由另一个服务器提供这时候RPC就闪亮登场了;

可以发现分布式与集群在底层构架上完全不同,所以要将一个原本集群的系统重构为分布式的话,则需要大量的修改,所以若系统后期存在高并发的需求,则可以在项目初期就采用分布式构架来搭建;

分布式是必要的吗?

分布式的优缺点:

  • 可将原本串行的任务变为并行执行(没有前后依赖),提高计算速度
  • 提高可用性,由于系统分布在不同的计算节点上,其中某个节点失效不会对整个系统产生太大的影响
  • 各个子系统独立运行,极大的降低了系统的耦合度,使得各个子系统的扩展性和可业务功能的维护性提高
  • 因为模块化,所以系统模块重用度更高(系统级别)
  • 技术开放,多样化,完全可以使用其他语言,其他平台来开发某个子系统
  • 更有效的利用硬件资源

缺点:

  • 因为需要走RPC,响应时间变长

  • 系统构架更加复杂,运维工作麻烦

  • 需要进行服务管理和调度

  • 测试和调试更复杂

  • 公共模块无法复用(代码级别)

需要强调的是:分布式和集群并不是只能二选一,在高并发下场景下还可以给压力大的节点组建集群;\

分布式与微服务:

分布式系统是多个处理机通过通信线路互联而构成的松散耦合的系统,是一个更宽泛的概念;

微服务从结构上来看也属于分布式,微服务强调的是将某个功能完完全全的独立出来,彻底的解开耦合;

RPC和微服务才算是同一级别的东西,即实现分布式可以使用rpc也可以使用微服务;

系统构架演进:

SOA是解决海量并发访问的终极解决方案,无论是采用RPC还是微服务

为什么需要Dubbo:

引用官方原话:

在大规模服务化之前,应用可能只是通过 RMI 或 Hessian 等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过 F5 等硬件进行负载均衡。

当服务越来越多时,服务 URL 配置管理变得非常困难,F5 硬件负载均衡器的单点压力也越来越大。此时需要一个服务注册中心,动态地注册和发现服务,使服务的位置透明。并通过在消费方获取服务提供方地址列表,实现软负载均衡和 Failover,降低对 F5 硬件负载均衡器的依赖,也能减少部分成本。

当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。 这时,需要自动画出应用间的依赖关系图,以帮助架构师理清关系。

接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器? 为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阈值,记录此时的访问量,再以此访问量乘以机器数反推总容量。

简单的说,Dubbo不仅仅是实现了RPC,同时提供了整套分布式服务的管理方案; 包括

  • 服务注册与发现

  • 负载均衡

  • 流量调度

  • 提供可视化的服务治理工具,和运维工具

构架及服务调用流程



举例

角色:

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

调用过程:

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

hello Dubbo

1.创建铺Maven工程DubboDemo

2.在当前工程下创建provider模块

3.为provider添加依赖

 <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<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.13</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</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>

4.dubbo发布服务的单位是接口,所以我们需要创建一个服务接口,在消费端也需要同样的接口来产生代理对象,为了抽取公共部分代码,可以新建一个模块然后让提供方和消费方依赖这个项目从而找到需要的接口

在公共模块中创建接口:

package com.yyh.service;

public interface HelloService {
String helloMan(String name);
}

​ 在pom中和依赖刚才新建的项目

<dependency>
<groupId>org.example</groupId>
<artifactId>hello_Interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

5.在provider中创建实现类

package com.yyh.service.impl;

import com.yyh.service.HelloService;

public class HelloServiceImpl implements HelloService {
public String helloMan(String name) {
return "hello: "+name;
}
}

6.编写提供方配置文件

<?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="hello-service">
<dubbo:parameter key="qos.enable" value="true"/>
</dubbo:application>
<!--dubbo这个服务所要暴露的服务地址所对应的注册中心-->
<dubbo:registry address="N/A"/>
<!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
<dubbo:protocol name="dubbo" port="20880"/>
<!--服务发布的配置,需要暴露的服务接口-->
<dubbo:service interface="com.yyh.service.HelloService" ref="helloService"/>
<!--Bean bean定义-->
<bean id="helloService" class="com.yyh.service.impl.HelloServiceImpl"/>
</beans>

7.启动服务

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class Runner {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:provider.xml");
context.start();
System.out.println("send anyket to exit");
System.in.read();
}
}

8.为了方便调试我们可以提供一个日志配置在资源目录下名为log4j.properties

log4j.rootLogger=info,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r]-[%p] %m%n

9.创建消费端模块

在pom中引入同样的依赖

10.创建配置文件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="hello-consumer"/>
<!--注册中心 -->
<dubbo:registry address="N/A"/>
<!--创建一个代理对象到容器中 -->
<dubbo:reference id="helloService" interface="com.yyh.service.HelloService"
url="dubbo://192.168.2.5:20880/com.yyh.service.HelloService"/> </beans>

11.运行测试:

import com.yyh.service.HelloService;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Runner {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
HelloService helloService = (HelloService) context.getBean("helloService");
String jerry = helloService.helloMan("jerry");
System.out.println(jerry);
}
}

若输出hello jerry则表示调用服务成功了;

Dubbo 入门-细说分布式与集群的更多相关文章

  1. Dubbo入门实例 本地伪集群测试Demo

    1.   概述 Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案 Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提 ...

  2. 分布式 PostgreSQL 集群(Citus),官方快速入门教程

    多租户应用程序 在本教程中,我们将使用示例广告分析数据集来演示如何使用 Citus 来支持您的多租户应用程序. 注意 本教程假设您已经安装并运行了 Citus. 如果您没有运行 Citus,则可以使用 ...

  3. dubbo源码解析五 --- 集群容错架构设计与原理分析

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 博客园 Dubbo 入门之二 --- 项目结构解析 博客园 Dubbo 源码分析系列之 ...

  4. ElasticSearch入门 第二篇:集群配置

    这是ElasticSearch 2.4 版本系列的第二篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  5. 分布式 PostgreSQL 集群(Citus)官方安装指南

    单节点 Citus Docker (Mac 与 Linux) Docker 镜像仅用于开发/测试目的, 并且尚未准备好用于生产用途. 您可以使用一个命令在 Docker 中启动 Citus: # st ...

  6. 在 Kubernetes 上快速测试 Citus 分布式 PostgreSQL 集群(分布式表,共置,引用表,列存储)

    准备工作 这里假设,你已经在 k8s 上部署好了基于 Citus 扩展的分布式 PostgreSQL 集群. 查看 Citus 集群(kubectl get po -n citus),1 个 Coor ...

  7. 分享在Linux下使用OSGi.NET插件框架快速实现一个分布式服务集群的方法

    在这篇文章我分享了如何使用分层与模块化的方法来设计一个分布式服务集群.这个分布式服务集群是基于DynamicProxy.WCF和OSGi.NET插件框架实现的.我将从设计思路.目标和实现三方面来描述. ...

  8. 京东分布式MySQL集群方案介绍

    背景 数据库作为一个非常基础的系统,任何一家互联网公司都会使用,数据库产品也很多,有Oracle.SQL Server .MySQL.PostgeSQL.MariaDB等,像SQLServer/Ora ...

  9. 分布式MySQL集群方案的探索与思考

    转载:http://www.infoq.com/cn/articles/exploration-of-distributed-mysql-cluster-scheme?utm_campaign=rig ...

随机推荐

  1. 数学中的距离distance(未完成)

    manhattan distance(曼哈顿距离) euclidean distance(欧几里得距离) cosine distance(cosine距离) 闵式距离 切比雪夫距离

  2. 电脑莫名重启,VS代码丢失的解决办法

    今天写了一天的代码,然后电脑放在公司了,出去看电影(公司组织红色文化培训..)回来发现电脑重启,再打开电脑,VS的代码都不见了.好慌.... 别慌处理办法来了: 打开everything(没有的可以下 ...

  3. android应用市场、社区客户端、漫画App、TensorFlow Demo、歌词显示、动画效果等源码

    Android精选源码 MVP架构Android应用市场项目 android刻度盘控件源码 Android实现一个社区客户端 android商品详情页上拉查看详情 基于RxJava+Retrofit2 ...

  4. QTP基本循环正常遍历(代码方式实现)

    0 环境 系统环境:win7 1 操作(正常遍历篇) 1.1 代码前看 systemutil.Run "D:\Program Files (x86)\HP\QuickTest Profess ...

  5. TreeMap简介

    在Map集合框架中,除了HashMap以外,TreeMap也是常用到的集合对象之一.与HashMap相比,TreeMap是一个能比较元素大小的Map集合,会对传入的key进行了大小排序.其中,可以使用 ...

  6. deeplearning.ai 神经网络和深度学习 week4 深层神经网络

    1. 计算深度神经网络的时候,尽量向量化数据,不要用for循环.唯一用for循环的地方是依次在每一层做计算. 2. 最常用的检查代码是否有错的方法是检查算法中矩阵的维度. 正向传播: 对于单个样本,第 ...

  7. Integer 中的缓存类 IntegerCache

    我们先看一段代码: public class TestAutoBoxing { public static void main(String[] args) { //-128到127之间 Intege ...

  8. 关于angular2跳路由防止页面刷新的做法(Angular2路由重载)

    simpleReuseStrategy.ts // 创建重用策略 import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStr ...

  9. mysql表关联问题(第一卷:外键1对多之1)

    表关联的问题在开发中是必不可少的,现在我先简单的谈谈我的学习经验.先来说一下外键一对多的问题. 步骤1:准备数据: (1)设计模拟场景: 一个游戏为了测试游戏的运行情况,招来了一批用户来试玩,现需要录 ...

  10. MOOC(4)- setup和teardown函数

    import unittest class TestRequest(unittest.TestCase): @classmethod def setUpClass(cls): print(" ...