高可用系列文章之二 - 传统分层架构技术方案

news2024/11/17 3:33:44

前文链接

高可用系列文章之一 - 概述 - 东风微鸣技术博客 (ewhisper.cn)

三 技术方案

3.1 概述

单点是系统高可用最大的风险和敌人,应该尽量在系统设计的过程中避免单点。

保障系统的高可用, 方法论上,高可用保证的原则是「集群化」(或 「冗余」), 只有一个单点,该单点宕机所有服务都会受影响而不可用;如果有冗余或备份,其中一个点宕机还有其他冗余或备份节点能够提供服务。

保证系统高可用,架构设计的核心准则是:冗余。

有了冗余之后,还不够,每次出现故障需要人工介入恢复势必会增加系统的 MTTR。所以,又往往是通过「自动故障转移」来实现系统的高可用。

在下面的技术方案中,详细介绍了如何通过冗余+自动故障转移来保证系统的高可用特性。

3.2 制造业系统的典型架构

制造业系统一般采用分层架构, 最简单的典型架构的展示如下:

:information_source: ​ 备注:

数据库以 MySQL 为例.

典型架构

常见的系统架构如上, 分为:

  1. 客户端层: 典型调用方式浏览器(browser) 和客户端(client)
  2. 应用服务层: 实现核心应用逻辑, 通常是 HTTP 协议或 TCP 协议. 这一层细分, 往往还包括:
    1. 表示层: 主要是 web 浏览页面;
    2. 业务逻辑层: 对具体问题进行逻辑判断和执行操作, 同时也是表示层和数据层的桥梁
    3. 可选: 服务层: 如果实现了服务化, 如 SOA 或微服务化, 就会有这一层;
    4. 数据访问层: 实现对数据的增删改查等操作, 并将结果反馈到业务逻辑层
    5. 可选: 数据缓存层: 缓存加速访问存储
  3. 数据库层: 数据库固话数据存储.

整个系统的高可用, 是通过对每一层的冗余+自动故障转移来综合实现的.

:information_source: 备注:

通过更加细化和细致的分层, 也可以提高可用性. 如将以上架构细化为:

  1. 客户端层;
  2. 可选新增: 反向代理层
  3. 可选新增: 表示层(Web Server)层
  4. 应用服务层(App Server)层
  5. 可选新增: 服务调用层
  6. 可选新增: 缓存层
  7. 数据库层

本文暂不涉及这一内容.

3.3 制造业系统的推荐高可用架构

通过冗余这一核心原则, 优化后的高可用架构如下图所示:

HA架构

:information_source: 说明:

  • 实线 : 请求调用
  • 点+横线: 心跳检测
  • 点虚线: 尚未真实发生的请求调用
  • 短横虚线: 数据库主从同步
  • "X" - 对应节点宕机不可用.

高可用方案调整说明如下:

  1. 在客户端层和应用服务层之间, 新增: 负载均衡层. 负责将客户端请求通过某种负载均衡方式科学地负载到应用服务外层;
  2. 负载均衡层: 这一层包含以下2个组件:
    1. NGINX: 负责 TCP/HTTP 请求的负载反向代理/负载均衡;
    2. Keepalived: 负责对外提供单个 IP, 且对 2 台 NGINX 进行心跳检测和故障时的故障转移;
  3. 应用服务层: 应用服务器至少为 2 个.
  4. 数据库层: 数据库进行主从同步, 读写分离

:information_source: 备注:

上图中, 也画出了高可用的另一种实施方案, 本文不做详细讨论:

  • 应用横向拆分: 单体应用(monolithic application)根据重要性进行拆分, 将重要性高的服务和重要性低的服务进行拆分, 单独部署.
  • 重要性高的应用, 如低延迟类应用, 流水线上应用等;
  • 重要性低的应用, 如高延迟类应用, 报表应用等.

除此之外, 还可以根据实际业务情况进一步将数据库进行拆分, 本文亦不做详细讨论:

  • 数据库拆为 2 个库, 其中一个库通过数据同步从另一个库定时(实时或非实时)同步数据. 举例说明: 业务库, 报表库. (业务库定期同步数据给报表库)
  • 重要性高的应用, 读取写入业务库;
  • 重要性低的应用. 如报表类应用. 不允许使用业务库, 而是使用报表库.

下面逐一进行分层论述.

3.4 客户端层 -> 负载均衡层 高可用

1578813330834

客户端层负载均衡层 高可用, 通过负载均衡层的冗余来实现的. 具体实现方式如下:

