掌握之分布式-1.Dubbo
掌握高并发、高可用架构
第三章 分布式
本章介绍分布式架构的底层技术。主要说明面试过程中可能被问到的技术点。
成都创新互联专注于壶关企业网站建设,响应式网站,商城开发。壶关网站建设公司,为壶关等地区提供建站服务。全流程按需搭建网站,专业设计,全程项目跟踪,成都创新互联专业和态度为您提供的服务
第一节 Dubbo
Duboo
服务治理
Zookeeper
1. Dubbo的概念
Dubbo是一个分布式、高性能、透明化的RPC(远程服务调用)服务框架, 提供服务自动注册、自动发现等高效服务治理方案,可以和Spring无缝集成。
2. Dubbo的由来
cdn.com/08158f23adc5919667e6715eaa23825f030dadee.jpeg">
当网站流量很小时,可以把所有功能都部署在一个项目中,叫单体应用框架。
随着流量的增大,应用拆分必不可少,此时会出现多个垂直应用,在美格尔应用中处理各自的业务逻辑。
当垂直应用越来越多,应用之间的交互不可避免,将核心业务抽离出来,作为独立的服务,逐渐形成稳定的服务中心。此时,用于提高业务复用和整合的 分布式服务框架 RPC是关键。
当服务越来越多,容量的评估、小服务资源的浪费等问题逐渐显现,此时需要增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高集群利用率的 资源调度和治理中心 SOA是关键。
3. Dubbo的主要特点
- 透明化的远程方法调用,没有API侵入
- 软负载均衡及容错机制,降低成本,拒绝单点
- 服务自动注册与发现,不再需要写死服务提供者地址,注册中心基于接口名查询服务提供者的IP地址,并能够平滑的添加或删除服务提供者
4. Dubbo的核心组件
Provider
,暴露服务的服务提供方Consumer
,调用远程服务的服务消费者Registry
,服务注册与发现的服务中心Monitor
,统计服务的调用次数和调用时间的监控中心Container
,服务运行容器
下面来解释上述的两张图:
- 服务容器启动、加载、运行服务提供者
- 服务提供者在启动时,向注册中心注册自己提供的服务
- 服务消费者在启动时,向注册中心订阅自己所需的服务,并将获得的地址列表进行缓存。如果没有订阅到自己想订阅的服务,它会不断尝试订阅
- 注册中心返回服务提供者地址列表给消费者。当新的服务注册到注册中心后,注册中心会基于长连接将这些服务通过notify到消费者
- 服务消费者从缓存的提供者地址列表中,基于软负载均衡算法,选一台进行服务调用(此处有容错机制)
- 服务提供者和消费者,在各自的内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
5. Dubbo的核心配置
配置 | 配置说明 |
---|---|
dubbo:service | 服务配置,用于暴露服务,定义服务的元信息,一个服务可用多个协议暴露,也可以注册到多个注册中心,对应ServiceBean |
dubbo:reference | 引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。对应ReferenceBean |
dubbo:protocol | 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。对应ProtocolConfig |
dubbo:application | 应用配置,用于配置当前应用信息,不管应用是服务提供方还是消费方 。对应ApplicationConfig |
dubbo:module | 模块配置,用于配置当前模块信息,可选。对应ModuleConfig |
dubbo:registry | 注册中心配置。对应RegistryConfig |
dubbo:monitor | 监控中心配置。对应MonitorConfig |
dubbo:provider | 提供者配置,当没有配置ProtocolConfig 或ServiceBean 时,采用该配置项,可选。对应ProviderConfig |
dubbo:consumer | 消费方配置,当没有配置ReferenceBean 时,采用该配置项,可选。对应ConsumerConfig |
dubbo:method | 方法配置 |
dubbo:argument | 参数配置 |
6. Dubbo支持的协议
协议名称 | 实现描述 | 连接 | 使用场景 |
---|---|---|---|
dubbo协议(默认) | 传输:mina、netty、grizzly 序列化:hessian2、java、json |
缺省采用单一长连接和NIO异步通信,TCP | 1.传入传出参数数据包较小 2.消费者数量远大于生产者 3.常规远程服务调用 4.不适合传输大数据量的服务,比如文件、视频等 |
rmi | 传输:rmi java 序列化:java标准序列化 |
连接个数:多连接 连接方式:短连接 传输协议:TCP/IP 传输方式:BIO |
1.常规RPC调用 2.传入传出参数大小包混合 3.可传文件 4.不支持防火墙穿透 5.生产者和消费者数量差不多 |
hessian | 传输:servlet容器 序列化:hessian2 |
连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 |
1.生产者的数量比消费者多 2.可传文件 3.传入传输参数数据包较大 4.跨语言传输 |
http | 传输:servlet容器 序列化:表单序列化JSON 采用Spring的httpInvoker实现,基于表单的远程服务调用 |
连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 |
1.生产者多余消费者 2.数据包大小混合 3.需同时给应用程序和浏览器使用的服务 |
webservice | 传输:HTTP 序列化:SOAP文本序列化 |
连接个数:多连接 连接方式:短连接 传输协议:HTTP 传输方式:同步传输 |
1.系统集成 2.跨语言传输 |
thrift | 与thrift rpc实现集成,并在基础上修改了报文头 | 长连接、NIO异步传输 | |
memcached | |||
redis |
7.支持的序列化框架
hessian(默认)、dubbo(不建议)、fastjson、Java自带序列化
8. 支持的通信框架
默认是Netty的NIO通信,还支持mina、Grizzly、Http等
9. 支持的集群容错机制
集群容错方案 | 说明 |
---|---|
Failover Cluster(默认) | 失败自动切换,自动重试其他服务器 |
Failfast Cluster | 快速失败,立即报错,只发起一次调用 |
Failsafe Cluster | 失败安全,出现异常时,直接忽略 |
Failback Cluster | 失败自动恢复,记录失败请求,定时重发 |
Forking Cluster | 并行调用多个服务器,只要一个成功立即返回 |
Broadcast Cluster | 广播逐个调用所有生产者,任意一个报错则报错 |
读操作建议使用Failover
失败自动切换,默认重试两次
写操作建议使用Failfast
快速失败,调用一次失败就报错
10. 支持的负载均衡算法
负载均衡测量 | 说明 |
---|---|
Random LoadBalance(默认) | 随机,按权重分配随机概率 |
RoundRobin LoadBalance | 轮询,按公约后的权重设置轮询比率 |
LeastActive LoadBalance | 最少活跃调用数,相同活跃数的随机 |
ConsistendHash LoadBalance | 一致性Hash,相同参数的请求总是发到同一生产者 |
11. 支持的注册中心
- Multicast注册中心
- Zookeeper注册中心
- Redis注册中心
- Simple注册中心
12. 服务暴露和服务消费的过程
服务暴露:在容器启动时,按照Spring的加载流程初始化BeanDefinition,把服务提供者解析成ServiceBean
。然后调用export()
方法进行暴露。(暴露过程相当长,以后慢慢看吧)
ServiceBean
拿到对外提供服务的实际类ref(如HelloWorldImpl)- 通过
ProxyFactory
的getInvoker()
方法使用ref生成一个AbstractProxyInvoker
实例。到这一步就完成了到Invoker的转换 - 将
Invoker
转换为Exporter
,这个根据不同的协议会有不同的实现- Dubbo的实现:发生在
DubboProtocol
的export()
,主要是打开socket侦听服务,并接收客户端发来的各种请求 - RMI的实现:发生在
RmiProtocol
的export()
- Dubbo的实现:发生在
服务消费,分为消费端的初始化和服务引用过程。
初始化:
- 把服务引用的信息封装成URL,并注册到zk中心
- 监听注册中心服务的上下线
- 连接服务提供端,创建
NettyClient
对象 - 将这些信息包装成
DubboInvoker
消费端的调用链,创建消费端Invoker实例的服务代理并返回
服务引用:
- 经过负载均衡策略,调用提供者
- 选择其中一个服务的URL与提供者netty建立连接,使用ProxyFactory创建远程代理或本地通信的Invoker,并将Invoker发送到netty提供端
- 服务提供端接到该Invoker请求后,找到对应的本地Invoker,处理
- 获取异步、同步处理结果
- 异步调用,不需要立即拿到返回值,使用
ExchangeClient.send()
- 同步调用,需要立即拿到返回值,使用
ExchangeClient.request()
,返回一个ResponseFuture
,一直阻塞到拿到返回值
- 异步调用,不需要立即拿到返回值,使用
ReferenceBean
的init()
方法调用Protocal
的ref()
方法生成Invoker
实例- 将
Invoker
实例转换成客户端需要的接口类
当前名称:掌握之分布式-1.Dubbo
标题链接:http://azwzsj.com/article/jgoige.html