系统设计的一些原则

系统设计的一些原则,第1张

系统设计的一些原则 高并发原则

在设计高并发的应用程序时,遵循以下原则可以更好的实现目的。

无状态

应用无状态方便水平扩展。实际的情况通常是,应用是无状态的,但是配置文件是有状态的,例如不同机房的应用读取不同的数据源。需要配置文件或配置中心来分配。

搭配K8S,水平扩展更方便。

拆分

系统设计时,要考虑到系统是否做拆分。如果资源有限,并且用户并没有那么多,可以做一个大而全的系统。

而高并发的应用,通常是要做拆分的。

拆分可以依据多个维度:

系统维度 :如订单、库存、商品系统等功能维度 :如,对登录系统再拆分,划分为 :验证码登录、微信登录、密码登录等功能。读写维度 :针对读写再做分离,读服务可以使用缓存、写服务使用分库分表。 服务化


首先判断单点服务是否可以满足,

如果不能满足,集群可以吗?使用Nginx做负载均衡是否可以解决?

服务越来越多,是否要使用服务自动注册与发现?

某些服务访问量太大,导致整个系统不可用,要不要上服务降级和限流?哪些是主要服务?

消息队列

消息队列的作用有三个 :削峰、解耦、异步。

某一个事件消息,多个系统需要使用到。如,注册了一个新的用户,优惠券系统需要送劵、积分系统送积分,会员系统可能要推荐用户开会员,并且以后还会有某些系统新增对这个事件的处理。这种如果用系统调用太复杂了,而且不解耦,每接入一个新系统,就可能需要修改代码。这种情况,使用MQ是最好的。

消息队列的另一个作用是削峰,比如某个应用的处理速度是每秒三千条,而上游系统突然来了大流量,产生速度是每秒一万条,使用MQ,可以保证下游应用不被大流量压垮。

在消息队列技术选型上,也要充分考虑。如:消息是否可丢,MQ高可用怎么做,如何确保幂等性、活跃度、排查难度。

数据异构

用户查询订单列表,需要聚合多个表,可能速度就很慢,体验很差。

此时需要依据用户的ID做分库分表。

但某些场景是无需做异构的,比如商品的信息,可以考虑使用异步加载的方式。

缓存

缓存是对抗大流量的最佳银d,并且可以划分多种缓存,分别存储不同的信息,以解决不同的场景。

浏览器端缓存

设置请求的过期时间,如响应头的Expires和Cache-Control。这种适合实时性不高的数据,如商品页框架、广告词、评价等。

301是永久转移,浏览器是会缓存的。

302是不会缓存的,搜索引擎也会保存原地址,这样就可能被网址劫持。

301并不总是比302好,比如在实现短链服务时,需要对短链的访问进行统计,就必须要用到302。

客户端缓存

APP可以提前在后台把即将要用到的东西先从服务端拉取,等到要使用的时候先检查本地有无。

CDN缓存

可以将静态资源推送到CDN上。

用户访问时,去最近的CDN节点拉取。

CDN资源的URL不能有随机数,如果每次URL都不同,那每次都会穿透到服务端去访问资源。

接入层缓存

使用Nginx做一层缓存。

在使用Nginx做缓存,可以考虑使用以下机制实现 :

URL重写,去除随机数一致性哈希 :对参数做哈希,确保相同数据落到同一台机器proxy_cache :使用内存级、ssd代理来缓存内容。proxy_cache_lock:lock机制,将回源合并,要设置lock的超时时间。

应用层缓存

应用在水平扩展启动新应用时、或者重启应用,本地缓存就会失效。而水平扩展时,可能流量就很大,这时候没有本地缓存就很慢。

可以考虑在本机搭建一个Redis,应用读本地的Redis,Redis集群之间主从同步。

分布式缓存

如果存放在Redis的数据量很大,那么单机Redis就不能用来。

要使用分布式缓存了。分片规则可以采用一致性哈希。

异步与并发

某些资源实时性没那么高,可以考虑使用异步加载,如用户评价、商品打分这种。

获取多个资源时,采用并发的方式获取,可以大大的加快访问速度。

高可用原则

高并发与高可用是相辅相成的。

服务降级

降级开关

高可用服务,很重要一个设计是降级开关。当监控发现流量达到阈值时,告知各系统打开降级。

可降级的多级读服务

可以指定服务调用降级为只读本地缓存、只读分布式缓存、只读默认数据。

业务降级

高并发流量时,将服务调用修改为异步调用,这样方便下游系统做优先级判断,优先确保高优先级的服务。保证最终一致性。

限流

限流的目的是,防止流量超出系统的峰值。

有些大流量是正常的用户,这种是要临时的水平扩容。

有些流量是恶意的,如爬虫,这种恶意流量需要加以限制。需要针对的设置一些防爬机制,如:

爬虫只访问到cache穿透到后端的应用可以考虑使用Nginx的limit模块恶意访问的IP,使用nginx deny进行限制。【作用不大,IP代理并不贵,可能误封】给恶意访问假数据 可回滚


灰度发布。版本化机制,当程序出错时,回滚到上一个版本。

流量调度

大型应用,切流量是很重要的,并且划分为多个层面。

DNS :切换机房的入口HttpDNS:APP绕过运营商实现更精准的流量调度LVS/HaProxy :切换故障的NginxNginx :切换故障的应用层 业务设计的原则 幂等性


会有一些重复性的调用,被调用方需要对接口进行幂等性校验。

比如,防止重复支付。

可以考虑使用防重Key。

并且如果重复调用了,需要及时监测并弥补。如,同一个订单用户使用不同的支付渠道支付了,检测到时,需要及时退款。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5709726.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存