高性能RPC框架——Dubbo一站式快速入门

一、Web应用架构的演变

​ 随着互联网的发展,网站应用的规模不断扩大,Web应用架构也在不断的演变

​ 四个阶段:单一应用、垂直应用、分布式服务、流动计算

高性能RPC框架——Dubbo一站式快速入门

1.单一应用架构

​ 当网站访问量很小时,只需要一个应用程序,将所有的功能都部署在一起,以减少部署节点和成本

​ 此时关键问题:简化数据库操作,数据访问框架ORM是核心

高性能RPC框架——Dubbo一站式快速入门

​ 适用场景:小型网站、管理系统、简易办公系统

​ 局限:

  1. 扩展性差
  2. 不便于协同开发
  3. 不利于升级维护

2. 垂直应用架构

​ 当访问量逐渐增大,单一应用(单机)负载太大,此时可以增加服务器来进行负载均衡,提高响应速度,即集群

​ 但是,当增加的服务器到达一定数据时所带来的加速度会越来越小,此时单纯的增加服务器已无法明显提升响应速度

​ 此时,需要将系统业务拆分成多个 互不相关的 系统,分别部署在独立的服务器上,以提升效率,称为垂直应用

​ 此时关键问题:加速前端页面开发MVC框架(MVVM)

高性能RPC框架——Dubbo一站式快速入门

​ 优点:通过拆分项目的业务,实现业务上的独立,降低了开发和维护的难度,便于协同开发,提高了扩展性

​ 局限:每个垂直模块中都有相同的内容(entity、dao、service、web),公共资源无法复用,且业务逻辑与界面无法分离

3. 分布式服务架构

​ 当垂直应用越来越多,应用之间的交互无法避免,有些业务系统无法完全拆分为独立系统。

​ 此时,可以将核心业务抽取出现,作为独立的服务Service,逐渐的形成稳定的服务中心,使前端应用能够更好的适应市场需要的变化。

​ 此时关键问题:提高业务的利用以及整合分布式服务框架RPC(Remote Procedure Call 远程过程调用)

高性能RPC框架——Dubbo一站式快速入门

4. 流动计算架构

​ 当服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务听架构体系(SOA: Service-Oriented Architecture )

​ 容量的评估,小服务资源的浪费等问题开始出现,此时需要增加一个调度中心,基于访问压力实时的管理集群容量,提高集群利用率

​ 此时关键问题:资源调度和治理中心,使用dubbo+zookeeper

高性能RPC框架——Dubbo一站式快速入门

二、RPC简介

1. RPC是什么

​ RPC:Remote Procedure Call 远程过程调用

  • 是一种进程间的通信方式
  • 它允许应用程序调用网络上的另一个应用程序中的方法
  • 对于服务的消费者而言,无需了解远程调用的底层细节,透明的

2. 执行流程

高性能RPC框架——Dubbo一站式快速入门

​ 执行流程:

  1. 客户端发起调用请求
  2. 客户端存根 对请求参数(接口、方法、参数等)进行序列化(封装)
  3. 客户端存根向 服务器存根 发送消息
  4. 服务端存根 对接收到的消息 进行反序列化
  5. 服务端存根发送请求调用本地方法
  6. 服务器执行业务处理
  7. 服务器返回处理结果
  8. 服务端存根 对处理结果进行序列化
  9. 服务端存根 将结果返回给 客户端存根
  10. 客户端存根 对接收到的结果进行反序列化
  11. 客户端存根 将结果返回给 客户端

三、Dubbo简介

1. Dubbo是什么

​ Apache Dubbo是一款高性能的Java RPC框架(由阿里巴巴开发,开源贡献给Apache)

​ 提供了三个核心功能:

  • 面向接口的远程方法调用
  • 智能容错和负载均衡
  • 服务自动注册和发现

​ 参考:官网 http://dubbo.apache.org

2. Dubbo体系结构

高性能RPC框架——Dubbo一站式快速入门

​ 执行流程:

  1. Provider:服务的提供者,负责对外提供服务,提供者在启动的时候,需要向Registry注册自己能够提供的服务
  2. Consumer:服务的消费者,消费者在启动的时候,需要向Registry订阅自己需要的服务
  3. Registry:注册中心,授受注册和订阅,会异步的通知订阅者,向消费者提供服务列表
  4. 当消费者需要执行远程过程调用时,会从Registry获取到服务地址列表(基于负载均衡算法)进行调用,如果调用失败会重新选择新的提供者再次调用
  5. Monitor:监控中心,统计服务的调用次数和调用时间,服务消费者和提供者会在内存中累计调用次数和调用时间,定时每分钟向监控中心发送一次统计数据

