大型网站分布式架构?
如下图所示:
分布式锁有哪些实现?
分布式锁一般有三种实现方式:
1. 数据库乐观锁;
2. 基于ZooKeeper的分布式锁;
3.基于Redis的分布式锁;
这里推荐使用Redis分布式锁的方案。
分布式锁有哪些特点?
首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:
1、互斥性:任意时刻,只能有一个客户端获取锁,不能同时有两个客户端获取到锁。
2、安全性:锁只能被持有该锁的客户端删除,不能由其它客户端删除。
3、死锁:获取锁的客户端因为某些原因(如down机等)而未能释放锁,其它客户端再也无法获取到该锁。
4、容错:当部分节点(redis节点等)down机时,客户端仍然能够获取锁和释放锁。
负载均衡有哪些作用?
1.解决并发压力
提高应用处理性能,增加吞吐量,加强网络处理能力。
2.实现高可用
提供故障转移,实现整个应用的高可用。
3.实现扩展性
通过添加或减少服务器数量,提供网站伸缩性扩展性。
4.实现安全防护
负载均衡设备上做一些过滤,黑白名单等处理。
负载均衡有哪些分类?
1.二层负载均衡(mac)
根据OSI模型分的二层负载,一般是用虚拟mac地址方式,外部对虚拟MAC地址请求,负载均衡接收后分配后端实际的MAC地址响应。
备注:MAC(Media Access Control Address)
2.三层负载均衡(ip)
一般采用虚拟IP地址方式,外部对虚拟的ip地址请求,负载均衡接收后分配后端实际的IP地址响应。
3.四层负载均衡(tcp)
四层的负载均衡在三层负载均衡的基础上,通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡。
四层负载均衡在中间传输层执行,它处理消息的传递,但不考虑消息的内容,用ip+port接收请求,再转发到对应的机器。
四层负载均衡不理解应用协议,比如:
- HTTP
- FTP
- MySQL等等
实现四层负载均衡的软件有:
- F5:硬件负载均衡器,功能很好,但是成本很高。
- lvs:重量级的四层负载软件
- nginx:轻量级的四层负载软件,带缓存功能,正则表达式较灵活
- haproxy:模拟四层转发,较灵活
4.七层负载均衡(http)
七层负载均衡不同于四层负载均衡,它在高级应用层上执行,会处理每个消息的实际内容。
所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,决定最终选择的内部服务器。
七层负载均衡它可以根据消息内容(如URL)做出负载均衡决策,比如:对URL图片类的请求转发到特定的图片服务器。
实现七层负载均衡的软件有:
- HAproxy:天生负载均衡技能,全面支持七层代理,会话保持,标记,路径转移;
- Nginx:只在http协议和mail协议上功能比较好,性能与haproxy差不多;
- apache:功能较差
总的来说,一般是LVS做4层负载,Nginx或者Haproxy做7层负载,性能上LVS>HA>Nginx,功能性和便利性上Nginx>HA>LVS。
分布式Session有哪些方案?
1.粘性session
粘性session是指Ngnix每次都将同一用户的所有请求转发至同一台服务器上,即将用户与服务器绑定。
2.服务器session复制
即每次session发生变化时,创建或者修改,就广播给所有集群中的服务器,使所有的服务器上的session相同。
3.session共享
缓存session,使用redis, memcached。
4.session持久化
将session存储至数据库中,像操作数据一样才做session。
Redis相比memcached有哪些优势?
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型;
(2) redis的速度比memcached快很多;
(3) redis可以持久化其数据。
为什么需要单点登录
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。
单点登录在大型网站里使用得非常频繁,例如,阿里旗下有淘宝、天猫等网站,还有背后的成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。
单点登录的实现方式?
我们可以部署一个SSO认证中心,认证中心就是一个专门负责处理登录请求。
所有的请求(登录、退出、获取用户信息、当前用户状态)都请求sso
系统,sso
系统维护用户信息。
此种实现方式相对复杂,支持跨域,扩展性好,是单点登录的标准做法。
基于SSO认证中心的开源项目代表:CAS,其中 CAS是Central Authentication Service,即中央认证服务,下图是CAS的基本过程:
什么是幂等性
幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。
所谓接口幂等性,就是一次和多次请求某一个资源对于资源本身应该具有同样的结果。
为什么需要幂等性
业务开发中,经常会遇到重复提交的情况,无论是由于网络问题无法收到请求结果而重新发起请求,或是前端的操作抖动而造成重复提交情况。
在交易系统,支付系统这种重复提交造成的问题有尤其明显,比如:用户在APP上连续点击了多次提交订单,后台应该只产生一个订单。
再比如:向支付宝发起支付请求,由于网络问题或系统BUG重试,支付宝应该只扣一次钱,而不是多次重试,造成多次扣钱。
再比如:现在是微服务的时代,服务化接口在外部调用者会存在多次调用的情况(考虑网络中断重试等),为了防止外部多次调用对系统数据状态的发生多次改变,将服务设计成幂等,就是为了防止多次重试,造成系统不一致的问题。
通过以上典型的支付场景就知道幂等性的重要性了,那问题来了,如何实现幂等性,有哪些解决方案?下面我们接着聊。
为什么要使用微服务?
技术为业务而生,架构也为业务而出现,当然SOA和微服务也是因为业务的发展而出现。出现SOA和微服务框架与业务的发展、平台的壮大密不可分,下面借用dubbo的网站架构发展图和说明:
- 单一应用架构
- 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
- 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
- 垂直应用架构
- 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
- 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
- 分布式服务架构
- 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
- 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
- 流动计算架构
- 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
- 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。
缓存雪崩
数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。
比如一个雪崩的简单过程:
1、redis集群大面积故障
2、缓存失效,但依然大量请求访问缓存服务redis
3、redis大量失效后,大量请求转向到mysql数据库
4、mysql的调用量暴增,很快就扛不住了,甚至直接宕机
5、由于大量的应用服务依赖mysql和redis的服务,这个时候很快会演变成各服务器集群的雪崩,最后网站彻底崩溃。
分布式服务集群有哪些?
一般分为如下三类:
- 负载均衡集群(Load balancing clusters)简称LBC
- 高可用性集群(High-availability clusters)简称HAC
- 高性能计算集群(High-perfomance clusters)简称HPC
Dubbo的架构设计?
Dubbo的总体架构,如图所示:
Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。
Dubbo框架设计一共划分了10个层:
- 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
- 配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
- 服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
- 服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
- 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
- 监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
- 远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
- 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
- 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
- 数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
什么是SOA
SOA(Service-Oriented Architecture),中文全称:面向服务的架构。
通俗点来讲,SOA提倡将不同应用程序的业务功能封装成“服务”并宿主起来,通常以接口和契约的形式暴露并提供给外界应用访问(通过交换消息),达到不同系统可重用的目的。
SOA是一个组件模型,它能将不同的服务通过定义良好的接口和契约联系起来。服务是SOA的基石。
微服务和SOA的区别
微服务是SOA架构演进的结果。两者说到底都是对外提供接口的一种架构设计方式,随着互联网的发展,复杂的平台、业务的出现,导致SOA架构向更细粒度、更通过化程度发展,就成了所谓的微服务了。
总之,微服务是SOA发展出来的产物,它是一种比较现代化的细粒度的SOA实现方式。
SOA与微服务的区别在于如下几个方面:
- 微服务相比于SOA更加精细,微服务更多的以独立的进程的方式存在,互相之间并无影响;
- 微服务提供的接口方式更加通用化,例如HTTP RESTful方式,各种终端都可以调用,无关语言、平台限制;
- 微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合。
什么是容器?
一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。
- 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
- 容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。
- 容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
再来看看容器较为通俗的解释:
如果需要通俗的描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。
Docker与虚拟机的区别
比较上面两张图,我们发现虚拟机是携带操作系统,本身很小的应用程序却因为携带了操作系统而变得非常大,很笨重。
Docker是不携带操作系统的,所以Docker的应用就非常的轻巧。
另外在调用宿主机的CPU、磁盘等等这些资源的时候,拿内存举例,虚拟机是利用Hypervisor去虚拟化内存,整个调用过程是虚拟内存->虚拟物理内存->真正物理内存,但是Docker是利用Docker
Engine去调用宿主的的资源,这时候过程是虚拟内存->真正物理内存。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》