热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分布式服务框架和原理简章

应用架构演进这里的架构演进应该是从服务化的角度来说,应该说随着业务发展,应用规模扩大,系统的一些公共服务就会抽取出来,独立开发,部署,维护,用来解决并发,扩展,维护的问题。传统垂直

应用架构演进

这里的架构演进应该是从服务化的角度来说,应该说随着业务发展,应用规模扩大,系统的一些公共服务就会抽取出来,独立开发,部署,维护,用来解决并发,扩展,维护的问题。

传统垂直架构

有的地方也叫单体应用,以mvc模式开发:

所有应用代码统一打包,代码所有接口本地api调用,很少存在远程服务调用;

单机或主备,应用做集群部署;

DB主从等。

这种并没有什么不好,发展初期大多是这样,体量没那么大,也不需要考虑高并发大流量可扩展性什么的,简单粗暴,解决业务需求就好,活下去才能活的更好。

但是必须明白这种简单架构存在的一些问题:

1. 业务不断发展,功能逐渐增多,应用的开发维护成本变高,部署效率降低,随便改个代码,编译一次十几分钟就浪费了。悲剧,我们有个系统才开发3年,就碰到这种情况,一次打包编译部署,13分钟结束。

2. 不同的人负责不同的部分,一些通用代码、公共代码就各写各的,不能复用,如果只是util还好,但是一些外部服务的都有重复,那就happy了(不过这种情况的出现,不一定是架构问题,更多可能是管理);

3. 不断地上新需求,不断地改代码,有时测试不到位,指定哪里埋了bug,上生产后系统就down了,牵一发而动全身;

4. 可维护性,可靠性,扩展性变差。

既然有这些问题,就要解决啊,业务就会提要求,你要解决啊,要不然影响我业务发展,影响我ipo上市啊,苦逼的码农开始干活了。

不提应用的拆分主从那些手段,但从拆分后应用交互看,原来的本地api交互变成的远程api的调用,这里就出现了rpc,当然也有走esb,webservice。其实拆分后挺麻烦的,光一个分布式事务就能折腾死人。

RPC架构

Remote Procedure Call,远程方法调用,屏蔽底层实现细节,像调用本地方法一样调用远程服务。

上个作者的图:

《分布式服务框架和原理简章》

这个图对于大多数rpc框架通用,实现的几个技术点:

1. 服务提供者发布服务:服务接口定义,数据结构,服务提供者信息等;

2. 客户端远程调用:通常是使用jdk的代码代理拦截;

3. 底层通信:现在应该更多是使用netty吧,当然也有走支持http的;

4. 序列化:关注序列化反序列性能,xml,json,hessiaon,pb,protostuff,kryo等;

作者给了个socket实现简单demo,来实现远程调用,说明上面几个技术点。

常用的rpc框架

1. Thrift;

2. Hadoop的Avro-RPC;

3. Hessian;

4. gRPC;

单论rpc的话,没太多可说的,可是如果加上服务治理,那复杂度就几何倍数增长了。服务治理里面东西太多了,动态注册,动态发现,服务管控,调用链分析等等问题这些问题,单凭rpc框架解决不了,所以现在常用的说的服务化框架,通常指的是rpc+服务治理2个点。

SOA服务化架构

感觉soa架构应该是在rpc之前出现,用来解决异构系统的交互,通常的实现是通过ESB,WSDL来处理。其粒度通常来说是比较粗的。也存在服务治理方面的问题。

微服务

MSA也是一种服务化架构风格,正流行ing,服务划分

1. 原子服务,粒度细;

2. 独立部署,主要是容器;

分享篇文章:云栖肥侠的文章 微服务(Microservice)那点事 。

MSA与SOA的对比:

服务拆分粒度:soa首要解决的是异构系统的服务化,微服务专注服务的拆分,原子服务;

服务依赖:soa主要处理已有系统,重用已有的资产,存在大量服务间依赖,微服务强调服务自治,原子性,避免依赖耦合的产生;

服务规模:soa服务粒度大,大多数将多个服务合并打包,因此服务实例数有限,微服务强调自治,服务独立部署,导致规模膨胀,对服务治理有挑战;

架构差异:微服务通常是去中心化的,soa通常是基于ESB的;

服务治理:微服务的动态治理,实时管控,而soa通常是静态配置治理;

交付:微服务的小团队作战。

