目录
架构的模式
管理和监控
性能和可扩展性
数据管理模式
设计和实现模式
消息模式
弹性模式
安全模式
总结
架构的核心要素
性能
可用性
伸缩性
扩展性
安全性
每一个模式描述了一个在我们周围不断重复发生的问题及该问题解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复工作。
所谓网站架构模式即为了解决大型网站面临的高并发访问、海量数据、高可靠运行灯一系列问题与挑战。为此,在实践中提出了许多解决方案,以实现网站高性能、高可靠性、易伸缩、可扩展、安全等各种技术架构目标。
分层是企业应用系统中最常见的一种架构模式,将系统在横向维度上切分成几个部分,每个部分负责一部分相对简单并比较单一的职责,然后通过上层对下层的依赖和调度组成一个完整的系统。
在网站的分层架构中,常见的为3层,即应用层
、服务层
、数据层
:
分层架构是逻辑上的,在物理部署上,三层架构可以部署在同一个物理机器上,但是随着网站业务的发展,必然需要对已经分层的模块分离部署,即三层结构分别部署在不同的服务器上,是网站拥有更多的计算资源以应对越来越多的用户访问。
所以虽然分层架构模式最初的目的是规划软件清晰的逻辑结构以便于开发维护,但在网站的发展过程中,分层结构对网站支持高并发向分布式方向的发展至关重要。
如果说分层是将软件在横向方面进行切分,那么分隔就是在纵向方面对软件进行切分。
网站越大,功能越复杂,服务和数据处理的种类也越多,将这些不同的功能和服务分隔开来,包装成高内聚低耦合的模块单元,不仅有助于软件的开发维护也便于不同模块的分布式部署,提高网站的并发处理能力和功能扩展能力。
大型网站分隔的粒度可能会很小。比如在应用层,将不同业务进行分隔,例如将购物、论坛、搜索、广告分隔成不同的应用,有对立的团队负责,部署在不同的服务器上。
对于大型网站,分层和分隔的一个主要目的是为了切分后的模块便于分布式部署,即将不同模块部署在不同的服务器上,通过远程调用协同工作。分布式意味着可以使用更多的计算机完同样的工作,计算机越多,CPU、内存、存储资源就越多,能过处理的并发访问和数据量就越大,进而能够为更多的用户提供服务。
在网站应用中,常用的分布式方案有一下几种.
分布式应用和服务
:将分层和分隔后的应用和服务模块分布式部署,可以改善网站性能和并发性、加快开发和发布速度、减少数据库连接资源消耗。
分布式静态资源
:网站的静态资源如JS、CSS、Logo图片等资源对立分布式部署,并采用独立的域名,即人们常说的动静分离。静态资源分布式部署可以减轻应用服务器的负载压力;通过使用独立域名加快浏览器并发加载的速度。
分布式数据和存储
:大型网站需要处理以P为单位的海量数据,单台计算机无法提供如此大的存储空间,这些数据库需要分布式存储。
分布式计算
:目前网站普遍使用Hadoop和MapReduce分布式计算框架进行此类批处理计算,其特点是移动计算而不是移动数据,将计算程序分发到数据所在的位置以加速计算和分布式计算。
对于用户访问集中的模块需要将独立部署的服务器集群化,即多台服务器部署相同的应用构成一个集群,通过负载均衡设备共同对外提供服务。
服务器集群能够为相同的服务提供更多的并发支持,因此当有更多的用户访问时,只需要向集群中加入新的机器即可;另外可以实现当其中的某台服务器发生故障时,可以通过负载均衡的失效转移机制将请求转移至集群中其他的服务器上,因此可以提高系统的可用性。
缓存目的就是减轻服务器的计算,使数据直接返回给用户。在现在的软件设计中,缓存已经无处不在。具体实现有CDN、反向代理、本地缓存、分布式缓存等。
使用缓存有两个条件:访问数据热点不均衡,即某些频繁访问的数据需要放在缓存中;数据在某个时间段内有效,不过很快过期,否则会因为数据过期而脏读,影响数据的正确性。
使用异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方法异步执行进行协作。
具体实现则在单一服务器内部可用通过多线程共享内存对了的方式处理;在分布式系统中可用通过分布式消息队列来实现异步。
异步架构的典型就是生产者消费者方式,两者不存在直接调用。
网站需要7×24小时连续运行,那么就得有相应的冗余机制,以防某台机器宕掉时无法访问,而冗余则可以通过部署至少两台服务器构成一个集群实现服务高可用。数据库除了定期备份还需要实现冷热备份。甚至可以在全球范围内部署灾备数据中心。
具体有自动化发布过程,自动化代码管理、自动化测试、自动化安全检测、自动化部署、自动化监控、自动化报警、自动化失效转移、自动化失效恢复等。
网站在安全架构方面有许多模式:通过密码和手机校验码进行身份认证;登录、交易需要对网络通信进行加密;为了防止机器人程序滥用资源,需要使用验证码进行识别;对常见的XSS攻击、SQL注入需要编码转换;垃圾信息需要过滤等。
积极接受需求变更,快速响应业务发展需求。
进程外的代理服务(之前介绍中间件的时候也提到了,很多框架层面的事情可以以软件框架的形式寄宿在进程内,也可以以独立的代理形式做一个网络中间件)。这里的大使模式意思就是这么一个网络代理进程,用于和远端的服务进行通讯,完成下面的工作:
由于是独立进程的网络服务,所以这个模式适合于我们有多语言多框架都需要干同样的事情,那么我们的框架中客户端部分的很多工作可以移出来放到大使服务中去。当然了,多一层网络调用多一层开销,大使服务的部署也要考虑到性能不一定可以集中部署,这些都是要考虑的问题。
使用一层反腐层来作为新老系统通讯的中间人。这样新系统可以完全使用新的通讯方式和架构方式,老的系统又不用进行特别改造可以暂时保留,等老系统不用之后可以废弃这个反腐层。这种模式适合新老系统迁移的过渡方案,不属于永久使用的架构设计模式。
这个模式说的就是可以有一个外部的配置服务来保存配置信息,在之前第五篇文章介绍中间件的时候我详细说明过配置服务的功能。不管是处于管理运维的角度还是方便安全的角度,具有配置共享配置外存特点的独立配置服务对于大型的网站来说必不可少。实现的话有很多开源项目提供了配置服务。
应用程序如果需要和多个服务交互的话,在中间构建起一个聚合网关层,网关并发发出多个请求给后面的服务,然后汇总数据给到应用程序。这种模式有几个好处:
其实这种模式不仅仅用于纯后端服务之间的通讯,很多面向前端的API请求都会做一个聚合层,这样前端可以只发一个请求的情况下任意向后端一次性索取多个API的返回,减少网络请求次数提高性能。
实现上最简单的方式可以使用OpenResty或Nginx实现。
名字有点难以理解,其实这种模式我们可能一直在用。就是用一个代理网关层做一些和业务无关的又麻烦的点,比如SSL,实现上用Nginx实现就很简单。我们经常会对外启用HTTPS服务,然后对内服务实际提供的是HTTP接口,通过网关做一下协议转换。
这也是很常见的作法,我们对外的接口可能是/cart、/order、/search这样的API,在其背后其实是不同的服务,通过网关层进行转发,不仅仅可以做后端服务的负载均衡和故障转移,在后端服务变更切换对外API路径(比如版本升级)的时候我们也可以进行灵活的路由,确保了对外接口的一致性。可以使用Nginx来实现,相信大部分公司都是由Nginx这样的网关来对外的,不会把域名直接解析到底层服务上对外。
这个模式其实是挺重要的一点,有几个点需要注意:
实现上,我们应当把health端口作为插件形式集成到系统,配置一下即可启用,用不着每一个系统都自己开发一套。如果使用SpringBoot的话可以直接使用Actuator模块实现。
名字挺吓人,这个模式说的是如何做迁移。通过建立一个门面来作为后端新老服务的路由,慢慢把服务替换为新服务,最后当所有的服务都是新服务后删除这个门面即可。这样对于消费者感知不到这个迁移的过程。在上一篇文章中我们提到的换引擎的方式其实说的是保留原有的门面,也是通过这个门面做底层引擎的替换。其实我觉得对于减少外围影响这种模式是完全可以理所当然想到的,真正难的过程还是之前说的数据迁移和底层服务实现的过程。
这个模式说的不是广义上的缓存使用,而是其中的一种使用方式。我们对于缓存的使用一般有这么几种方式:
这个模式说的是后一种方式,对于数据变动不大,这种模式是性能最好的,几乎实现了100%的命中率,而且如果数据量不大可以容纳进进程的话不需要跨进程通讯。往细致一点去想,这里还有一层性能优化的点,因为我们在内存中维护了一套复杂的全量数据的数据结构,内存中对象的引用只是指针引用,内存中的数据搜索可以很快,对于数据量不大但是关系复杂的数据,这个搜索效率可以是数据库的几百倍。实现上一般会在应用程序启动的时候把数据完全加入内存,在后续通过一些策略进行数据更新:
英文缩写是CQRS,看到这个关键字你可能会觉得有点熟悉了。CQRS原来说的是我们可以有两套数据模型分别用于读和写。好处是,我们可以让读和写具有完全不同的数据结构,减少相互的干扰,减少权限控制的复杂度。这里说的不一定是指架构层面我们可以这么做,也指在程序内部,我们可以有两套命令模型来处理读写这两个事情,分别进行优化和定制。
现在一般的做法是类似于上图的做法,为读写配置两套独立的数据源,并且和事件溯源的方式结合起来做(见后面一节)。我们来说说读写两套模型在存储上分离这个事情,在《相辅相成的存储五件套》一文中我们的架构图其实就有这方面的意思。对于读写这两个事情,我们完全可以不用一套数据源,为读建立专门的物化视图,可以针对读进行优化,避免在读的时候做很多Join的工作,可以把性能做到极致(后面会有物化视图模式的介绍)。事件溯源+CQRS+物化视图三者一般会结合起来使用。
事件溯源(ES)是一种有趣的模式,说的是我们记录的不是数据的当前状态而是叠加的数据变化序列(是不是想到了区块链的数据记录方式)。传统的CRUD方式因为有更新这个操作,所以会产生性能并发方面的局限性,而且我们还需要配备额外的日志来做审计,否则就产生了信息丢失。而事件溯源模式记录的是事件而不是当前状态,所以有下面的特点:
其实有一些业务场景下这种模式会比CRUD存储更适合:
反过来说,业务逻辑很简单的系统,需要强一致性的系统,数据很少更新的系统不适合这种模式。不知你所了解到的采用ES模式的业务场景有哪些?大家一起交流一下。
我们在使用数据存储的时候往往会更多考虑存储而不是读取。我们使用各种数据库范式来设计数据库,在读取数据的时候我们需要做大量的关联查询以输出符合需要的查询结果。这个时候性能往往会成为瓶颈,物化视图是一种空间换时间的做法。与其在查询的时候做关联,倒不如提前保存一份面向于查询和输出的数据格式。因此,物化视图适合下面的场景:
但是因为需要考虑到物化视图计算保存的开销,所以也不太适合于数据变化太频繁的情况,因为数据加工需要时间,所以不适合需要数据强一致性的场景。
实现上一般是基于消息监听做额外维护一套物化视图的数据源和主流程解耦。惠普的Vertica是一款高性能的列式分析数据库,它的一个特性就是物化视图,通过事先提供SQL语句直接缓存面向于统计的查询结果,极大程度提高了性能,也是空间换时间的思想。
消息队列我们太熟悉了,之前我们也反复提高过好多次,甚至我说这是架构三马车之一。这个模式在这里强调的是削峰的优势。这里我还想提几点:
区别于FIFO结构的队列,优先级队列允许消息标识处理优先级。这里实现上如上面两个图有两种方式:
在方案选择和实现上要考虑消息优先级是否需要绝对按照优先级来处理,还是说相对优先处理即可,如果需要绝对优先那么除了消息位置重排还需要有抢占处理。还有,如果我们采用第二种多池的方式来处理的话可能会发生低级别的消息处理时间比高级别的消息更快的可能性(如果两者处理业务逻辑是完全不同的话)。
实现上的话RabbitMQ 3.5以上版本支持了消息优先级,实现的是第一种方式,在消息有缓冲的堆积的时候进行消息重排,消费端可以先看到先处理优先级高的消息,这种方式在消费速度大于产出速度的场景下是无法实现高级别消息优先处理的。
补充一点,对于队列中的消息,还有一种需要特别考虑的就是一直停留在队列的消息应当视为低优先级或是死信消息来处理,最好是有单独的消费者来处理,避免此类消息影响了整个队列的处理,见过很多个事故是由于队列中被废弃消息卡死导致彻底丧失处理能力的。
在做压力测试的时候我们会发现,随着压力的上升系统的吞吐慢慢变大而且这个时候响应时间可以基本保持可控(1秒内),当压力突破一个边界后,响应时间一下子会不可控,随之系统的吞吐就会下降,最后会彻底崩溃。任何系统对于压力的负荷是有边界的,超过这个边界之后系统的SLA肯定无法满足标准,导致大家都无法好好用这个服务。因为系统的扩展往往不是秒级可以做到的,所以这个时候最快的手段就是限流,只有限流了才能保护现在的系统不至于突破这个边界彻底崩溃。对于业务量超大的系统搞活动,对关键服务甚至入口层面做限流是必然的,别无它法,淘宝双11凌晨0点那一刻也能看到一定比例的下单被限流了。
常见的限流算法有这么几种:
令牌桶算法限制的是平均流入速度,允许一定程度的突发请求,漏桶算法限制的是常量的流出速率用于平滑流入的速度。实现上,常用的一些开源类库都会有相关的实现,比如google的Guava提供的RateLimiter就是令牌桶算法。
限流模式有下面的一些注意事项:
一直有一个说法就是不到没路可走的时候不要考虑数据库分片。有的时候业务量大到单个业务表在经过缓存+队列削峰等措施之后的平均的TPS超过1万,单表实在是扛不住,还是只能考虑分片手段。
分片前:
分片后:
相信互联网公司90%+肯定都使用了这个模式。把静态资源从动态网站中剥离由Nginx等高性能服务器来处理静态资源,然后使用三方CDN对静态资源进行加速,不但减轻了动态网站的负载而且数据在边缘节点加速让用户的访问跟快,使用单独的一个或多个子域名做静态资源还能提高下载资源的并行度提高网页加载的速度。
使用CDN来进行资源加速一般有主动数据传送到CDN存储和在CDN配置回源站拉取两种方式,文件类一般使用主动推送数据,静态资源类一般使用回源方式。在使用CDN的时候考虑下面的问题:
出于下面的原因,我们会考虑索引表:
不过需要考虑一点索引只有在数据区分度高的情况下才能发挥价值,如果90%以上的数据都是相同的值,那么走索引进行查询性能会比全表扫还要差一点。
这里说的是不同的前端配以不同的专用后端。比如PC网站和APP的后端是两套程序。这种模式是否适合其实还是看两端的后端提供的数据差异有多大,我们总是希望可以尽量统一一套后端,业务逻辑不用重复写,但是我们要考虑到PC网站和APP的差异性:
考虑到这些差异,我们是在一个工程内根据来源做适配,还是独立两套工程来做独立的后端取决于差异度有多大了。
这个模式从资源节省的角度来说我们的计算单元任务可以进行一些合并,减少因为资源限制导致不必要的开销。
对于分布式服务,我们趋向于把服务设计为无状态可以任意扩展的,但是在某些业务场景下我们不得不在服务中选举出一个Leader(Primary节点,Master节点)来做一些不适合重复做的协调管理工作。这个时候我们需要有算法来做选举。
最常见的实现方式是使用Zookeeper来实现,我们知道ZK的znode有Sequence和NonSequence两种,前者多个客户端只有一个可创建成功同名节点,后者创建后会自动加上序列号命名多个客户端可以创建多个同名节点,利用这个特性有两种常见实现方式:
非公平实现。多个客户端同时创建EPHEMERAL+NONSEQUENCE节点。只有一个可以创建成功,创建成功的就是Leader,其它的Follower需要注册watch,一旦Leader放弃节点(注意,EPHEMERAL意味着Leader待机后Session结束节点被删除),再一次重复之前的过程注册节点抢占成为Leader。这个模式实现简单,问题是在节点数量过多的时候一旦发生重新竞选,这个时候可能会有性能问题。
公平实现。多个客户端同时创建EPHEMERAL+SEQUENCE节点。客户端都可以创建成功节点,客户端如果判断自己是最小的节点则为Leader否则为Follower。每一个Follower都去watch序号比自己小的节点(大家都看前一位)。一旦有Leader节点因为宕机被删除(还是EPHEMERAL特性),收到通知的节点会看自己是不是最小的序号,如果是的话成为Leader。节点宕机后,原先watch宕机节点的客户端重新watch比自己序号小的有效节点。这个模式实现复杂,但是由于watch的都只是一个节点所以不会发生像非公平实现的性能问题,而且竞选根据节点序号来而不是抢占式所以显得Leader的选举公平有序。
在软件设计模式中过滤器构成的管道这种模式很常见(图上的业务逻辑就是Handler,之前的那些Task就是Filter,模式上可以是Filter+Handler也可以是Filter+Handler+Filter也可以是Handler+Filter),不管是Spring MVC框架也好,Netty这种网络框架也好都提供了这样的设计。每一个过滤器单独完成一个功能,可以独立插拔随意组合配置成一套管道,不但数据处理的整个过程清晰可见还增加了灵活性。
对于架构上也可以有这样的模式,在数据源进入到业务逻辑处理之前(或之后,或前后),我们可以配置一系列的数据过滤器完成各种数据转化和处理的任务。Task和Task之间可以是同步调用,也可以使用MQ做一定的可伸缩性设计。还可以把过滤器的配置信息保存在配置系统中甚至根据上下文动态构建出管道,实现更灵活的前置或后置流程处理。
这里说的是消息队列的消息消费者是一组对等的消费者,通过竞争方式来拉取数据执行。之前提到过这是MQ的最常见的一种模式,一般而言我们会部署多个消费节点进行负载均衡,在负载较大的时候可以方便得增加消费者进行消费能力扩容。不过对于这种模式消费者应当是对等的无状态的,在某个消费者在消费失败的时候消息重新回到队列随后可能会被另一个消费者进行处理。
重试适用于瞬态故障,之后会提到断路器模式,两种模式可以结合使用。首先说说重试的几个发起人:
重试也要考虑几种策略:
这个模式说的是三者的角色:
三个角色相互配合完成复杂的,具有较多远程服务参与的任务,确保任务的最终有效执行。在之前架构三马车一文中说到定时任务的时候提到过一种任务驱动表的模式,说到了一些驱动表的实现细节,其实整体和这个模式是类似的思想。当我们的一个复杂逻辑有多个步骤构成,每一步都依赖外部服务,这个时候我们可以选择全程MQ+补偿方式(乐观方式),也可以选择全程任务驱动的被动模式(悲观方式),具体选择取决于更看重可靠性还是及时性。
资源隔离有好几个层次,可以在进程内部做线程池或队列的隔离,在微服务的服务划分上考虑隔离出单独的物理服务,或是在服务器层面通过虚拟化技术或Docker技术进行资源隔离。隔离了就不会相互影响,但是会有成本、性能、管理便利性方面的开销。实现能够根据需求分析出可能的资源相互影响的点,提前规划隔离往往可以避免很多问题的发生。之前有遇到过几个事故是这样的:
分布式应用环节多网络环境复杂,如果遇到依赖服务调用失败的情况我们或许可以进行重试期待服务马上可以恢复,但是在某些时候依赖的服务是彻底挂了而不是网络故障无法及时恢复,如果不考虑进行熔断的,可能服务调用方会被服务提供方拖死。这个时候可以引入断路器机制,如图所示断路器一般采用三态实现,瞬间恢复可能会让底层服务压力过大:
实现模式的时候考虑下面注意点:
实现上我们可以看一下Netflix的Hystrix进行进一步了解。
这个模式说的是失败时必须进行撤销的操作,可以由一组补偿程序来做相应的补偿。在这里我想说的更广一点,在服务调用的时候,调用失败有几种可能:
所以在出现服务调用失败或超时的时候,服务端执行究竟有没有成功客户端是不明确的(只有客户端收到了明确的服务端返回的业务错误才真正代表执行失败),这个时候需要有补偿逻辑来同步服务端的执行状态。如果这样的补偿不可避免而且需要补偿的服务特别多,这样的逻辑逐一来写是一件很烦的事情,我们可以把这个工作封装成一个补偿中间件来处理:
这样,我们在服务调用的时候就不需要考虑补偿逻辑的实现,只要实现这个标准即可。
这个模式说的是,在访问敏感资源的时候,我们可以不必让应用程序在其中作为一个代理转一层做权限控制,而是生成一个密钥,让用户直接拿着密钥到资源池换数据。
一些CDN在提供资源上传下载服务的时候一般都会提供类似的安全策略,需要实现生成Token才能去使用下载和上传服务,避免了CDN数据被非法利用作为图床的可能。
实现上比较简单,应用程序和资源提供方约定好Token的生成算法,对资源+请求资源的时间+密钥联合在一起做签名,资源提供方如果校验到签名不正确或Token过期或资源不匹配都将拒绝服务。
这个模式说的是将身份验证委托给专门的程序或模块来做。使用专门的模块来统一负责登录授权不仅仅可以提供单点登录的功能,而且服务实现上更简单不需要每次都考虑登录那套东西。实现上可以看一下Spring Security实现的OAuth 2.0。
总结一下,对于其中的很多模式,我们可以发现其实在之前的一些介绍或多或少有一些涉及。这里提到的30种模式有些体现的是一些设计细节,有些体现的是一种设计理念,它们大多时候是组合使用的,适合的就是最好的,大家可以细细品味一下每种模式的适合场景,在合适的时候可以想到它或许会有一种豁然开朗的感觉。
所谓架构,一种通俗的说法就是“最高层次的规划,难以改变的决定”,这些规划和决定奠定了事物未来发展的方向和最终的蓝图。
而软件架构即“有关软件整体结构与组件的抽象描述,用于指导大型软件系统各方面的设计”。一般来说软件架构需要关注性能、可用性、伸缩性、扩展性和安全性这5个架构要素。
性能是网站架构设计的一个重要方面,任何软件架构设计方案都必须考虑可能带来的性能问题。也正因为性能问题几乎无处不在,所以优化网站性能的手段也非常多:
浏览器端
:可以通过浏览器缓存、页面压缩传输、合理布局页面、减少Cookie传输等手段,甚至可以使用CDN加速功能。
应用服务器端
:可以使用服务器本地缓存和分布式缓存,也可以通过异步操作方式来加快响应,在高并发请求的情况下,可以将多台应用服务器组成一个集群共同对外服务,提高整体处理能力,改善性能。
数据库服务器端
:可用使用索引、缓存、SQL性能优化等手段,还可以使用NoSQL数据库来优化数据模型、存储结构等。
衡量网站性能有一系列指标,重要的有响应时间、TPS、系统性能计数器等,通过这些指标以确定系统设计是否达到目标。
可用性即能够不间断提供服务的时间。几乎所有网站都承诺7×24小时可用,但事实上任何网站都不可能达到完全的7×24,总会有一些故障时间,扣除这些故障时间,就是网站的可用时间。一些大型网站可以做到4个9以上的可用性,也就是99.99%。
网站高可用的主要手段就是冗余,应用部署在多台服务器上同时提供服务,数据存储在多台服务器上相互备份,任何一台服务器都不会影响应用的整体可以,通常的实现手段即把多台服务器通过负载均衡设备组成一个集群。
衡量一个系统架构设计是否满足高可用的目标,就是假设系统中任何一台或者多台服务器宕机时,以及出现各种不可预期的问题时,系统整体是否依然可用。
大型网站需要面对大量用户的高并发访问和存储海量数据,网站通过集群的方式将多台服务器组成一个整体共同提供服务。所谓伸缩性是指通过不断向集群中加入服务器的手段来缓解不断整体上市用户并发访问压力和不断增长的数据存储需求。
衡量架构伸缩性的主要标准就是是否可用多台服务器构建集群,是否容易向集群中添加新的服务器。加入新的服务器后是否可以提供和原来的服务器无差别的服务。集群中可容纳的总服务器数量是否有限制。
不同于其他架构要素主要关注非功能性需求,网站的扩展性架构直接关注网站的功能需求。网站快速发展,功能不断扩展,如何设计网站的架构使其能够快速响应需求变化,是网站可扩展架构的主要目标。
衡量网站架构扩展性好坏的主要标准就是在网站增加新的业务产品时,是否可以实现对现有产品透明无影响,不同产品之间是否很少耦合等。
网站可扩展架构的主要手段是事件驱动架构和分布式服务。
事件驱动通常利用消息队列实现,通过这种方式将消息生产和处理逻辑分隔开。
服务器服务则是将业务和可复用服务分离开来,通过分布式服务框架调用。新增加产品可用通过调用可复用的服务来实现自身的业务逻辑,而对现有产品没有任何影响。
互联网是开发的,任何人在任何地方都可以访问网站。网站的安全架构就是保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取。
衡量网站安全架构的标准就是针对现存和潜在的各种攻击和窃密手段,是否有可靠的应对策略。