分布式RPC框架Dubbo详解

简介: 分布式RPC框架Dubbo详解

1.架构演进

架构演进如下图:


fd63343509ed4c71a56c6afa589ed8b6.png


1.1 单体架构

这里假设A,B,C,D为四个模块


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


a901592742324c36b91310e4c1d03326.png


优点:

简单:开发部署都很方便,小型项目首选

缺点:

项目启动慢。可靠性差·可伸缩性差

扩展性和可维护性差·性能低


1.2  垂直架构

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


83af1410e8c74b6bb6643f37bc6502a9.png


垂直架构是指将单体架构中的多个模块拆分为多个独立的项目。形成多个独立的单体架构。垂直架构存在的问题:·重复功能太多。


1.3 分布式架构

分布式架构是指在垂直架构的基础上,将公共业务模块抽取出来,作为独立的服务,供其他调用者消费,以实现服务的共亨和重用。

RPC: Remote Procedure Call远程过程调用。有非常多的协议和技术来都实现了RPC的过程。比如:HTTP REST风格,JavaRMl规范、WebService SOAP协议. Hession等等。

分布式架构存在的问题:服务提供方一旦产生变更,所有消费方都需要变更。


1.4 SOA架构


3c468514f7584a24956837bf1ab76f6a.png

SOA: (Service-OrientedArchitecture,面向服务的架构)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。


ESB: (Enterparise Servce Bus)企业服务总线,服务中介。主要是提供了一个服务于服务之间的交互。ESB包含的功能如:负载均衡,流量控制,加密处理,服务的监控,异常处理,监控告急等。


1.5 微服务架构


f5374f97582245a2ba459b0184cd96f0.png


微服务架构是在SOA上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。微服务架构=80%的SOA服务架构思想+100%的组件化架构思想+80%的领域建模思想。


特点:

1.服务实现组件化:开发者可以自由选择开发技术。也不需要协调其他团队。

2.服务之间交互一般使用REST API。

3.去中心化,每个微服务有自己私有的数据库持久化业务数据。

4.自动化部署,把应用拆分成为一个一个独立的单个服务,方便自动化部署、测试、运维。


2.RPC框架

2.1 RPC基本概念介绍

2.1.1 RPC协议

远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。


OSI参考模型如下图:


4db3ea7cc7304c1f8e5cc91b3c949946.png



RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行


2.1.2 RPC框架

在单机时代一台电脑运行多个进程,进程之间无法通讯,显然这会浪费很多资源,因此后来出现IPC(Inter-process communication:单机中运行的进程之间的相互通信),这样就能允许进程之间进行通讯,比如在一台计算机中的A进程写了一个吃饭的方法,那在以前如果在B进程中也要有一个吃饭的方法,必须要在B进程中进行创建,但有了RPC后B只需要调用A进程的程序即可完成,再到后来网络时代的出现,大家电脑都连起来,这时可不可以调用其他电脑上的进程呢,当然可以,这样RPC框架出现了。严格意义上来讲: Unix的生态系统中RPC可以在同一台电脑上不同进程进行,也可以在不同电脑上进行;而在windows里面同一台电脑上不同进程间的通讯还可以采用LPC(本地访问)。综上:RPC或LPC是上层建筑,IPC是底层基础。

RPC框架有很多:比如JAVA RMT、Thrift、Dubbo、grpc等。



2.1.3 RPC与HTTP、TCP/ UDP、Socket的区别


TCP/UDP:都是传输协议,主要区别是tcp协议连接需要3次握手,断开需要四次挥手,是通过流来传输的,就是确定连接后,一直发送信息,传完后断开。udp不需要进行连接,直接把信息封装成多个报文,直接发送。所以udp的速度更快写,但是不保证数据的完整性。

Http:超文本传输协议是一种应用层协议,建立在TCP协议之上

Socket:是在应用程序层面上对TCPIP协议的封装和应用。其实是一个调用接口,方便程序员使用TCPIP协议栈而已。程序员通过socket来使用tcp/ip协议。但是socket并不是一定要使用tcp/ip协议,Socket编程接口在设计的时候,就希望也能适应其他的网络协议。

RPC是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。所以RPC的实现可以通过不同的协议去实现比如可以使http、RMl等。


2.1.4 RPC的运行流程


首先,要解决通讯的问题,主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。