至少有 2 台 nginx, 其中一台提供服务, 另一台冗余以保证高可用. 并通过 Keepalived 的 virtual IP 来提供同一 IP(如上图为: 1.2.5.6), 通过心跳探测来进行故障检测和故障转移.

在上图中, NGINX 主节点提供对外服务.

当 NGINX 主节点(如: 192.168.0.1)发生宕机, Keepalived 能够探测到, 会自动进行故障转移, 将流量自动转移到 NGINX 从节点(如: 192.168.0.2). 由于使用的是相同的 virtual IP(仍为: 1.2.5.6), 这个切换过程对调用方是透明的.

1578812475962

3.5 负载均衡层 -> 应用服务层高可用

负载均衡层应用服务层 的高可用, 是通过应用服务层的冗余来实现的. 在NGINX的配置文件 nginx.conf 中, 可以通过 upstream 指令配置多个应用服务器, 并且 nginx 能够探测到多个应用服务器的存活性.

应用服务层高可用1

:information_source: 知识点:

在 NGINX 开源版本中, 如果不使用第三方插件,NGINX 的存活探测为: 被动探测.

应用服务层 其中一个节点宕机的时候, nginx 能够探测到, 会自动进行故障转移, 不会将流量分发到发生故障的节点, 而是分发到其他的正常应用服务器节点, 整个过程由 NGINX 自动完成, 对调用方透明.

应用服务层高可用2

3.6 应用服务层 -> 数据库层高可用

数据库层建议采用「主从同步, 读写分离」架构. 数据库的高可用, 又可细分为: 「读库高可用」 和「写库高可用」 两类.

:information_source: 备注:

由于制造业采用了多种数据库, 包括但不限于:

  • Oracle
  • SQL Server
  • MySQL

不同数据库的高可用解决方案并不完全相同, 所以本文不对数据库的具体高可用技术做细节描述. 只进行理论论述.(以 MySQL 为例)

常见的数据库高可用方案有:

  1. MySQL: 主从同步;
  2. Oracle: RAC
  3. SQL Server: Alwayon

3.6.1 读库高可用

读库高可用, 是通过读库的冗余来实现的.

如果要对读库实现高可用, 一般来说至少有 2 个从库, 数据库连接池会建立与读库的多个连接, 每次请求会路由到这些读库.

读库高可用1

当读库 - 从1发生宕机的时候, 应用服务层的数据库连接池能够探测到, 会自动的进行故障转移, 将流量自动迁移到其他的读库, 如读库 - 从2, 整个过程由数据库连接池自动完成, 对调用方是透明的.

读库高可用2

:information_source: 备注:

需要应用系统或中间件的数据库连接层实现数据库连接池功能.

3.6.2 写库高可用

写库的高可用, 是通过写库的冗余来实现的.

以 MySQL 为例, 可以设置两个 MySQL 双主同步, 一台对线上提供服务, 另一台冗余以保证高可用.

3.7 技术选型

3.7.1 负载均衡器技术选型

:heavy_check_mark: 选型结果:

  • 负载均衡器: NGINX + Keepalived
  • 版本:
    • NGINX: 1.16.1 (:exclamation: 选型版本至少每半年评估一次, 根据评估结果对版本进行调整)
    • Keepalived: 2.0.10(❗️ 选型版本至少每半年评估一次, 根据评估结果对版本进行调整)
  • 操作系统类型: Linux
  • 操作系统版本: SUSE 12 (按需调整,遵循制造业的相关技术规范要求.)

:information_source: 定义及概述:

在分布式系统中,负载均衡(load balance)是一种有效的将网络请求分配到多个服务器的过程。通过将负载进行负载均衡,可以有效地改进系统响应时间,提高系统的可用性。随着系统变的愈发复杂,用户增多和网络流量增大,负载均衡已经成为系统设计中的必要一环。

负载均衡器可以是硬件也可以是软件,它会将网络请求分发到服务器集群上。

选型过程概述

常见的硬件负载均衡器包括:

  • F5
  • A10

常见的软件负载均衡器包括:

  • Nginx
  • LVS
  • HAProxy

结合制造行业最佳实践, 以及制造业的实际情况考虑, 制造业在全国乃至全球拥有多座工厂, 每个工厂拥有独立的机房. 采用硬件负载均衡成本过高. 确定采用软件负载均衡器作为负载均衡技术实现. 下面对软件负载均衡器逐一进行论述:

NGINX:

Nginx("engine x")是一款是由俄罗斯的程序设计师 Igor Sysoev 所开发高性能的 Web 和 反向代理 服务器.