​ 具体业务流程:

高性能RPC框架——Dubbo一站式快速入门

四、使用Dubbo

1. Spring版

1.1 创建common工程

​ 创建entity和service接口

1.2 创建provider工程

​ 步骤:

  1. 添加依赖

    <!--依赖于dubbon-common-->
    <dependency>
       <groupId>com.itany</groupId>
       <artifactId>dubbo-common</artifactId>
       <version>1.0-SNAPSHOT</version>
    </dependency>
    
    <!--spring-->
    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-core</artifactId>
       <version>${springversion}</version>
    </dependency>
    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-beans</artifactId>
       <version>${springversion}</version>
    </dependency>
    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>
       <version>${springversion}</version>
    </dependency>
    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-expression</artifactId>
       <version>${springversion}</version>
    </dependency>
    
    <!--dubbo核心包-->
    <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>dubbo</artifactId>
       <version>2.6.2</version>
    </dependency>
    
    <!--使用zookeeper作为注册中心,在dubbo中会访问zookeeper-->
    <dependency>
       <groupId>org.apache.zookeeper</groupId>
       <artifactId>zookeeper</artifactId>
       <version>3.4.13</version>
    </dependency>
    
    <!--zookeeper的客户端实现-->
    <dependency>
       <groupId>org.apache.curator</groupId>
       <artifactId>curator-framework</artifactId>
       <version>4.0.1</version>
    </dependency>
  2. 编写实现类

    public class UserServiceImpl implements UserService {
       @Override
       public User findById(int id) {
           System.out.println("UserServiceImpl.findById");
           User user = new User();
           user.setId(id);
           user.setUsername("tom");
           user.setPassword("123");
           return user;
       }
    }
  3. 配置dubbo

    <!--配置当前dubbo应用程序的名称,可自定义,但必须唯一,一般使用项目名-->
    <dubbo:application name="dubbo-provider"/>
    
    <!--指定注册中心地址-->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    
    <!--配置dubbo协议和端口(通过该端口来提供服务)-->
    <dubbo:protocol name="dubbo" port="8888"/>
    
    <!--指定要暴露的服务接口-->
    <dubbo:service interface="com.itany.service.UserService" ref="userService"/>
    
    <bean id="userService" class="com.itany.service.impl.UserServiceImpl"/>

1.3 创建consumer工程

​ 步骤:

  1. 添加依赖

    同1.2

  2. 编写使用类

    @Controller
    public class UserController {
    
       private UserService userService;
    
       public void setUserService(UserService userService) {
           this.userService = userService;
       }
    
       public void findUser(){
           User user = userService.findById(1001);
           System.out.println(user);
       }
    }
    }
  3. 配置Dubbo

    <dubbo:application name="dubbo-consumer"/>
    
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    
    <!--指定要引用的服务-->
    <dubbo:reference id="userService" interface="com.itany.service.UserService"/>
    
    <bean class="com.itany.controller.UserController">
       <property name="userService" ref="userService" />
    </bean>

1.4 测试

  1. 启动zookeeper

  2. 编写并运行provider

    public static void main(String[] args) {
       ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:provider.xml");
    
       //阻塞线程
       new Scanner(System.in).next();
    }
  3. 编写并运行consumer

    public static void main(String[] args) {
       ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:consumer.xml");
       UserController userController = ac.getBean(UserController.class);
       userController.findUser();
    
       //阻塞线程
       new Scanner(System.in).next();
    }

2. Spring注解版

2.1 改写provider

<!--dubbo组件的扫包-->
<dubbo:annotation package="com.itany.service.impl"/>

<!--spring组件的扫包-->
<context:component-scan base-package="com.itany.service.impl"/>
// 方式1
// @Service
// @com.alibaba.dubbo.config.annotation.Service
// 方式2
@Component
@Service
public class UserServiceImpl implements UserService {

2.2 改写consumer

<dubbo:annotation package="com.itany.controller"/>

<context:component-scan base-package="com.itany.controller"/>
@Controller
public class UserController {

    // 使用dubbo的@Reference注入远程服务对象
    @Reference
    private UserService userService;

3. SpringBoot版

3.1 创建provider工程

​ 步骤:

  1. 添加依赖