感觉在有了docker后,微服务这个概念突然火了起来,总结就是微服务+容器+DevOps。

《分布式服务框架和原理简章》

分布式服务框架入门

背景

应用从集中式走向分布式

随着业务的发展导致功能的增多,传统的架构模式开发,测试,部署整个流程变长,效率变低,后台服务的压力变大,只能通过硬件扩容来暂时缓解压力,但解决不了根本性问题:

应用规模变大,开发维护成本变高,部署效率降低;

代码复用:原来是本地api调用,导致一些公用功能可能是按需开发,不统一,随意等问题;

交付面临困难:主要是业务变得复杂,新增修改测试变得困难,拉长整个流程。

通用法宝:拆分,大系统拆小系统,独立扩展和伸缩。

纵向:分业务模块;

横向:提炼核心功能,公共业务;

需要服务治理

大拆小,核心服务提炼后,服务的数量变多,而且需要一些运行态的管控,这时候就需要服务治理:

服务生命周期管理;

服务容量规划;

运行期治理;

服务安全。

服务框架介绍

Dubbo

阿里开源的Dubbo应该是业界分布式服务框架最出名的了吧,看过公司的rpc框架,Dubbo的扩展性比我们的好的多了,我们的框架每次升级,改动都很多,改天要看下Dubbo的源码了解了解扩展性。

《分布式服务框架和原理简章》
《分布式服务框架和原理简章》

HSF

淘宝的体量决定了他对极致性能的追求,HSF跨机房特性挺牛。

《分布式服务框架和原理简章》
《分布式服务框架和原理简章》

Coral Service

这个没听说过,孤陋寡闻了。

《分布式服务框架和原理简章》

框架设计

架构原理

万变不离其中,这张图可以概括rpc的一些通用原理:

《分布式服务框架和原理简章》

细化了下:

《分布式服务框架和原理简章》

rpc层:底层的通讯框架,通讯协议,序列化和反序列化;

服务发布订阅;

服务治理;

功能

《分布式服务框架和原理简章》
《分布式服务框架和原理简章》
《分布式服务框架和原理简章》

性能

《分布式服务框架和原理简章》

可靠性

《分布式服务框架和原理简章》

分布式的,面试会问,用池子的话讲就是,知识点啊。

服务治理

《分布式服务框架和原理简章》
《分布式服务框架和原理简章》

通讯框架

技术点

长连接:主要是链路的创建过程到最后的关闭,耗时耗资源;每次调用都要创建的话,调用时延的问题,很可能链路创建的耗时比代码真正执行时长还多;

BIO还是NIO:主要是线程模型的选择,推荐篇文章 IO – 同步,异步,阻塞,非阻塞 (亡羊补牢篇);

自研还是使用开源NIO框架:一般来说还是使用开源吧,技术成熟,社区支持,现在netty和mina使用较多了吧。

《分布式服务框架和原理简章》

在功能设计方面,作者基于netty给了demo服务端和客户端的代码,个人理解:

1. 通用性api;

2. 扩展性,封装底层,提供上层接口,隔离协议和底层通讯;

可靠性设计

谈分布式系统必谈可靠性。

链路有效性

通过心跳来确认双方c、s存活,保证链路可用,心跳检测机制分为3个层面:

1. tcp层面,即tcp的keep-alive,作用于整个tcp协议栈;

2. 协议层的心跳检测,主要存在于长连接协议中,例如smpp协议;

3. 应用层的心跳,业务双方的定时发送心跳消息;

第2个没听说过,常用的是1,3。一般使用netty的话用的是netty的读写空闲来实现心跳。

断连

不管因为网络挂了还是服务端宕机,还是心跳超时什么的,导致链路不可用关闭,这时候就需要链路重连,需要注意的一点就是短连后,不要立即重连,留时间给系统释放资源,可以scheduler处理。

消息缓存重发

底层消息不会立即发送(也会导致半包粘包),断链后,导致消息丢失,看有无业务需求,有就支持断链后消息重发。

资源释放

主要是断链后,一定要保证资源销毁和释放,当然也包括一些线程池,内存等的释放。

性能设计

性能差的三宗罪

对于底层通讯框架来说,主要是下面几个:

1. 通讯模型的选择,主要是阻塞非阻塞那些东西;

2. 序列化反序列化(后面有章单讲序列化);

3. 线程模型,主要是服务端选择什么样的线程模型来处理消息。

