这里的架构演进应该是从服务化的角度来讲,应该说随着业务发展,应用规模扩大,系统的一些公共服务就会抽取出来,独立开发,部署,维护,用来解决并发,扩展,维护的问题。web
传统垂直架构面试
有的地方也叫单体应用,以mvc模式开发:redis
这种并无什么很差,发展初期大可能是这样,体量没那么大,也不须要考虑高并发大流量可扩展性什么的,简单粗暴,解决业务需求就好,活下去才能活的更好。算法
可是必须明白这种简单架构存在的一些问题:sql
1. 业务不断发展,功能逐渐增多,应用的开发维护成本变高,部署效率下降,随便改个代码,编译一次十几分钟就浪费了。悲剧,咱们有个系统才开发3年,就碰到这种状况,一次打包编译部署,13分钟结束。docker
2. 不一样的人负责不一样的部分,一些通用代码、公共代码就各写各的,不能复用,若是只是util还好,可是一些外部服务的都有重复,那就happy了(不过这种状况的出现,不必定是架构问题,更多多是管理);编程
3. 不断地上新需求,不断地改代码,有时测试不到位,指定哪里埋了bug,上生产后系统就down了,牵一发而动全身;json
4. 可维护性,可靠性,扩展性变差。api
既然有这些问题,就要解决啊,业务就会提要求,你要解决啊,要否则影响我业务发展,影响我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的对比:
感受在有了docker后,微服务这个概念忽然火了起来,总结就是微服务+容器+DevOps。
背景
应用从集中式走向分布式
随着业务的发展致使功能的增多,传统的架构模式开发,测试,部署整个流程变长,效率变低,后台服务的压力变大,只能经过硬件扩容来暂时缓解压力,但解决不了根本性问题:
通用法宝:拆分,大系统拆小系统,独立扩展和伸缩。
须要服务治理
大拆小,核心服务提炼后,服务的数量变多,并且须要一些运行态的管控,这时候就须要服务治理:
服务框架介绍
Dubbo
阿里开源的Dubbo应该是业界分布式服务框架最出名的了吧,看过公司的rpc框架,Dubbo的扩展性比咱们的好的多了,咱们的框架每次升级,改动都不少,改天要看下Dubbo的源码了解了解扩展性。
HSF
淘宝的体量决定了他对极致性能的追求,HSF跨机房特性挺牛。
Coral Service
这个没据说过,孤陋寡闻了。
框架设计
架构原理
万变不离其中,这张图能够归纳rpc的一些通用原理:
细化了下:
功能
性能
可靠性
分布式的,面试会问,用池子的话讲就是,知识点啊。
服务治理
技术点
在功能设计方面,做者基于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个问题,那就针对这些作优化了:
高性能之道这节做者讲了netty的优点。
也就是一般所说的编码、解码。一般的通信框架会提供编解码的接口,也会内置一些经常使用的序列化反序列化工具支持。
与通信框架和协议的关系,感受能够理解为:通信框架是通道,其上跑的码流数据是利用各类序列化编码后的各类协议。
功能设计
各类序列化框架须要考虑的主要有:
在扩展性这节,做者讲了netty的对序列化的一些内置支持,但实际开发中,通常不太会使用这些东西,都会提供序列化反序列接口,自行扩展定义,因此扩展性特重要。
经常使用的序列化,xml,json,hessian,kryo,pb,ps,看需求须要支持那种,具体能够搜索各序列化的性能和压缩后大小。
这一章最主要的是讲了自定义协议栈的设计,已经交互的过程,其余讲的可靠性设计什么的跟以前通信框架一章有重复。
通讯模型
服务提供者和消费者之间采用单链路,长链接通讯,链路建立流程:
1. 客户端发送握手请求,携带节点ID等认证信息;
2. 服务端校验:节点ID有效性,重复登陆,ip地址黑白名单等,经过后,返回握手应答信息;
3. 链路创建后,客户端发送业务消息;
4. 客户端服务端心跳维持链路;
5. 服务端退出时,关闭链接,客户端感知链接关闭,关闭客户端链接。
协议消息定义
经过attachment兼容了扩展性。做者还讲了将消息头的通用序列化和消息体的自定义序列化,看需求吧,咱们公司的框架没作这部分支持,作了简化,将消息头和消息体统一封装,而后再加一个序列化方式组成一条消息发送。
安全性设计
服务路由指的是服务提供者集群部署,消费端如何从服务列表中选择合适的服务提供者提供服务进行调用。
透明化路由
负载均衡
这些都是点对点的链接,负载均衡大多会在客户端执行,有种场景会取决于服务端负载,就是服务端服务配置的是域名。
本地路由优先策略
路由规则
除了上面提供的各类路由负载均衡,还允许自定义路由规则:
- 条件路由:主要是经过条件表达式来实现;
- 脚本路由:经过脚本解析实现。
其实应该还有一种客户端经过代码自定义路由选择。这些主要是为了扩展性。
路由策略定制
自定义路由场景:
1. 灰度;
2. 引流;
路由策略:
1. 框架提供接口扩展;
2. 配置平台提供路由脚本配置;
配置化路由
指的是服务调用失败后,根据容错策略进行自动容错处理。
集群容错场景
业务执行异常不属于服务端异常。
容错策略
这图不错,关系很清晰。
容错策略扩展
其实还有一点,感受也挺重要,就是支持容错后本地mcok。调用失败后的链路切换和快速失败确定要支持,缓存重发能够不用。
本篇篇幅过长,相信能坚持看到最后的都是对知识求知如渴的人,未来一定不凡。顺便点点关注点点赞呗。
欢迎工做一到五年的Java工程师朋友们加入Java架构开发:878249276
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用本身每一分每一秒的时间来学习提高本身,不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!