    <!--依赖于dubbo-common-->
    <dependency>
       <groupId>com.itany</groupId>
       <artifactId>dubbo-common</artifactId>
       <version>1.0-SNAPSHOT</version>
    </dependency>
    
    <!--dubbo的starter-->
    <dependency>
       <groupId>com.alibaba.boot</groupId>
       <artifactId>dubbo-spring-boot-starter</artifactId>
       <version>0.2.0</version>
    </dependency>
  2. 编写实现类

    @Component
    @Service
    public class UserServiceImpl implements UserService {
       @Override
       public User findById(int id) {
           User user = new User();
           user.setId(id);
           user.setUsername("alice");
           user.setPassword("123");
           return user;
       }
    }
    
  3. 配置dubbo

    server:
     port: 8881
    
    dubbo:
     application:
       name: boot-provider
     registry:
       address: zookeeper://127.0.0.1:2181
     protocol:
       name: dubbo
       port: 8888
  4. 启用dubbo

    @SpringBootApplication
    @EnableDubbo //启用dubbo
    public class BootProviderApplication {
    
       public static void main(String[] args) {
           SpringApplication.run(BootProviderApplication.class, args);
       }
    }

3.2 创建consumer

​ 步骤:

  1. 添加依赖,同3.1

  2. 编写使用类

    @Controller
    @RequestMapping("/user")
    public class UserController {
    
       @Reference
       private UserService userService;
    
       @RequestMapping("/findUser")
       public String findUser(int id, Model model) {
           User user = userService.findById(id);
           model.addAttribute("user", user);
           return "success";
       }
    }
  3. 配置dubbo

    server:
     port: 8882
    
    dubbo:
     application:
       name: boot-consumer
     registry:
       address: zookeeper://127.0.0.1:2181
    
    spring:
     thymeleaf:
       cache: false

五、配置dubbo

1. 配置的覆盖关系

​ dubbo属性可以配置在如下六个位置:

  • 消费者引用方法处
  • 提供者暴露方法处
  • 消费者引用接口处
  • 提供者暴露接口处
  • 消费者全局配置处
  • 提供者全局配置处

​ 它们的优先顺序如下:

  • 方法级优先,接口级次之,全局配置再次之。
  • 如果级别一样,则消费方优先,提供方次之

​ 注:建议由服务提供者设置超时时间

高性能RPC框架——Dubbo一站式快速入门

2. 常用配置

配置项 作用
timeout 超时时间,单位为毫秒, 默认1000ms
retries 重试次数,不包括第一次调用,默认为2,0表示不重试
check 启动时检查提供者是否存在,true表示不存在时报错,false表示启动时不检查,默认为true
url 点对点直连服务提供者,绕过注册中心,以服务接口为单位

六、监控中心

1. dubbo-admin

​ Dubbo的管理控制台,可以对提供者和消费者进行管理,便于调试,发现问题,解决问题

​ 下载:GitHub——>搜索dubbo-admin——>选择master分支——>Download

​ 配置:修改dubbo-admin目录下的application.properties文件(指定注册中心地址)

​ 打包:mvn package

​ 运行:java -jar dubbo-admin-0.0.1-SNAPSHOT.jar

​ 访问 :http://localhost:7001 默认用户名和密码都为root

2. dubbo-monitor-simple

​ 简单的监控中心

​ 配置:修改dubbo-monitor-simple目录下的dubbo.properties文件(指定注册中心地址)

​ 打包:mvn package

​ 运行:将生成的dubbo-monitor-simple-2.0.0-assembly.tar.gz解压缩,运行解压后assembly.bin/start.bat 或 start.sh

​ 访问:http://loclahost:8080

​ 在提供者和消费者中配置,指定监控中心,可以定时每分钟向监控中心发送一次统计数据

dubbo:
  monitor:
    protocol: registry # 配置监控中心,从注册中心查找监控中心的地址

七、高可用性

​ 通过对系统进行专门设计,从而减少停机时间,提高系统的高可用性

1. 负载均衡

1.1 简介

​ 将接收到的请求按照一定的规则(负载均衡算法)分发到不同的服务器进行处理,从而提高系统响应和处理速度,称为负载均衡 Load Balance

​ Dubbo提供了四种负载均衡策略:

  • Random LoadBalance 基于权重的随机负载均衡(默认)

    按照权重的比例,随机选择集群中的服务器

高性能RPC框架——Dubbo一站式快速入门

  • RoundRobin LoadBalance 基于权重的轮循负载均衡