优点:

  1. 工作在网络的 4 层(TCP/UDP)和 7 层(HTTP/websocket),可以针对 http 应用做一些分流的策略,比如针对域名、目录结构,其正则规则比 HAProxy 更为强大和灵活, 同时 NGINX 目前是使用最广泛的负载均衡器和 Web Server,适用场景丰富.
  2. Nginx 对网络稳定性的依赖非常小,理论上能 ping 通就就能进行负载功能;相反 LVS 对网络稳定性依赖比较大;
  3. Nginx 安装和配置比较简单,测试起来比较方便,NGINX 拥有完善的且可自定义的日志, 包括 access 日志和 error 日志。LVS 的配置、测试需要花费比较长的时间。
  4. NGINX 可以承担高负载压力且稳定,在硬件不差的情况下很容易能支撑几万次的并发量。
  5. Nginx 可以通过端口检测到应用服务器的故障,如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点。如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx 会将上传切到另一台服务器重新处理,如果是 LVS就直接断掉了。
  6. Nginx 不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的 Web 应用服务器。LNMP 也是近几年非常流行的 web 架构,在高流量的环境中稳定性也很好。
  7. Nginx 作为 Web 反向加速缓也比较成熟,速度比传统的 Squid 服务器更快,在未来场景用, 也可以扩展 NGINX 的用途。
  8. Nginx 可作为反向代理使用,作为反向代理, Nginx 使用最广泛, 同类产品还有 lighttpd 了,不过 lighttpd 目前还没有做到 Nginx 完全的功能,配置也不清晰易读,社区资料也远远没 Nginx 活跃。
  9. Nginx 也可作为静态网页和图片服务器,这方面的性能也无对手。
  10. Nginx 社区非常活跃,第三方模块也很多。

缺点:

  1. 对后端服务器的健康检查, 开源版 NGINX 支持持被动检测. 不支持主动检测.
  2. 对于负载均衡的会话保持, 开源版 NGINX 默认不支持cookie会话保持. 但是能通过 ip_hash 实现源地址会话保持, 且可以通过第三方模块实现cookie会话保持.

LVS:

LVS:使用 Linux 内核集群实现一个高性能、高可用的负载均衡服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。

优点:

  1. 抗负载能力强、是工作在网络 4 层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,对内存和cpu 资源消耗比较低。
  2. 配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率。
  3. 工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,如 LVS+Keepalived。
  4. 无流量,LVS 只分发请求,而流量并不从它本身出去,这点保证了均衡器 IO 的性能不会收到大流量的影响。
  5. 应用范围比较广,因为 LVS 工作在 4 层,所以它几乎可以对所有应用做负载均衡,包括 http、数据库、在线聊天室等等。

缺点:

  1. 软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是 Nginx+Keepalived 的优势所在。
  2. 如果是网站应用比较庞大的话,LVS 实施起来比较复杂了,特别后面有 Windows Server 的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx + Keepalived就简单多了。

HAProxy:

HAProxy 是一个使用 C 语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于 TCP 和 HTTP 的应用程序代理。

优点:

  1. HAProxy 支持虚拟主机。
  2. HAProxy 的优点能够补充 Nginx 的一些缺点,比如支持 Session 的保持,Cookie 的引导;同时支持通过获取指定的 url 来检测后端服务器的状态。
  3. HAProxy 跟 LVS类似,本身就只是一款负载均衡软件。
  4. HAProxy 支持 TCP 协议的负载均衡转发。
  5. HAProxy 负载均衡策略比较丰富

缺点:

  1. 不支持 POP/SMTP 协议
  2. 不支持 SPDY 协议
  3. 不支持 HTTP cache 功能。
  4. 重载配置的功能需要重启进程,虽然也是 soft restart,但没有 Nginx 的 reload 更为平滑和友好。
  5. 多进程模式支持不够好

选型结论:

LVS 试用场景单一, 且存在硬伤(即: 后面有Windows Server的机器的话, 实施比较复杂). 直接排除.

HAPorxy 针对 HTTP 的支持没有 NGINX 丰富, 且重启中断相对 NGINX 时间更长.

另外, nginx 除了当前可以用作负载均衡器之外, 还可以用作 web server, http 缓存等场景, 且容易上手.

最终确定选择 NGINX 作为某制造业公司负载均衡器.

3.7.2 NGINX高可用技术方案选型

NGINX 高可用技术方案只有一种, 即: NGINX + Keepalived 实现高可用.

