本笔记为本人在 B 站学习时整理而成,为了更好的学习,将其整理成笔记,以防忘记相关知识点。
RPC 基础知识
软件架构
单一应用架构
当网站流量很小时,应用规模小时,只需一个应用,将所有功能都部署在一起,以减少部署服务器数量和成本。
此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。数据库的处理时间影响应用的性能。
这种结构的应用适合小型系统,小型网站,或者企业的内部系统,用户较少,请求量不大,对请求的处理时间没有太高的要求。
将所有功能都部署到一个服务器,简单易用。开发项目的难度低。
缺点:
1、性能扩展比较困难
2、不利于多人同时开发
3、不利于升级维护
4、整个系统的空间占用比较大
垂直架构
当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分。
优点:
1、系统拆分实现了流量分担,解决了并发问题
2、可以针对不同模块进行优化
3、方便水平扩展,负载均衡,容错率提高
4、系统间相互独立
分布式服务架构
当应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
此时,用于提高业务复用及整合的分布式服务框架(RPC)
是关键。
分布式系统将服务作为独立的应用,实现服务共享和重用。
分布式系统
什么是分布式系统
分布式系统是若干独立计算机(服务器)的集合,这些计算机对于用户来说就像单个相关系统,分布式系统(distributed system)是建立在网络之上的服务器端一种结构。
分布式系统中的计算机可以使用不同的操作系统,可以运行不同应用程序提供服务,将服务分散部署到多个计算机服务器上。
RPC
RPC 【Remote Procedure Call】是指远程过程调用
,是一种进程间通信方式,是一种技术思想,而不是规范。
它允许程序调用另一个地址空间(网络的另一台机器上)的过程或函数
,而不用开发人员显式编码这个调用的细节。调用本地方法和调用远程方法一样。
RPC 的实现方式可以不同。例如 java 的 rmi, spring 远程调用等。
RPC 概念是在上世纪 80 年代由 Brue Jay Nelson(布鲁·杰伊·纳尔逊)提出。使用 PRC 可以将本地的调用扩展到远程调用(分布式系统的其他服务器)。
RPC 的特点
1、简单:使用简单,建立分布式应用更容易。
2、 高效:调用过程看起来十分清晰,效率高。
3、 通用:进程间通讯的方式,有通用的规则。
rpc 通讯是基于 tcp 或 udp 议 。
序列化方式
(xml/json/二进制) 。
Dubbo 框架
dubbo 概述
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架
,它提供了三大核心能力:
面向接口的远程方法调用
,智能容错和负载均衡
,以及服务自动注册和发现
。
Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC
远程服务调用方案、服务治理方案。
官网:https://dubbo.apache.org/zh/
特性:
面向接口代理:调用接口的方法,在 A 服务器调用 B 服务器的方法,由 dubbo 实现对 B 的调用,无需关心实现的细节,就像 MyBatis 访问 Dao 的接口,可以操作数据库一样。
不用关心 Dao 接口方法的实现。这样开发是方便,舒服的。
基本架构
服务提供者(Provider)
:暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer)
: 调用远程服务的服务消费方,服务消费者在启动时,向注册 中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry)
:注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者 。
监控中心(Monitor)
:服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
调用关系说明:
⚫ 服务容器负责启动,加载,运行服务提供者。
⚫ 服务提供者在启动时,向注册中心注册自己提供的服务。
⚫ 服务消费者在启动时,向注册中心订阅自己所需的服务。
⚫ 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
⚫ 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用, 如果调用失败,再选另一台调用。
⚫ 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
dubbo 支持的协议
支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。
dubbo 官方推荐使用 dubbo 协议
。dubbo 协议默认端口 20880
。
使用 dubbo 协议,spring 配置文件加入:
<dubbo:protocol name="dubbo" port="20880" />
直连方式 dubbo
点对点的直连项目:
消费者直接访问服务提供者,没有注册中心
。消费者必须指定服务提供者的访问地址(url)。
消费者直接通过 url 地址访问固定的服务提供者。这个 url 地址是不变的。
1 | 直接访问服务提供者 |
实现步骤
创建服务提供者:
1 | 1.新建空项目 |
创建服务消费者:
1 | 1.创建一个maven web工程:服务的消费者 |
具体实现:
创建服务提供者
1、新建空项目
2、创建一个 maven web 工程:服务的提供者,命名为001-link-userservice-provider
3、创建 java 和 resources 文件夹,并 mark directory as Sources root
和 Resources root
4、整理 pom.xml,导入对应的 jar 包和 jdk 编译插件,加完依赖最好右键 pom.xml–>Maven–>Reimport
1 |
|
5、创建一个实体 bean(在分布式中的实体 bean 一定要序列化)
1 | package com.kwxy.model; |
6、创建服务接口 UserService
1 | package com.kwxy.service; |
7、实现服务接口,由于这里是模拟业务的,所以就不创建 dao 层了
1 | package com.kwxy.service.impl; |
8、配置 dubbo 服务提供者的核心配置文件,创建 spring 配置文件,命名为 dubbo-userservice-provider.xml
1 |
|
9、在 web.xml 中添加监听器(最好把 web.xml 的版本修改成 4.0),添加 tomcat。
修改方法:
点击 File–>Project Stucture–>Modules–>点开创建的 module
–>点击 web–>将 Deployment Descriptors 中的那个配置删掉(点击减号)
–>再点击加号新增一个 web.xml 配置,命名为 web1.xml,版本选择 4.0–>确定、应用
–>将 webapp/WEB-INF 中的 web1.xml 重新修改成 web.xml(修改快捷键为shift+F6
)
1 |
|
创建服务消费者
1、创建一个 maven web 工程:服务的消费者,命名为 002-link-consumer
2、创建 java 和 resources 文件夹,并 mark directory as Sources root
和 Resources root
3、服务接口中的方法要给消费者使用,消费者项目需要知道接口名称和接口中的方法名称、参数等。
将服务提供者接口项目的类文件打包为 jar
1 | #注释掉001-link-userservice-provider的pom文件的<packaging>war</packaging> |
4、配置 pom 文件:添加需要的依赖(spring,dubbo),以及 001-link-userservice-provider 的 jar 依赖
1 |
|
5、设置 dubbo 的核心配置文件,命名为 dubbo-consumer.xml
1 |
|
6、编写 controller
1 | package com.kwxy.controller; |
7、配置 spring 的配置文件,命名为 application.xml
1 |
|
8、添加 tomcat,在 Project Structure 中将 tomcat 的依赖加进去。
在 web.xml 中配置中央调度器(DispatcherServlet),同样先改变 web.xml 约束版本
1 |
|
9、在 webapp 下编写显示信息的页面:userDetail.jsp
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
10、分别启动提供者和消费者的 tomcat,注意两个 tomcat 的 HTTP port 和 JMX port 要设置不一样。
比如我设置了提供者的 HTTP port 和 JMX port 为:8080、1099,消费者的 HTTP port 和 JMX port 为:8081、1098
启动 tomca 快捷键为:alt+shift+F9
在消费者弹出的页面地址栏输入:http://localhost:8081/user?id=1
页面结果:
1 | 用户详情 |
dubbo 服务化最佳实践
分包
建议将服务接口、服务模型、服务异常等均放在公共包
中。
粒度
服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。
不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义, 会给后期维护带来不便。
版本
每个接口都应定义版本号,为后续不兼容升级提供可能,如:
<dubbo:service interface=”com.xxx.XxxService” version=”1.0” />。
建议使用两位版本号,要变更服务版本。先升级一半提供者为新版本,再将消费者全部升为新版本,然后将剩下的一半提供者升为新版本。
改造 dubbo 项目
抽象分散在多个项目中的公共接口,实体类,异常,工具类到一个项目中,在其他项目如服务提供者,消费者共用公共的资源。
dubbo官方推荐使用的一个模式,将实体bean和业务接口存放到接口工程中。
具体实现
创建接口工程
1、创建 maven 工程,普通的 java 工程,不用模板。名字叫 003-link-interface。
2、编写实体 bean(序列化别忘了)
1 | package com.kwxy.model; |
3、编写业务接口
1 | package com.kwxy.service; |
创建提供者
1、创建 maven web 工程,名字叫 004-link-userservice-provider。
2、整理 pom.xml 文件,加入 spring、dubbo、接口工程依赖,以及 jdk 编译插件。
1 |
|
3、创建 java 和 resources 目录,并 mark
3、编写结构实现类,实现相关方法
1 | package com.kwxy.service.impl; |
4、编写 dubbo 配置文件 dubbo-userservice-provider.xml
1 |
|
5、在 web.xml 中添加监听器(改变约束版本),添加 tomcat
1 |
|
创建消费者
1、创建 maven web 工程,名字叫 005-link-consumer。
2、整理 pom.xml 文件,加入 spring、dubbo、接口工程依赖,以及 jdk 编译插件。(同上)
3、编写 dubbo 核心配置文件 dubbo-consumer.xml
1 |
|
3、编写控制器
1 |
|
4、编写 spring 配置文件,配置扫描组件、开启注解驱动、视图解析器
1 |
|
5、在 web.xml 中配置中央调度器(DispatcherServlet),同样先改变 web.xml 约束版本,添加 tomcat
1 |
|
6、在 webapp 下编写显示信息的页面:userDetail.jsp
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
7、分别启动提供者和消费者的 tomcat,启动 tomca 快捷键为:alt+shift+F9
在消费者弹出的页面地址栏输入:http://localhost:8081/userDetail?id=1
页面结果:
1 | 用户详情 |
dubbo 常用标签
Dubbo 中常用标签。分为三个类别:公用标签,服务提供者标签,服务消费者标签。
公用标签
1 | <dubbo:application/> 和 <dubbo:registry/> |
A、配置应用信息
<dubbo:application name=”服务的名称”/>
B、配置注册中心
<dubbo:registry address=”ip:port” protocol=”协议”/>
服务提供者标签
配置暴露的服务
<dubbo:service interface=”服务接口名” ref=”服务实现对象 bean”>
服务消费者标签
配置服务消费者引用远程服务
<dubbo:reference id=”服务引用 bean 的 id” interface=”服务接口名”/>
注册中心-Zookeeper
注册中心概述
对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀;
对于服务消费方,它最关心如何获取到它所需要的服务,而面对复杂的应用系统,需要管理大量的服务调用。
而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即需要提供服务,有需要消费服务。
通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。
服务注册中心可以通过特定协议来完成服务对外的统一。Dubbo 提供的注册中心有如下几种类型可供选:
Multicast 注册中心:组播方式
Redis 注册中心:使用 Redis 作为注册中心 。
Simple 注册中心:就是一个 dubbo 服务。作为注册中心。提供查找服务的功能。
Zookeeper 注册中心:使用 Zookeeper 作为注册中心 。
官方推荐使用 Zookeeper 注册中心。
Zookeeper 注册中心
Zookeeper 是一个高性能的,分布式的,开放源码的分布式应用程序协调服务。简称 zk。
Zookeeper 是翻译管理是动物管理员。可以理解为 windows 中的资源管理器或者注册表。他是一个树形结构。
这种树形结构和标准文件系统相似。ZooKeeper 树中的每个节点被称为 Znode。
和文件系统的目录树一样,ZooKeeper 树中的每个节点可以拥有子节点。
每个节点表示一个唯一服务资源。Zookeeper 运行需要 java 环境。
下载安装文件
官网下载地址::http://zookeeper.apache.org/
安装配置 Zookeeper
以 zookeeper-3.5.6 为例。
Windows 平台 Zookeeper 安装,配置
下载的文件 zookeeper-3.5.6beta.tar.gz. 解压后到目录就可以了,例如 d:/servers/ zookeeper-3.5.4
修改 zookeeper-3.5.6/conf/ 目录下配置文件 :
复制 zoo-sample.cfg 改名为 zoo.cfg
文件内容:
1 | # The number of milliseconds of each tick |
tickTime:
心跳的时间,单位毫秒. Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。表明存活状态。
dataDir:
数据目录,可以是任意目录。存储 zookeeper 的快照文件、pid 文件,默认为/tmp/zookeeper,建议在 zookeeper 安装目录下创建 data 目录,将 dataDir 配置改为 D:/zookeeper-3.4.10/data
clientPort:
客户端连接 zookeeper 的端口,即 zookeeper 对外的服务端口,默认为 2181
1 | #配置内容: |
Linux 平台 Zookeeper 安装、配置
Zookeeper 的运行需要 jdk。使用前 Linux 系统要安装好 jdk。
①:上传 zookeeper-3.5.4-beta.tar.gz,并解压(根据自己的版本来)
解压文件 zookeeper-3.5.4-beta.tar.gz
1 | tar -zxvf zookeeper-3.5.4-beta.tar.gz. -C /usr/local/ |
②:配置文件
在 zookeeper 的 conf 目录下,将 zoo_sample.cfg 改名为 zoo.cfg
1 | cp zoo_sample.cfg zoo.cfg |
zookeeper 启动时会读取该文件作为默认配置文件。
③:启动 Zookeeper 启动(切换到安装目录的 bin 目录下)
1 | ./zkServer.sh start |
④:关闭 Zookeeper 关闭(切换到安装目录的 bin 目录下)
1 | ./zkServer.sh stop |
改造 dubbo—使用 Zookeeper
接口工程
同改造的 dubbo 项目
服务提供者
在改造的 dubbo 项目基础上作了一下改动:
1、pom 文件新增依赖
1 | <!--注册中心依赖--> |
如果使用上面的依赖注册 Zookeeper 报错的话,改用下面的依赖:
1 | <dependency> |
2、dubbo 配置文件(去掉 dubbo:service 标签的 registry 属性,增加 dubbo:registry 标签)
1 |
|
服务消费者
做法同服务提供者。
1、pom 文件新增注册中心依赖
2、dubbo 配置文件(去掉 dubbo:reference 标签的 registry 属性,增加 dubbo:registry 标签)
注册中心的高可用
概念:
高可用性(High Availability):通常来描述一个系统经过专门的设计,从而减少不能提供服务的时间,而保持其服务的高度可用性。
Zookeeper 是高可用的,健壮的
。Zookeeper 宕机,正在运行中的 dubbo 服务仍然可以正常访问
。
健壮性:
⚫ 监控中心宕掉不影响使用,只是丢失部分采样数据
⚫ 注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
⚫ 服务提供者无状态,任意一台宕掉后,不影响使用
⚫ 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
演示操作:
1、先启动 zookeeper, dubbo 服务提供者,dubbo 服务消费者。
2、 测试正常访问
3、 停止 zookeeper
4、 测试消费者仍然可以访问提供者
dubbo 的配置
配置原则
在服务提供者配置访问参数。因为服务提供者更了解服务的各种参数。
关闭检查
dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check=true。
通过 check=”false”关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
例 1:关闭某个服务的启动时检查
<dubbo:reference interface=”com.foo.BarService” check=”false” />
例 2:关闭注册中心启动时检查
<dubbo:registry check=”false” />
默认启动服务时检查注册中心存在并已运行。注册中心不启动会报错。
重试次数
消费者访问提供者,如果访问失败,则切换重试访问其它服务器,但重试会带来更长延迟。
访问时间变长,用户的体验较差。多次重新访问服务器有可能访问成功。
可通过 retries=”2” 来设置重试次数(不含第一次)。
1 | 重试次数配置如下: |
超时时间
由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。
为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。
timeout
:调用远程服务超时时间(毫秒)
dubbo 服务提供端
1 | 指定接口超时配置 |
dubbo 消费端
1 | 指定接口超时配置 |
版本号
每个接口都应定义版本号,为后续不兼容升级提供可能。当一个接口有不同的实现,项目早期使用的一个实现类, 之后创建接口的新的实现类。区分不同的接口实现使用 version。
特别是项目需要把早期接口的实现全部换位新的实现类,也需要使用 version.
可以用版本号从早期的接口实现过渡到新的接口实现,版本号不同的服务相互间不引用。
可以按照以下的步骤进行版本迁移:
1、在低压力时间段,先升级一半提供者为新版本
2、再将所有消费者升级为新版本
3、然后将剩下的一半提供者升级为新版本
dubbo 服务提供端
1 | <!--不管是否一个接口有多个实现类,只要服务提供者服务接口服务的时候指定了版本号,那做为消费者引用远程接口服务的时候就必须指定版本号--> |
dubbo 消费端
1 | <!--引用远程接口服务--> |
控制器
1 |
|
监控中心
什么是监控中心
dubbo 的使用,其实只需要有注册中心,消费者,提供者这三个就可以使用了。
但是并不能看到有哪些消费者和提供者,为了更好的调试,发现问题,解决问题,因此引入 dubbo-admin
。
通过 dubbo-admin 可以对消费者和提供者进行管理。可以在 dubbo 应用部署做动态的调整, 服务的管理。
dubbo-admin
图形化的服务管理页面;安装时需要指定注册中心地址,即可从注册中心中获取到所有的提供者/消费者进行配置管理
dubbo-monitor-simple
简单的监控中心;
发布配置中心
下载监控中心:https://github.com/apache/incubator-dubbo-ops
这里下载的是源代码,需要手工编译才能使用。
运行管理后台 dubbo-admin
到 dubbo-admin-0.0.1-SNAPSHOT.jar 所在的目录。执行下面命令
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
修改配置 dubbo-properties 文件
dubbo-admin-0.0.1-SNAPSHOT.jar/BOOT-INF/classes 下的 application.properties 文件,内容如下:
1 | # |
运行 dubbo-admin 应用
1) 先启动注册中心
2) 执行提供者项目
3) java -jar dubbo-admin-0.0.1-SNAPSHOT.jar 启动 dubbo 管理后台
4) 在浏览器地址栏输入 http://localhost:7001 访问监控中心-控制台。
监控中心的数据来源
dubbo.registry.address=zookeeper://127.0.0.1:2181
应用监控中心
通过浏览器,访问监控中心主页。点击菜单访问功能选项。
发布时间: 2020-07-26
最后更新: 2024-06-24
本文标题: dubbo学习笔记
本文链接: https://blog-yilia.xiaojingge.com/posts/e6921d63.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可。转载请注明出处!