通信性能三原则

既然有上面的3个问题,那就针对这些做优化了:

传输:BIONIOAIO的选择;

选择自定义协议栈,便于优化;

服务端线程模型,单线程处理还是线程池,线程池是一个,还是分优先级,Reactor还是其他什么的。

高性能之道这节作者讲了netty的优势。

序列化与反序列化

也就是通常所说的编码、解码。通常的通讯框架会提供编解码的接口,也会内置一些常用的序列化反序列化工具支持。

与通讯框架和协议的关系,感觉可以理解为:通讯框架是通道,其上跑的码流数据是利用各种序列化编码后的各种协议。

功能设计

各种序列化框架需要考虑的主要有:

序列化框架本身的功能的丰富,支持的数据类型;

多语言的支持;

兼容性,往大了说:

服务接口的前后兼容;

协议的兼容;

支持的数据类型的兼容。

性能,目的是最少的资源,最快的速度,最大的压缩:

序列化后码流大小;

序列化的速度;

序列化的资源占用。

在扩展性这节,作者讲了netty的对序列化的一些内置支持,但实际开发中,一般不太会使用这些东西,都会提供序列化反序列接口,自行扩展定义,所以扩展性特重要。

常用的序列化,xml,json,hessian,kryo,pb,ps,看需求需要支持那种,具体可以搜索各序列化的性能和压缩后大小。

协议栈

这一章最主要的是讲了自定义协议栈的设计,已经交互的过程,其他讲的可靠性设计什么的跟之前通讯框架一章有重复。

通信模型

《分布式服务框架和原理简章》

服务提供者和消费者之间采用单链路,长连接通信,链路创建流程:

1. 客户端发送握手请求,携带节点ID等认证信息;

2. 服务端校验:节点ID有效性,重复登录,ip地址黑白名单等,通过后,返回握手应答信息;

3. 链路建立后,客户端发送业务消息;

4. 客户端服务端心跳维持链路;

5. 服务端退出时,关闭连接,客户端感知连接关闭,关闭客户端连接。

协议消息定义

《分布式服务框架和原理简章》
《分布式服务框架和原理简章》

通过attachment兼容了扩展性。作者还讲了将消息头的通用序列化和消息体的自定义序列化,看需求吧,我们公司的框架没做这部分支持,做了简化,将消息头和消息体统一封装,然后再加一个序列化方式组成一条消息发送。

安全性设计

内部的,不一定需要认证,也有基于系统,域名,ip的黑白名单,安全认证的;

外部开发平台的话,基于秘钥认证;

服务路由

服务路由指的是服务提供者集群部署,消费端如何从服务列表中选择合适的服务提供者提供服务进行调用。

透明化路由

基于zk的服务注册中心的发布订阅;

消费者本地缓存服务提供者列表,注册中心宕机后,不影响已有的使用,只是影响新服务的注册和老服务的下线。

负载均衡

随机

轮循

服务调用时延

一致性Hash

有个一致性hash算法,挺有意思的,redis的客户端shard用的

《分布式服务框架和原理简章》

黏滞连接

这个应该不太常用,服务提供者多数无状态,一旦有状态,不利于扩展

这些都是点对点的连接,负载均衡大多会在客户端执行,有种场景会取决于服务端负载,就是服务端服务配置的是域名。

本地路由优先策略

injvm:jvm也提供了消费端的服务,可以改成优先本jvm,对于消费端来说,不需关注提供者;

innative:injvm比较少,多得是可能是这种,一个物理机部署多个虚拟机,或者一个容器部署多个服务提供者,消费者不需远程调用,本机,本地或本机房优先。

路由规则

除了上面提供的各种路由负载均衡,还容许自定义路由规则:

– 条件路由:主要是通过条件表达式来实现;

– 脚本路由:通过脚本解析实现。

其实应该还有一种客户端通过代码自定义路由选择。这些主要是为了扩展性。

路由策略定制

自定义路由场景:

1. 灰度;

2. 引流;

路由策略:

1. 框架提供接口扩展;

2. 配置平台提供路由脚本配置;

配置化路由

本地配置:包括服务提供者和消费者,全局配置3种;

注册中心:路由策略统一注册到服务注册中心,集中化管理;

动态下发:配置后动态下发各服务消费端。

集群容错

指的是服务调用失败后,根据容错策略进行自动容错处理。

集群容错场景

