1.架构完整解决方案:
1)具体业务场景
2)架构如何选型
3)架构如何设计
4)架构如何折中
5)架构线上问题如何解决
附:架构背后哲学思考
为什么要这样设计
其它方案为什么不优雅
架构的实践
拒绝空理论,空概念
实际项目架构落地经验
拒绝忽悠
2.互联网发展三阶段
1)互联网发展的三个阶段的特点:静态化,动态化,万物乱接,容易理解
3.单体架构设计
适应场景:
1)业务简单,功能不复杂
2)创业公司初期,研发人员较少的项目
3)性格要求极其苛刻
单体架构的优点:
1)容易开发
2)容易测试
3)容易部署
4)容易扩展
单体架构的缺点:
1)系统耦合性高
2)技术选型单一
3)开发效率越来越低
架构破局:
1)垂直方向拆分(业务维度)例如用户模块,订单模块,商品模块
2)水平方向拆分(功能维度)垂直拆分后,用户模块依然是一个单体,在功能上继续拆分,网关层,业务逻辑层,数据访问层,数据库怎么拆,架构就怎么拆
3)如果单体架构承载不了更高的压力怎么办?可以使用nginx做反向代理,基于不同负载均衡策略把请求压力发送到其它单体应用上。单体架构的应用是一个war包部署在tomcat上,扩展只需要再高一台机器使用Tomacat部署war包就可以了。
04 水平分层架构设计与实践
水平方向物理分为多个进程,每层逻辑解耦
网关层
业务逻辑层
数据访问层
数据存储层
水平分层架构拆分的设计原则
1)单独的页面展示服务
2)单独的网关服务
3)单独的业务逻辑服务
4)单独的数据服务
5)根据系统职能单独划分服务(类似公司职能部门划分一个道理)
任意两层之间加入消息队列都可以从同步变为异步,每层和消息队列都是同步的。消息队列的高效来源于本身的顺序写入。
业界主流的网关开源组件,没有最好,只有更合适。
业务逻辑层应该具备的基本功能
1)业务逻辑判断
2)根据不同逻辑判断实现不同功能
数据访问层应该具备的基本功能
1)CRUD 业务增删改查接口
2)ORM框架
3)Sharding支持分库分表
4)屏蔽底层存储库的差异性(redis/mysql/mongodb)
5)针对以上功能的聚合可以使用NewSql替代
同步架构
异步架构
通过引入MQ消息中间件实现分层的异步处理,提升系统吞吐量
异步目的:提升吞吐量
异步方式:消息队列
适用场景一:请求类型(读请求不可以,写请求可以)
适用场景二:业务类型(充值场景低并发用同步,社交场景并发异步)
水平分层架构的设计事项
设计过多
1)请求路径边长
2)平均响应延迟变高
3)定位问题变的复杂化
4)运维成本增加
设计过少
和单体架构基本类似
设计合理适中
- 同步架构(四层)
- 网关层
- 业务逻辑层
- 数据访问层
- 数据存储层
- 异步架构(五层)
- 网关层
- 异步消息队列层
- 业务逻辑层
- 数据访问层
- 数据存储层
以上两种架构也存在严重的问题:部分层粒度过粗,如业务逻辑层包含了所有的业务逻辑。
即便使用了水平分层架构,也还是存在缺点的,这样的分层方式还是粒度过粗,我们看看最后水平分层架构的全貌图
真正的APP请求第一步是经过DNS的,DNS通过域名获IP,去请求静态接口和动态接口的数据。静态的资源如CSS、图片是放在CDN上的,通过阿里、腾讯、百度的CDN获取静态图片,如果请求的静态资源在CDN上没有命中,CDN会请求Nginx,Nginx会把静态资源返回给CDN,CDN会把静态资源缓存起来再返回给APP,Object Store(对象存储)同理,常用的对象存储是阿里的Fastdfs和Ceph,规模比较小的话建议用Fastdfs,规模比较大的话,建议用Ceph,但是Ceph会给运维团队增加很大的压力,
05 面向服务架构设计与实践
58同城的简化模型图:
为什么SOA不是微服务架构,因为它仅仅做了一个垂直拆分。所以缺点也很明显:
- 每个服务还是单体架构
- 对ESB严重依赖
微服务架构设计与实践
服务网格架构设计与实践
应用程序A部署在一台机器上,同样的sidecarA也同样部署在这样机器上,sidecarA是基础设施组件,其实现了服务发现,配置管理,熔断限流,各种服务治理的功能,这使得应用程序不用再关注服务治理的相关编码实现,只需要注重业务编码的实现,关注点拆分(而在微服务架构中是需要同时兼顾考虑的)。打个比方需要修重试策略,修改注册中心,修改服务调用路由规则,这些在微服务架构中需要修改应用编码重新部署才能生效,而在服务网格架构中只需要修改技术设施组件,在不影响业务功能代码的情况下进行修改发布升级。
下图是一个服务网格架构图:
- 请求:应用程序A将req发送到SidecarA,SidecarA将req发送到SidecarB,SidecarB将req发送到应用程序B
- 响应:应用程序B将resp发送到SidecarB,SidecarB将resp发送到SidecarA,SidecarA将resp发送到应用程序A
官方服务网格架构图
Service Mesh的优点
- Service Mesh独立进程、独立升级
- 业务团队专注于业务逻辑本身
- 一套基础设施支持多语言开发
- 业务团队和基础设施团队物理解耦
Service Mesh的技术框架
框架 |
开发语言 |
开发公司 |
---|---|---|
Linkerd |
Scala |
Buoyant |
Conduit |
Rust |
Buoyant |
Envoy |
C++ |
Lyft |
Nginmesh |
Go |
Nginx |
Istio |
Go/C++ |
Goole,IBM,Lyft |
由于Istio是集大成这于一身,所以这里介绍一下Istio,更多详细的内容可以参考 Istio官方文档
Istio
总体架构
- Istio服务网格逻辑上分为数据面板(执行者)和控制面板(指挥者)
- 数据面板由一组智能代理(Envoy)组成,代理部署sidecar,调解和控制微服务之间所有的网络通信
- 控制面板负责管理和配置代理来路由流量,以及在运行时执行策略
数据面板Envoy
- 动态服务发现,负载均衡,TLS连接终止,HTTP/2 & gRPC代理
- 熔断器,健康检查
- 基于百分比流量灰度,故障注入和丰富指标
- Envoy被部署为sidecar,和对应服务在同一个kubernetes pod 中
Mixer
- 负责在服务网格上执行访问控制和使用策略,并从Envoy代理和其它服务收集metric信息
- Central component
Pilot
- pilot特为sidecars提供服务发现
- 智能路由的流量管理功能(例如...A/B测试、canary部署等)
- 弹性(超时、重试、断路器等)
- 松耦合允许Istio在多个环境中运行(例如...Kubernetes(Consul/Nomad))同时维护相同的操作员界面进行通信管理
Citadel
- 提供强大的服务间认证和终端用户认证,使用内置身份和证书管理
- 它可以用于升级服务网格中的未加密流量,并未操作人员提供了基于服务标识而不是网络控制执行策略的能力
- 从0.5版本开始,Istio支持基于角色的访问控制来控制谁可以访问你的服务
流量控制
- 请求路由
- Request Routing
- 版本控制V1/V2
服务发现与负载均衡
- 三种负载均衡模式:轮询、随机和带权重的最少请求
- 当为定实例的健康检查失败次数超过预定阀值时,它将从负载均衡池中弹出。当通过的健康检查数超过预定阀值时,该实例将被添加回负载均衡池
流量控制/处理故障
- Envoy提供了一套开箱即用,选择加入的故障恢复功能,可以在应用程序中受益。功能包括:
- 超时
- 带超时预算有限重试以及重试之间的可变抖动
- 并发连接数和上游服务请求数限制
- 对负载均衡池的每个成员进行主动(定期)运行健康检查
- 细粒度熔断器(被动健康检查),适用于负载均衡池中的每个实例
流量控制/错误注入
- 错误配合的故障恢复策略(例如:跨服务调用的不兼容/限制性超时)可能导致应用程序中关键服务持续不可用,从而导致用户体验不佳
- 可以注入两种类型的故障:延迟和中止
- 延迟是计时故障,模拟增加的网络延迟或过载的上游服务
- 中止是模拟上游服务的崩溃故障。中止通常以HTTP错误代或TCP连接失败的形式表现