一.基础知识
1.分布式基础理论
1.1什么是分布式系统
分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统。
分布式系统是建立在网络之上的软件系统。
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算框架势在必行,需要一个治理系统确保架构有条不紊的演进。
1.2发展演变
- 单一应用架构
当网站流量很小时,只需要一个应用,将所有功能部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
- 垂直应用架构
1.界面+业务逻辑的实现分离
2.应用不可能完全独立,大量的应用之间需要交互
- 分布式服务架构
RPC:远程过程调用
- 流动计算架构
调度,治理中心。基于访问压力实时管理集群容量,提高集群利用率。
1.3RPC
- 什么叫RPC
RPC(Remote Procedure Call)是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而用程序员显示编程这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
- RPC基本原理
RPC俩个核心模块:通讯,序列化。
RPC框架有很多:dubbo,gRPC,Thrift,HSF(High Speed Service Framework)
2.dubbo核心概念
2.1简介
Apache Dubbo是一款高性能,轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
1.将服务提供者注册到注册中心(暴露服务)
1)导入dubbo依赖和操作zookeeper的客户端(curator)
2)配置服务提供者
2.让服务消费者去注册中心订阅服务提供者的服务地址
3.监控中心
3.1dubbo-admin
图形化的服务管理页面,安装时需要指定注册中心地址,即可从注册中心中获取到所有的提供者/消费者进行配置管理。
3.2dubbo-monitor-simple
简单的监控中心
4.配置覆盖关系
以timeout为例,显示了配置的查找顺序,其他retries,loadbalance,actives等类似:
- 方法级优先,接口级次之,全局配置再次之。
- 如果级别一样,则消费方优先,提供方次之。
5.SpringBoot与Dubbo整合的三种方式:
- 导入dubbo-starter,在application.properties配置属性,使用@Service【暴露服务】使用@Reference【引用服务】
- 保留dubbo xml配置文件;导入dubbo-starter,使用@ImportResource导入dubbo的配置文件即可。
- 使用注解API的方式:将每一个组件手动创建到容器中,让dubbo来扫描其他的组件。
二.高可用
1.zookeeper宕机与dubbo直连
现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务。
原因:
健壮性:
- 监控中心宕掉不影响使用,只是丢失部分采样数据。
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务。
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台。
- 注册中心全部宕掉后服务提供者和服务消费者仍能通过本地缓存通讯。
- 服务提供者无状态,任意一台宕掉后,不影响使用。
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复。
高可用:通过设计,减少系统不能提供服务的时间。
2.集群下dubbo负载均衡配置
在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。
负载均衡策略
Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
轮询,按公约后的权重设置轮询比率。
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
一致性hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其他提供者,不会引起剧烈变动。算法参见:en.wikipedia.org/wiki/Consis…
缺省只对第一个参数Hash,如果要修改,请配置<dubbo:parameter key="hash.arguments" value="0,1" />
缺省用160份虚拟节点,如果要修改,请配置<dubbo:parameter key="hash.nodes" value="320" />
3.服务降级
什么是服务降级?
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
向注册中心写入动态配置覆盖规则:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.registry(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
其中:
- mock=force:return+null 表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
- 还可以改为mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
4.集群容错
在集群调用失败时,Dubbo提供了多种容错方案,缺省为failover重试。
集群容错模式
Failover Cluster
失败自动切换,当出现失败,重试其他服务器。通常用于读操作,但重试会带来更长延迟。可通过retries="2"来设置重试次数(不含第一次)。
重试次数配置如下:
<dubbo:service retries="2" />
或<dubbo:reference retries="2" />
或<dubbo:reference>
<dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
Failfast Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志操作。
Failback Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
Forking Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2"来设置最大并行数。
Broadcast Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
集群模式配置
按照以下示例在服务提供方和消费方配置集群模式
<dubbo:service cluster="failsafe" />
或<dubbo:reference cluster="failsafe" />
5.整合hystrix
Hystrix 旨在通过控制那些访问远程系统,服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。
三.dubbo原理
1.RPC原理
一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub 接收到调用后负责将方法,参数等组装成能够进行网络传输的消息体;
3)client stub 找到服务地址,并将信息发送到服务端;
4)server stub收到信息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接受到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架的目标就是要2-8这些步骤都封装起来,这些细节对于用户来说是透明的,不可的。
2.netty通信原理
Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。它极大的简化并简化了TCP和UDP套接字服务器等网路编程。
BIO(Blocking IO): 一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub 接收到调用后负责将方法,参数等组装成能够进行网络传输的消息体;
3)client stub 找到服务地址,并将信息发送到服务端;
4)server stub收到信息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接受到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架的目标就是要2-8这些步骤都封装起来,这些细节对于用户来说是透明的,不可的。
2.netty通信原理
Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。它极大的简化并简化了TCP和UDP套接字服务器等网路编程。
BIO(Blocking IO):
NIO(Non-Blocking IO):
Selector一般称为选择器,也可以翻译为多路复用器。
Connect(连接就绪),Accept(接受就绪),Read(读就绪),Write(写就绪)
Netty基本原理:
3.dubbo原理
1)dubbo原理——框架设计
2)dubbo原理——启动解析,加载配置信息
3)dubbo原理——服务暴露
4)dubbo原理——服务引用
5)dubbo原理——服务调用