常用中间件分享

一、最开始的网站架构 最初的架构,应用程序、数据库、文件都部署在一台服务器上,

如图:

 

 

二、应用、数据、文件分离 随着业务的扩展,一台服务器已经不能满足性能需求,故将应

用程序、数据库、文件各自部署在独立的服务器上,并且根据服务器的用途配置不同的硬件,

达到最佳的性能效果。

三、利用缓存改善网站性能 在硬件优化性能的同时,同时也通过软件进行性能优化,在大

部分的网站系统中,都会利用缓存技术改善系统的性能,使用缓存主要源于热点数据的存在,

大部分网站访问都遵循 28 原则(即 80%的访问请求,最终落在 20%的数据上),所以我们可以对

热点数据进行缓存,减少这些数据的访问路径,提高用户体验。

 

 

缓存实现常见的方式是本地缓存、分布式缓存。当然还有 CDN、反向代理等。本地缓存,

顾名思义是将数据缓存在应用服务器本地,可以存在内存中,也可以存在文件,OSCache 就是

常用的本地缓存组件。本地缓存的特点是速度快,但因为本地空间有限所以缓存数据量也有限。

分布式缓存的特点是,可以缓存海量的数据,并且扩展非常容易,在门户类网站中常常被使用,

速度按理没有本地缓存快,常用的分布式缓存是 Memcached、Redis。缓存的主要作用,提高服务响应速度,减少数据库的访问压力,从而提高服务的性能提升。

有关redis常见问题

1、缓存与数据库双写一致性问题是指在并发场景下,缓存和数据库之间的数据同步出现问题,导致数据的不一致性。解决这一问题,通常有以下几种策略:

  • 先更新数据库,再更新缓存。这种策略简单,但在并发更新场景下可能导致脏数据被写入缓存,即数据库中的新数据还未写入缓存时,其他线程已经读取并可能使用了旧的缓存数据。
  • 先删除缓存,再更新数据库。这种策略可以避免脏数据的产生,但在删除缓存和更新数据库之间,如果其他线程读取数据,可能会读取到旧数据并写入缓存。此外,如果删除缓存失败,也会导致数据不一致。
  • 先更新数据库,再删除缓存。这种策略可以确保数据库的更新优先于缓存的更新,避免了脏数据的产生。但是,如果删除缓存失败,仍然可能导致数据不一致。
  • 延时双删策略。即在删除缓存后,休眠一定时间(如1秒或200ms),再次删除缓存。这样可以确保在读请求结束前,写请求可以删除读请求造成的缓存脏数据。但这种方法会影响系统的吞吐量。

此外,还有基于消息队列的解决方案,通过将读请求和写请求串行化,可以保证数据的一致性,但这样做会大幅降低系统的吞吐量。在实际应用中,需要根据具体的业务场景和性能需求来选择合适的解决方案。

2、缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。

解决缓存击穿的方法也有两种,第一种是设置key永不过期;第二种是使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。

3、缓存雪崩是指当缓存中有大量的key在同一时刻过期,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。针对大量key同时过期的情况,解决起来比较简单,只需要将每个key的过期时间打散即可,使它们的失效点尽可能均匀分布。

常用场景:

比如网站的用户个人设置信息、商品详情、热搜榜单这些都会使用 redis缓存数据

综合系统中使用redis的场景觉少,比如用户的主题设置信息是缓存在redis中的。

 

四、使用集群改善应用服务器性能 应用服务器作为网站的入口,会承担大量的请求,我

们往往通过应用服务器集群来分担请求数。应用服务器前面部署负载均衡服务器调度用户请求,

根据分发策略将请求分发到多个应用服务器节点。

目前常用的是Nginx,分发机制有下面几种:

1、轮询机制,即有10个服务器,第一个请求过来会分发到服务器1,第二个请求会分发到服务器2,10个服务器依次接受请求,通常对服务器性能差不多的服务会使用轮询机制;

