《大型网站技术架构》摘要与心得

注:【】部分为笔者心得,非原文摘抄。

  • 大型互联网应用系统有以下特点:
    • 高并发、大流量;
    • 高可用;
    • 海量数据;
    • 用户分布广泛,网络情况复杂;
    • 安全环境恶劣;
    • 需求快速变更,发布频繁;
    • 渐进式发展。
  • 大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据。
  • 网站使用的缓存可以分为两种:缓存在应用服务器上的本地缓存和缓存在专门的分布式缓存服务器上的远程缓存。
  • 当一台服务器的处理能力、存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求。这种情况下,更恰当的做法是增加一台服务器分担原有服务器的访问和存储压力。
  • 网站访问延迟和用户流失率正相关。
  • CDN和反向代理的基本原理都是缓存,区别在于CDN部署在网络提供商的机房,使用户在请求网站服务时,可以从距离自己最近的网络提供商机房获取数据;而反向代理则部署在网站的中心机房,当用户请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,就将其直接返回给用户。
  • 分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才使用,网站更常用的数据库拆分手段是业务分库,将不同业务的数据库部署在不同的物理服务器上。
  • 将共用的业务提取出来,独立部署。由这些可复用的业务连接数据库,提供共用业务服务,而应用系统只需要管理用户界面,通过分布式服务调用共用业务服务完成具体业务操作。
  • 模式的关键在于模式的可复用性,问题与场景的可复用性带来解决方案的可重复使用。
  • 人生不同于软件,精彩的人生绝不会来自于复制。
  • 在网站规模还很小的时候就应该采用分层的架构,这样将来网站做大时才能有更好地应对。
  • 将不同的功能和服务分割开来,包装成高内聚低耦合的模块单元,一方面有助于软件的开发和维护;另一方面,便于不同模块的分布式部署,提高网站的并发处理能力和功能扩展能力。
  • 在网站应用中,常用的分布式方案有以下几种:
    • 分布式应用和服务;
    • 分布式静态资源;
    • 分布式数据和存储;
    • 分布式计算。
  • 缓存是改善软件性能的第一手段。
  • 使用缓存有两个前提条件,一是数据访问热点不均衡,二是数据在某个时段内有效,不会很快过期。
  • 访问和负载很小的服务也必须部署至少两台服务器构成一个集群,其目的就是通过冗余实现服务高可用。数据库除了定期备份,存档保存,实现冷备份外,为了保证在线业务高可用,还需要对数据库进行主从分离,实时同步实现热备份。
  • 许多网站故障出在发布环节,通过减少人为干预,使发布过程自动化可有效减少故障。
  • 网站需要对线上生产环境进行自动化监控,对服务器进行心跳检测,并监控其各项性能指标和应用程序的关键数据指标。如果发现异常、超出预设的阀值,就进行自动化报警。
  • 任何软件架构设计方案都必须考虑可能会带来的性能问题。
  • 网站高可用架构设计的前提是必然会出现服务器宕机,而高可用设计的目标就是当服务器宕机的时候,服务或者应用依然可用。
  • 网站高可用的主要手段是冗余,应用部署在多台服务器上同时提供访问,数据存储在多台服务器上互相备份,任何一台服务器宕机都不会影响应用的整体可用,也不会导致数据丢失。
  • 衡量架构伸缩性的主要标准就是是否可以用多台服务器构建集群,是否容易向集群中添加新的服务器。加入新的服务器后是否可以提供和原来的服务器无差别的服务。集群中可容纳的总的服务器数量是否有限制。
  • 关系数据库的集群伸缩性方案必须在数据库之外实现,通过路由分区等手段将部署有多个数据库的服务器群组成一个集群。
  • 衡量网站架构扩展性好坏的主要标准就是在网站正加新的业务产品时,是否可以实现对现有产品透明无影响,不需要任何改动或者很少改动既有业务功能就可以上线新产品。不同产品之间是否很少耦合,一个产品改动对其它产品无影响,其它产品和功能不需要受牵连进行改动。
  • 网站可扩展架构的主要手段是事件驱动架构和分布式服务。事件驱动架构在网站通常利用消息队列实现,将用户请求和其它业务事件构成消息发布到消息队列,消息的处理者作为消息者从消息队列中获取消息进行处理。分布式服务则是将业务和可复用服务分离出来,通过分布式服务框架调用。
  • 衡量网站安全架构的标准就是针对现存和潜在的各种攻击与窃密手段,是否有可靠的应对策略。
  • 性能、可用性、伸缩性、扩展性和安全性是网站架构最核心的几个要素。
  • 响应时间是系统最重要的性能指标。
  • 在网站产品设计初期,产品经理和运营人员就需要规划不同发展阶段的网站系统用户数,并以此为基础,根据产品特性和运营手段,推算在线用户数和并发用户数。这些指标将成为系统非功能设计的重要依据。
  • 网站性能优化的目的,除了改善用户体验的响应时间,还要尽量提高系统吞吐量,最大限度利用服务器资源。
  • 系统负载(System Load),指当前正在被CPU执行和等待被CPU执行的进程数目总和,是反映系统忙闲程度的重要指标。多核CPU的情况下,完美情况是所有CPU都在使用,没有进程在等待处理,所有Load的理想值是CPU的数目。
  • 性能测试具体可细分为:
    • 性能测试:以系统设计初期规划的性能指标为预期目标,对系统不断施加压力,验证系统在资源可接受范围内,是否能达到性能预期;
    • 负载测试:对系统不断地增加并发请求以增加系统压力,直到系统的某项或多项性能指标达到安全临界值;
    • 压力测试:超过安全负载的情况下,对系统继续施加压力,直到系统崩溃或不能再处理任何请求,以此获得系统最大压力承受能力;
    • 稳定性测试:被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定。
  • 排查一个网站的性能瓶颈和排查一个程序的性能瓶颈的手法基本相同:检查请求处理的各个环节的日志,分析哪个环节响应时间不合理、超过预期;然后检查监控数据,分析影响性能的主要因素是内存、磁盘、网络还是CPU,是代码问题还是架构设计不合理,或者系统资源确实不足。
  • Web前端主要优化手段有优化浏览器访问、使用反向代理、CDN等。
  • 减少HTTP请求数量的主要手段是合并CSS、合并JavaScript、合并图片。
  • 通过设置HTTP头中Cache-Control和Expires的属性,可设定浏览器缓存。
  • 静态资源文件变化需要及时应用到客户端浏览器,可通过改变文件名实现。
  • 使用浏览器缓存策略的网站在更新静态资源时,应采用逐量更新的办法,以免用户浏览器突然大量缓存失效,集中更新缓存,造成服务器负载骤增、网络堵塞的情况。
  • 在服务器端对文件进行压缩,在浏览器端对文件解压缩,可有效减少通信传输的数据量。但是压缩对服务器和浏览器产生一定的压力,在通信带宽良好,而服务器资源不足的情况下要权衡考虑。
  • 浏览器会在下载完全部CSS之后才对整个页面进行渲染,因此最好的做法是将CSS放在页面最上面,让浏览器尽快下载CSS。JavaScript则相反,浏览器在加载JavaScript后立即执行,有可能会阻塞整个页面,造成页面显示缓慢,因此JavaScript最好放在页面最下面。但如果页面解析时就需要用到JavaScript,这时放在底部就不合适了。
  • Cookie包含在每次请求和响应中,太大的Cookie会严重影响数据传输,可以考虑静态资源使用独立域名访问,避免请求静态资源时发送Cookie,减少Cookie传输的次数。
  • CDN部署在网络运营商的机房,这些运营商又是终端用户的网络服务提供商,因此用户请求路由的第一跳就到达了CDN服务器,当CDN中存在浏览器请求的资源时,从CDN直接返回给浏览器,最短路径返回响应,加快用户访问速度,减少数据中心负载压力。
  • CDN能够缓存的一般是静态资源,如图片、文件、CSS、Script脚本、静态网页等。
  • 应用服务器优化手段主要有缓存、集群、异步等。
  • 网站性能优化第一定律:优先考虑使用缓存优化性能。
  • 缓存的本质是一个内存Hash表。
  • 通过HashCode计算Hash表的索引下标,最简单的是余数法:使用Hash表数组长度对HashCode求余,余数即为Hash表索引。
  • 缓存主要用来存放那些读写比较高、很少变化的数据。
  • 通过分布式缓存数据库集群,将缓存数据分布到集群多台服务器上可在一定程度上改善缓存的可用性。当一台缓存服务器宕机的时候,只有部分缓存数据丢失,重新从数据库加载这部分数据不会对数据库产生很大影响。
  • 产品在设计之初就需要一个明确的定位:什么是产品要实现的功能,什么不是产品提供的特性。在产品漫长的生命周期中,会有形形色色的困难和诱惑来改变产品的发展方向。左右摇摆,什么都想做的产品,最后有可能成为一个失去生命力的四不像。
  • 将不存在(其value为null)的数据也缓存起来。
  • 分布式缓存架构方式有两种:一种是以JBoss Cache为代表的需要更新同步的分布式缓存;一种是以Memcached为代表的不互相通信的分布式缓存。
  • JBoss Cache的分布式缓存在集群中所有服务器中保存相同的缓存数据,当某台服务器有缓存数据更新的时候,会通知集群中其它机器更新数据或清除缓存数据。这种方案多见于企业应用系统中,而很少在大型网站使用。
  • Memcached采用一种集中式的缓存集群管理,也被称作互不通信的分布式架构方式。缓存与应用分离部署,缓存系统部署在一组专门的服务器上,应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据,缓存服务器之间不通信,缓存集群的规模可以很容易地实现扩容,具有良好的可伸缩性。
  • 集群内服务器互不通信使得集群可以做到几乎无限制的线性伸缩。
  • 消息队列具有很好的削峰作用——即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。
  • 任何可以晚点做的事情都应该晚点再做。
  • 假设服务器上执行的都是相同类型任务,针对该类任务启动的线程数有个简化的估算公式可供参考:
    • 启动线程数=[任务执行时间÷(任务执行时间-IO等待时间)]×CPU内核数
  • 网站故障中,许多所谓偶然发生的“灵异事件”都和多线程并发问题有关。
  • 编程上,解决线程安全的主要手段有如下几点:
    • 将对象设计为无状态对象:所谓无状态对象是指对象本身不存储状态信息(对象无成员变量,或者成员变量也是无状态对象)。不过从面向对象设计的角度看,无状态对象是一种不良设计;
    • 使用局部对象:即在方法内部创建对象,这些对象会被每个进入该方法的线程创建;
    • 并发访问资源时使用锁:但是锁导致线程同步顺序执行,可能会对系统性能产生严重影响。
  • 从编程角度,资源复用主要有两种模式:单例(Singleton)和对象池(Object Pool)。
  • HashCode越随机散列,Hash表的冲突就越少,读写性能也就越高。
  • 技术是为业务服务的,技术选型和架构决策依赖业务乃至企业战略规划,离开业务发展的支撑和驱动,技术走不远,甚至还会迷路。
  • 网站不可用时间(故障时间)=网站修复时间点-故障发现(报告)时间点
  • 网站年度可用性指标=(1-网站不可用时间÷年度总时间)×100%
  • 可用性指标是网站架构设计的重要指标,对外是服务承诺,对内是考核指标。
  • 网站高可用架构设计的主要目的就是保证服务器硬件故障时服务依然可用、数据依然保存并能够访问。主要手段是数据和服务的冗余备份及失效转移。
  • 大型网站的分层架构及物理服务器的分布式部署使得位于不同层次的服务器具有不同的可用性特点。关闭服务或者服务器宕机时产生的影响也不相同,高可用的解决方案也差异甚大。
  • 网站的可用性架构设计不但要考虑实际的硬件故障引起的宕机,还要考虑网站升级发布引起的宕机,而后者更加频繁。
  • 集群环境下,Session管理主要有以下几种手段:
    • Session复制;
    • Session绑定;
    • 利用Cookie记录Session;
    • Session服务器;
  • 可以使用类似负载均衡的失效转移策略实现高可用的服务。除此之外,具体实践中,还有以下几点高可用的服务策略:
    • 分级管理:核心应用和服务优先使用更好的硬件。同时在服务部署上也进行必要的隔离,避免故障的连锁反应。
    • 超时设置;
    • 异步调用;
    • 服务降级;
      • 拒绝服务:拒绝低优先级应用的调用,减少服务调用并发数,或者随机拒绝部分请求调用,节约资源,让另一部分请求得以成功;
      • 关闭功能:关闭部分不重要的服务,或者服务内部关闭部分不重要的功能;
    • 幂等性设计:服务重复调用是无法避免的,因此必须在服务层保证服务重复调用和调用一次产生的结果相同。
  • 保护网站的数据就是保护企业的命脉。
  • 保证数据存储高可用的手段主要是数据备份和失效转移机制。
  • 扩大缓存服务器集群规模的一个简单手段就是整个网站共享同一个分布式缓存集群,单独的应用和产品不需要部署自己的缓存服务器,只需要向共享缓存集群申请缓存资源即可。并且通过逻辑或物理分区的方式将每个应用的缓存部署在多台服务器上,任何一台服务器宕机引起的缓存失效都只影响应用缓存数据的一小部分,不会对应用性能和数据库负载造成太大影响。
  • 高可用的数据有如下几个层面的含义:
    • 数据持久性:保证数据可持久存储,在各种情况下都不会出现数据丢失的问题;
    • 数据可访问性:在多分数据副本分别存放在不同存储设备的情况下,如果一个数据存储设备损坏,就需要将数据访问迅速切换到另一个数据存储设备上;
    • 数据一致性:在数据有多份副本的情况下,如果网络、服务器或者软件出现故障,会导致部分数据写入成功,部分副本写入失败。这就会造成各个副本之间的数据不一致,数据内容冲突。
  • CAP原理认为:一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Partition Tolerance,系统具有跨网络分区的伸缩性)这三个条件。
  • 在大型网站中,通常会选择强化分布式存储系统的可用性(A)和伸缩性(P),而在某种程度上放弃一致性(C)。
  • 数据热备可分为两种:
    • 异步热备方式
      • 在异步写入方式下,存储服务器分为主存储服务器(Master)和从存储服务器(Slave),应用程序正常情况下只连接主存储服务器,数据写入时,由主存储服务器的写操作代理模块将数据写入本机存储系统后立即返回写操作成功响应,然后通过异步线程将写操作数据同步到从存储服务器;
    • 同步热备方式
      • 同步热备具体实现的时候,为了提高性能,在应用程序客户端并发向多个存储服务器同时写入数据,然后等待所有存储服务器都返回操作成功的响应后,再通知应用程序写操作成功。
  • 关系数据库热备机制就是通常所说的Master-Slave同步机制。Master-Slave机制不但解决了数据备份问题,还改善了数据库系统的性能。实践中,通常使用读写分离的方法访问Slave和Master数据库,写操作只访问Master数据库,读操作只访问Slave数据库。
  • 若数据服务器集群中任何一台服务器宕机,那么应用程序针对这台服务器的所有读写操作都需要重新路由到其它服务器,保证数据访问不会失败,这个过程叫作失效转移。
  • 失效转移操作有三部分组成:
    • 失效确认
      • 系统确认一台服务器是否宕机的手段有两种:心跳检测和应用程序访问失败报告;
    • 访问转移
      • 几台存储服务器存储的数据完全一样,我们称几台服务器为对等服务器;
    • 数据恢复
  • 网站发布时,并不是把测试通过的代码包直接发布到线上服务器,而实现发布到预发布机器上,开发工程师和测试工程师在预发布服务器上进行预发布验证,执行一些典型的业务流程,确认系统没有问题后才正式发布。预发布服务器是一种特殊用途的服务器,它和线上的正式服务器唯一的不同就是没有配置在负载均衡服务器上,外部用户无法访问。
  • 在网站应用中强调的一个处理错误的理念是快速失败(fast failed),即如果系统在启动时发现问题就立刻抛出异常,停止启动让工程师介入排查错误,而不是启动后执行错误的操作。
  • 很多网站选择周四作为发布日,这样一周前面有三天时间可以准备发布,后面还有一天时间可以挽回错误。如果选择周五发布,发现问题就必须要周末加班了。
  • 大型网站会使用灰度发布模式,将集群服务器分成若干部分,每天只发布一部分服务器,观察运行稳定没有故障,第二天继续发布一部分服务器,持续几天才把整个集群全部发布完毕,期间如果发现问题,只需要回滚已发布的一部分服务器即可。
  • 在部分服务器上发布新版本,其余服务器保持老版本(或者发布另一个版本),然后监控用户操作行为,收集用户体验报告,比较用户对两个版本的满意度,已确定最终的发布版本,这种手段也被称作AB测试。
  • 不允许没有监控的系统上线。
  • 网站的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力。
  • 大型网站的“大型”,在用户层面可以理解为大量用户及大量访问;在功能方面可以理解为功能庞杂、产品众多;在技术层面可以理解为网站需要部署大量的服务器。
  • 网站的伸缩性设计可分成两类:一类是根据功能进行物理分离实现伸缩,一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内的多台服务器部署相同的服务,提供相同的功能。
  • 应用服务器应该设计成无状态的,即应用服务器不存储请求上下文信息,如果将部署有相同应用的服务器组成一个集群,每次用户请求都可以发送到集群中任意一台服务器上去处理,任何一台服务器的处理结果都是相同的。
  • 实现负载均衡的基础技术不外以下几种:
    • HTTP重定向负载均衡
      • 优点是比较简单;
      • 缺点是浏览器需要两次请求服务器才能完成一次访问,性能较差;重定向服务器本身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限;使用HTTP302响应码重定向,有可能使搜索引擎判断为SEO作弊,降低搜索排名;
    • DNS域名解析负载均衡
      • 优点是将负载均衡的工作转交给DNS,省掉了网站管理维护负载均衡服务器的麻烦,同时许多DNS还支持基于地理位置的域名解析,即会将域名解析成距离用户地理最近的一个服务器地址,这样可加快用户访问速度,改善性能;
      • 缺点是目前DNS是多级解析,每一级DNS都可能缓存A记录,当下线某台服务器后,即使修改了DNS的A记录,要使其生效也需要较长时间,这段时间,DNS依然会将域名解析到已经下线的服务器,导致用户访问失败;而且DNS负载均衡的控制权在域名服务商那里,网站无法对其做更多改善和更强大的管理;
      • 大型网站总是部分使用DNS域名解析,利用域名解析作为第一级负载均衡手段,即域名解析得到的一组服务器并不是实际提供Web服务的物理服务器,而是同样提供负载均衡服务的内部服务器,这组内部负载均衡服务器再进行负载均衡,将请求分发到真实的Web服务器上。
    • 反向代理负载均衡
      • 反向代理服务器转发请求在HTTP协议层面,因此也叫应用层负载均衡;
      • 优点是和反向代理服务器功能集成在一起,部署简单;
      • 缺点是反向代理服务器是所有请求和响应的中转站,其性能可能会成为瓶颈;
    • IP负载均衡
      • IP负载均衡在内核进程完成数据分发,较反向代理负载均衡(在应用程序中分发数据)有更好的处理性能,但是由于所有请求响应都需要经过负载均衡服务器,集群中最大响应数据吞吐量不得不受制于负载均衡服务器网卡带宽;
    • 数据链路层负载均衡
      • 使用三角传输模式的链路层负载均衡是目前大型网站使用最广的一种负载均衡手段。
  • 负载均衡算法通常有以下几种:
    • 轮询(Round Robin,RR);
    • 加权轮询(Weighted Round Robin,WRR);
    • 随机(Random);
    • 最少连接(Least Connections);
    • 源地址散列(Source Hashing)。
  • 在网站访问量最少的时候扩容缓存服务器集群,这时候对数据库的负载冲击最小。然后通过模拟请求的方法逐渐预热缓存,使缓存服务器的数据重新分布。但是这种方案对业务场景有要求,还需要技术团队通宵加班。
  • 计算机的任何问题都可以通过增加一个虚拟层来解决。
  • 数据分库的制约条件是跨库的表不能进行join操作。
  • 具有良好伸缩性架构设计的网站,其设计总是走在业务发展的前面,在业务需要处理更多访问和服务之前,就已经做好了充足准备,当业务需要时,只需要购买或者租用服务器简单部署实施就可以了,技术团队亦可高枕无忧。
  • 扩展性(Extensibility)是指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在系统基础设施稳定不需要经常变更,应用之间较少依赖和耦合,对需求变更可以敏捷响应。它是系统架构设计层面的开闭原则(对扩展开放,对修改关闭),架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。
  • 伸缩性(Scalability)是指系统通过增加或减少自身资源规模的方式增强或减少自己计算处理事务的能力。如果这种增减是成比例的,就被称作线性伸缩型。
  • 度量一个开发框架、设计模式、编程语言优劣的重要尺度就是衡量它是不是让软件开发过程和软件产品更加低耦合。
  • 软件架构师最大的价值不在于掌握了多少先进的技术,而在于具有将一个大系统切分成N个低耦合的子模块的能力,这些子模块包含横向的业务模块,也包含纵向的基础模块。这种能力一部分源自专业的技术和经验,还有一部分源自架构师对业务场景的理解、对人性的把握、甚至对世界的认知。
  • 事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作。
  • 为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器,等消息真正被消息消费者服务器处理后才删除消息。
  • 分布式消息队列通过消息对象分解系统耦合性,不同子系统处理同一个消息;分布式服务则通过接口分解系统耦合性,不同子系统通过相同的接口进行服务调用。
  • 将模块独立部署,降低系统耦合性。拆分可以分为:
    • 纵向拆分:将一个大应用拆分为多个小应用,如果新增业务较为独立,那么就直接将其设计部署为一个独立的Web应用系统;
    • 横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务,不需要依赖具体的模块代码,即可快速搭建一个应用系统,而模块内业务逻辑变化的时候,只要接口保持一致就不会影响业务程序和其它模块。
  • 应用较少侵入是指,应用程序只需要调用服务接口,服务框架根据配置自动调用本地或远程实现。
  • 马克思的劳动价值理论:产品的内在价值在于劳动的时间,劳动的时间不在于个体付出的劳动时间,而在于行业一般劳动时间,资本家只会为行业一般劳动时间买单。
  • XSS攻击即跨站点脚本攻击(Cross Site Script)指通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
  • 图片防盗链是指如果图片访问的页面来源不是来自自己网站的网页就拒绝。
  • 单向散列加密是指通过对不同输入长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出进行计算从而获得输入信息。
  • 常用的单向散列算法有MD5、SHA等。单向散列算法还有一个特点就是输入的任何微小变化都会导致输出的完全不同,这个特性有时也会被用来生成信息摘要、计算具有高离散程度的随机数等用途。
  • 对称加密是指加密和解密使用的密钥是同一个密钥(或者可以互相推算),常用在信息需要安全交换或存储的场合。
  • 常用的对称加密算法有DES算法、RC算法等。
  • 非对称加密和解密使用的密钥不是同一个密钥,其中一个对外界公开,被称作公钥,另一个只有所有者知道,被称作私钥。用公钥加密的信息必须用私钥才能解开,反之,用私钥加密的信息只有用公钥才能解开。
  • 非对称加密的常用算法有RSA算法等。HTTPS传输中浏览器使用的数字证书实质上是经过权威机构认证的非对称加密的公钥。
  • 改善密钥安全性的手段有两种:
    • 一种方案是把密钥和算法放在一个独立的服务器上,甚至做成一个专门的硬件设施,对外提供加密和解密的服务,应用系统通过调用这个服务,实现数据的加解密;
    • 另一种方案是将加解密算法放在应用系统中,密钥则放在独立服务器中,为了提高密钥的安全性,实际存储时,密钥被切分成数片,加密后分别保存在不同存储介质中,兼顾密钥安全性的同时又改善了性能。
  • 常用的信息过滤与反垃圾手段有以下几种:
    • 文本匹配:主要解决敏感词过滤的问题;
    • 分类算法:比较简单实用的分类算法有贝叶斯分类算法。分类算法除了用于反垃圾,还可以用于信息自动分类。邮件服务商根据邮件内容推送的个性化广告也可以使用分类算法提高投送相关度;
    • 黑名单。
  • 交易安全是电子商务网站的底线。
  • Wikipedia CDN缓存的几条准则为:
    • 内容页面不包含动态信息,以免页面内容缓存很快失效或者包含过时信息;
    • 每个内容页面有唯一的REST风格的URL,以便CDN快速查找并避免重复缓存;
    • 在HTML响应头写入缓存控制信息,通过应用控制内容是否缓存及缓存有效期等。
  • 包括缓存、存储、数据库等被应用服务器依赖的服务都可以归类为后端服务。
  • 后端优化最主要的手段是使用缓存,将热点数据缓存在分布式缓存系统的内存中,加速应用服务器的数据读操作速度,减轻存储和数据库服务器的负载。
  • 对于一个数据存储系统而言,高可用意味着两个意思:
    • 高可用的服务:任何时候,包括宕机、硬盘损坏、系统升级、停机维护、集群扩容等各种情况,都可以对系统进行读写访问操作;
    • 高可靠的数据:任何情况下,数据可靠存储,不丢失。
  • 影像系统整体可用性的故障可以分成以下三类:
    • 瞬时故障;
    • 临时故障;
    • 永久故障。
  • 应用程序自己的日志输出配置和第三方组件日志输出要分别配置。
  • 日志输出级别至少为Warn,并且检查log输出代码调用,调用级别要符合其真实日志级别。
  • 首页不应该访问数据库,首页需要的数据可以从缓存服务器或者搜索引擎服务器获得。
  • 首页最好是静态的。
  • 当缓存已经不仅仅是改善性能,而是成为网站架构不可或缺的一部分时,对缓存的管理就需要提高到和其它服务器一样的级别。
  • 存储的使用需要根据不同文件类型和用途进行管理,图片都是小文件,应该使用专门的存储服务器,不能和大文件共用存储。批处理用的大文件可以使用其它类型的分布式文件系统。
  • 访问线上生产环境要规范,不小心就会导致大事故。
  • 代码提交前使用diff命令进行代码比较,确认没有提交不该提交的代码。
  • 代码在正式提交前必须被至少一个其他工程师做过code review,并且同共同承担因代码引起的故障责任。
  • 程序在处理一个输入的对象时,如果不能明确该对象是否为空,必须做空指针判断。
  • 程序在调用其它方法时,输入的对象尽量保证不是null,必要时构造空对象(使用空对象模式)。
  • 架构师除了架构设计、软件开发等技术类工作,通常还需要承担一些管理职能:规划产品路线、估算人力资源和时间资源、安排人员职责分工,确定计划里程碑点、指导工程师工作、过程风险评估与控制等。
  • 最好的软件项目管理不是制订计划、组织资源、跟踪修正项目进展、对成员进行奖励和惩罚,而是发掘项目组每个成员的优秀潜能,让大家理解并热爱软件产品最终的蓝图和愿景。
  • 领导的真谛:寻找一个值得共同奋斗的目标,营造一个让大家都能最大限度发挥自我价值的工作氛围。
  • 是事情成就了人,而不是人成就了事。指望优秀的人来帮自己成事,不如做一件事让自己和参与的人都变得优秀。
  • 发掘人的优秀远比发掘优秀的人更有意义。
  • 架构师要和项目组全体成员共同描绘一个蓝图,这个蓝图是整个团队能够认同的,是团队共同奋斗的目标:
    • 蓝图应该是表述清楚的:产品要做什么、不做什么、要达到什么业务目标,都需要描述清楚;
    • 蓝图应该是形象的:产品能为用户创造什么价值、能实现什么样的市场目标、产品最终会长什么样,都需要形象地想象出来;
    • 蓝图应该是简单的:不管内部还是外部沟通,都能一句话说明白——我们在做什么。
  • 在项目过程中,架构师要保持对目标蓝图的关注。
  • 架构师不要把架构当做自己的私有财产,让项目参与者对架构充分争论,大家越是觉得自己是项目架构的重要贡献者,就越是愿意对开发过程承担责任,越是愿意共同维护架构和改善软件。
  • 不要企图去证明自己了不起,永远也别干这种浪费时间、伤害感情的事。
  • 架构师作为团队的技术领导者,在项目过程中不要去试图控制什么,带着一个弹性的计划和蓝图推进,团队会管好他们自己。越是强加禁令,队伍就越是没有纪律;越是强制,团队就越是不能独立自主;越是从外面寻找帮助,大家就越是没有信心。

《大型网站架构技术》