每一个大型的网站都是由最简单的架构演变而来的,随着业务的拓展,技术也不断升级。经常有人说:“没有最好的方案,只有最合适的方案”,“技术是服务于业务的”。而大型网站技术架构,通常可以从几点来说:高性能、高可用、可伸缩、可拓展、安全,以下从这几点展开。
一.高性能
1.缓存
缓存是常用的提高性能的手段。通常使用redis缓存,相较mysql而言,redis的性能更好,如果一个请求可以从redis拿到需要的数据,就可以很快地响应用户的请求。
但是用缓存也要注意业务场景适合。缓存使用于对少量热点数据进行,例如80%的请求访问20%的数据,像这样的热点数据就适合缓存。同时,频繁变更的数据不适合缓存,如果数据变更频繁,缓存需要频繁更新,也会加大数据不一致的风险,但是如果业务确实需要缓存就没办法了。
2.异步
异步是将一些耗费时间但又不是核心链路的事情放到后面来完成,将结果立即返回。例如,下单成功后需要记录日志,并且需要加积分,那么就可以把记录日志和加积分,类似的非下单的核心链路的事情交给异步线程完成,而不是在所有事情完成后再响应用户的请求。在开发中可以多考虑是否能将一些功能异步执行,提高接口性能。
常见的异步方式有两种:
线程池:适合简单场景,通过复用线程达到提高执行速度、管理线程的功能。
消息队列:如果任务的可靠性要求高,可以用Kafka之类的消息队列,通过持久化以及提交偏移量的机制保证消息的可靠。
二.高可用
高可用是指通过冗余设计、自动故障转移等手段,确保系统在组件故障或维护时能继续提供服务,最大限度减少停机时间。主要分为两个方面:应用服务器、数据服务器
1.应用服务器:多台应用服务器通过负载均衡的机制共同对外提供服务,单个应用服务器宕机,可以通过其他服务器继续提供服务。前提是应用服务器设计成无状态的,如果应用服务器保存了会话信息,宕机之后就算请求其他应用服务器,还是无法正常提供服务。
2.数据服务器:可以分为缓存类的redis服务器,以及持久化的MySQL服务器。对于redis服务器,可以通过主从和哨兵进行数据冗余和故障转移,还可以用rdb、aof日志来兜底。对于MySQL服务器,同样可以定期备份数据,同时通过binlog进行主从复制,如果主节点挂了,可以连从节点进行服务。对于主从复制,需要从性能和一致性之间权衡。
三.可伸缩
伸缩性是指在用户快速增长的情况下通过向集群中增加服务器来缓解用户访问压力并满足数据存储需求。分为三个方面:应用服务器、缓存服务器、关系数据库。
1.应用服务器:与高可用类似,将应用服务器设计为无状态,通过负载均衡的方式来将请求分发到新加入集群的服务器中
2.缓存数据库:redis集群通过hash槽进行分片,每个元素按照在hash槽的位置决定落在哪个分片上。扩容redis集群可能会导致大量的旧元素对应到新的分片,造成类似缓存击穿的影响,对数据库造成很大的压力,可以通过使用一致性hash来优化这个问题。一致性hash的原理是一个hash环,在hash环上有不同的节点,某个元素存到哪个分片,取决于落在hash环的位置的顺时针的下一个节点,这样的话新增节点对旧元素的变动就比较小。通常会将物理节点分为多个虚拟节点,使数据分布地更均匀,
3.关系型数据库
关系型数据库的扩容相对复杂,虽然MySQL有数据同步的机制,但是扩容通常涉及到数据复制、双写、对账的过程,这里不展开。
4.可拓展
可拓展指的是系统是否可以快速响应需求变化,以满足业务的不断发展。
1.消息队列:满足系统可拓展的一个重要方式是使用消息队列,这样的事件驱动架构。使用消息队列可以减小服务间的耦合,利于服务的拓展。