架构设计培训心得

来源:互联网 发布:私有云存储软件 编辑:程序博客网 时间:2024/04/29 17:49

首先要感谢公司给我们提供的这次培训和给我们请到这么好的讲师,这次培训真是大大的开拓了自己的技术视野,更是了解到当前流行的一些技术,通过孙老师细致入微的讲解了解到各种web架构的优点与不足,以及各种架构的演进历史,架构设计中高可用、高并发的设计手段,同时对当下流行的微服务有了大致的了解,尤其是讲课过程中MQ队列、异步处理请求、负载均衡、无状态化服务、服务降级、注册中心这些架构设计方面的知识真的是让自己的眼前一亮,才知道在高可用高并发方面还有这些门道,更是接触到了系统柔韧性以及流量劫持名词,还有就是孙老师讲到的分布式事务,让我对工作中的分库分表等的理解进一步加深,或许很多知识对我来说距离使用还很遥远但我相信至少在以后用到这方面的技术的时候给我指明前进的方向。下面主要是给大家分享一下我在这次培训中的收获,同时也希望通过这次的分享能给大家带了更多的收获与帮助,不足之处请大家多提宝贵意见。

Monoliths架构

最开始的互联网架构即为Monoliths架构,该架构一个工程包含了系统所有的功能,即app-web-db,该架构的功能会随着项目功能的增多变得日益臃肿、庞大,随着功能的扩展也会带来一系列的问题,高耦合、开发效率低、代码阅读难度提高、技术选型单一、扩展性差。

水平分层级架构

未解决以上问题人们对Monoliths架构进行了水平方向的分层,拆成app、网关、业务逻辑层、数据访问层、DB几层,分工细化且明确,解决了Monoliths架构的高耦合、开发效率低。技术选型单一、扩展性差的难题,但有因为层数增多导致

 

l 请求的路径过长;

l 平均响应的延迟的增加;

l 定位问题复杂,运维成本提高。

Monoliths架构如果水平分层层次太少就又回到了Monoliths的单一架构,下边介绍几种常用分层方案:

三层(MVC);

四层(接入层,业务逻辑层、数据访问层、数据层);

五层(接入层、异步提交层、业务逻辑层、数据访问层、数据层)

接入层又叫应用网关层:负责请求的转发分流、数据的加解密、鉴权、请求合法性校验、连接管理等工作。

异步提交层:顾名思义改成只会处理异步请求,同步请求将越过改成交给业务逻辑层,

那么什么请求需要异步处理呢?这种请求必然是不需要将结果反馈处理结果给页面的,在一个也可能是比较耗时的请求,比如典型的耗时操作写数据库;这样的请求异步处理再合适不过了;当然在接入层与异步层之间还需要添加一个MQ(消息队列)来保存接收到的异步请求供异步层去消费。


SOA架构

当然项目的功能增加以后水平分层同样会显得臃肿,分层太多又会导致请求路径过长,所以就有了垂直分层结构SOA架构。

SOA架构是一种面向服务的架构,各个服务都是相互独立的,可以独立的开发部署跟运行具有低耦合,易维护,开发效率高的特点。正因为每个服务都是独立的所以所有的服务与消费者之间需要有一条服务总线串联起来,这样才能让所有独立的服务协调的区完成任务。

PS:个人感觉SOA架构有些类似于两个通过路由器连接的网络之间数据传输的原理,主机A与主机B通过路由器通信的话需要主机A将目的地址的IP地址与数据下送到数据链路层封装成数据帧在通过物理层将数据包发送给路由器,但是物理层是不会根据IP地址去给路由器发送数据包的,物理层只能根据网卡的硬件地址进行通信,路由器物理层收到数据包后将数据通过数据链路层上传到网络层网络层解析出IP地址以后再比对路由表然后再将数据进行转发。那么问题来了既然物理层之间的传输都是通过物理地址传输的那为啥还有弄一个虚拟的IP地址了?答案当然是希望通过IP地址去屏蔽物理地址,毕竟硬件的厂商啥的是不同的,而且硬件也可能更换导致物理地址失效,所以就抽象除了一个固定的Ip地址Ip地址可以通过网络层的ARP网络协议将IP地址转换为目的地址的MAC物理地址。这样实现以不变应万变的情况了。同样的SOA的ESB总线也是通过服务提供的接口与服务进行绑定,这样即使服务产生了变化只要接口不变前台依然可以找到指定的服务提供者。

