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):架构篇(转)的更多相关文章
- web开发性能优化---项目架构篇
项目技术架构层级规划和介绍 简称四横两纵 四横即四大层次.分别为: 1.用户渠道层:用户渠道层是直接面向终于用户.通过站点的形式向用户提供产品展示.企业市场宣传.对产品的订购.互动分享.客户关怀以及用 ...
- 【目录】mysql 架构篇系列
随笔分类 - mysql 架构篇系列 mysql 架构篇系列 4 复制架构一主一从搭建(半同步复制) 摘要: 一.概述 在mysql 5.5之前,mysql 的复制是异步操作,主库和从库的数据之间存在 ...
- 【Java探索道路安全系列:Java可扩展的安全架构】一间:Java可扩展的安全体系结构开始
笔者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...
- 构建安全的Xml Web Service系列之SSL篇
原文:构建安全的Xml Web Service系列之SSL篇 首先介绍一下SSL, SSL 的英文全称是 "Secure Sockets Layer" ,中文名为 "安全 ...
- mysql 架构篇系列 3 复制运行状态监控与选项参数说明
一. 概述 在上一篇中,搭建了一主一从的复制架构,这篇通过一些诊断方法来了解复制的运行状态和一些选项参数说明.上次mysql主从服务关机,今天在打开mysql服务,出现了错误信息. 1.首先 启动主从 ...
- web前端知识大纲:系列一 js篇
web前端庞大而复杂的知识体系的组成:html.css和 javascript 一.js 1.基础语法 Javascript 基础语法包括:变量声明.数据类型. ...
- 【目录】sql server 架构篇系列
随笔分类 - sql server 架构篇系列 sql server 高可用镜像 摘要: 一.什么是数据库镜像 基本软件的高可用性解决方案 快速的故障转移恢复(3秒转移),低硬件成本 基于数据库级别的 ...
- mysql 架构篇系列 2 复制架构一主一从搭建(异步复制)
一. 环境准备 1.1 主库环境(172.168.18.201) 环境 说明 查看脚本 操作系统版本 CentOS Linux release 7.4.1708 (Core) cat /etc/red ...
- Webpack系列-第三篇流程杂记
系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节 ...
随机推荐
- PHP面对对象总结
一个关于面对对象知识的问答总计:https://wenku.baidu.com/view/391eeec483c4bb4cf6ecd1ad.html 面对对象的三大特征: 1.封装 为了保护类封装了之 ...
- 大数据(10) - HBase的安装与使用
HBaes介绍 HBase是什么? 数据库 非关系型数据库(Not-Only-SQL) NoSQL 强依赖于HDFS(基于HDFS) 按照BigTable论文思想开发而来 面向列来存储 可以用来存储: ...
- IOC控制反转
IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”,还有些书籍翻译成为“控制反向”或者“控制倒置”. 1996年,Michael Mattson在一篇有关探讨面 ...
- This表示当前对象
This表示当前对象. Public void printNum(){ Int number=40: System.out.println(this.number); } 此时打印的是实例变量,而非局 ...
- php -- php的事务处理
MYSQL的事务处理主要有两种方法. 1.用begin,rollback,commit来实现 begin 开始一个事务 rollback 事务回滚 commit 事务确认 2.直接用set来改变mys ...
- 【BZOJ】1492: [NOI2007]货币兑换Cash(cdq分治)
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 蒟蒻来学学cdq神算法啊.. 详见论文 陈丹琦<从<Cash>谈一类分治算法 ...
- Android动态禁用或开启屏幕旋转工具
package com.gwtsz.gts2.util; import android.content.Context; import android.provider.Settings; impor ...
- Sokect异步连接发送
客户端 static void Main(string[] args) { Console.WriteLine("this is a Client!"); Socket clien ...
- H5学习之--前端和PHP后端的简单交互
最近在学习前端的东西,H5+CSS3+JS,又分别学习了原生JS和jQuery库,还有Bootstrap框架,因为我是做ios开发的,所以先熟悉WebApp相关的开发知识,其他的学习资料,网上有很多的 ...
- Javascript实现图片的预加载的完整实现
图片预加载是web开发中一种应用相当广泛的技术,比如我们在做图片翻转显示等特效的时候,为了让图片在转换的时候不出现等待,我们最好是先让图片下载到本地,然后在继续执行后续的操作.今天我们将来实现一个完整 ...