2、针对多个服务器性能不一致的情况会采用权重的分发机制来处理,即硬件性能较高的服务器来处理更多的请求;

3、根据请求访问的ip,固定访问同一个服务器;

4、最少连接:下一个请求会被分配到连接数最少的服务器上。

 

 

 

五、随着用户量的增加,数据库成为最大的瓶颈,改善数据库性能常用的手段是进行读写分离以及分库分表。

读写分离顾名思义就是将数据库分为读库和写库,通过主备功能实现数据同步,主从数据不同步是读写分离常见问题,主从库之间需要通过日志的方式进行数据同步,如果此时用户的读请求交给从库去处理,一旦数据同步操作未完成,则用户此时读到的数据是旧数据,会导致用户获取数据不可靠,影响业务的正常运行和用户体验。链接是常见的解决思路,有兴趣的可以了解下https://blog.csdn.net/u013247401/article/details/113929942

分库分表则分为水平切分和垂直切分,水平切分则是对一个数据库特大的表进行拆分(比如bi中每日产生的bi数据量过大,会根据月份分表每月一张表),例如用户表。垂直切分则是根据业务不同来切分,如用户业务、商品业务相关的表放在不同的数据库中(比如车辆数据,会将车辆主要数据放在一张表中,其他次要信息存储在另一张表中)。

 

六、使用 CDN 和反向代理提高网站性能 假如我们的服务器都部署在成都的机房,对于四川

的用户来说访问是较快的,而对于北京的用户访问是较慢的,这是由于四川和北京分别属于电

信和联通的不同发达地区,北京用户访问需要通过互联路由器经过较长的路径才能访问到成都

的服务器,返回路径也一样,所以数据传输时间比较长。对于这种情况,常常使用 CDN 解决,

CDN 将数据内容缓存到运营商的机房,用户访问时先从最近的运营商获取数据,这样大大减少

了网络访问的路径。比较专业的 CDN 运营商有蓝汛、网宿。

而反向代理,则是部署在网站的机房,当用户请求达到时首先访问反向代理服务器,反向

代理服务器将缓存的数据返回给用户,如果没有没有缓存数据才会继续走应用服务器获取,也

减少了获取数据的成本,静态资源服务器、反向代理、负载均衡都可使用nginx。

正向代理:

正向代理是代理用户客户端,为客户端发送请求,对服务器隐藏自己的真实客户端。我们常接触的正向代理场景使用vpn访问内网、、使用抓包工具抓包。

反向代理:

是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端。

 

七、使用分布式文件系统 用户一天天增加,业务量越来越大,产生的文件越来越多,单

台的文件服务器已经不能满足需求。需要分布式的文件系统支撑。常用的分布式文件系统有

NFS。

 

八、使用 NoSql 和搜索引擎 对于海量数据的查询,我们使用 nosql 数据库加上搜索引擎可

以达到更好的性能。并不是所有的数据都要放在关系型数据库中。常用的 NOSQL 有 mongodb 和

redis,搜索引擎有 lucene。

 

九、将应用服务器进行业务拆分 随着业务进一步扩展,应用程序变得非常臃肿,这时我们

需要将应用程序进行业务拆分,如百度分为新闻、网页、图片等业务。每个业务应用负责相对

独立的业务运作。业务之间通过消息队列进行通信或者同享数据库来实现。

mq主要作用:异步、解耦、削峰

1. 流量削峰

举个例子,这里有一个订单系统处理用户下单的业务逻辑。这个系统的服务能力假设为 1S 处理1万次订单,那么正常来说,不超过1万次对它来说都没问题。但是,如果到了用户下单的高峰期,这时候的单量可能就要超过系统服务能力。

这时候可以加入 MQ,把1s内下的订单进行排队,分散在一段时间内处理,虽然说会导致有些用户会在几秒之后才能收到下单成功,但是比起不能下单还是要好很多了。

