博客加载速度一直较慢,在查阅了配置文件之后发现可以用CDN提升加载速度,于是乎了解了一下CDN并运用到自己的配置中。
CDN是什么CDN英文全称Content Delivery Network,中文翻译为内容分发网络。它是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。CDN应用广泛,支持多种行业、多种场景内容加速,例如:图片小文件、大文件下载、视音频点播、直播流媒体、全站加速、安全加速。
借用上图阿里云官网的例子,来简单介绍CDN的工作原理。假设通过CDN加速的域名为www.a.com,接入CDN网络,开始使用加速服务后,当终端用户(北京)发起HTTP请求时,处理流程如下:
当终端用户(北京)向www.a.com下的指定资源发起请求时,首先向LDNS(本地DNS)发起域名解析请求。
LDNS检查缓存中是否有www.a.com的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向授权DNS查询。
当授权DNS解析www.a.com时,返回域名CNAME www.a.tbcdn.com对应IP地址。
域名解析请求发送至阿里云DNS调度系统,并为 ...
1 背景当今的数据中心和应用程序在高度动态的环境中运行,为了应对高度动态的环境,它们通过额外的服务器进行横向扩展,并且根据需求进行扩展和收缩。同时,服务器和网络故障也很常见。
因此,系统必须在正常操作期间处理服务器的上下线。它们必须对变故做出反应并在几秒钟内自动适应;对客户来说的话,明显的中断通常是不可接受的。
幸运的是,分布式共识可以帮助应对这些挑战。
1.1 拜占庭将军
在介绍共识算法之前,先介绍一个简化版拜占庭将军的例子来帮助理解共识算法。
假设多位拜占庭将军中没有叛军,信使的信息可靠但有可能被暗杀的情况下,将军们如何达成是否要进攻的一致性决定?
解决方案大致可以理解成:先在所有的将军中选出一个大将军,用来做出所有的决定。
举例如下:假如现在一共有 3 个将军 A,B 和 C,每个将军都有一个随机时间的倒计时器,倒计时一结束,这个将军就把自己当成大将军候选人,然后派信使传递选举投票的信息给将军 B 和 C,如果将军 B 和 C 还没有把自己当作候选人(自己的倒计时还没有结束),并且没有把选举票投给其他人,它们就会把票投给将军 A,信使回到将军 A 时,将军 A 知道自己收到了 ...
一、需求分析通过前面RPC 框架的功能已经比较完善了,接下来我们就要思考如何优化这个框架。
开发者会更关注框架的这些情况:
框架的知名度和用户数:尽量选主流的、用户多的,经过了充分的市场验证。
生态和社区活跃度:尽量选社区活跃的、能和其他技术兼容的。
简单易用易上手:最好能开箱即用,不用花很多时间去上手。这点可能是我们在做个人小型项目时最关注的,可以把精力聚焦到业务开发上。
回归到我们的 RPC 项目,其实框架目前是不够易用的。光是示例服务提供者,就要写下面这段很长的代码。
123456789101112131415161718192021222324252627282930public class ProviderExample { public static void main(String[] args) { ProviderBootstrap.ServiceRegisterInfo // RPC 框架初始化 ProviderBootstrap.init(); // 注册服务 St ...
一、需求分析上节给 RPC 框架增加了重试机制,提升了服务消费端的可靠性和健壮性。
但如果重试超过了一定次数仍然失败,又该怎么处理呢?
或者说当调用出现失败时,我们一定要重试么?有没有其他的策略呢?
本节实现另一种提高服务消费端可靠性和健壮性的机制 —— 容错机制。
二、设计方案容错机制容错是指系统在出现异常情况时,可以通过一定的策略保证系统仍然稳定运行,从而提高系统的可靠性和健壮性。
在分布式系统中,容错机制尤为重要,因为分布式系统中的各个组件都可能存在网络故障、节点故障等各种异常情况。要顾全大局,尽可能消除偶发 / 单点故障对系统带来的整体影响。
打个比方,将分布式系统类比为一家公司,如果公司某个优秀员工请假了,需要 “触发容错”,让另一个普通员工顶上,这本质上是容错机制的一种 降级 策略。
容错机制一般都是在系统出现错误时才触发的,这点没什么好讲,需要重点学习的是容错策略和容错实现方式。
容错策略容错策略有很多种,常用的容错策略主要是以下几个:
1)Fail-Over 故障转移:一次调用失败后,切换一个其他节点再次进行调用,也算是一种重试。
2)Fail-Back 失败 ...
一、需求分析目前,如果使用 RPC 框架的服务消费者调用接口失败,就会直接报错。
调用接口失败可能有很多原因,有时可能是服务提供者返回了错误,但有时可能只是网络不稳定或服务提供者重启等临时性问题。这种情况下,我们可能更希望服务消费者拥有自动重试的能力,提高系统的可用性。
本节实现服务消费端的重试机制。
二、设计方案重试机制我们需要掌握的是 “如何设计重试机制”,重试机制的核心是 重试策略,一般来说,包含以下几个考虑点:
什么时候、什么条件下重试?
重试时间(确定下一次的重试时间)
什么时候、什么条件下停止重试?
重试后要做什么?
重试条件首先是什么时候、什么条件下重试?
如果我们希望提高系统的可用性,可当由于网络等异常情况发生时,触发重试。
重试时间重试时间(也叫重试等待)的策略就比较丰富了,可能会用到一些算法,主流的重试时间算法有:
1)固定重试间隔(Fixed Retry Interval):在每次重试之间使用固定的时间间隔。
比如近 5 次重试的时间点如下:
123451s2s3s4s5s
2)指数退避重试(Exponential Backoff Retry):在每次失 ...
一、需求分析现在RPC 框架已经可以从注册中心获取到服务提供者的注册信息了,同一个服务可能会有多个服务提供者,但是目前消费者始终读取了第一个服务提供者节点发起调用,不仅会增大单个节点的压力,而且没有利用好其他节点的资源。
我们完全可以从服务提供者节点中,选择一个服务提供者发起请求,而不是每次都请求同一个服务提供者,这个操作就叫做 负载均衡。
本节为 RPC 框架支持服务消费者的负载均衡。
二、负载均衡什么是负载均衡?把这个词拆开来看:
1)何为负载?可以把负载理解为要处理的工作和压力,比如网络请求、事务、数据处理任务等。
2)何为均衡?把工作和压力平均地分配给多个工作者,从而分摊每个工作者的压力,保证大家正常工作。
用个比喻,假设餐厅里只有一个服务员,如果顾客非常多,他可能会忙不过来,没法及时上菜、忙中生乱;而且他的压力会越来越大,最严重的情况下就累倒了无法继续工作。而如果有多个服务员,大家能够服务更多的顾客,即使有一个服务员生病了,其他服务员也能帮忙顶上。
所以,负载均衡是一种用来分配网络或计算负载到多个资源上的技术。它的目的是确保每个资源都能够有效地处理负载、增加系统的并发量、避免 ...
一、需求分析目前的 RPC 框架,我们使用 Vert.x 的 HttpServer 作为服务提供者的服务器,代码实现比较简单,其底层网络传输使用的是 HTTP 协议。
问题来了,使用 HTTP 协议会有什么问题么?或者说,有没有更好的选择?
一般情况下,RPC 框架会比较注重性能,而 HTTP 协议中的头部信息、请求响应格式较 “重”,会影响网络传输性能。
举个例子,利用浏览器网络控制台随便查看一个请求,能看到大量的请求和响应标头。
所以,我们需要自己自定义一套 RPC 协议,比如利用 TCP 等传输层协议、自己定义请求响应结构,来实现性能更高、更灵活、更安全的 RPC 框架。
本节会自定义 RPC 协议,巩固计算机网络知识,并提升自己的系统设计能力。
二、设计方案自定义 RPC 协议可以分为 2 大核心部分:
自定义网络传输
自定义消息结构
1、网络传输设计网络传输设计的目标是:选择一个能够高性能通信的网络协议和传输方式。
需求分析中已经提到了,HTTP 协议的头信息是比较大的,会影响传输性能。但其实除了这点外,HTTP 本身属于无状态协议,这意味着每个 HTTP 请求都是独立的 ...
一、需求分析上节基于 Etcd 完成了基础的注册中心,能够注册和获取服务和节点信息。
但目前系统仅仅是处于可用的程度,还有很多需要解决的问题和可优化点:
数据一致性:服务提供者如果下线了,注册中心需要即时更新,剔除下线节点。否则消费者可能会调用到已经下线的节点。
性能优化:服务消费者每次都需要从注册中心获取服务,可以使用缓存进行优化。
高可用性:保证注册中心本身不会宕机。
可扩展性:实现更多其他种类的注册中心。
本节将实践 4 个注册中心的优化点:
心跳检测和续期机制
服务节点下线机制
消费端服务缓存
基于 ZooKeeper 的注册中心实现
二、注册中心优化心跳检测和续期机制心跳检测介绍心跳检测(俗称 heartBeat)是一种用于监测系统是否正常工作的机制。它通过定期发送 心跳信号(请求)来检测目标系统的状态。
如果接收方在一定时间内没有收到心跳信号或者未能正常响应请求,就会认为目标系统故障或不可用,从而触发相应的处理或告警机制。
心跳检测的应用场景非常广泛,尤其是在分布式、微服务系统中,比如集群管理、服务健康检查等。
我们怎么检测自己做的 web 后端是否正常运行呢?
一 ...
一、需求分析RPC 框架的一个核心模块是注册中心,目的是帮助服务消费者获取到服务提供者的调用地址,而不是将调用地址硬编码到项目中。
本节先实现一个具有基本功能的注册中心,跑通注册中心的流程,之后再优化。
二、设计方案注册中心核心能力我们先明确注册中心的几个实现关键(核心能力):
数据分布式存储:集中的注册信息数据存储、读取和共享
服务注册:服务提供者上报服务信息到注册中心
服务发现:服务消费者从注册中心拉取服务信息
心跳检测:定期检查服务提供者的存活状态
服务注销:手动剔除节点、或者自动剔除失效节点
更多优化点:比如注册中心本身的容错、服务消费者缓存等。
技术选型明确了注册中心的核心能力后,我们可以根据这些能力进行技术选型。
第一点是最重要的,我们首先需要一个能够集中存储和读取数据的中间件。此外,它还需要有数据过期、数据监听的能力,便于我们移除失效节点、更新节点列表等。
此外,对于注册中心的技术选型,我们还要考虑它的性能、高可用性、高可靠性、稳定性、数据一致性、社区的生态和活跃度等。注册中心的可用性和可靠性尤其重要,因为一旦注册中心本身都挂了,会影响到所有服务的调用。
主流的注册中 ...
一、需求分析前面已经讨论过序列化器的作用:无论是请求或响应,都会涉及参数的传输。而 Java 对象是存活在 JVM 虚拟机中的,如果想在其他位置存储并访问、或者在网络中进行传输,就需要进行序列化和反序列化。
此外还编写了通用的序列化器接口,并且已经实现了基于 Java 原生序列化的序列化器。但是对于一个完善的 RPC 框架,我们还要思考以下 3 个问题:
有没有更好的序列化器实现方式?
如何让使用框架的开发者指定使用的序列化器?
如何让使用框架的开发者自己定制序列化器?
二、设计方案依次分析这三个问题的实现方案。
1、序列化器实现方式我们所追求的 “更好的” 序列化器,可以是具有更高的性能、或者更小的序列化结果,这样就能够更快地完成 RPC 的请求和响应。
之前是为了方便,我们使用 Java 原生序列化实现序列化器,但这未必是最好的。市面上还有很多种主流的序列化方式,比如 JSON、Hessian、Kryo、protobuf 等。
下面简单列举它们的优缺点:
主流序列化方式对比1)JSON
优点:
易读性好,可读性强,便于人类理解和调试。
跨语言支持广泛,几乎所有编程语言都有 J ...