Skip to content

第六章-分布式技术篇

1、消息队列的作用与使用场景 难度系数:⭐

消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景

2.1异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种 1.串行的方式;2.并行方式

(1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端

image68

(2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间

image69

假设三个业务节点每个使用 50 毫秒钟,不考虑网络等其他开销,则串行方式的时间是 150 毫秒,并行的时间可能是 100 毫秒。

因为 CPU 在单位时间内处理的请求数是一定的,假设 CPU1 秒内吞吐量是 100 次。则串行方式 1 秒内 CPU 可处理的请求量是 7 次(1000/150)。并行方式处理的请求量是 10 次(1000/100)

小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:

image70

按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是 50 毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是 50 毫秒。因此架构改变后,系统的吞吐量提高到每秒 20 QPS。比串行提高了 3 倍,比并行提高了两倍

2.2 应用解耦

场景说明:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。如下图

image71

传统模式的缺点:

假如库存系统无法访问,则订单减库存将失败,从而导致订单失败

订单系统与库存系统耦合

如何解决以上问题呢?引入应用消息队列后的方案,如下图:

image72

订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功

库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作

假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦

2.3 流量削锋

流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

可以控制活动的人数

可以缓解短时间内高流量压垮应用

image73

用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面

秒杀业务根据消息队列中的请求信息,再做后续处理

2.4 日志处理

日志处理是指将消息队列用在日志处理中,比如 Kafka 的应用,解决大量日志传输的问题。

日志采集客户端,负责日志数据采集,定时写受写入 Kafka 队列

Kafka 消息队列,负责日志数据的接收,存储和转发

日志处理应用:订阅并消费 kafka 队列中的日志数据

以下是新浪 kafka 日志处理应用案例:转自

你们线上问题是怎么处理

http://cloud.51cto.com/art/201507/484338.htm)

image74

(1)Kafka:接收用户日志的消息队列

(2)Logstash:做日志解析,统一成 JSON 输出给 Elasticsearch

(3)Elasticsearch:实时日志分析服务的核心技术,一个 schemaless,实时的数据存储服务,通过 index 组织数据,兼具强大的搜索和统计功能

(4)Kibana:基于 Elasticsearch 的数据可视化组件,超强的数据可视化能力是众多公司选择 ELK stack 的重要原因

2.5 消息通讯

消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等

点对点通讯:

image75

客户端 A 和客户端 B 使用同一队列,进行消息通讯。

聊天室通讯:

客户端 A,客户端 B,客户端 N 订阅同一主题,进行消息发布和接收。实现类似聊天室效果。

以上实际是消息队列的两种消息模式,点对点或发布订阅模式。模型为示意图,供参考。

2、RabbitMQ 如何保证消息的顺序性 难度系数:⭐⭐

消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常。举例: 比如通过 mysql binlog 进行两个数据库的数据同步,由于对数据库的数据操作是具有顺序性的,如果操作顺序搞反,就会造成不可估量的错误。比如数据库对一条数据依次进行了 插入->更新->删除操作,这个顺序必须是这样,如果在同步过程中,消息的顺序变成了 删除->插入->更新,那么原本应该被删除的数据,就没有被删除,造成数据的不一致问题。

举例场景:

RabbitMQ:① 一个 queue,有多个 consumer 去消费,这样就会造成顺序的错误,consumer 从 MQ 里面读取数据是有序的,但是每个 consumer 的执行时间是不固定的,无法保证先读到消息的 consumer 一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。

image76

② 一个 queue 对应一个 consumer,但是 consumer 里面进行了多线程消费,这样也会造成消息消费顺序错误。

解决方案:

① 拆分多个 queue,每个 queue 一个 consumer,就是多一些 queue 而已,确实是麻烦点;这样也会造成吞吐量下降,可以在消费者内部采用多线程的方式取消费。

image78

一个 queue 对应一个 consumer

② 或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理

image79

一个 queue 对应一个 consumer,采用多线程

3、为什么要使用消息队列?为什么要使用 Kafka?

异步处理

应用解耦

流量削锋

4、Kafka 消费的时候,如何保证消息幂等性?

SetNX

唯一索引

乐观锁

分布式锁

分布式 ID

5、Producer 是否直接将数据发送到 broker 的 leader(主节点)?

Kafka 生产者(Producer)通常并不直接将数据发送到 broker 的 leader(主节点)。它遵循 Kafka 生产者-分区-副本的工作流程。下面是 Kafka 生产者发送消息的一般过程:

选择分区:生产者首先需要决定将消息发送到哪个分区。这通常是通过配置的分区选择策略或者手动指定的分区号来决定的。

查找分区的 leader 副本:一旦确定了要发送消息的分区,生产者需要查找该分区的 leader 副本所在的 broker。这通常是通过 Kafka 集群的元数据(metadata)来获取的。

连接到 leader 副本:生产者会与分区的 leader 副本建立连接,然后将消息发送给该 leader 副本。

消息发送:生产者将消息发送到分区的 leader 副本。Leader 副本将负责协调消息的复制和分发到其他副本。

消息复制:一旦消息到达 leader 副本,它会协调将消息复制到其他分区副本(通常包括 follower 副本)。这确保了消息的持久性和冗余性。

确认:一旦消息被 leader 副本成功写入,它会向生产者发送确认,以表明消息已成功接收并复制到足够数量的副本。生产者可以根据确认来决定是否将消息视为已成功发送。

6、请简述一下你在项目中哪些情况下会选择 Kafka

日志收集:一个公司可以用 Kafka 可以收集各种服务的 log,通过 kafka 以统一接口服务的方式开放给各种 consumer,例如 hadoop、HBase、Solr 等。

消息系统:解耦和生产者和消费者、缓存消息等。

用户活动跟踪:Kafka 经常被用来记录 web 用户或者 app 用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到 kafka 的 topic 中,然后订阅者通过订阅这些 topic 来做实时的监控分析,或者装载到 hadoop、数据仓库中做离线分析和挖掘。

运营指标:Kafka 也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。

流式处理:比如 spark streaming 和 Flink

7、Kafka 的分布式的情况下,如何保证消息的顺序传递

在 Kafka 中,消息的顺序传递通常是按照分区来保证的,而不是全局保证。这意味着对于单个分区内的消息,它们的顺序是得到保证的,但跨多个分区的消息之间的顺序不能被保证。

8、Kafka 的名词解释,请介绍一下 Kafka

主题(Topic):主题是 Kafka 中消息的分类。它类似于消息队列中的队列或主题,用于组织和分类消息。生产者将消息发布到主题,而消费者从主题订阅消息。

分区(Partition):主题可以划分为多个分区,每个分区是消息的存储单元。分区可以提高消息的并行性和可扩展性。消息在分区内保持顺序。

副本(Replica):每个分区可以配置多个副本,这些副本是分区的备份。副本提供了数据冗余和容错性。一个分区有一个 leader 副本,其余是 follower 副本。Leader 副本负责写入消息,而 Follower 副本用于数据冗余和故障恢复。

生产者(Producer):生产者是将消息发布到 Kafka 主题的应用程序。它负责将消息发送到指定主题中的一个或多个分区。

消费者(Consumer):消费者是从 Kafka 主题中订阅消息的应用程序。它可以消费一个或多个分区中的消息,并处理这些消息。

消费者组(Consumer Group):消费者可以组成消费者组。每个消费者组内的消费者共同协作,以从主题中消费消息。每个分区只能由一个消费者组内的一个消费者消费。

位移(Offset):位移是一个标识,用于表示消费者在主题分区中的位置。消费者记录其消费进度,以确保它可以在需要时继续从正确的位置消费消息。

Brokers:Kafka 集群由多个 Kafka 服务器组成,每个服务器称为一个 Broker。Brokers 负责存储消息、处理生产者和消费者的请求,并协调分区的复制。

Zookeeper:ZooKeeper 是 Kafka 集群的协调服务。它用于管理和维护 Kafka 集群的元数据、位移和其他关键信息。

Leader 和 Follower:在每个分区中,有一个 leader 副本和若干个 follower 副本。Leader 副本负责读写消息,而 follower 副本用于数据复制和冗余。

生产者确认(Producer Acknowledgments):生产者可以配置确认机制,以确保消息被成功写入 Kafka。确认机制可以设置为“无”、"全部"或"副本",用于控制消息的可靠性。

消费者位移管理(Consumer Offset Management):消费者需要管理自身的位移,以跟踪已消费的消息。Kafka 提供了消费者位移管理的机制。

9、Kafka 有几种消费模式

Pull(拉模式,也叫发布订阅模式):Kafka 现在使用的方式,消费者可以自主选择从哪个分区开始拉取消息,并可以自主控制拉取消息的速度。Kafka 中为消费者维护着一个 offset,表示消费者已经消费的消息序号,当消费者拉取消息时,Kafka 会返回该消费者还未消费的消息。虽然相比 push 模式实时性低一些,但是消费者灵活性高可以减少资源浪费。

Kafka 现在采用这种方式。可以有多个 topic 主题(例如:发送短息、发送邮件、保存日志等),消费者消费数据后,不会删除数据,消费数据的多个消费者都可以消费到数据

Push(推模式,也叫点对点模式):Kafka 最初的默认方式,此模式生产者将消息直接推送到 Kafka 集群中的分区中,分区自动将消息存储在磁盘上,并异步将消息传输到消费者。生产者主动控制消息的推送速度,消费者则以自己的速度从 Kafka 集群中拉取可用消息。虽然 push 模式实时性高,但是可能会发送大量重复或无效消息,浪费资源。

10、ISR、OSR、AR 你了解吗?简要说一下

ISR:In-Sync Replicas 副本同步队列

OSR:Out-of-Sync Replicas

AR:Assigned Replicas 所有副本

ISR 是由 leader 维护,follower 从 leader 同步数据有一些延迟(具体可以参见 图文了解 Kafka 的副本复制机制),超过相应的阈值会把 follower 剔除出 ISR, 存入 OSR(Out-of-Sync Replicas )列表,新加入的 follower 也会先存放在 OSR 中。AR=ISR+OSR。

11、Kafka 分区数可以增加或减少吗?为什么?

我们可以使用 bin/kafka-topics.sh 命令对 Kafka 增加 Kafka 的分区数据,但是 Kafka 不支持减少分区数。Kafka 分区数据不支持减少是由很多原因的,比如减少的分区其数据放到哪里去?是删除,还是保留?删除的话,那么这些没消费的消息不就丢了。如果保留这些消息如何放到其他分区里面?追加到其他分区后面的话那么就破坏了 Kafka 单个分区的有序性。如果要保证删除分区数据插入到其他分区保证有序性,那么实现起来逻辑就会非常复杂

12、Kafka 中的 Zookeeper 的作用是什么?

协调和领导者选举:Kafka 集群通常由多个 Broker 组成,ZooKeeper 用于协调这些 Broker 之间的活动和领导者(Leader)选举。Kafka 中的主题分区被分配给不同的 Broker,ZooKeeper 协助监视和维护这些分区的 Leader,以确保高可用性。

存储元数据:ZooKeeper 存储了 Kafka 集群的关键元数据,包括主题和分区的配置信息、Broker 的状态以及生产者和消费者的元数据。这些元数据对于 Kafka 的正常运行非常重要。

监控和故障检测:ZooKeeper 监视 Kafka 集群中各个 Broker 的状态,并在发生故障或节点失效时通知 Kafka。这有助于 Kafka 集群快速适应故障并保持高可用性。

分布式锁管理:Kafka 中的一些组件需要分布式锁,以确保操作的原子性和一致性。ZooKeeper 提供了分布式锁服务,以支持这些需求。

13、Kafka 中的消息偏移量是什么?

消息的唯一标识:消息偏移量用于唯一标识主题分区中的每个消息。它是消息在分区内的位置标识符。

消费者位移管理:Kafka 消费者使用消息偏移量来跟踪它们已经消费的消息,以便在断开连接后重新连接时从上次的位置继续消费。这有助于确保数据的不丢失和消息的一次性处理。

实现精确的消费语义:通过消息偏移量,消费者可以实现不同的消费语义,如最多一次、最少一次或精确一次。消费者可以控制它们如何使用消息偏移量来满足其需求。

处理顺序性:消息偏移量可以用于确保消息按照它们在主题分区中的顺序进行处理。消费者可以根据消息偏移量来保持处理顺序性。

容错性:消息偏移量还用于实现容错性。如果消费者出现故障,它可以使用保存的消息偏移量信息来恢复并继续从上次的位置进行消费。

14、Kafka 中的 Consumer Group 是什么?

Consumer Group(消费者组)是一种组织和管理多个消费者实例的机制。它允许多个消费者实例协同工作以处理一个主题(或多个主题)的消息流。

Kafka 中的消息保留策略有哪些?

消息保留策略定义了消息在主题中的保留时间和何时应该被删除。不同的消息保留策略允许您根据应用的需求来管理消息的生命周期。

15、Kafka 中的消息丢失问题如何解决?

确认生产者发送:确保生产者将消息成功发送到 Kafka 主题。生产者可以使用确认机制来检查消息是否已成功提交,如果没有成功,可以进行重试。

使用同步生产者:Kafka 生产者提供了异步和同步发送消息的方式。使用同步生产者可以确保消息在成功提交之前等待确认,从而减少消息丢失的风险。

设置生产者 acks 参数:在 Kafka 生产者配置中,通过设置 acks 参数为 all,可以确保消息在所有 ISR(In-Sync Replicas)中成功复制后才返回确认。这提供了更高的消息可靠性,但可能会降低性能。

消息复制和 ISR:确保 Kafka 主题的配置正确,包括适当的副本数和 ISR 列表。这可以确保消息被复制到足够多的副本中,并且在 ISR 中保持活跃。

监控和警报系统:建立监控和警报系统,以及时检测消息丢失情况。Kafka 提供了许多监控指标,可以使用工具如 Prometheus、Grafana 等来实现监控和报警。

处理消费者错误:消息丢失也可能在消费者端发生。确保您的消费者应用程序能够处理异常情况,例如处理消息时的错误,以避免数据丢失。

数据备份和恢复:定期备份 Kafka 数据,以便在不可避免的数据丢失情况下进行恢复。您可以使用 Kafka 的工具或第三方备份工具来实现这一点。

分区分配策略:在消息生产和消费之间,确保使用合适的分区分配策略,以防止消息被误发送到错误的分区。

消息幂等性:设计生产者和消费者应用程序,以处理重复消息,从而确保即使消息发送多次也不会引发不正确的结果。

日志和审计:实施日志和审计机制,以跟踪消息的生命周期,便于故障排查和数据完整性验证。

16、Kafka 中的生产者和消费者是如何实现消息的传输?

生产者:

生产者负责将消息发送到 Kafka 集群的主题中。

生产者使用 Kafka 客户端库来建立与 Kafka 集群的连接。

生产者将消息发布到一个或多个主题,通常选择主题和分区来确定消息的最终存储位置。

生产者可以选择同步或异步地发送消息。同步发送会等待直到接收到 Kafka 集群的确认,而异步发送则不会等待确认,可以提高性能。

生产者还可以配置消息的键(key),这有助于确定消息被发送到哪个分区。

Kafka 集群:

Kafka 集群由多个 Kafka Broker 组成,每个 Broker 负责处理消息的接收、存储和分发。

Kafka 集群会根据主题和分区的配置将消息分发到相应的分区,并确保复制消息以提高可用性。

Kafka 集群会维护分区的 ISR(In-Sync Replicas)列表,确保消息被复制到足够多的副本中,以防止数据丢失。

消费者:

消费者负责从 Kafka 主题中获取消息,并处理这些消息。

消费者也使用 Kafka 客户端库来建立与 Kafka 集群的连接。

消费者可以订阅一个或多个主题,然后从这些主题的分区中拉取消息。

消费者可以根据配置来控制消息拉取的频率,以及如何处理消息。

消息传输:

生产者使用 Kafka 客户端库将消息发送到 Kafka 集群的指定主题和分区。

Kafka 集群接收消息后,根据分区的配置将消息分发到相应的分区,并确保复制到 ISR 中的其他副本。

消费者使用 Kafka 客户端库从 Kafka 集群中拉取消息。它可以选择拉取最新的消息或指定的偏移量。

消费者处理接收到的消息,并可以进行应用程序特定的操作。

17、什么是 ElasticSearch 怎么解决中文分词 难度系数:⭐

Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了具有 HTTP Web 界面和无架构 JSON 文档的分布式,多租户能力的全文搜索引擎。Elasticsearch 是用 Java 开发的,根据 Apache 许可条款作为开源发布。

采用 IK 中文分词器插件进行中文分词处理。

18、Elasticsearch 中的倒排索引是什么 难度系数:⭐

正排索引:

在说倒排索引之前我们先说说什么是正排索引。正排索引也称为"前向索引",它是创建倒排索引的基础。

这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于维护;因为索引是基于文档建立的,若是有新的文档加入,直接为该文档建立一个新的索引块,挂接在原来索引文件的后面。若是有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。

他适合根据文档 ID 来查询对应的内容。但是在查询一个 keyword 在哪些文档里包含的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。

比如有几个文档及里面的内容,他正排索引构建的结果如下图:

image80

**优点:**工作原理非常的简单。 **缺点:**检索效率太低,只能在一起简单的场景下使用。

倒排索引:

根据字面意思可以知道他和正序索引是反的。在搜索引擎中每个文件都对应一个文件 ID,文件内容被表示为一系列关键词的集合(文档要除去一些无用的词,比如’的’这些,剩下的词就是关键词,每个关键词都有自己的 ID)。例如“文档 1”经过分词,提取了 3 个关键词,每个关键词都会记录它所在在文档中的出现频率及出现位置。

那么上面的文档及内容构建的倒排索引结果会如下图(注:这个图里没有记录展示该词在出现在哪个文档的具体位置):

image81

如何来查询呢?

比如我们要查询‘搜索引擎’这个关键词在哪些文档中出现过。首先我们通过倒排索引可以查询到该关键词出现的文档位置是在 1 和 3 中;然后再通过正排索引查询到文档 1 和 3 的内容并返回结果。

19、Nginx 原理 难度系数:⭐

Nginx 内部进程模型:

image82

1.在 nginx 启动后,会有一个 master 进程和多个 worker 进程,master 进程主要用来管理 worker 进程,包括:接受信号,将信号分发给 worker 进程,监听 worker 进程工作状态,当 worker 进程退出时(非正常),启动新的 worker 进程。基本的网络事件会交给 worker 进程处理。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的 。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求。 worker 进程的个数是可以设置的,一般我们会设置与机器 cpu 核数一致,这里面的原因与 nginx 的进程模型以及事件处理模型是分不开的 。

2.当 master 接收到重新加载的信号会怎么处理(./nginx -s reload)?,master 会重新加载配置文件,然后启动新的进程,使用的新的 worker 进程来接受请求,并告诉老的 worker 进程他们可以退休了,老的 worker 进程将不会接受新的,老的 worker 进程处理完手中正在处理的请求就会退出。

3.worker 进程是如何处理用户的请求呢?首先 master 会根据配置文件生成一个监听相应端口的 socket,然后再 faster 出多个 worker 进程,这样每个 worker 就可以接受从 socket 过来的消息(其实这个时候应该是每一个 worker 都有一个 socket,只是这些 socket 监听的地址是一样的)。当一个连接过来的时候,每一个 worker 都能接收到通知,但是只有一个 worker 能和这个连接建立关系,其他的 worker 都会连接失败,这就是所谓的惊群现在,为了解决这个问题,nginx 提供一个共享锁 accept_mutex,有了这个共享锁后,就会只有一个 worker 去接收这个连接。当一个 worker 进程在 accept 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。

image83

master-workers 的机制的好处

首先,对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。

其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快启动新的 worker 进程。

当然,worker 进程的异常退出,肯定是程序有 bug 了,异常退出,会导致当前 worker 上的所有请求失败,不过不会影响到所有请求,所以降低了风险。

需要设置多少个 worker

Nginx 同 redis 类似都采用了 io 多路复用机制,每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。

所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。

#设置 worker 数量

conf
worker_processes 4

#work 绑定 cpu(4 work 绑定 4cpu)。

worker_cpu_affinity 0001 0010 0100 1000

#work 绑定 cpu (4 work 绑定 8cpu 中的 4 个) 。

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

#连接数

worker_connections 1024

这个值是表示每个 worker 进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于 HTTP 请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,如果是支持 http1.1 的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes /2,而如果是 HTTP 作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/4

20、Nginx 作用以及常见配置 难度系数:⭐

**作用:**反向代理、负载均衡、动静分离(静态资源服务器,可以进行图片等资源管理)

具体配置实现:

反向代理:

在 nginx.conf 配置文件中增加如下配置

image84

负载均衡:

常见策略

权重:

weight 代表权,重默认为 1,权重越高被分配的客户端越多

指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。 例如:

conf
upstream server_pool{
server 192.168.5.21 weight=1;
server 192.168.5.22 weight=2;
server 192.168.5.23 weight=3;
}

ip_hash:

每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。 例如:

conf
upstream server_pool{
ip_hash;
server 192.168.5.21:80;
server 192.168.5.22:80;
}

fair(第三方):

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

conf
upstream server_pool{
server 192.168.5.21:80;
server 192.168.5.22:80;
fair;
}

轮询(默认)

image85

image86

静态资源(动静分离):

image87

根据 MIT 许可发布。