天天看点

架构演进之路

架构设计:

一:如何分层。

1 为什么要分层:分而治之,各施其职,有条不紊。

常见的分层 计算机osi七层,mvc模型分层,领域模型分层。

2 单系统分层模型演进

浏览器-->servlrt-->javabean-->db-->渲染jsp

浏览器-->web层-->业务层-->持久层-->db-->渲染vue(ssh,ssm,springboot)

3 分布式分层:水平扩展,负载均衡,高可用,数据一致性。

3.1 web概念层:

客户端:pc,app

访问层:lvs(ip层进行分发,比ng快),上游nginx,应用nginx

接口层:websocket,http/https,tcp/udp,api网关。

3.2 业务概念层:

服务通信,业务服务模块,服务管理,任务调度,

基础服务(redis,mq,隔离管理,设备管理),监控。

3.3 数据访问及存储层:

存储接入层:mycat,redis proxy,shardingjdbc

存储层:mysql,redis

二 访问层架构知识。

1 lvs:通过dns网络找到公网ip,然后通过lvs ip层进行分发,比ng快

架构演进之路

2 ng性能之所以快:

2.1 master-worker进程模型 

2.2 协程机制

协程和进程的区别:

架构演进之路

ng的作用:反向代理,动静分离,负载均衡。缓存结果。

三 api网关层架构知识。

1 分布式会话管理

1.1 cookie:并非安全,被劫持概率高,xss,csrf安全攻击等。有跨域问题

1.2 token:凭证被劫持,伪造请求。有跨域问题

1.3 session: 依赖服务端,分布式则存储在中央管理机制中。

解决方案L:https请求防泄露,风控主动失效及过期机制。

2 接入层控制

需要实现的逻辑,身份验证,流量控制,路由服务,记录调试,或统计信息。

使用filter.

3 服务调用和聚合

重接入:srpingmvc+dubbo,由网关服务通过controller去接收响应结果,统一响应体。

轻接入:springcloud+zuul,交给业务服务处理。专注于网关,没有好与坏。

四 核心服务层架构知识。

1 微服务:服务治理(服务通信,健康管理,限流熔断),数据一致性,调用性能,

研发流程,测试,部署。

2 dubbo:轻量级rpc框架,远程方法调用,智能容错,负载均衡,自动服务注册和发现。

服务治理:

2.1 服务注册和发现,

2.2 服务消费获取服务,并通过负载均衡策略选择服务提供者。

(服务优雅的下线,消费端通过监听机制是可以感知的。zk通过钩子机制也是可以感知的)

2.3 动态增减服务提供者和服务消费者。

2.4 服务监控,服务限流,服务降级,高容错,定制化开发

3 异步化消息服务

削峰,解耦,异步。

4 任务调度

5 池化技术,通过对象池和连接池,减少系统消耗,提升系统性能。

5.1 java线程池(对象池):ThreadPoolExecutor

核心线程数-->队列-->最大线程-->拒绝策略-->idle等待时间

线程池状态:空闲 繁忙

5.2 数据库连接池:HTTP client连接池:redis连接池:(属于服务端的连接池)

核心连接数:  

最大连接数: 

连接等待时间:(服务之间的连接超过例如100ms,则连接中断)

数据读取时间:(读取之后响应数据的时间) 

等待释放时间(等待多久才会释放最大连接)

validate:各种网络原因等,在使用的时候会对连接validate一下,确保连接是正常释放的

连接池状态:init connect busy close

tomcat连接池:

5.3 tomcat连接池:每个请求进来,会创建维护一个client socket,放在连接池中。

属于维护客户端的连接池,并且client socket是没有办法处理读写请求的,则维护了一个io线程池。

tomcat io线程池:selector epoll,根据多路复用机制,感知到client socket有数据了,就会主动

去获取连接池socket的数据,然后获取的数据可以组成完整的http数据包时,就会把数据发给worker

线程池。(返回的工作线程可能是同一个,也可能不是同一个)

tomcat 工作线程池:工作线程,处理完数据之后又会将对应处理的结果,返回给空闲的io线程,然后

再返回给socket。返回的socket连接必定是同一个)

5.4 dubbo连接池:和tomcat机制一样,区别是一个发送的是http请求,一个是dubbo请求。

五 数据存储及接入层知识。

1 缓存分类:cdn缓存,反向代理缓存,分布式redis缓存,本地应用缓存(GUAVA)。

2 如何缓存:修改时实时写入,修改时异步写入,读取时实时写入,读取时异步写入。

3 多级缓存:

cdn缓存(仅静态资源)--> ng接入层缓存proxy cache缓存-->

ng应用层缓存(nginx lua shared dic)-->ng应用层缓存(通过应用层ng的lua redis脚本请求)

-->tomcat本地内存-->tomcat redis-->db