    根据权重,按照一定的顺序将请求分发给每个服务器(轮流提供服务)

高性能RPC框架——Dubbo一站式快速入门

  • LeastActive LoadBalance 最少活跃数的负载均衡

    最少活跃调用数,活跃时间(请求的响应时间)较小的服务器会处理更多的请求

高性能RPC框架——Dubbo一站式快速入门

  • ConsistentHash LoadBalance 一致性hash的负载均衡

    相同参数的请求总是发给同一台服务器

高性能RPC框架——Dubbo一站式快速入门

1.2 操作

@Controller
@RequestMapping("/user")
public class UserController {

    // 修改负载均衡策略
    @Reference(loadbalance = "roundrobin")
    private UserService userService;

​ 修改权重的两种方式:

  • 修改暴露服务时的权重
  • 动态调整权重

2. 服务降级

​ 当服务器压力剧增时根据实际业务情况及流量,对一些服务有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运行或高效运行。

​ 简单来说,就是将非核心服务进行降级,暂时性的关闭或延迟使用,保证核心服务的正常运行

​ Dubbo支持两种服务降级:

  • mock=force:return+null

    表示消费方对该服务的方法调用都直接返回null,不发起远程调用

    用来屏蔽不重要服务不可用时对调用方的影响

  • mock=fail:return+null

    表示消费方对该服务的方法调用在失败后,再返回null,不抛出异常

    用来容忍不重要服务不稳定时对调用方的影响

八、补充:面试题

1. 高并发的处理

​ 高并发如何优化?

  1. 负载均衡:集群,通过多台服务器进行负载均衡,提高响应和处理速度
  2. 动静分离:使用Nginx实现,CDN 内容分发网络
  3. 缓存:以空间换时间,提高系统效率
  4. 限流:即流量控制,将过量的请求先放到队列中,等待一定时间后再从队列中取出处理,类似于地铁限流
  5. 降级:即服务降级

2. 集群环境下session的处理

​ 几种解决方式:

  1. Session保持:负载均衡进行请求分发时保证每个客户端固定的访问后端的同一台服务器,如Nginx的ip_hash策略

    优点:简单,不需要对session做任何处理

    缺点:无法保证负载绝对均衡

    ​ 缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上,此时他的session信息将失效

  2. Session复制:将每个服务器的Session信息复制到其他服务器节点,保证Session的同步

    缺点:如果Session量很大的话可能会造成网络堵塞,拖慢服务器性能