keepalived开源项目包括三个组成部分:

  • keepalivedLinux服务器的守护程序。

  • 虚拟路由器冗余协议(VRRP)的实现,用于管理虚拟路由器(虚拟 IP 地址或 VIP)。

    VRRP 确保始终存在一个主节点。备用节点侦听来自主节点的 VRRP 通告包。如果在超过配置的广播间隔的三倍的时间内未收到广播包,则备用节点将作为主节点接管,并将配置的 VIP 分配给自己。

  • 一种运行状况检查工具,用于确定服务(例如,Web 服务器,PHP 后端或数据库服务器)是否已启动并且可以运行。

    如果节点上的服务未通过配置的运行状况检查次数,keepalived 则将虚拟 IP 地址从主(主动)节点重新分配给备用(被动)节点。

3.7.3 NGINX 负载均衡策略

:heavy_check_mark:选型结果:

负载均衡策略: RR(轮询, 默认策略)

会话保持策略: (非必须)

  • 不需要会话保持, 则不进行配置.
  • 需要根据源地址进行会话保持: ip_hash

NGINX负载均衡策略:

  1. 轮询调度算法: rr (默认调度算法).
  2. 加权循环调度算法: wrr. 适用场景: nginx服务器性能不相同, 性能高的需要负载更多请求.
  3. 最小的连接数: least_conn
  4. 会话保持策略:
    1. IP会话保持: ip_hash
    2. hash - 指定服务器组的负载均衡方法,其中客户机-服务器映射基于hash 值。key可以包含文本、变量及其组合。

选型过程:

负载均衡策略,根据实际情况按需选择,无特殊要求的情况下选择 rr 即可。 会话保持策略, 需要根据特定的场景进行选择:

  • 不需要会话保持, 则不进行配置.
  • 需要根据源地址进行会话保持: ip_hash
  • 需要进行 cookie 会话保持: sticky
  • 源地址会话保持和 cookie 会话保持均无法满足需求, 则可能需要通过 hash 来定制会话保持策略.

3.7.3 应用服务层 -> 数据库层高可用选型

略.

由于应用系统的多样性, 本文不对应用服务层 -> 数据库层高可用选型做约束. 仅提供顶层架构要求:

  1. 数据库: 主从同步, 读写分离
  2. 应用:
    1. 实现数据库连接池功能. 可以配置多个数据库连接.
    2. 根据应用功能模块的重要性进行横向拆封. 将: 报表, 数据统计, 批处理类功能与低延迟重要业务功能剥离开来.

参考文件

参考文件
Availability - Wikipedia
High Availability - Wikipedia
system-design-primer - GitHub
High Availability Support for NGINX
Usage of web servers broken down by ranking

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode HOT 100 —— 312.戳气球

题目 有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。 现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i 1] 枚硬币。 这里的 i - 1 和 i 1 代表和 i…

别只关注chatGPT能不能写论文了,它还支持49中场景,代码都给你写好了,速领

简介 chatGPT最近非常不稳定,访问一不小心就出现了网络错误,根本就不能很好的使用。那么我们该怎么办呢?勇哥给大家想到了一个种办法,就是用程序去调用openapi的接口,这个接口虽然是收费的,但是可免费使用…

linux下源码编译cloudcompare(解决无法加载pcd文件的问题)

cloudcompare是一款点云处理软件,里面有很多算法,值得大家学习研究。 下面介绍linux下源码编译cloudcompare的方法。 1.安装依赖: sudo apt-get install doxygen sudo apt install cmake-curses-gui2.下载: git clone --recurs…

Qt之天气预报——界面优化篇(含源码+注释)

一、界面优化效果 下方为界面优化完成和优化前的效果对比。 优化前: 优化后: 二、优化内容 添加标题栏添加图片(图图标素材源自阿里巴巴矢量图标库)更新UI内容(微调大小、布局比例)添加鼠标事件函数&…

Java 教程

Java 教程 Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言。 Java 可运行于多个平台,如 Windows, Mac OS 及其他多种 UNIX 版本的系统。 本教程通过简单的实例将让大家更好的了解 Java 编程语言。 移动操作系统 Android 大部分的代码采用…

RepVGG:一个结构重参数化网络

本文来自公众号“AI大道理” ResNet、DenseNet 等复杂的多分支网络可以增强模型的表征能力,使得训练效果更好。但是多分支的结构在推理的时候效率严重不足。 看起来二则不可兼得。 能否两全其美? RepVGG通过结构重参数化的方法,在训练的时候…

2022 年 Kubernetes 高危漏洞盘点