4 会涉及到缓存不一致问题,看业务是否容忍和接受。(在缓存周期内,通过异步更新)

5 隔离术:

硬件隔离(虚拟机):物理层面隔离,浪费资源

操作系统隔离(容器虚拟化):物理层面隔离,docker

进程隔离(系统拆分):微服务,按业务区分

线程隔离(线程池独立):服务之间的调用,也就是级联,

调用不同的服务使用不同的线程池,调用失败的则采取熔断降级等操作。

可以确保服务调用失败之后,不影响到该服务调用其他服务。

读写隔离(读写分离):主从模式

动静隔离(动态资源和静态资源隔离):在cdn取静态资源,在应用程序取动态资源。

热点隔离(热点账号,热点数据):走热点账号数据库,普通账号数据库。

6 队列术:异步,解耦,削峰

削峰:排队有时候比并发效率更高(不需要涉及到cpu去竞争抢占锁资源),

排队可以控制并发流量涌入。如redis就是单线程的排队机制,效率高。

常用的方案是使用线程池,通过设置核心线程数,最大线程数都为1,来实现简单的队列术。

六 数据存储及接入层架构设计

1 数据存储。结构化数据,非结构化数据(音频,视频),半结构化数据(用户简历,文件)

常见的数据库存储中间件

nas:网络文件系统,基底层设备,提供文件磁盘。(服务器基于挂载的形成操作nas路径)

阿里oos:想象成无限大的网盘,阿里云oss网络文件存储。

sql关系型数据库:mysql,db2,slqlite等

非关系型数据库:mongdb,hbase。

缓存型数据库:H2,Redis。

2 关系型与非关系型。

3 代理访问。反向代理,数据库代理,redis代理。

为什么要代理:收口逻辑,负载均衡,路由策略,故障转移,缓存策略,减少后端被代理对象压力。

代理后端应用服务器:nginx

没有后端代理服务器:需多个公网ip支持多服务器,负载均衡只能通过dns寻址,

每个后端各自缓存热点数据

有后端代理服务器:仅需要一个公网ip绑定到代理服务器,可故障转移,可负载,可缓存热点

代理数据库服务器:mycat

没有数据库代理:应用层需要处理分库分表逻辑,应用层需要处理主从切换,应用层需要

各个数据库都维护连接池,数据连接池不够。

有数据库代理:可支持分库分表路由策略逻辑,可支持主从切换,可支持连接池管理。

代理缓存服务器:Twemproxy。(通常生产环境redis无需代理,自身支持)

没有代理缓存服务器:应用层需要处理分key分片逻辑,应用层需要处理主从切换,应用层需要

各个缓存都维护连接池,缓存连接数量不够。

有代理缓存服务器:可支持分key分片路由策略逻辑,可支持主从切换,可支持连接池管理。

七 监控,限流,降级知识。

1 监控:

为什么要监控:

线上发布了服务,怎么知道它一切正常

某个核心服务挂了,导致各级系统大量报错,如何确定问题在哪

系统上线后不知道业务进来多少,不知道服务器是否够用

业务搞大促,请求量激增,我们居然是最后一个知道的人

监控什么:通过cat监控软件指标,通过zabbix监控硬件指标。

硬件指标:cpu idle time,free memory,io wait,network free 可以使用zabbix等

软件指标:cpu load average,parNewCount,parNewTime,old gc count,old gc time

可以使用cat heart beat监控

接口指标:url请求,保证95线,即99.999%成功率。可以使用cat transaction监控。

异常指标:可以使用cat execption监控,会打印堆栈信息。

大盘指标:基线成功率,基线失败率,总统响应时间指标。cat 大盘监控。

2 限流:

为什么要限流:流量远比并发处理能力大,永远不知道对方怎么样,永远不知道自己怎么样。

因此需要有保护自己的决心。

限流的维度一:url的限流,dubbo接口限流,sql操作数。

限流的维度二:限制TPS/QPS,限制并发数,限制总数。

限流算法:

限制并发数(通过每个url计数器),

令牌桶算法,(通过固定时间重置桶中的令牌,每次请求取一个)

漏桶算法。往桶中涌入tps,不能超过桶的剩余量,桶会匀速下发请求过来的tps,

可以处理突发流量

如果是集群限流,对应所有操作都要加入中间体(如redis)

单机限流,不能保证绝对意义的均衡限流,通常建议使用单机限流。

可以使用guava包中的RateLimter类

limit = RateLimter.create(2),即每秒允许请求2个limit令牌,limit.acquire()获取令牌。

3 降级:保护系统,保证用户体验,给到充足时间排查问题。

关闭接口并设置默认返回,等同于隔离术。

降级逻辑,给到用户一个友好的体验响应。

随着架构的演进,可以看出分布式构建的繁杂体系,使得开发无法专注于业务本身,所以

云原生架构才会应运而生叭。