分布式服务框架:原理与实践

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35781178/article/details/86430012

应用架构演进《一》

垂直应用框架面临的挑战:

一.复杂应用的开发和维护成本变高,部署效率逐渐降低。

二.团队协作效率差,部分公共功能重复开发代码重复率居高不下。

三.系统可靠性变差。随着业务的发展,访问量逐渐攀升。网络流量负载均衡,数据库连接等面临巨大的压力。某个节点的故障会导致分摊到其他节点的流量都增。引起雪崩效应高并发,大流量对系统的可要求非常高。

四.维护和定制困难。随着业务代码不断膨胀,功能越来越复杂。有的垂直架构模式已经无法应付,大的业务进行拆分代码修改,牵一发而动全身,维护和盯着都非常麻烦。

五.新功能上线周期变长。

RPC框架的目的就是让远程过程调用变得更加简单,透明。rpc框架负责屏蔽底层的传输方式,序列化方式和通信细节。

在高并发,大流量的应用场景中,需要做集群,通常的组网方案是前端通过F5等负载均衡器做七层负载均衡(或者使用SLB等软负载),后端做对等集群部署。

RPC 的全程是remote procedure call .它是一种通信方式。允许像调用本地服务一样调用远程服务,它的具体实现方式可以不同,例如spring 的http innoker ,facebook 的thrift 二进制似有协议通信。

PRC 框架的目标就是让远程过程(服务)调用更加简单,透明,PRC框架负责屏蔽底层的传输方式(TCP/UDP),序列化方式(XML/JSON/二进制)和通信细节。

PRC 框架的几个核心技术点总结:

1.远程服务提供者需要以某种形式提供服务调用相关的信息,包括但不限于服务接口定义,数据结构,或者中间态的服务定义文件。例如Thrift 的IDL文件,WS-RPC的WSDL文件定义,甚至也可以是服务端的接口说明文档;服务调用者需要通过一定的途径获取远程服务调用相关信息例如服务端接口定义jar包导入,获取服务端IDL文件等。

2.远程代理对象:服务调用者调用的服务实际是远程服务的本地代理,对于java 语言,它的实践就是JDK的动态代理,通过动态代理的拦截机制,将本地调用封装成远程服务调用。

3.通信:RPC框架与具体的协议无关,例如spring 的远程调用支持http invoke,RMI invoke, MessagePack 使用的是私有的二进制压缩协议。

4.序列化:远程通信,需要将对象转换成二进制码流进行网络传输,不同的序列化框架,支持的数据类型,数据包报销,异常类型和性能都不同。不同的PRC框架应用场景不同。

简单的PRC框架实现:

java 原生序列化,socket 通信,动态代理和反射机制,实现最简单的RPC框架。

1.服务提供者,它运行在服务端,负责提供服务接口定义和服务实现类。

2.服务发布者,它运行在RPC服务端,负责将本地服务发布成远程服务,供其他消费者调用。

3.本地服务代理,它运行在RPC客户端,通过代理调用远程服务提供者,然后将结果进行封装返回给本地消费者。

代码见:http://www.baidu.com [book-1,2,3]

业界主流RPC框架:

1 由Facebook 开发的远程服务调用框架Apacke Thrift
2 Hadoop 的子项目Avro-PRC
3 caucho 提供的基于binary-RPC 实现的远程通信框架Hession
4 google 开源的基于http/2 和protobuf 的通信RPC 框架gRPC

Apacke Thrift: 是Facebook 实现的一种高效的,支持多种编程语言的远程服务调用框架,它采用接口描述语言(IDL)定义并创建服务,支持可扩展的跨语言服务开发。所包含的代码生成引擎可以在多种语言中创建高效无缝的服务,如C++,java,python,php,ruby,erlang,perl,c#,cocoa,smalltack等。其传输数据采用二进制格式,相对XML 和json 等序列化方式体积更小,对于高并发,大数据量和多语言的环境更有优势。

Apacke Thrift 服务包含用于绑定协议和传输层的基础架构,它提供阻塞,非阻塞,单线程和多线程的模式运行在服务器上,可以和现有的J2EE服务器/web 容器无缝对接。Apacke Thrift支持的基本类型:bool,byte,i16,i32,i64,double,string ;结构体类型:struct(java pojo 对象);容器类型:list,set,map;异常类型:exception.它可以满足各种语言复杂数据结构的传输。Thrift 允许开发者选择客户端和服务端之间通信协议的类型,在传输协议上总体可以划分未文本和二进制传输协议。为节约带宽,提高传输效率,一共情况下使用二进制传输协议。在性能要求不要的场合,为了提高可读性有时也可以使用文本类型的协议。