同样的SOA架构也就暴露出来了一个致命的缺点 那就是过于依赖于ESB服务总线。一旦总线出现问题那么所有的服务提供者都将瘫痪。

微服务

微服务与SOA的区别就是将SOA架构去掉了ESB服务总线,使系统更加的灵活与稳定。

微服务架构由微服务网关层、微服务层、数据层、微服务注册中心、为服务配置中心、微服务发现几部分组成

微服务网关层:

1.海量用户接入管理;

2.请求合法性和安全性校验

3.负责简单的antispam

i. IP、Token过滤

ii. 访问频率控制

iii. 黑白名单等

iv. 请求路由

v. 请求回包·

微服务层: 数据访问处理、业务逻辑处理

数据层:持久化存储、缓存加速

注册中心:

1.为服务层Host

2.微服务层Port

3.数据层Host

4.数据层Port

5.注册中心高可用

配置中心

1.每层服务配置KV统一管理

2.配置更新实时同步

3.微服务配置项热加载

4.配置项最终一致性

5.配置中心高可用、高可靠

微服务路由

1.网关层获取微服务层注册信息

2.网关层请求路由到微服务层

3.微服务层获取数据层注册信息

4.微服务层请求路由到数据层

服务冗余

说到服务冗余就不得不说一下请求的无状态化,“无状态化请求”也是我第一次听说这个名词,请原谅我的无知^_^,有无状态请求,相对应的就有“有状态请求”,有状态请求就是当app访问server端的时候会在server端保留一些状态,等下次相关请求需要这些状态时候只需要传sessionid过来即可获得之前在session中保存的状态信息,比如说登录状态,那无状态请求自然是不需要在服务端保存状态的请求;实现服务冗余就是说针对app发送的请求我任何一台服务器都可以得到有效的响应,这样就要求服务是无状态化的,不会再特定的服务器上保存状态信息;服务器没有保存客户端的状态信息,客户端就需要每次都带上自己的状态去请求服务器。客户端以URL形式提交的请求包含了cookies等带状态的数据。这样的设计即使有一两台服务器出现宕机情况仍然会有其他冗余的服务器去响应用户的请求。

负载均衡

负载就是将app请求均衡的分发到冗余设计的服务上边去处理请求,负载均衡一定要注意幂等性的设计,“幂等性”这个词不用说了也是我参加工作后听说的,所谓幂等就是针对同一操作发起的一次或多次请求处理的结果必须是一致的,绝对不能同一个请求分发到不同的服务上边得到了不同的处理结果。

数据库的creat、update操作

i. 数据库表设计时不使用主键自增,使用逻辑主键或者唯一索引去代替主键,这种设计可以保证数据库插入的幂等,同时也将方便日后的数据迁移操作(没有过多的关联的id)

ii. update绝对值的修改是幂等,但是i++这种修改非幂等。

超时机制

合理的超时机制可以最大限度的减少下游服务宕机对上层服务的影响。

• 上游超时时间一般设置下游平均响应延迟的2倍,避免过长时间的等待。

• 响应延迟高/低,超时时间设置长/短  3s/100ms

• 下游请求超时后,业务层根据预设的调度策略,继续重试

® 一般3次

® 多次无好处

® 请求转移到下游不同服务。

服务降级

服务降级主要是用来应对流量高峰期、短时请求量大的问题,是服务具有一定的柔韧性,从而减少因为短时大量请求造成的服务宕机,系统雪崩

目标:保证核心服务可用;非核心服务弱可用,甚至不可  用

服务降级策略:

• 拒绝部分老请求(根据请求出入消息队列的时间差进行   新老请求的判断)

® 减少服务请求数量

® 确保“新请求的正常响应”

® RPC队列方式(请求入队、出队时间处理请求时,检 查请求在队列请求时间超过一定时间比如1s,直接丢)

• 优先级请求方式

® 非核心请求直接丢弃