第二,要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么,这样才能完成调用。比如基于Web服务协议栈的RPC,就要提供一个endpoint URI,或者是从UDD(一种目录服务,通过该目录服务进行服务注册与搜索)服务上查找。如果是RMI调用的话,还需要一个RMl Registry来注册服务的地址。

第三,当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。

第四,B服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。

第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接到后,再反序列化,恢复为内存中的表达方式,交给A服务器上的应用


如图所示:


6e476058ef8644a7ba3764a242ca8035.png


2.1.5 为什么需要RPC

论复杂度,RPC框架肯定是高于简单的HTTP接口的。但毋庸置疑,HTTP接口由于受限于HTTP协议,需要带HTTP请求头,导致传输起来效率或者说安全性不如RPC。


现在问题是,遇到怎样的瓶颈了才需要或者说更适合用RPC(比如像阿里这么大的请求并发量,简单的HTTP肯定达不到预期),但问题是像阿里这么大的量是比较少的,甚至说1/1000的量可能都没有,那我们还需要使用RPC吗?技术应该不是为了使用新技术而去使用,而应该是旧技术存在某些瓶颈,存在难以支撑或者扩展性越老越差等问题暴露出来之后,用新技术来进行解决。


那RPC最大的优点,或者说它相比简单的HTTP接口,它的优势、更适合它的业务场景是怎样呢?简单的HTTP又哪里不足,哪些场景明显不太适合呢?


http接口是在接口不多、系统与系统交互较少的情况下,解决信息初期常使用的一种通信手段;优点就是简单、直接、开发方便。利用现成的http协议进行传输。但是如果是一个大型的网站,内部子系统较多、接口非常多的情况下,RPC框架的好处就显示出来了,首先就是长链接,不必每次通信都要像http一样去3次握手什么的,减少了网络开销(这个问题在http2.0已经被解决不再算是问题了);其次就是RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。第三个来说就是安全性。最后就是流行的服务化架构、服务化治理,RPC框架是一个强力的支撑。


RPC是一种概念,http也是RPC实现的一种方式,用http交互其实就已经属于RPC了。RPC框架可以做到灵活部署和解耦。系统做大了,肯定是需要做微服务的。现在我们做电商就是这样,单独有一个订单系统,支付系统,商品系统,用户系统。都是分开部署,单独上线的。



RPC:远程过程调用。RPC的核心并不在于使用什么协议。RPC的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里。通过RPC能解耦服务,这才是使用RPC的真正目的。RPC的原理主要用到了动态代理模式,至于http协议,只是传输协议而已。

RPC是一个软件结构概念,是构建分布式应用的理论基础。就好比为啥你家可以用到发电厂发出来的电?是因为电是可以传输的。至于用铜线还是用铁丝还是其他种类的导线,也就是用http还是用其他协议的问题了。这个要看什么场景,对性能要求怎么样。比如在java中的最基本的就是RMI技术,它是java原生的应用层分布式技术。我们可以肯定的是在传输性能方面,RMI的性能是优于HTTP的。那为啥很少用到这个技术?那是因为用这个有很多局限性,首先它要保证传输的两端都要要用java实现,且两边需要有相同的对象类型和代理接口,不需要容器,但是加大了编程的难度,在应用内部的各个子系统之间还是会看到他的身影,比如EJB就是基于rmi技术的。这就与目前的bs架构的软件大相径庭。用http必须要服务端位于http容器里面,这样减少了网络传输方面的开发,只需要关注业务开发即可。


2.2 Dubbo

2.2.1 Dubbo 概述

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架。


dubbo提供了三大核心能力:


面向接口的远程方法调用;

智能容错和负载均衡;

以及服务自动注册和发现;

dubbo 架构图如下所示:


133513b36fff4cf28a48ab5406ea8806.png


节点角色说明:


78fbf6e81bf24e6b91a7dbbe5bc8a1d3.png



调用关系说明


1、服务容器负责启动,加载,运行服务提供者。

2、服务提供者在启动时,向注册中心注册自己提供的服务。

3、服务消费者在启动时,向注册中心订阅自己所需的服务。

4、注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

5、服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

6、服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。



2.2.2 Dubbo实战


这里设置一个订单微服务和一个用户微服务,通过查询订单返回订单信息,订单中有用户信息,所有需要根据订单中的用户id调用用户微服务进行查询然后进行赋值返回订单信息,这里采用nacos和Dubbo相结合的方式。


