JAVA面试常问针对性问题精华帖

1.是什么状况造成了要从springmvc框架改为微服务springcloud框架?

可扩展性差,性能提升困难

web应用性能瓶颈基本都在数据库上。这个系统使用mysql作为数据库。三个应用对应三个数据库。没有读写分离。读写都在一个库上操作。数据量最大的表当时在5000万条数据。高峰期数据库操作的QPS在1000左右,压测结果是可以支撑2000的QPS。这个指标令我诧异。为什么能有这么好的性能?首先是,没有复杂的查询逻辑,所有查询都在一个表里操作,没有跨表事务处理,复杂的处理,分解为多个语句来执行。最复杂的一个action中,执行了将近20次数据查询。其次,也是最重要的因素,这里用的是SSD磁盘。从目前情况看,撑到年底应该是可以的,这也为我们技改争取了足够的时间。尽管这样,对mysql还是没有把握。每次运营部门搞活动,我们都玩胆战心惊地盯着,祈祷活动不要太有效果。

从应用层来看,目前读写比在10:1,接口日访问量10亿。高峰期访问量在300QPS。公司业务增长迅猛,数据量半年翻一番,访问量预估10倍增长。还有一个严峻的挑战,产品同学扬言要搞秒杀,秒杀…每秒十万的量必须支持到。这就超过MYSQL能承受的压力范围,需要把读操作切到内存数据库上,但是在SSH架构下,读写分离实现就得伤筋动骨了。另外由于Hibernate封装了对数据库的操作,不用写SQL了,精细优化也搞不定了。每次系统变慢,就得求DBA,帮看看有那些SQL被卡住了。每隔一段时间,还得请DBA导出SQL语句,研究怎么建索引。

系统臃肿,学习周期长

100多个接口,分为三个大项目。最大项目有1300多个类,其次是600多个和300多个类。SSH架构,SVN版本控制,resin作为容器,Nginx前置路由。路由这个让人欣慰,它是整个重构工作的有力支撑。纯后端的项目,为移动端app,PCWEB应用提供接口。这也使得重构工作难度大大降低。如果把前端也耦合进来,那就更酸爽了。

庞大的系统规模为团队成员接手带来困难。 支付业务独立出来后,开发人员从原来的5人,在2个月内扩充到10人。与此同时,兴奋的产品同学也都跟打鸡血一样,各种想法纷纷变为产品,开发压力骤增。但是新增的同学,看着几百个类,往往一片茫然,无法下手。不知道哪些功能实现了,哪些功能是待改进的。一直到3个月后,新员工才逐步进入角色。尽管如此,还是有不少恐龙级代码,无人敢挑战。最大的一个类的规模是2000多行, 核心方法超过500行,大量重复代码, 每次调整都以失败告终。

合作成本高

随着项目组人员增加,每次新版本开发都需要多人一起合作,修改同一个项目代码。 虽然使用版本控制工具来对分支进行管理,但是不可避免的,大量的时间花费在代码冲突处理上。新增功能,增强功能,bug修复,支持各种客户端,都在一个项目上进行,需要建立不同的分支,高峰期五六个分支同时进行都是常见的。这种情况下,代码冲突的频率非常高。一个周的小版本开发,1天时间在解决冲突都是很正常的。

测试难度大

 

测试工作也逐步的恶化了。

测试环境构建难度高。随着分支的增加,每个进入测试的分支,都需要准备独立的测试环境。环境构建成本高。

刚测试完的功能,由于分支合并冲突处理,又得重新跑一遍。严重影响项目进度。

上线风险高

 

随着系统复杂度的增加,上线风险也越来也大。一个小功能的修改,打印一个日志,修复一个bug,都需要整体上线。一旦有一个地方修改错了,这个系统就崩溃了。上线时间长,一次上线,半晚上是必须的

 

 

微服务改造优点

在开始支付项目改造之前,我们刚刚完成了公司数据仓库项目的微服务架构改进。这个项目实施详细过程,在dockone社区做了分享,详情参见这里。 我们认为调整为微服务架构可以解决上述问题。

性能问题

对于性能要求高的接口,可以通过建立数据缓存的方式进行优化。

学习周期

一个项目仅包含少数紧耦合的接口,接口的业务逻辑单一,开发人员1-2小时通读代码,即可快速上手。

合作成本