通信链路故障:

通信过程中,对方宕机导致链路中断;

解码失败等原因Rest掉链接;

消费者read-write socketchannel发生IOException导致链路中断;

网络闪断故障;

交换机异常导致链路中断;

长时间Full GC导致;

服务端超时:

服务端没有及时从网络读取客户端请求消息,导致消息阻塞;

服务端业务处理超时;

服务端长时间Full GC;

服务端调用失败:

服务端解码失败;

服务端流控;

服务端队列积压;

访问权限校验失败;

违反SLA策略;

其他系统异常;

业务执行异常不属于服务端异常。

容错策略

《分布式服务框架和原理简章》

这图不错,关系很清晰。

失败自动切换(Failover):

调用失败后切换链路调用;

服务提供者的防重;

重试次数和超时时间的设置。

失败通知(FailBack):失败后直接返回,由消费端自行处理;

失败缓存(Failcache):主要是失败后,缓存重试重发,注意:

缓存时间、缓存数量;

缓存淘汰算法;

定时重试的周期T、重试次数;

快速失败(Failfast):失败不处理,记录日志分析,可用于大促期间,对非核心业务的容错。

容错策略扩展

容错接口的开放;

屏蔽底层细节,用户自定义;

支持扩展。

其实还有一点,感觉也挺重要,就是支持容错后本地mcok。调用失败后的链路切换和快速失败肯定要支持,缓存重发可以不用。


推荐阅读
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 本文详细介绍了Java代码分层的基本概念和常见分层模式,特别是MVC模式。同时探讨了不同项目需求下的分层策略,帮助读者更好地理解和应用Java分层思想。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 本文探讨了在一个物理隔离的环境中构建数据交换平台所面临的挑战,包括但不限于数据加密、传输监控及确保文件交换的安全性和可靠性。同时,作者结合自身项目经验,分享了项目规划、实施过程中的关键决策及其背后的思考。 ... [详细]
  • 本文通过基准测试(Benchmark)对.NET Core环境下Thrift和HTTP客户端的微服务通信性能进行对比分析。基准测试是一种评估系统或组件性能的方法,通过运行一系列标准化的测试来衡量其表现。 ... [详细]
  • 本文详细介绍了在CentOS 6.5 64位系统上使用阿里云ECS服务器搭建LAMP环境的具体步骤。首先,通过PuTTY工具实现远程连接至服务器。接着,检查当前系统的磁盘空间使用情况,确保有足够的空间进行后续操作,可使用 `df` 命令进行查看。此外,文章还涵盖了安装和配置Apache、MySQL和PHP的相关步骤,以及常见问题的解决方法,帮助用户顺利完成LAMP环境的搭建。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文介绍了一个使用Spring框架和Quartz调度器实现每周定时调用Web服务获取数据的小项目。通过详细配置Spring XML文件,展示了如何设置定时任务以及解决可能遇到的自动注入问题。 ... [详细]
  • 本文详细记录了 MIT 6.824 课程中 MapReduce 实验的开发过程,包括环境搭建、实验步骤和具体实现方法。 ... [详细]
  • 深入解析Dubbo:使用与源码分析
    本文详细介绍了Dubbo的使用方法和源码分析,涵盖其架构设计、核心特性和调用流程。 ... [详细]
  • 对象存储与块存储、文件存储等对比
    看到一篇文档,讲对象存储,好奇,搜索文章,摘抄,学习记录!背景:传统存储在面对海量非结构化数据时,在存储、分享与容灾上面临很大的挑战,主要表现在以下几个方面:传统存储并非为非结 ... [详细]
  • Java EE 平台集成了多种服务、API 和协议,旨在支持基于 Web 的多层应用程序开发。本文将详细介绍 Java EE 中的 13 种关键技术规范,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 阿里面试题解析:分库分表后的无限扩容瓶颈与解决方案
    本文探讨了在分布式系统中,分库分表后的无限扩容问题及其解决方案。通过分析不同阶段的服务架构演变,提出了单元化作为解决数据库连接数过多的有效方法。 ... [详细]
  • PHP 5.5.31 和 PHP 5.6.17 安全更新发布
    PHP 5.5.31 和 PHP 5.6.17 已正式发布,主要包含多个安全修复。强烈建议所有用户尽快升级至最新版本以确保系统安全。 ... [详细]
author-avatar
鄢都浪子_562
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有