常见应用扩展方案(二)
仔细想想确实有点憋屈,那么多软件都放一个服务器,都这么多用户了老板也赚了不少钱,加服务器!
负载均衡
先加两台服务器。分别给cache,和DB各准备一台服务器
故障转移
这样加服务器虽然可以分别对它们进行扩展,但目前的实际效果只是让cache和DB使用到了更多的服务器资源,再加一台!现在我们又增加了一台web服务器,还增加了一个负载均衡器。
用户可以直接通过公共IP连接负载均衡器,然后负载均衡器通过私有IP分配网络请求,为了提高安全性服务器之间通信使用私有IP,在公网中无法访问。
再来看看我们的应用:
- 假如一台server宕机或者压力太大出现问题,所有请求都会被负载均衡器分配到另一台服务器上,避免当前网站不可用。
- 如果流量还是很大,这时候我们只需要继续增加server,继续分配私有IP给新的服务器即可,这样扩展起来非常容易。
主从数据库
NoSQL
先说一下我们的缓存Cache,它作用我们都知道了,在web服务和关系型数据库缓存一些数据,这种策略叫做缓存读(Read-through Cache),并且缓存通常会用NoSQL数据库,这种数据库操作非常简单,它们都会有get和put方法的API,就像操作hashMap一样。
1 | cache.put("key","value") |
读写分离
在我们的系统中,单一的东西就意味着有风险,可提升。回过头看一下我们的应用架构,现在还有cache和DB是单独的系统,那么我们就用最常见的主从分库方法,分别对cache和DB进行增强。这里cache使用Redis,DB使用MySQL。
主库通常只支持写操作,从库提供读操作,并且会保存主库中的数据。多数场景中读操作会多于写操作,所以从库一般都会有多个。下图展示了MySQL和Redis的主从形式
主从特点
- 更好的性能:读写分离后,多个从库可以让系统并行的处理更多请求,从而提升系统的性能
- 高可用:多个从库都复制了系统数据,如果有一台数据库服务宕机,我们的网站仍然可以正常使用,不会影响到用户
- 高可靠:如果一台数据库服务遭遇自然灾害而损坏,我们的数据也不会丢失,它们已经被复制到其他数据库中
- 从库宕机:如果只有一个从库,那么读操作会被路由到主库,等待新的从库准备好后,转移读操作到新的库。如果有多个从库,那么读操作会被路由到其他从库,然后创建一个新的从库来替代宕机的库
- 主库宕机:会有一个从库被选为主库。如果有多个从库那么到底选哪一个作为主库,不同的数据库有不同的算法。这里还涉及到数据恢复的问题,因为主库宕机时可能有部分数据还未同步到从库中,这是就需要数据恢复脚本来补全这部分数据。
现在来看一下我们的系统,这里为了减少系统复杂度没有对cache进行分库,但是之前的描述如果需要cache也可以分库。
内容分发网络
内容分发网络(Content Delivery Network,CDN)是一种通过在全球范围内分布式部署服务器来加速和优化对互联网内容的传输的网络架构。CDN 可以加速网站、移动应用、流媒体和其他互联网服务的内容传输,提高访问速度、降低延迟和减少网络拥塞,从而改善用户体验。
CDN 的主要功能包括:
- 内容缓存:CDN 服务器会缓存网站的静态内容,如图片、视频、CSS 文件等。当用户请求这些内容时,CDN 会根据用户的地理位置和网络条件,从离用户最近的服务器上提供所需内容,加快内容传输速度。
- 负载均衡:CDN 可以根据用户的地理位置和网络状况,将用户请求分发到最优的服务器上,从而分散服务器负载,提高系统的整体性能。
- 安全防护:CDN 可以提供基本的安全防护功能,如 DDoS 攻击防护、网站安全加固等,保护源服务器免受恶意攻击。
- 流媒体加速:CDN 可以加速流媒体内容(如音频、视频)的传输,提供更流畅的观看体验。
- 即时刷新:CDN 可以在源服务器内容更新后,快速将更新内容同步到各个 CDN 节点,确保用户获取最新的内容。
CDN是一个非常强大的网络架构,目前我们只讨论用它来做静态资源的缓存。CDN就像是在网络架构中增加了一层缓存,CDN 的工作原理是将内容缓存复制到位于全球各地的多个服务器节点上,用户请求内容时,CDN 会根据用户的地理位置和网络状况,将内容从离用户最近的服务器节点传输给用户,从而实现加速传输和优化网络性能的目的。通过 CDN,网站和服务提供商可以更快地将内容传输给用户,并且能够更好地应对突发的高流量情况。
使用CDN需要注意的问题:
- 选择合适的 CDN 服务提供商:市场上有很多不同的 CDN 服务提供商,选择合适的供应商至关重要。考虑到您的需求,可以比较不同供应商的服务特点、价格、地理分布和可用性等因素。
- 配置正确的缓存策略:CDN 服务器会缓存您的内容,但需要确保正确配置缓存策略。根据不同类型的内容,设置合适的缓存时间和缓存规则,以确保用户得到最新的内容,同时减少对源服务器的请求负载。
- 注意缓存失效和更新:当您的内容发生更改时,需要及时通知 CDN 更新缓存。CDN 提供商通常提供刷新缓存的接口或工具,以便您手动刷新缓存或设置自动刷新机制。
- 监控和分析:使用 CDN 后,您需要监控和分析 CDN 的性能和效果。关注关键指标如响应时间、带宽使用率、缓存命中率等,以便及时发现和解决问题,并调整 CDN 配置以优化性能。
- 安全性考虑:使用 CDN 时,确保 CDN 提供商具备良好的安全防护措施,以保护您的内容免受恶意攻击。此外,您可能需要采取额外的安全措施,如使用 HTTPS 加密传输、设置访问控制策略等。
- 地理分布和网络覆盖:考虑您的目标用户所在的地理位置和网络环境,选择具有足够广泛的网络覆盖和节点分布的 CDN 提供商。这将有助于实现更好的访问速度和性能。
使用 CDN 需要综合考虑性能、安全、成本等多个方面的因素。良好的配置和监控是确保 CDN 正常运行并提供最佳性能的关键。
现在我们系统的静态资源(JS、CSS、图片等)由CDN提供,进一步提升了系统性能,增加CDN后系统架构如下:
有状态和无状态网络层
架构设计之“无状态”和“有状态”浅析 - 掘金 (juejin.cn)
有状态服务
服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,来自相同发起者的请求在服务器端是否具备上下文关系,典型的设计如 tomcat 中的 session。
例如登录:用户登录后,我们把登录者的信息保存在服务端 session 中,并且给用户一个 cookie 值,记录对应的 session。然后下次请求,用户携带 cookie 值来,我们就能识别到对应 session,从而找到用户的信息。
如果是状态化请求,那么服务器端一般都要保存请求的相关信息,每个请求可以默认地使用以前的请求信息。
有状态的缺点:
- 服务端保存大量数据,增加服务端压力
- 服务端保存用户状态,无法进行水平扩展
- 客户端请求依赖服务端,多次请求必须访问同一台服务器
无状态服务
服务器端的处理信息必须全部来自于请求所携带的信息以及可以被所有请求所使用的公共信息。
用户的HTTP请求可以发给任意Web服务器,然后Web服务器从共享的数据存储中拉取数据。状态数据存储在共享数据存储而非Web服务器中。无状态的系统更加简单,更健壮,也更容易扩展。
现在多个服务器都使用Redis保存状态数据
消息队列
消息队列是一个持久化组件,它的作用可以参考外卖柜、菜鸟驿站。
它的实际作用通常有三种:流量消峰、应用解耦、异步处理。工作原理就是输入消息任务,存储消息任务,输出消息任务,在此基础上衍生出了各种额外功能,比如消息的多种订阅模式,消息确认机制,消息重发等。
其中应用解耦是消息队列成为构建可扩展和可靠应用的首选架构。消费者没时间处理时就放在队列中,有时间处理再去处理。
记录日志、收集指标和自动化
当我们的网站服务还比较简单时,记录日志、自动化这些功能的使用成本较高,并不值得我们接入。但是当网站使用人数变多,服务数量增加后,这些工作是必须要做的。
记录日志:可以用一个日志服务统一处理所有服务的日志,方便查看和搜索,这些日志可以帮助我们识别系统的错误和问题。
收集指标:对日志分类,这样更有助于我们了解系统状态和服务使用情况
- 主机级别指标:CPU、内存、IO等
- 聚合级别指标:数据库使用情况、缓存使用情况等
- 关键业务指标:用户活跃数、点击量、访问量等
自动化:当系统变得庞大而复杂时自动化的优势就能体现出来,通过自动化工具自动构建、测试和部署,它可以极大的提高生产力。
数据中心
这时候你的网站访问量峰值以达到百万,拥有几十台服务器,并且吸引了非常多的国际用户时,可以在各个地区建立数据中心,通过在不同地区设置数据中心,可以避免单个数据中心故障,提高应用的可用性和用户体验。
《搞定系统设计》