2.2.2.1 生产者(用户模块微服务)和消费者(订单模块微服务)导入依赖


       <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-dubbo</artifactId>
        </dependency>

2.2.2.2 公共模块

设置接口用于查询用户信息

public interface UserService {
    public User queryUserId(Long id);
}


2.2.2.3 生产者(用户模块微服务)

application.yml文件配置

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SH
dubbo:
   #服务名称
  application:
    name: dubbo-user
  #注册中心
  registry:
    address: nacos://127.0.0.1:8848
  protocol:
    #协议名称
    name: dubbo
    #协议端口号
    port: 20880
  scan:
    base-packages: com.example.user.Imp  #扫描包的位置

在com.example.user.Imp中建立DubboUserServiceImpl类并继承UserService类,代码如下;

package com.example.user.Imp;
import com.example.entity.JieKou.UserService;
import com.example.entity.entities.User;
import org.apache.dubbo.config.annotation.Service;
@Service(version = "1.0")
public class DubboUserServiceImpl implements UserService {
    public User queryUserId(Long id) {
        User user=new User();
        user.setId((long) 3);
        user.setUsername("admin");
        user.setAddress("ShanDon");
        return user;
    }
}

2.2.2.4 消费者(订单模块微服务)

application.yml文件配置如下:

dubbo:
  protocol:
    port: 20881
    name: dubbo
  registry:
    address: nacos://localhost:8848

Controller类业务逻辑代码如下:

@RestController                                                                                
@RefreshScope                                                                                  
public class UserController {  
    @Autowired                                                                                 
    OrdersMapper ordersMapper;                                                                 
    @Reference(version = "1.0",parameters = {"unicast","false"})  //服务提供的可以被多个消费者消费            
    UserService userService;                                                                   
    @GetMapping("/order1/{id}")                                                                
    public Orders orders1(@PathVariable("id") Long id){                                        
        Orders orders = ordersMapper.selectById(id);                                           
        User user = userService.queryUserId(orders.getUserId());                               
        orders.setUser(user);                                                                  
        return orders;                                                                         
    }                                                                                          
}                                                                                              

至此代码基本完成,运行结果如下图:


e9bb2282600f44888cc5b6e738389436.png

相关文章
|
4天前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
4天前
|
存储 人工智能 PyTorch
基于PyTorch/XLA的高效分布式训练框架
基于PyTorch/XLA的高效分布式训练框架
44 2
|
4天前
|
XML Dubbo Java
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
【Dubbo3高级特性】「框架与服务」服务的异步调用实践以及开发模式
37 0
|
4天前
|
存储 分布式计算 监控
Hadoop【基础知识 01+02】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
141 2
|
22小时前
|
机器学习/深度学习 分布式计算 调度
机器学习分布式框架Ray
Ray是UC Berkeley RISELab推出的一个高性能分布式执行框架,它比Spark更具计算优势,部署简单,支持机器学习和深度学习的分布式训练。Ray包括节点(head和worker)、本地调度器、object store、全局调度器(GCS),用于处理各种分布式计算任务。它支持超参数调优(Ray Tune)、梯度下降(Ray SGD)、推理服务(Ray SERVE)等。安装简单,可通过`pip install ray`。使用时,利用`@ray.remote`装饰器将函数转换为分布式任务,通过`.remote`提交并用`ray.get`获取结果。5月更文挑战第15天
18 3
|
4天前
|
存储 Java 分布式数据库
【分布式计算框架】HBase数据库编程实践
【分布式计算框架】HBase数据库编程实践
13 1
|
4天前
|
分布式计算 并行计算 Java
【分布式计算框架】 MapReduce编程初级实践
【分布式计算框架】 MapReduce编程初级实践
9 2
|
4天前
|
分布式计算 数据可视化 Hadoop
【分布式计算框架】HDFS常用操作及编程实践
【分布式计算框架】HDFS常用操作及编程实践
6 1
|
4天前
|
分布式计算 Ubuntu Hadoop
【分布式计算框架】hadoop全分布式及高可用搭建
【分布式计算框架】hadoop全分布式及高可用搭建
9 1
|
4天前
|
存储 分布式计算 Hadoop
【分布式计算框架】Hadoop伪分布式安装
【分布式计算框架】Hadoop伪分布式安装
8 2