常用的协议:
TBinaryProtocol 二进制编码格式数据传输协议
TCompactProtocol 高效率的压缩二进制编码格式数据传输协议
TJSONProtocol 使用JSON 编码的数据传输协议
Thrift支持的通信方式有:
TSocket 使用阻塞式I/O 进行传输,最简单常用的模式
TFramedTransport 使用非阻塞方式,按块的大小进行传输,类似Java中的NIO非阻塞通信
TNonblockingTransport 使用非阻塞方式,用于构建异步客户端
Apache Avro 是 hadoop 下的一个子项目,它本身既是一个序列化框架,同时也实现了RPC的功能,特性如下:
1 丰富的数据结构类型
2 快速可压缩的二进制数据形式
3 存储持久数据的文件容器
4 提供远程过程调用PRC
5 简单的动态语言结合功能
特点
1.支持动态模式 avro 不需要生成代码,这有利于搭建通用的数据处理系统,同时避免了对业务代码的侵入
2.数据无需加标签 读取数据前,avro 能获取模式定义,avro在数据编码时只需要保留更少的类型信息,有利于减少序列化后的数据大小。
3.无需手工分配的域标识 Thrift和protocol buffers 使用一个用户添加的整型域唯一性定义一个字段,而avro 则直接使用域名,该方法更加直观,更加易扩展。

Apcche Avro 的可定制性非常好,主要体现在:

1.传输层和业务逻辑层分离,用户可以专注于业务逻辑开发;

2.服务端有一个协议注册工厂和序列化注册工厂,针对不同的应用场景用户可以定制私有协议和不同的序列化方式,满足业务领域服务的需求。客户端支持同步和异步调用,用户可以根据实际业务场景做不同的选择。

Hessian 是一个轻量级的二进制PRC框架,它通过Servlet 提供远程服务,可以将某个请求映射到hessian 服务。Spring 的DispatcherServlet 支持该功能,DispatcherServlet 可将匹配模式的请求转发到hessian 服务。hessian 的server 端提供一个servlet 基类,用来处理发送的请求,而hessian 的远程过程调用则使用动态代理来实现,采用面向接口编程。因此,hessian 服务通常通过Java 接口对外暴露。

hessian 优点:简单易用,面向接口编程,通过接口暴露服务,轻量级,可以穿透防火墙;采用二进制传输,序列化效率高;支持多语言,概括:Java,python,c++,.net,c#,php,ruby 等,可以与spring集成,配置比较简单。

gPRC是一个高性能,通用的开源PRC框架,主要面向移动应用开发并基于HTTP/2 协议标准而设计,基于protobuf(protocol buffers)序列化协议开发,支持众多开发语言。gprc 基于http/2 标准设计,带来诸如双向流,流控,头部压缩,单TCP连接上的多复用请求等特性。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

gPRC 目前提供C,JAVA,GO语言版本,全部托管在GitHub 上,分别是gPRC,gPRC-Java,gPRC-go.

gPRC框架的主要特性:

1.支持protobuf: gPRC 使用 protobuf 的IDL 来定义数据结构和服务。protobuf 是一个灵活,高效,结构化的数据序列化框架,相比于XML等传统的序列化工具,它更小,更快,更简单。protobuf 支持数据结构化一次可以到处使用,设置跨语言使用,通过代码生成工具可以自动生成不同语言版本的源代码,甚至可以在使用不同版本的数据结构进程间进行数据传递,实现数据结构的前向兼容。当前gPRC仅支持protobuf ,且不支持在浏览器中使用。由于gPRC的设计能够支持多种数据格式,所以读者能够很容易实现对其他数据格式(XML,JSON)的支持。

2.支持多种语言:gPRC支持多种语言,并能够根据语言类型自动生成客户端和服务端代码,gPRC-Java 已经支持Android 开发。

3.支持http/2 设计:由于gPRC基于http/2 标准设计,所以相对于其他rpc 框架,gPRC带来了更多强大的功能,如双向流,头部压缩,多复用请求等,这些功能给移动设备带来重大好处,比如节省贷款,降低TCP连接次数,节省CPU 使用和延长电池寿命等。同时,gPRC 还能够提高了云端服务和web 应用的性能,gPRC即能够在客户端应用,也能够在服务端应用,从而以透明的方式实现客户端和服务端的通信和简化通信系统的构建。

RPC 框架面临的挑战:

1.在大规模服务化之前,应用可能只是通过PRC框架简单的暴露和引用远程服务,通过配置服务端的URL地址进行远程服务调用,路由则通过F5硬件负载均衡器火SLB进行简单的负载均衡。当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器压力变大。此时需要一个服务注册中欧新,动态的注册和发现服务,使服务的位置透明,消费者在恩地缓存服务提供者列表,实现软负载均衡。