2022 年,Kubernetes继续巩固自己作为关键基础设施领域的地位。从小型到大型组织,它已成为广受欢迎的选择。出于显而易见的原因,这种转变使 Kubernetes 更容易受到攻击。但这还没有结束,开发人员通常将Kubernetes 部署与其他云原生…

【2022.12.18】备战春招Day13——每日一题 + 234. 回文链表 + 139. 单词拆分

【每日一题】1703. 得到连续 K 个 1 的最少相邻交换次数 题目描述 给你一个整数数组 nums 和一个整数 k 。 nums 仅包含 0 和 1 。每一次移动,你可以选择 相邻 两个数字并将它们交换。 请你返回使 nums 中包含 k 个 连续 1 的 最少 交换次数 输入:nums …

【数据结构】堆(二)——堆排序、TOP-K问题

作者:一个喜欢猫咪的的程序员 专栏:《数据结构》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 目录 堆排序:(以小堆为例) Heapsort函数…

C语言重点解剖关键字要点速记

1.在windows中,双击的本质是运行该程序,就是将程序(.exe)加载到内存当中去。任何程序在被运行之前都必须加载到内存当中去。 2.所有的变量本质都是在内存的某个位置开辟的。变量不能定义在硬盘上,因为变量必须在程序运行的时候才能被开辟&am…

SPRING-了解1

1)最终address: 查找路径比较长,很有趣 JFrog 原始步骤1)进入 spring.io,点击右上角黑色标记边的标记 2)进入 git,找到 Binaries下面的 Spring Framework Artifacts 3)进一步找到Downlaoding a Distribution,下面有 https://repo.spring.io 4)x选择…

牛客SQL每日一题之SQL136 每类试卷得分前3名

文章目录SQL136 每类试卷得分前3名描述示例1输入:输出:答案SQL136 每类试卷得分前3名 描述 现有试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间)&#x…

C# 中的 Infinity 和 NaN

C# 语言中,对于 int,long 和 decimal 类型的数,任何数除以 0 所得的结果是无穷大,不在 int,long 和 decimal 类型的范围之内,所以计算 6/0 之类的表达式会出错。 但是,double 和 float 类型实际…

Java入门笔记补充

Java基础笔记补充数据类型数据类型整形拓展浮点型拓展字符型拓展类型转换变量变量作用域局部变量实例变量静态变量变量的命名规范数组三种初始化静态初始化动态初始化数组的默认初始化Arrays类内存分析栈 stack:堆 heap:方法区(也是堆):封装继…

卷积神经网络 图像处理,卷积神经网络图片处理

1、在做图像处理时,如何提高识别算法的设计与效果的精度? 得到更多的数据 这无疑是最简单的解决办法,深度学习模型的强大程度取决于你带来的数据。增加验证准确性的最简单方法之一是添加更多数据。如果您没有很多训练实例,这将特…

AllegroBGA如何自动fanout操作指导

AllegroBGA如何自动fanout操作指导 当我们需要给BGA做fanout的时候,逐个pin去fanout是件比较麻烦的事情,下面介绍Allegro中如何自动fanout,以下图BGA为例 具体操作如下 选择Route-Create Fanout 选择Via类型,比如Via10 Via Direction BGA Quadrant Style Pin-via Space…

数字化母婴店,母婴智慧会员管理小程序

会员店想必很多小伙伴都接触过或有所耳闻,会员店的本质是通过好产品、好服务及好内容营造出完整且完美的用户消费体验,虽然纯会员店并不多,但如今越来越多的各行业商家意识到每个流量用户都很重要,需要维护好每个用户,…

18.Django大型项目之用户中心页面

1. 用户中心的搭建 1.1 基础搭建 这里,主要就是基础的页面渲染,使用的也是继承主模板,对其进行修改的方式。就直接看代码吧 1.2 上下文的应用 什么是上下文? 对于上下文,可以理解成一个公用的函数或者类 我们这里使…

Qt使用MSVC2015找不到编译器的解决办法

Qt使用MSVC2015找不到编译器的解决办法 1、问题描述 安装qt前,已安装vscode,构建套件MSVC2015 32/64bit出现红色感叹号,并报错构建套件中未设置编译器 2、解决办法 step1:通过windows SDK工具安装调试器。 工具下载地址:https:/…

244. 谜一样的牛——二分+树状数组

有 n 头奶牛,已知它们的身高为 1∼n 且各不相同,但不知道每头奶牛的具体身高。 现在这 n 头奶牛站成一列,已知第 i 头牛前面有 Ai 头牛比它低,求每头奶牛的身高。 输入格式 第 1 行:输入整数 n。 第 2…n 行&#x…