2. 应用解耦

现在有个电商应用,里面包含了好多个子系统:订单系统、库存系统、物流系统、支付系统等。

先看下耦合在一起的情况,当用户创建订单后,如果后面任何一个子系统出现了故障,都会造成用户的下单操作异常。

加上 MQ 后,订单系统的工作完成后,接下来的事情就转交给MQ了。MQ 会分配消息给其他的3个系统,直到3个系统执行完成。如果存在其中有不能完成的系统,队列会监督它继续完成。比如物流系统坏了,但是订单系统不受影响,用户感觉不出来有异常,依旧可以看到成功下单的提示。当物流系统恢复正常以后,继续处理订单信息即可,从而提升了整个系统的可用性。

3. 异步处理

在生产中,有些服务间的调用是异步的。A 调用 B,但是 B 需要花费一段时间来处理。没有 MQ 的时候通常这样处理:

  • A 轮询的调用 B的查询,看看结果是不是处理好了。

  • A 提供一个callback 回调接口,B 执行好了调用这个api接口通知 A。

加入 MQ 后,这时 A 再调用 B 后,只需要监听 B 处理完成的消息即可。当 B 处理完成后,会发送一条消息给 MQ,然后 MQ 会把消息转发给 A。所以,现在 A 既不用轮询 B,也不用提供回调api)

MQ 的组成

1. 角色

  • Broker:消息服务器,提供消息核心服务

  • Producer:消息生产者,业务的发起方,负责生产消息传输给broker。

  • Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理。

  • Topic:主题,发布订阅模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的广播。

  • Queue:队列,点对点模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收。

  • Message:消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输。

2. MQ 消息模式

1)点对点模式
使用 queue 作为通信载体,消息生产者生产消息发送到 队列中,然后消息消费者从 队列 中取出并且消费消息。

  • 消息被消费以后,队列中不再存储,所以消息消费者不可能消费到已经被消费的消息。

  • 队列支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

2)发布订阅模式
使用topic作为通信载体,1个生产者可以对应多个消费者。消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。

就像你发了个朋友圈,你的朋友们都可以看到一样。

3.MQ 测试需要的关注点

 对于生产者

  • 生成的数据格式是否跟定义的一致

  • 数据是否有成功推送到队列里

  • 数据是否有成功推动到对应的 topic

  • 推送失败时如何处理

  • 重复推送同一条数据,如何处理

  • 不同顺序推送消息,注意队列优先级

  • 推消息耗时,队列容量达到上限,无法推送后如何处理

 对于消费者

  • 消费的消息是否来自订阅的 topic

  • 消息被消费了,是否有清除

  • 生产者推送过快,消费速度过慢(堵塞),会如何

  • 无法消费没订阅的 topic 消息

  • 生产者推送消息后,消费者接受到的消息内容跟生产者推的一致

  • 如何处理重复消息,比如幂等

  • 处理超时

  • 消息处理失败

  • 消费消息的优先级是否跟推的一致

  • 消费消息耗时

  • 消费者宕机,消息堆积,无人处理,会如何处理

  • 是否能正常消费消息

对于队列

  • 宕机恢复后,消息是否丢失

  • 宕机预案,多久能恢复,如果无法恢复的预案

  • 不同的消息格式,是否能正常识别及转发

 

 

十、搭建分布式服务 这时我们发现各个业务应用都会使用到一些基本的业务服务,例如用

户服务、订单服务、支付服务、安全服务,这些服务是支撑各业务应用的基本要素。我们将这

些服务抽取出来利用分布式服务框架搭建分布式服务。淘宝的 Dubbo 是一个不错的选择。

分布式是将一种业务拆分成多个子业务部署在多台服务器上,而集群就是将多台服务器组合在一起提供同一种服务

 

posted @ 2024-06-09 08:45  贰号猿  阅读(57)  评论(0编辑  收藏  举报