1.分布式:
分布式系统就是由多个节点(计算机服务器)组成的系统。而且这些节点一般不是孤立的,是互通的。这些联通的节点上部署了我们的节点,并且相互的操作会有协同。
2.微服务:
通常而言,微服务是一种架构风格,一个大型复杂软件应用是由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好的完成该任务。在所有情况下每个任务代表着一个小的业务能力。
传统项目开发应用程序都是单体型,所有的功能和业务模块都集中在一个项目中,虽然开发部署比较方便,但是后期随着业务的不断增加,开发迭代和性能瓶颈等问题,将会困扰开发工作工作。微服务就是解决此问题的有效手段。要用微服务,涉及到的技术大致如下:
流行的微服务java项目框架:SpringBoot
微服务治理:Dubbo,SpringCloud
涉及技术:Zookeeper,Eureka,Redis,MQ等
3.分布式环境中如何实现单点登录与session共享
在单服务器web应用中,登录用户信息只需存在该服务的session中。在分布式系统中,微服务已成为主流,用户登录由某一个单点服务完成并存储session后,在高并发量的请求到达服务端的时候通过负载均衡的方式分发到集群中的某个服务器,这样就有可能导致同一个用户的多次请求被分发到集群的不同服务器上,就会出现取不到session的情况;
目前实现session共享的解决方案:
(1)Session复制与共享
多个server之间相互同步session,这样每个server上都包含全部Service的session。
优点:tomcat等多数主流web服务器都支持此功能。
不足:session同步需要数据传输,占内网带宽,有时延。所有服务器都包含所有session数据,特别是当session中保存了较大的对象,而且对象变化较快时,性能下降显著,这种特性使得web应用的水平扩展受到了限制。
(2)客户端存储法
服务端存储所有用户的session,内存占用较大,也可以将session存储到浏览器cookie中,每个端只要存储一个用户的数据了
优点:服务端不需要存储
缺点:每次http请求都携带session,占外网带宽,数据存储在端上,并在网络传输,存在泄漏,篡改,窃取等安全隐患。Session存储的数据大小受cookie限制。
(3)反向代理hash一致性
为了保证高可用,有多台冗余,反向代理层能不能做一些事情,让同一个用户的请求保证落在一台web服务上呢?
具体方案:反向代理层使用IP或http协议中的某些业务参数来做hash,以保证同一个浏览器用户的请求落在同一个web服务器上。
优点:只需要改nginx配置,不用改应用代码,负载均衡,只要hash属性是均匀的,多台web服务器是均衡的。可以支持web服务器水平扩展
缺点:如果web服务器重启,一部分session会丢失,产生业务影响,例如部分用户重新登陆。如果web服务器水平扩展,rehash后session重新分布,也会有一部分用户路由不到正确的session。
(4)服务器端集中存储
将session存储在后端的存储层,如:数据库或者缓存。客户端每发一次请求,都会从存储中获取 ,再处理具体的业务逻辑。
优点:无安全隐患,可以水平扩展,服务器重启或者扩容都不会造成session丢失。
不足:增加了一次网络调用,要修改应用代码。
总结:一般对于单点登录和session共享的处理,大都选择在服务端集中存储来实现。对于db存储还是cache,肯定cache是首选。因为session读取的频率很高,使用数据库压力会比较大。如果有session高可用需求,cache可以做高可用,但大部分情况下session可以丢失,一般也不需要考虑高可用。目前主流的实现方案是用redis实现session的存储。
4.分布式环境下的事务处理方案
对于分布式事务来说,事务的每个操作步骤是运行在不同机器上的服务的。本质上说,分布式事务是为了保证不同数据库的数据一致性。
事务的ACID特性:原子性,一致性,隔离性,持久性。
解决方案:
(1)消息事务+最终一致性
消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功并且对外发消息成功,要么两者都失败。以支付宝转账到余额宝为例,当支付宝账户扣除1万后,只要生成一个凭证(消息)即可,这个凭证(消息)上写着“让余额宝账户增加1万“,只要这个凭证能可靠保存,我们最终是可以拿着这个凭证让余额宝账户增加1万的,即我们能依靠这个凭证完成最终一致性。
(2)TCC编程模式
TCC提供了一个编程框架,将整个业务逻辑分为三块:Try,Confirm和Cancel 三个操作。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,如果更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是通过代码人为实现了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因此,这种模式并不能很好地被复用。
5.Zookeepeer的原理及选举机制
Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。Zookeeper 可以作为服务协调的注册中心,还可以做分布式锁。它作为注册中心,主要存储的数据是ip,端口,还有心跳机制。
Zookeeper做集群做好是奇数个,她的集群管理主要检查是否有机器的退出和加入,选举maste。Zookeeper的角色主要分为:Leader,Follower,Observer.Leader主机负责读和写,Follower负责读,并将写操作转发给Leader,Follower还参与Leader选举投票。Observer充当观察者的角色,不参与投票。当Leader不可用时,会重新选举Leader。超过半数的Follower选举投票即可。
6.使用Redis做缓存有哪些优势
Redis是内存式缓存,它的存取是纯内存操作,因此性能非常出色,每秒可处理超过1 0万次读写,它的优势如下:
a内存式缓存,读写速度特别快;
b支持丰富的数据类型:String, list ,set, sorted set,hash;
c支持事务,操作都是原子性,所谓原子性就是对数据的更改要么全部执行,要么全部不执行;
d丰富的特性:可用于缓存,消息,按key设置过期时间,过期后自动清除;
线程,单进程,采用IO多路复用技术;
7.分布式系统中如何生成唯一ID
1)数据库自增长序列实现
优点:a简单代码方便,性能可以接受。
b数字ID天然排序,对分页或者需要排序的结果很有帮助;
缺点:
a不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候需 b要处理;
c在单个数据库或读写分离或一主多从的情况下,只有一个主库可以生成,有单点故障的风险
d在性能达不到要求的情况下,比较难于扩展;
e如果遇见多个系统需要合并或者涉及到数据迁移会相当复杂;
f分表分库的时候会麻烦;
2)通过UUID实现
可以利用数据库也可以利用程序生成
优点A简单,代码方便
B基本不会有性能问题
C全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。
缺点:
A没有排序,无法保证趋势递增。
B UUID往往使用字符串存储,查询的效率比较低
C存储空间比较大,如果是海量数据库,就需要考虑存储量的问题了
D传输数据量大,不可读。
3)Redis生成ID
当使用数据库来生成ID性能不够要求的时候,可以使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以生成全局唯一的ID。可以用Redis的原子操作INCR和INCRBY来实现。可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis,可以初始化每台Redis的值分别是1,2,3,4,5;然后步长都是5.各个Redis生成的ID为:
A:1,6,11,16,21
B: 2,7,12,17,22
C:3,8,13,18,23
D:4,9,14,19,24
E:5,10,15,20,25
优点:
A不依赖于数据库,灵活方便,且性能优于数据库。
B数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点:
A如果系统中没有Redis,还需要引入新的组件增加系统复杂度。
B需要编码和配置的工作量比较大。
4)Twitter的snowflake算法
Snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思 想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机 器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID), 最后 还有一个符号位,永远是0。
Snowflake算法可以根据自身项目需要进行一定的修改,比如估算未来的数据中心个数,每个数据中心的机器数以及统一毫秒可以并发数来调整在算法中所需要的bit数。
优点;
A不依赖于数据库,灵活方便,且性能优于数据库。
B ID按照时间在单机上递增的
缺点;
A在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完 全同步,也许有时候也会出现不是全局递增的情况。