进行web开发时应该考虑的架构性因素

功能实现前端

  这个自没必要说。web

 

性能与可伸缩性redis

  根据预期的访问量,评估机器负载状况。若是在可预期的将来一台服务器能够撑得住,则不必使用多台服务器。须要对多个环节进行性能评估:web服务器、逻辑服务器、DB等等。同时每一个环节均可以考虑是否须要缓存。sql

  在web服务器层面,有一个重要的点,即系统的 URL 选择。首先,要尽最大可能避免访问量差异很大的系统共用一个域名。由于随着系统的发展,颇有可能须要对访问量大的系统进行扩容。扩容引入分流机制。若是这两个系统共用同一个域名,且 URL 的区分度不高,会对分流机制形成很大的障碍。虽说有些系统或模块(或页面)的 URL 相对可变,可是对于开放给外部(尤为是公司外部)访问的 URL 来讲,变动是不可能的。这种类型的 URL 本质上是 API。这又牵扯到另一个主题:《API 设计》。这里暂且 pass。数据库

  在逻辑服务器层面,切记读写分离,若是预计系统不须要多台服务器,也该为读写分离留下后路。还有一点须要关注的是,不一样的服务之间互相访问,不要直接以 ip:端口 的形式,而尽可能以域名的方式。若是是用前者,后期扩容时,也能够引入虚拟 ip 补救。设计模式

  在 DB 层面,考虑是否须要引入 memcache 或 redis 之类的缓存。考虑是否须要作 M-S。另外,考虑 DB 层是直接对上层暴露 ip 端口,仍是引入一个抽象层(如虚拟 ip)。再者,作库表设计时,考虑是否应该分库、分表。浏览器

  在引入了多服务器架构以后,随之而来的是数据同步与合并问题。好比,A 服务器上产生了一张图片,可能须要把它同步到 B 服务器上。或者数据库须要作 M-S 同步。须要合并的,最典型是日志。若是日志分散在许多台机器上,定位问题和分析日志都显得很是麻烦,须要有一种合并机制。还有一个也是很重要的点,即 session 的合并。同一个用户,可能第一次请求到 A 服务器上,下一次请求到 B 服务器上,如何使这两台机器能共享一个 session,是一个须要解决的问题。一个解决方案是使用 redis 存储会话信息。缓存

  在多服务器架构下,动态脚本和静态文件分离是一个比较好的经验。这里的分离指使用不一样的域名,代码文件放在不一样的机器上。这是由于动态脚本和静态文件的性能属性差异比较大。将它们分开能够对它们使用不一样的部署策略。例如,静态文件能够更有效地利用浏览器缓存。安全

 

可用性服务器

  可用性这个方面,有不少与上一个重叠的地方,由于都涉及到多服务器。他们之间的区别是:可伸缩性考虑的是系统能不能撑得住很大的访问量,以及当访问量意外性的出现暴增时,系统可否快速提高自身的处理能力来进行响应。而可用性关注的问题是:这个服务的重要性如何?若是特别重要,怎么保证它不会挂?

  提高可用性的经常使用手段之一是引入冗余灾备措施。一样涵盖上面提到的那几个环节。若是要引入冗余,切记重点关注两个问题:1,单点故障;2,跨机房。

  单点故障。假设把架构设计成:前端两台 web 服务器,域名经过 dns 解析到这两台机器上,逻辑服务器也两台,可是 DB 只有一台。那么 DB 这个环节就是一个单点。若是 DB 服务器挂掉,整个系统都会挂掉。前面设计了两台 web 服务器和两台逻辑服务器都没有任何意义。

  而后说一下跨机房。跨机房是一个很大的挑战,除非十分必要,不然尽可能不要使用跨机房架构。由于一般状况下,咱们几乎不可能把全部的服务都在两个地方部署一份。99.99% 会出现这样的状况:部署了跨机房的系统,须要访问另一个只在一个机房有部署的服务。这个时候,其中一个机房必须经过通道访问另一个机房。这样,两个机房就不是彻底同样的了。此外,两个机房的数据、日志等都须要同步、合并。这些都会使运维的难度大大提升。

  除了冗余以外,考虑可用性,还应想到监控措施。监控有多种方法。经常使用的方法有:

  1,日志或数据分析。服务器上后台跑进程,不停地对日志或类日志的数据进行分析,一旦发生异常,报警。

  2,代码中植入对服务或接口的监控。当用代码访问一个服务时,检查其响应。若是响应异常,报警。

  3,心跳式轮询检测。每隔一段时间向服务发送特殊的请求,检查其响应。若是响应异常,报警。

  4,服务器负载监控。例如 CPU、内存、硬盘、IO、cgi 进程数等等。有些状况下这些工做有运维工程师去作。

  5,代码中植入对响应时间的统计,并另起后台进程,对响应时间进行监控。

  其中,一、二、四、5是系统内部的监控,3是系统外部监控。系统内部监控能够更加细致,能监控到一些外部监控不到的东西。可是,一旦系统自己挂掉(例如服务器挂了),内部监控也会失效。

 

可扩展性

  这个方面涉及到软件的逻辑架构,更多的与业务相关。考虑可扩展性的目的是为了应对需求变动。这要求首先对需求有较深刻的了解,而且可以大体把握到需求变动的方向。这以后,在代码结构层面,为预期的变动方向留下空间。要求设计者具备很是丰富的编码经验和对设计模式有深入的理解。

 

可调试性

  这个方面容易被忽略,倒是很是重要的一环。web 系统的部署环境和交互流程愈来愈复杂,有时候定位一个线上问题很是困难。一般是开发环境没法重现,同时又得到不到足够的信息进行定位。所以这个因素应该在系统设计时就考虑进去:当出现问题时,如何方便地进行定位和调试?这里分服务端和页面两个部分考虑。

  日志没必要说,是重要的信息来源。服务端写日志,须要对日志进行有效的组织(这里也是一门学问)。

  另外,服务端须要注意的一点,是统一的错误码处理。错误码管理混乱会影响问题的定位。最好的状况是,错误码分得很细,而且保证绝对无重复。这样,开发一拿到错误码,马上就能大概判断出问题所在。

  再者,服务端,可能须要备好调试工具。能够理解为后门,可是只有通过受权才能使用。

  前端写不了日志是个大问题,须要另寻途径把错误信息拿到手。最差的方法是牺牲部分用户体验,把错误码以某种方式展现出来,而后经过询问用户来得到错误码。这种方式不建议使用。更好的作法是,在前端搜集错误信息,而后经过接口上报到服务器进行存储。

 

可测试性

  可测试性和可调试性的区别是什么?可调试性考虑的问题是:系统上线运行以后,如何快速定位并处理线上出现的问题;可测试性考虑的问题是:测试人员怎么测这个系统。

  在开发以前就考虑测试,一来是未雨绸缪,为未来的测试阶段提供便利;二来有利于提升代码质量。关于这一点,实践过TDD的人都心照不宣。

 

安全

  安全的重要性再怎么强调都不为过。xss、csrf、sql注入、敏感信息泄露、刷接口、重放等等等等。安全领域涉及到的东西不少。

 

数据统计与后台

  考虑系统是否须要后台管理、是否须要收集数据进行统计分析,这些都会影响到系统的设计。后台管理者一般在通过受权以后会获得高权限,所以系统设计上须要区分角色。而数据的收集容易致使所谓的“霰弹式修改”,引发系统的快速腐烂。

相关文章
相关标签/搜索