每个项目相对独立,项目之间仅通过接口来交互。确定完接口后,开发、测试、上线,都是独立进行的,从而降低了沟通成本。

版本控制

由于项目之间是接口依赖而不是代码依赖,每个项目都可以建立独立的代码库。同时项目切分的比较细,每个项目开发时,仅会有一个开发人员对其做修改。这基本就不存在代码合并工作,也避免了代码合并过程中的各种问题。实际上,基于微服务架构的开发,我们并没有采用分支策略,而是直接用主干开发。

测试难度

每个项目独立部署、独立测试。由于消除了代码分支,没有代码合并的隐患,重复测试的工作量减少了。

上线风险

每个项目独立上线,就算出现问题了,也仅影响到少数接口。

新技术

在微服务改造进行一个季度后,各种新技术被引入到系统中,开发不再局限于SSH架构。Spark, Hadoop, Hbase等大数据处理相关的技术,Couchbase, Redis等缓存系统,都开始在项目中使用,并有效地解决的业务上存在的问题。

当然,有利必有弊,微服务带来的问题,也不少,包括项目多、出问题时排查难等

2 .如何保证大数据流量下用户登录信息等数据一致性问题?

使用Redis作为分布式缓存,还会涉及缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题。

先删除缓存中的数据,然后再去更新数据库,最后更新缓存中的数据
写请求过来,我们先删除缓存中的数据,
删除成功之后,我们再更新数据库中的数据,此时如果更新数据库中的数据失败,则整个写请求失败,直接返回,数据没有发生变化,此时读请求过来,发现缓存中没有对应的数据,则会从数据库中读取数据,同时将数据写入到缓存中,此时缓存中的数据和数据库中的数据都是一样的, 不存在数据一致性的问题
更新数据库中的数据之后 ,再来更新缓存中的数据,此时更新缓存中的数据失败,直接返回,数据库中的数据是最新的数据,开始读请求过来,发现缓存中没有对应的数据,则会从数据库中读取数据,同时将数据写入到缓存中,此时缓存中的数据和数据库中的数据都是一样的, 不存在数据一致性的问题
更新缓存成功,此时缓存中的数据和数据库的数据是一致的,不存在数据一致性的问题

乍一看,这种方案完美的解决了数据一致性的问题,我们不妨再来将业务场景复杂点,并发量再大一点,比如说每秒的读QPS为1w+,这是我们再来分析下上述方案的业务逻辑:

用户写请求过来,我们还是先删除缓存,然后再更新数据库
在更新数据库的过程中,此时更新还没有完成,数据库的值依旧是原来的旧值,这时一个读请求过来
发现缓存中没有值,就会到数据库中去查询数据,然后写入到缓存中,此时数据库还没有更新结束,读请求获取的数据依旧是原来的旧数据
这时数据库更新完成,但是更新缓存失败,此时缓存中是用的之前的旧数据与数据库中的新数据就会出现数据不一致的情况,数据一致性的问题又出现了
 

由此可见,上述的方案也是存在问题的,尤其是并发量很大的情况下,这类现象出现的几率就很大;对于这种情况我们该如何处理呢?

我们仔细分析上述的情况,可以发现,读请求和写请求是并行的,这是导致数据一致性的根本原因,并行的请求会导致数据一致性的问题,那么解决此类问题的思路就有了——将请求串行!

具体的业务逻辑如下:

写请求过来,将写请求缓存到缓存队列中,并且开始执行写请求的具体操作(删除缓存中的数据,更新数据库,更新缓存)
如果在更新数据库过程中,又来了个读请求,将读请求再次存入到缓存队列中,等待队列前的写请求执行完成,才会执行读请求
之前的写请求删除缓存失败,直接返回,此时数据库中的数据是旧值,并且与缓存中的数据是一致的,不会出现缓存一致性的问题
写请求删除缓存成功,则更新数据库,如果更新数据库失败,则直接返回,写请求结束,此时数据库中的值依旧是旧值,读请求过来后,发现缓存中没有数据, 则会直接向数据库中请求,同时将数据写入到缓存中,此时也不会出现数据一致性的问题
更新数据成功之后,再更新缓存,如果此时更新缓存失败,则缓存中没有数据,数据库中是新值 ,写请求结束,此时读请求还是一样,发现缓存中没有数据,同样会从数据库中读取数据,并且存入到缓存中,其实这里不管更新缓存成功还是失败, 都不会出现数据一致性的问题

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值