原文:Web应用扩展系列(1):架构篇

在这篇文章中,我将尽量涵盖Web应用扩展或性能调优时可能会遇到的一些架构问题。

首先,让我们来统一一些名词或项目的概念,下文中我将列举在扩展Web应用时可能会遇到的多种问题,包括:

  • 架构瓶颈
  • 数据库扩展
  • CPU依赖的应用
  • IO依赖的应用

而如何确定优化Web应用线程池大小的内容将会在下一篇文章中给出。

性能(performance)这个词对于Web应用来说通常意味着一些指标,对于大部分的开发者而言,他们主要关心的是响应时间(response time)以及扩展性(scalability)。

  • 响应时间

响应时间指的是自Web应用接收到请求到其返回所用的时间。应用的响应时间应该控制在合理的范围之内,如果一个应用的相应时间超出了可接受的时间范围,那么这个应用就不是一个好的应用。

  • 扩展性

如果一个应用在增加资源的情况下,其服务请求的能力能够按线性增长,那么这个应用就可以说是可扩展的。有两种增加资源的模式:

    • 纵向扩展(Scaling Up) :- 在单个服务单元增加计算能力数量或计算能力性能。
    • 横向扩展(Scaling Out) :- 增加更多的服务单元。

横向扩展 vs 纵向扩展

横向扩展考虑的是发挥相对廉价的硬件数量优势,以取代某些需要特别购置的昂贵设备(比如超算)。但是,在单个廉价硬件单元上提升一个服务所能响应的请求数也同样重要。我们说一个应用的性能优异是指它能够在不延长响应时间的情况下通过增加更多的资源而处理更多的请求。

响应时间 vs 扩展性

响应时间和扩展性不会都朝着你所希望的方向变化。举个例子,有些应用可能有不错的响应时间,但是只能处理一定数量的请求;而其他有些应用能够处理不断增长的请求,但却需要消耗比较长的时间。所以我们必须要在这两者之间做出平衡以得到最好的应用性能。

能力规划

能力规划(capacity planning)是弄清产品需要多少硬件资源以处理期望的负载的一种活动。通常它涉及到弄清应用产品性能的极限,即基于更少的服务单元最多能响应多少请求以及单个服务单元的性能。最终,通过负载性能测试来进行验证。

可扩展架构

如果一个应用是多层次架构,并且在每个层次上都是可扩展的(横向扩展),那么这个应用的架构就说是具有扩展性的。举个例子:如下图所示,我们可以在应用层或数据库层线性地增加额外的计算单元。

扩展负载均衡器

负载均衡器能够通过指定DNS到多个IP地址,或是使用DNS轮询的办法进行扩展。还有一种方法是使用分级的的负载均衡器,由前端负载均衡器将请求分发到下一级的负载均衡器。

增加多个负载均衡器对使用nginx或HAProxy的单个计算单元来说是十分罕见的,这类强大的软件能够在单个单元上同时处理超过两万个并发连接,这比其他的web应用容器要强大得多。所以通过它们单个的负载均衡单元能够处理多个web应用单元的请求。

扩展数据库

数据库的扩展是一种最常见的扩展问题。在数据库层中增加额外的业务(存储过程或函数)会带来额外的负担和复杂性。

关系型数据库

关系型数据库可以通过主-从模式进行扩展,这样做可以实现读写分离,即主库负责读写,而从库负责读。主-从模式提供了读的有限扩展,除此之外,开发者们通常将数据库进行划分来进行横向扩展。

NoSQL

CAP理论说得明白,不可能同时满足一致性、可用性以及分区容错性。NoSQL数据库通常牺牲一致性来获取高可用及分区容错性。

数据库划分

数据库的划分可以采用纵向划分(分区)或横向划分(分片)的模式。

  • 纵向划分(分区):数据库能够基于领域概念而被划分成为多个松散的子库。举个例子,客户数据库、产品数据库诸如此类。还可以将一个实体少量的列移动到不同的数据库中。比如客户数据库、客户联系方式数据库以及客户订单数据库。
  • 横向划分(分片):数据库能够基于一些离散的属性被横向的划分为多个库。比如美国客户数据库、欧洲客户数据库等。

使用分区或分片,将数据库从单库模式转换到多库模式是一项具有挑战性的工作。

架构瓶颈

扩展的瓶颈主要因为两个问题而存在:

  • 中心化组件:应用架构中的某个组件,它不能够通过增加整个架构或请求通道处理的请求数量上限来进行横向扩展。
  • 高延迟组件:一个速度较慢的组件,拉低了应用请求通道响应时间的下界。通常的解决方式是将此类高延迟组件作为后台任务执行,或是异步地使用队列的方法来执行。

CPU密集型应用

如果一个应用的吞吐量被CPU所限制,那么我们称这个应用为CPU密集型应用(CPU Bound Application)。通过增加CPU的运行速度,可以使应用的响应时间减少。

一些可能的CPU密集型应用场景:

  • 应用是用来计算或处理数据的,而不会发生IO操作(金融或交易应用)
  • 应用严重依赖缓存,而不会产生IO操作
  • 应用是异步的(非阻塞式),不需要等待外部资源(被动模式的应用,NodeJS应用)

在上面提到的场景中,应用已经在高效的运行了,不过有少数应用实例可能是因为代码层面的原因,发生了一些完全不必要的操作去计算或轮询每个请求,进而使CPU利用率很高。通过分析可以很容易的发现低效之处并作出改进。

这些问题可以通过以下方式解决:

  • 缓存住先前的计算结果
  • 在互相分离的后台任务中运行计算

