分布式面试题整理
1.多系统之间怎么实现通信的?A系统—》B系统的服务
有两种通信方式,第一种是利用HttpClient,HttpClient提供了http服务的能力,其工作原理就类似于我们去打开浏览器访问一个网页去获取数据,最终网页将数据展现出来。HttpClient可以利用get或者post请求去抓取一个接口的数据,从而得到我们需要的数据。
还有一种便是MQ,使用前,首先搭建一个rabbitMQ的服务器,MQ和HttpClient不同的地方在于HttpClient是同步调用,而MQ可以解耦的异步调用的,正是因为这个原因,MQ才很好的解决了同步的响应速度慢的问题。在这里我们使用的是rabbiMq,同类的产品还有例如ActiveMQ,Kafka等。 什么时候使用异步,什么时候同步? (比如我们的缓存系统)
2.Solr集群的搭建
服务器的数量:zookeeper:3台服务器
solr:4台服务器
先搭建zookeeper集群,因为zookeeper集群有存活过半机制,一般服务器选用奇数台最少3台,因为一台就不叫集群了叫zookeeper服务器了,一个leader主节点,两个follower节点
搭建完zookeeper集群,启动zookeeper,启动4台tomcat实例,更改tomcat端口号一般改为8080,8081,8082,8083,再搭建4个单机版solr实例,让zookeeper集群集中管理配置文件,将配置文件上传到zookeeper,将conf下面的内容上传到zookeeper集群中,修改solr.xml的文件,告诉每个solr实例zookeeper集群的位置,在每台Tomcat的bin目录下catalina.bat文件中加入DzkHost指定的zookeeper服务器地址
3.请你谈谈对MQ的理解?以及你们在项目中是怎么用的?
MQ(消息队列)是一种应用程序对应应用程序的通信方法,由于在高并发环境下,由于来不及同步处理,请求往往发生堵塞,通过消息队列,我们可以异步处理请求,缓解系统压力;MQ( Message Queue) ,即消息队列是在消息的传输过程中保存消息的容器。
通俗的说, 就是一个容器, 你把消息丢进去, 不需要立即处理。 然后有个程序去从你的容器里面把消息一条条读出来处理。一般用于应用系统解耦、 消息异步分发, 能够提高系统吞吐量。
消息队列
注册用户,发邮件(异步)
登录,发短信通知(异步),加积分(异步)
商品添加,异步更新solr,异步更新静态页面
静态页面—库存—实时性较差
接口,库存修改后,重新生成新的静态页面
4.请你谈谈对Redis的认识?
Redis是一种基于键值对的NoSQL数据库(非关系型数据库);是一个key-value存储系统
Redis有两个特点:高能性 可靠性
高能性:Redis将所有数据都存储在内存中,所有读写性特别高
可靠性:Redis将内存中的数据利用RDB和AOF的形式保存到硬盘中,这样就可以避免发生断点或机器故障时内存数据丢失的问题
功能应用
1.数据缓存功能,减少对数据库的访问压力
2.消息队列功能(轻量级)
Redis提供了发布订阅功能和阻塞队列功能
3.计数器-应用保存用户凭证
比如计算浏览数,如果每次操作都要做数据库的对应更新操作,那将会给数据库的性能带来极大的挑战
缓存:优化网站性能,首页 (不常变的信息)
存储:单点登陆,购物车
计数器:登陆次数限制,incr
时效性:验证码expire
订单号:数字
5.redis空间不够,怎么保证经常访问的数据?
淘汰策略:在redis.conf 里面配置,来保证热点数据保存在reids里面。
6.redis应用场景场景:
1.缓存数据服务器
SSO单点登录
2.应对高速读写的场景
秒杀高可用
3.分布式锁
秒杀数据一致性
4.数据共享
库存数据
7.请你谈谈对Spring的认识?
方便解耦,简化开发:通过spring提供的ioc容器,可以将对象之间的依赖关系交由spring进行控制,避免硬编码所造成的过度程序耦合
aop编程的支持;通过spring提供的aop功能,方便进行面向切面的编程
声明式事务的支持
方便几次各种优秀框架
降低JavaEE API的使用难度
Spring是一个开放源代码的设计层面框架,解决业务逻辑层和其他各层的松耦合问题
IOC是一个生产和管理bean的容器,原来调用类中new的东西,现在在IOC容器中产生;
ioc是控制反转,是spring的核心思想,通过面向接口编程来实现对业务组件的动态依赖
Spring的IOC有三种方式注入
1、根据属性注入—set方法注入
2、根据构造方法注入
3、根据注解注入
AOP是面向切面的编程,将程序中的交叉业务逻辑,封装成一个切面,然后注入目标对象;是一种编程思想,将系统中非核心的业务提取出来单独处理
8.请你谈谈单点登录的实现方案?你们怎么包括cookie的安全性?跨域取cookie的问题,你们怎么解决的?
单点登录使用了Redis+Cookie实现
把用户信息放在Redis中,Key作为用户凭证存放在Cookie中放在客户端,通过获取Cookie凭证判断用户是否有登录
Cookie的安全性,我们的凭证是唯一的UUID,使用工具类统一字符串命名,并且设置了Cookie,关闭document.cookie的取值功能
Cookie的跨域问题,在二级域名使用共享Cookie的将多个系统的域名统一作为二级域名,统一平台提供使用主域名,cookie.setPath("/")设置Cooie路径为根路径,通过cookie.setDomain(".父域名")使得项目之间跨域互相访问他们的Cookie
9.请你谈谈购物车的实现方案?当商品信息发生变更,购物车中的商品信息是否可以同步到变化?
现实中购物车有两种情况,未登录时的购物车和登录时的购物车。我们用Redis+Cookie的方法来实现购物车。当点击“加入购物车”按钮时,先获取用户登录凭证,如果没有登录,就将商品的id保存在Redis未登录购物车中,当拦截器拦截到用户登录时,把购物车的内容合并到数据库中登录后购物车里,通过json解析商品id查到商品信息,所以购物车中的商品信息是可以变化的。
10.如何应对高并发问题?
1.HTML静态化,消耗最小的纯静态化的html页面避免大量的数据库访问请求
2.分离图片服务器,对于web服务器来说,图片是最消耗资源的将图片资源和页面资源进行分离,进行不同的配置优化,保证更改的系统消耗和执行效率
3.数据库集群和库表散列,数据库集群由于在架构、成本、扩张性方面都会受到所采用的关系型的限制,在应用程序安装业务和功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再进行更小的数据库散列,最终可以再配置让系统随时增加数据库补充系统性能;
4.缓存,使用外加的redis模块进行缓存,减轻数据库访问压力
5.负载均衡,在服务器集群中需一台服务器调度角色Nginx,用户所有请求先由它接收,在分配某台服务器去处理;实现负载均衡:http重定向实现,DNS匹配,反向代理
6.动静态分离,对于动态请求交给Tomcat而其他静态请求,搭建专门的静态资源服务器,使用nginx进行请求分发
11.Zookeeper应用场景
1.统一配置管理
持久化节点存放配置信息,监听内容修改
2.集群管理
临时节点机器(节点)退出或者加入,Master选举投票
临时顺序节点选举时候直接使用编号最小的即可
3.分布式锁
创建临时节点,创建成功者获得锁,执行业务操作,独占操作
也可以进行顺序执行,通过最顺序临时节点的编号
4.命名服务
/dubbo
/provider:存放服务地址
/consumer:存放消费地址(没实际意义),
/conf:存放配置信息
…
consumer通过监听provider节点的内容修改实现动态读取地址,并且支持集群,只需要在provider中存放多个地址然后程序中通过代码实现随机调用即可
12.Nginx应用场景
1.Http服务器,具有提供http服务的能力
location /{
root /home
}
2.虚拟主机,可以对不同的进行端口映射
server{
port:端口
server_name:域名
…
}
3.反向代理,负载均衡
tomcatlist{
ip1:port [weight=n1];
ip2:port [weight=n2];
}
location{
proxy_pass : tomcatlist;
}
4.动静态分离
location ~.(jpg|css|js|png|html|htm)
13.RabbitMq应用场景
1.系统间异步调用
添加商品时,索引工程创建索引,详情工程生成静态页面
2.顺序消费
队列的特点
3.定时任务
订单的30分钟后关闭
4.请求削峰
双十一和平时的时候的处理
通过消息中间件的消息存储到队列中,服务层只拿取指定数量的消息进行消费从而保证服务层的稳定性,用时间的代价换取性能和稳定的保证再通过成本可以接受的集群搭建提高时间基础
14.谈谈你对ThreadLocal的理解,以及他的作用
答:线程局部变量ThreadLocal为每个使用该变量的线程提供独立的变量副本,每次调用set()方法的时候,每个当前线程都有一个ThreadLocal。应用场景:当很多线程需要多次使用同一个对象,并且需要改对象具有相同初始化值的时候最适合使用ThreadLocal
作用:解决多线程程序并发问题
15.Erueka和ZooKeeper的区别
1.Erueka是一个是服务端,ZooKeeper是一个进程
2.Erueka是自我保护机制,ZooKeeper是过半存活机制
3.Erueka是AP设计,ZooKeeper是CP设计
4.Erueka没有角色的概念,ZooKeeper有leader和follow
16.池化技术
对象池技术基本原理的核心有两点:缓存和共享,即对于那些被频繁使用的对象,在使用完后,不立即将它们释放,而是将它们缓存起来,以供后续的应用程序重复使用,从而减少创建对象和释放对象的次数,进而改善应用程序的性能。事实上,由于对象池技术将对象限制在一定的数量,也有效地减少了应用程序内存上的开销。
网友评论