2.随着业务量的增加,业务的发展,服务间依赖关系变得复杂,甚至分不清哪个应用要在哪个应用之前启动,所以,此时,需要一个分布式消息跟踪系统可视化展示服务调用链,用于依赖分析,业务调用路径梳理等,防止业务架构腐朽化。

SOA 服务化架构:SOA 是一种粗粒度,松耦合的以服务为中心的架构,接口之间通过定义明确的协议和接口进行通信。SOA帮助人们站在一个新的高度理解企业级架构中各种组件的开发和部署形式,它可以帮助企业系统架构师更迅速,可靠,可重用的形式规划整个业务系统。相比传统的非服务化架构,SOA能够更加从容的应对复杂企业系统集成和需求的快速变化。

面向服务设计的原则:

1.服务可用性:不管是否存在即时复用的机会,服务均被设计为潜在的可复用。

2.服务共享一个标准契约:为了服务提供者交互,消费者需要导入服务提供者的服务契约,这个契约可以是一个IDL文件,Java接口定义,WSDL文件,甚至是个接口说明文档。

3.服务是松耦合的:服务被设计为功能相对独立,尽量不依赖其他服务的独立功能提供者。

4.服务是底层逻辑的抽象:只有经服务契约所暴露的服务对外部世界可见,契约之外底层的实现逻辑是不可见的。

5.服务是可组合,可编排的:多个服务可能被编排组合成一个新的服务,者允许不同逻辑抽象的自由组合,促进服务的复用。

6.服务是自治的:逻辑由服务所控制,并位于一个清晰的边界内,服务已经在边界内被控制,不依赖于其他服务。

7.服务是无状态的:服务应当不需要管理状态信息,因此能够维持松耦合。服务应当被尽可能设计成无状态。

8.服务是可被自动发现的:服务发布上线后,允许被其他消费者自动发现;当服务提供者下线后,允许消费者接收服务下线通知。

服务治理:

SOA 服务化之后,业务的发展,服务数量的增多,运维带来的挑战:

1.分布式框架下的服务调用性能

2.服务化架构如何支持线性扩展

3.如何实现高效,实时的服务多维度监控

4.大规模分布式环境下的故障快速定界和定位

5.分布式环境下海量日志在线检索,模糊查询

6.服务的流控,超时控制,服务升降级等管控手段

7.服务的划分原则,如何实现最大程度复用

SOA 服务治理主要包括:

1.服务定义

2.服务生命周期管理

3.服务版本治理

4.服务注册中心

5.服务监控

6.运行期服务质量保障

7.快速的故障定界定位手段

8.服务安全

微服务架构:微服务架构是一种服务化架构风格,通过将功能分散到各个离散的服务中以实现对解决方案的解耦。

微服务架构的主要特征:

1.原子服务,专注于做一件事:功能单一,依赖小,内聚性强。

2.高密度部署:重要的服务可以独立进程部署,非核心服务可以独立打包,合设到同一个进程中,服务被高密度部署。一台服务器上可以部署多个服务实例进程;如果是云端部署,则可以利用docker 实现容器级部署,以降低部署成本,提升资源利用率。

3.敏捷交付:服务由小团队设计,开发,测试,部署,线上治理,灰度发布和下线,运维整个生命周期支撑,实现真正的devops

4.微自治:服务足够小,功能单一,可以独立打包,部署,升级,回滚,弹性收缩,不依赖其他服务,实现局部自治。

微服务对比SOA
1.服务拆分粒度 SOA 首先要解决的是异构应用的服务化; 微服务强调的是服务拆分尽可能小,最好是独立的原子服务
2.服务依赖 传统的SOA 服务,有哦与需要重用已有的资产,存在大量的服务间依赖 微服务的设计理念是服务自治,功能单一独立,避免依赖其他服务产生耦合,耦合会带来更高的复杂度
3.服务规模 传统的SOA服务粒度比较大,多数会采用将多个服务合并打包为war,因此服务实例数有限 微服务强调尽可能拆分,同时很多服务会独立部署,导致服务规模急剧膨胀,对服务治理和运维带来挑战 
4.架构差异   微服务化之后,服务数量的激增会引起架构质量属性的变化
5.服务治理 传统基于SOA的静态治理转变为服务运行态微治理,实时生效
6.敏捷交付   服务由小团队设计,开发,设计,部署,治理,发布等。

猜你喜欢

转载自blog.csdn.net/qq_35781178/article/details/86430012
今日推荐