使用不同的方式进行缓存,缓存如何能够减少负载以提升效能和web应用的扩展性在接下来的博文中会有有详述。

IO密集型应用

如果一个应用的吞吐量被IO或网络能力所限制,无法通过增加CPU速度的方法带来应用性能提升的话,那么这个应用就被称为IO密集型应用(IO Bound Application)。大部分的应用都是IO密集型应用,因为大部分应用都依赖于CURD操作,在这些应用中提升性能或扩展都是一件很困难的事情因为 它严重依赖于其他的下游系统。

下面一些是可能的IO密集型应用场景:

  • 应用依赖于数据库与大量的CRUD操作
  • 应用使用web服务来完成它自身的操作

下篇博文将会聊聊如何优化设置Web应用的线程池大小。

Web应用扩展系列(1):架构篇(转)的更多相关文章

  1. web开发性能优化---项目架构篇

    项目技术架构层级规划和介绍 简称四横两纵 四横即四大层次.分别为: 1.用户渠道层:用户渠道层是直接面向终于用户.通过站点的形式向用户提供产品展示.企业市场宣传.对产品的订购.互动分享.客户关怀以及用 ...

  2. 【目录】mysql 架构篇系列

    随笔分类 - mysql 架构篇系列 mysql 架构篇系列 4 复制架构一主一从搭建(半同步复制) 摘要: 一.概述 在mysql 5.5之前,mysql 的复制是异步操作,主库和从库的数据之间存在 ...

  3. 【Java探索道路安全系列:Java可扩展的安全架构】一间:Java可扩展的安全体系结构开始

    笔者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...

  4. 构建安全的Xml Web Service系列之SSL篇

    原文:构建安全的Xml Web Service系列之SSL篇 首先介绍一下SSL, SSL 的英文全称是 "Secure Sockets Layer" ,中文名为 "安全 ...

  5. mysql 架构篇系列 3 复制运行状态监控与选项参数说明

    一. 概述 在上一篇中,搭建了一主一从的复制架构,这篇通过一些诊断方法来了解复制的运行状态和一些选项参数说明.上次mysql主从服务关机,今天在打开mysql服务,出现了错误信息. 1.首先 启动主从 ...

  6. web前端知识大纲:系列一 js篇

    web前端庞大而复杂的知识体系的组成:html.css和 javascript           一.js           1.基础语法 Javascript 基础语法包括:变量声明.数据类型. ...

  7. 【目录】sql server 架构篇系列

    随笔分类 - sql server 架构篇系列 sql server 高可用镜像 摘要: 一.什么是数据库镜像 基本软件的高可用性解决方案 快速的故障转移恢复(3秒转移),低硬件成本 基于数据库级别的 ...

  8. mysql 架构篇系列 2 复制架构一主一从搭建(异步复制)

    一. 环境准备 1.1 主库环境(172.168.18.201) 环境 说明 查看脚本 操作系统版本 CentOS Linux release 7.4.1708 (Core) cat /etc/red ...

  9. Webpack系列-第三篇流程杂记

    系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节 ...

随机推荐

  1. sql 记录

    INSERT INTO B([name],[info]) SELECT [name,'10'] FROM A 级联更新1:update tb1, tb2 set tb1.a=tb2.a,tb1.b=t ...

  2. linux udhcpc 后无法自动设置网卡ip

    arm 主板用 udhcpc 获取租赁的空闲的ip后,并没有直接设置在网卡上. 查了一下相关原因,是因为虽然已经获取了ip, 但是并没有通过脚本去设置这个IP. 在 busybox 里面有相关的脚本要 ...

  3. 打印-print.js

    //打印开始// strPrintName 打印任务名// printDatagrid 要打印的datagridfunction CreateFormPage(ctx,strPrintName, pr ...

  4. unity导弹算法 预计目标点

    关于导弹的飞行算法,网上有很多教程.简单算法无非是获取目标点的当前位置,然后导弹朝目标方向移动.高深点的,就是通过计算获取碰撞点然后朝着目标移动.如果你能看懂这个高深算法的话,可以去看原帖:http: ...

  5. Java各种日期格式的获取和设置指定日期

    因为近期在做一个项目,发现项目中日期设置的bug,于是查阅了多方资料后.最终攻克了,为此写篇总结.方便日后的查阅. 多的不说了.直接上代码 package com.example.testdate; ...

  6. WebService远程调用(命令行调用)

    远程调用webservice 方法, 通过wsdl命令,生成webservice 对应asmx 文件的对应类(cs文件),然后将此cs文件引用到当前项目中,项目其他地方需要调用webservice方法 ...

  7. 高级service之ipc ADIL用法

    感谢 如果你还没有看过前面一篇文章,建议先去阅读一下 Android Service完全解析,关于服务你所需知道的一切(上) ,因为本篇文章中涉及到的代码是在上篇文章的基础上进行修改的. 在上篇文章中 ...

  8. springboot tomcat的使用

    使用自带的tomcat 以java 项目启动: 默认端口号为8080       1.必须导入此包       2.有启动类

  9. 5个基于Linux命令行的文件下载和网站浏览工具

    导读 命令行是GNU/Linux中最神奇迷人的部分,它是非常强大的工具;命令行本身功能多样,多种内建或者第三方的命令行应用使得Linux变得更加健壮和强大.Linux Shell支持多种不同类型的网络 ...

  10. ASP.NET操作Excel(终极方法NPOI)

    ASP.NET操作Excel已经是老生长谈的事情了,可下面我说的这个NPOI操作Excel,应该是最好的方案了,没有之一,能够帮助开发者在没有安装微软Office的情况下读写Office 97-200 ...