  3. Session共享:将Session放到一个统一的地方,如可以放到数据库中,实际中更推荐使用Redis或Memcached。

原文地址:http://blog.51cto.com/12402007/2345531

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在网络请求时,总会有各种异常情况出现,我们需要提前处理这种情况。在完善的rpc组件dubbo中,自然是不会少了这一层东西的。我们只需要通过一些简单的配置就可以达到超时限制的作用了。dubbo的设计理念是,客户端控制优先,服务端控制兜底。 1.超时机制的实现思路要想实
作者:宇曾背景软件技术的发展历史,从单体的应用,逐渐演进到分布式应用,特别是微服务理念的兴起,让大规模、高并发、低延迟的分布式应用成为可能。云原生时代下,微服务框架本身也在不断地进化和迭代演进。微服务框架一般会涉及到以下几个知识点:本文我们着重探讨以下三大微服务框架:
hello,大家好呀,我是小楼。最近一个技术群有同学at我,问我是否熟悉Dubbo,这我熟啊~他说遇到了一个Dubbo异步调用的问题,怀疑是个BUG,提到BUG我可就不困了,说不定可以水,哦不...写一篇文章。问题复现遇到问题,尤其不是自己遇到的,必须要复现出来才好排查,截一个当时的聊天记录:他的问题
 一个软件开发人员,工作到了一定的年限(一般是3、4年左右),如果他还没学会阅读源码,那么他就会遇到瓶颈。因为到了这个时候的开发,他应该不仅仅只会做那些CURD的业务逻辑,而应该会根据公司的实际情况去写框架。而基本上没有谁能像天才一样从零写出一个框架,很多人写框架其实
当一个服务调用另一个远程服务出现错误时的外观Dubbo提供了多种容错方案,默认值为failover(重试)1)、FailoverCluster(默认)失败自动切换,当出现失败,重试其他服务器,通常用于读操作,但重试会带来更长延迟,可以通过属性retries来设置重试次数(不含第一次)2)、FailfastC
最近在看阿里开源RPC框架Dubbo的源码,顺带梳理了一下其中用到的设计模式。下面将逐个列举其中的设计模式,并根据自己的理解分析这样设计的原因和优劣。责任链模式责任链模式在Dubbo中发挥的作用举足轻重,就像是Dubbo框架的骨架。Dubbo的调用链组织是用责任链模式串连起来的。责任链
在过去持续分享的几十期阿里Java面试题中,几乎每次都会问到Dubbo相关问题,比如:“如何从0到1设计一个Dubbo的RPC框架”,这个问题主要考察以下几个方面:你对RPC框架的底层原理掌握程度。考验你的整体RPC框架系统设计能力。具体,mike来为大家详解。RPC和RPC框架1.RPC(RemoteProcedure
Dubbo在启动时会检查服务提供者所提供的服务是否可用,默认为True。(1)、单个服务关闭启动时检查(check属性置为false)1)、基于xml文件配置方式1<!--3、声明需要调用的远程服务接口,生成远程服务代理,可以和本地Bean一样使用-->2<dubbo:referenceid="userService"i
(1)、新建一个普通Maven项目,用于存放一些公共服务接口及公共的Bean等。项目: 公共Bean:1packagecn.coreqi.entities;23importjava.io.Serializable;45publicclassUserimplementsSerializable{6privateIntegerid;7privateStringuserName;
1.安装java:yuminstalljava2.下载Tomcat:wgethttp://mirrors.shu.edu.cn/apacheomcatomcat-9/v9.0.14/bin/apache-tomcat-9.0.14-fulldocs.tar.gz3.解压Tomcat:tar-xvfapache-tomcat-9.0.14.tar.gz-C/usr/local/cd/usr/local/mvapache-tomcat-9.0.14//usr/local
工程结构:主pom<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.ap
微服务架构到底应该如何选择? 什么是微服务?微服务的概念最早是在2014年由MartinFowler和JamesLewis共同提出,他们定义了微服务是由单一应用程序构成的小服务,拥有自己的进程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用HTTPAPI通讯。同时,服务会
(1)、dubbo-admin(管理控制台)1)、从https://github.com/apache/incubator-dubbo-ops下载解压2)、修改dubbo-admin配置文件中zookeeper的注册地址3)、使用Maven命令打包mvncleanpackage4)、使用java-jar dubbo-admin-0.0.1-SNAPSHOT.jar命令运行5)、访
Dubbo概述Dubbo的背景随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。  单一应用架构当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
前言跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽。切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来,期间也没有准备充分,到底是因为技术原因,影响自己的发展,偏移自己规划的轨迹,还是钱给少了,不受重视。准备不充分的面试,完全是浪费时间,更是对自己的不负责
Dubbo是阿里巴巴内部使用的分布式业务框架,2012年由阿里巴巴开源。由于Dubbo在阿里内部经过广泛的业务验证,在很短时间内,Dubbo就被许多互联网公司所采用,并产生了许多衍生版本,如网易,京东,新浪,当当等等。由于阿里策略变化,2014年10月Dubbo停止维护。随后部分互联网公司公开了自行维护的Du
1.java.lang.NoSuchMethodError:org.jboss.resteasy.specimpl.BuiltResponse.getHeaders()Ljavax/wss/core/MultivaluedMap;解决:参考https://stackoverflow.com/questions/17618587/jetty-9-0-embedded-and-resteasy-3-0-keeps-throwing-nosuchmethoderror将依赖提到最前
服务消费者引用服务提供者的服务时可能由于网络原因导致长时间未返回相应,此时大量的线程将会阻塞,引起性能下降等问题。可以通过引入服务超时来解决该问题 服务超时指服务在给定的时间内未返回相应将立即终止该请求,一般配合retries(重试次数)使用。单位毫秒,默认值1000 
服务超时后重试次数【retries】,不包含第一次调用,0代表不重试*我们应该在幂等方法上设置重试次数【查询、删除、修改】,在非幂等方法上禁止设置重试次数。★幂等:指多次运行方法所产生的最终效果是一致的1<!--3、声明需要调用的远程服务接口,生成远程服务代
一、Web应用架构的演变​随着互联网的发展,网站应用的规模不断扩大,Web应用架构也在不断的演变​四个阶段:单一应用、垂直应用、分布式服务、流动计算1.单一应用架构​当网站访问量很小时,只需要一个应用程序,将所有的功能都部署在一起,以减少部署节点和成本​此时关键