• 随机拒绝方式

® 随机丢弃一定比率的请求

® 可能造成系统一会可用一会不可用。

数据层的服务降级

此时数据层不再对数据库进行读写,将所有读写操作全 部转移到缓存

• 更新请求

® 持久到消息队列

® 只更新缓存

• 读请求

® 读缓存

• 数据补齐

® 消息队列->数据库

(此处也有疑问为啥开始不适用这种策略)

Ps:此处的服务降级感觉类似数据库数据的存储方式,执行 更新语句时解析完sql语句后,将首先更新日志,日志成功后再此更新缓存成功之后即可返回成功的状态,之 后当缓存达到一定时间后再进行数据的持久化。  这样即 使服务突然宕机导致缓存数据未持久化也可以通过日志找 回需要持久化的数据。

移动端服务柔韧性

DNS优化

i. 访问自己的服务都是通过ip地址不使用域名

ii. 使用IP地址自己负载均衡,随机从IP地址池获取IP,对于处理能力强的服务器的IP地址再IP地址池多写几次或者使用加权的IP地址。

iii. 对于信息的推送:

1) 优先TCP长链接

2) 离线Push推送

之前在学校时有写过Android的消息推送,是自己在安卓创建一个后台service,里面跑一个线程去定时的请求服务器,但是这个服务线程总是再运行一段时间以后就会被杀死(谷歌固有机制不让一个服务在后台长久的运行),最后又写了一个service跟这个service互相查看,一旦死掉一个就将对方主动激活,这样下来这个service大概可以存活一周左右还是会被杀死,最后不得再次添加一个捕获用户解锁屏幕发出的系统广播去检测服务一旦死掉就将他们全部复活的功能,才能堪堪维持后台service的运行,当时还是很自豪自己的这个设计的。

然而现在看来这个设计显然是很low的,第一个就是采用了tcp的短链接,不停的跟服务器握手无疑是很耗费资源与手机电量的,多开了一个服务更是加大了电量的消耗。

可以只是用一个service服务用安卓的AlarmManager会更容易让服务区常住后台,另外将tcp短链接改为使用tcp长链接。

tcp长链接:连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接(一个TCP连接通道多个读写通信); 

至于离线push消息就是针对刚上线的用户一次性拉去所有离线的数据,优化方案是采用时间戳,每次上线对比时间戳去决定是否需要拉取数据。从而减少不必要的流量消耗。

所以还是按照老师说的关于推送如果可以还是建议使用固有的技术成熟的推送插件。而且一旦这个推送功能稳定了那么服务器的压力会更大,因为只要客户端后台在线就相当于每个一段时间就会有请求到达服务器,就相当于服务器的常住用户,一旦用户数量增多,对服务器的要求就大大的增多了,需要维护这么多设备同时在线也可以说是高并发了。

数据迁移

关键词:队列,主键自增

分布式事务(分库分表):

1.一次执行无回滚事务:例子(银行转账)

拆分分布式事务为几个工作的本地事务,事务间协作通过队列协调,生产者本地事务完成后需要将请求记录日志发送到消息队列中,供消费者消费,消费者需要支持幂等,队列中可能存在多个同样的请求,消费失败需要人工介入。

2.可多次执行有回滚操作的事务:

设计补偿服务机制:

•事务组表(txid、state)

•事务调用组(txid、actionid、callmethod、paramtypes、params)

• 取消事务调用组(txid、actionid、onqueue、isok)补偿策略:

• 事务补偿服务扫描需补偿事务组到消息队列

• 事务补偿线程从消息队列中取出并执行

• 事务组间并行执行

• 事务组内串行执行

• 服务端定时检查,1-5分钟入队一次

• 服务需要加定时检查,如果有超过半天没有被处理成功的事务 组,需要报警,人工处理。

3.本身补偿 日志、报警、人工

设计考虑和技术难点

记录调用链:

• 记录和数据更新在一个事务里

缺点:每个db创建“事务表”业务侵入太大

• 基于补偿幂等性前提,保证调用动作记录成功即可

缺点:有可能会执行一次无效的补偿,但不影响数据。

                                                                                                                       

 

 

原创粉丝点击