专栏名称: 石杉的架构笔记
专注原创、用心雕琢!十余年BAT一线大厂架构经验倾囊相授
目录
相关文章推荐
51好读  ›  专栏  ›  石杉的架构笔记

面试官:画一下你项目的核心链路图?遇到过某个关键步骤失败的情况吗?

石杉的架构笔记  · 公众号  ·  · 2019-10-22 08:30

正文


扫描下方海报 试读



一、写在前面

大家好,我是《从零开始带你成为消息中间件实战高手》的作者原子弹大侠。


专栏开始已经一周了,在这一周里,咱们的评论区非常活跃,不少小伙伴就文章内容提出了大量的问题,并结合自己的工作深度思考,这是我非常高兴看到的。 技术就是要这样学,才能学的深,学的扎实。


下面列出了我对大家第一周提出的问题的答疑。 除答疑之外,咱们专栏特有的授人以渔环节,引导各位将文章中的内容和自己公司的项目深度结合,不少同学也按照要求做了,并且做的非常好,在此一并呈现给大家。


二、答疑汇总 & 学员授人以渔回答

问题:

公司做的是药品保险审核的项目。一共有四个端,一个app端,三个pc端,app端是客户端,主要是用来提交用户的申请药品信息。


然后经过pc端医疗机构的初审,pc端保险公司的复审,复审通过后,pc端药房就可以给用户配送药品。


当前项目做成了两个应用,两个应用之间用hessian调用,并一块儿部署到tomcat中。


架构比较简单,当前主要能想到的痛点就是三个pc端更新状态的不一致性


比如用户提交申请药品信息后,经过pc端医疗机构的初审后,当前药品的状态变为待复审


然后当pc端保险公司复审后,它的状态变为找药房,找药房的状态只能在pc端保险公司可见,但是在pc端医疗机构那里的状态还是待复审,需要手动刷新页面才能看到最新的状态。


我想请教一下 在这种情况下,是用websocket做长连接的方式好,还是在接口上做判断,当用户申请的药品达到某个状态后才能进行当前操作,否则给用户提示?


回答:
这真是一个非常好的一个场景,其实你如果拓展开来思考,你们架构里有多个子系统,是否可以引入一个MQ,然后有一些事件变更发布消息到MQ,各个端的系统自行消费MQ,然后更新自己的数据和状态。


问题:

电商购物流程图中的购物车是否要单独的做一个购物车系统 ? 在此流程中是否需要有库存系统?


回答:

购物车系统,库存系统,那些肯定都是有的,会有非常复杂的交互。但是这里跟没写那么详细的流程,因为主要是关注后面跟订单系统相关的引入MQ技术的一些地方。


问题:

老师你好,我所在的公司是一家传统公司,现在所负责的项目用户访问量也不大, 没有用到中间件,也没用到MQ,对MQ的了解也紧紧是停留在基础和理论阶段,没有实战过,对电商项目更加没有接触过,那我应该如何学好MQ呢,毕竟没有实战经验,也没有让我实战的平台,谢谢老师了


回答:

在这种情况下,你跟着这个专栏学习是非常合适的。


首先你可以跟着专栏的案例实战去学习,积累MQ实战的思路和经验。


其次,专栏有大量的授人以渔的环节,会引导你们去思考自己一个没什么技术挑战的普通系统,如何让他有技术挑战,然后如何引入MQ技术去解决。


你完全可以拿你公司的代码,然后后续跟着专栏,慢慢加入MQ技术进去,自己去写代码,重构系统



问题:

老师你好,在我们项目中有这么一种场景, 千人大会签到功能


有一种就是,来一个人签到一次,这种并发量较小。


另外一种就是人到了之后,现场展示二维码,此时所有人都会去用手机扫二维码签到(H5页面)


签到逻辑,就是有一个验证过程,然后添加签到记录,展示是否签到等等。 然后签到成功在有个加积分的逻辑,或者其他逻辑。


请问一下老师,这种场景是否可以引入消息队列削峰呢?


如果引入消息队列,客户端是轮询查询签到结果吗?


签到流程的哪一部分适合用消息队列处理呢?谢谢老师。


回答:

这个流程就非常适合用MQ,对于签到的核心逻辑完全可以保持同步执行,但是对于签到中的增加积分等非核心逻辑,都可以剥离出来写消息到MQ


然后后台有个服务慢慢执行这些非核心的业务逻辑,保证你的核心业务逻辑并发能力很高。



授人以渔:

能概括一下你们系统的架构设计、业务流程以及负载情况吗?

学员回答:

电商订单30分钟未支付关闭订单,订单发起时,将消息写入到延迟队列,消息接受者查询订单是否支付,未支付取消订单


点评: 非常好的一个运用MQ的场景


问题:

单独出一个大促模块,这个模块里是不是得包括订单系统中其他的模块内容?维护两套吗?


回答:
大促一般独立的一个模块,里面要有一些特殊的架构处理


问题:

老师您好,我现在的情况非常非常尴尬。我真的完全不知道该如何去把这些技术融入到现有项目中。


目前所在的部门是BI部门,手上的项目也是一个很老的BI的项目,部门领导也不懂技术,只知道业务。


然后我目前干的工作连CRUD都算不上,只有查询,做各种报表,日常工作是报表,双十一也是报表,没有并发量,都是给公司领导层看的,一共也没几个人,最多有个数据量吧,有的单表千万级,oracle的。更不要说和其他系统去对接了。


请问一下老师,这样的情况下该怎么引入MQ啊?


回答:

很简单,你要梳理出来这个BI系统的全业务流程, 比如:

  • 数据从哪儿来?

  • 进到哪里去?

  • 怎么进去的?

  • 数据如何存储?

  • 多大数据量?

  • 如何对外提供服务?

好,现在假设你已经梳理清楚上述问题了!


那么现在如果数据量暴增100倍怎么处理?如果现在不是几个人看你的报表,是几万人甚至10万人同时要看你的报表呢?


自己去设想技术挑战,然后去计算对系统的压力,再考虑瓶颈点在哪里,最后解决这个问题!



问题:

订单服务和商品库存服务分开了,下单时要减库存,这就需要涉及分布式事务,这种情况是用TCC方案吗?


回答: 是的


问题:
MQ只能是后台与后台之间的通信,不可以是后台与前端的通信,是吗?


回答:

也可以的,但是一般是后台系统之间异步通信



问题:

老师,订单支付后,如果第三方回调超过几分钟,还没通知,但是用户接着支付,这样直接报错,不好吧!


回答:
那你可以在支付系统里加入一笔支付订单,状态是支付中,这样可以通过这个避免重复支付。


问题:

日活百万的app,正常的每天高峰期QPS能达到2000吗?一般是什么场景,能详细说下么,谢谢老师~


回答:
日活百万的APP,高峰期的QPS可以到小几千,一般看你的APP的集中活跃时间了,比如晚上高峰期。


问题:

之前遇到了一个问题,我们网关接口服务部署了3台,在支付回调的时候因为要涉及拆单,以及多个表数据的更新,发现这些表都不能成功,可以说没有发生变化。


但是如果只对一张表操作就可以成功。看网上说是支付宝或者微信的回调,都支持轻应用,拆单加上各种逻辑判断不适合放在回调中吗?最后用了队列处理的,将支付完成的订单号放在队列中,回调的时候从队列中拿出来,单独起线程处理。还有多系统部署,生成重复的多个订单问题。老师这个是什么原因呢?


回答:

对于拆单等重要的逻辑,应该是放在mq里来完成的。


另外一个,对于重复的订单问题,你应该选择基于分布式锁来解决这个问题,可以在处理之前加入分布式锁,不允许其他人同时处理这个订单了,就能保证数据的准确性。



问题:

老师。用了mq会比没有用mq有延迟,那大概会有多长的延迟,要如何预估呢?除了做压测之外


回答:
这个延迟一般要综合多方面的因素,其实你既然用了mq,就要允许这个业务是可以延迟的


问题:

情况差不多,这样在公司没有机会,只能业余自己模拟项目区练了。


回答:
肯定的,如果没机会,自己还不模拟不练习,那出去面试靠什么作为自己的核心竞争力,对吧?


问题:

回调系统~发放优惠卷为什么放在订单系统,为什么不放在在支付系统


回答:

支付系统不负责干这些事,他只是做跟支付相关的


问题:

老师,您好,请教一个问题: 目前我们公司的业务子系统与公共登录系统分离出来了,各个业务库和公共库(存储用户角色权限之类)分离,当用户登录在公共系统登录,对用户角色权限等表的增删改在公共系统完成。


此时遇到问题:各个业务子系统的业务表要跟用户表进行联表查询无法进行,此时打算在各个业务子系统也同步公共库的表,请问此时如何利用MQ来实现数据的同步?


回答:
如果你要做这个事的话,我给你一个建议:不要走多数据库同步,然后用多表查询。建议你走接口,从其他系统查数据过来,内存里完成数据处理



问题:

老师,目前我们公司的解决方案是各个子业务子系统分别定时去公共库拉取用户等表的数据然后比对版本号同步到业务库的用户等表中


但这种方案不能及时同步且增加公共库的访问压力,若部署公共子系统的服务器发生时间会调,此时依赖时间生成的版本号将会出错,这种方案比较low。


若是用MQ去实现,利用MQ的发布订阅机制,各个业务子系统订阅公共系统,此时公共系统的用户等数据发生增删改时触发业务子系统做同步操作。


问题:

  1. MQ应该选哪种MQ比较适合?

  2. 发布订阅模式下,如何保证MQ的消息不被各个业务子系统重复消费?

  3. 若MQ丢了消息怎么办


回答:
这是你确定打算用MQ做数据分发和同步的了,你的那些问题很好,如果确实要这么做,可以跟着后续内容学习,你提的这些问题都会在专栏中得到解答的


问题:

有两个疑问,请老师解答一下:

  1. 如果服务注册中心分开注册,服务怎么知道它该往哪个中心注册?如果那个服务注册中心master和slave挂了怎么办?

  2. 一个服务注册中心master挂了后,slave自动升级为master,服务拉取的时候如何知道需要从master拉取转为从slave拉取?

回答:

  1. 要给服务注册中心再做一个路由中心的角色,维护不同的客户端到注册中心的映射关系,也可以是客户端知道所有注册中心的地址,自己随机去选择一个,不需要路由了

  2. master和slave都挂了,那就彻底完了,一般不会这样

  3. master挂了,客户端感知到,自动连接他的slave,从slave抓取



问题:

老师有一点不懂,下单流程图第一步为什么是订单系统确认订单呢?不应该是用户下单,然后订单系统确认订单嘛?


回答:
第一步是用户确认订单,用户在购物车提交订单,会进入一个确认订单的界面

问题:

QPS = 并发量 / 总执行时间,文中说“这个系统每天高峰期大概会有2000左右的QPS,也就是每秒会有2000左右的请求过来”这句话不太正确吧。


回答:

你的那个公式理解有误,QPS是一种瞬时值。


文章里说了,QPS往往是曲线波动的,在一个小小的时间段内,比如高峰期的10分钟内,QPS可能会达到最高



问题:

我们系统的压力主要来自数据库mysql的压力。随着业务量的增大,单表数据量也会越来越大,可能最后一张表里有千万级甚至亿级数据,这时候要考虑数据库的查询优化了


还有我想问一下,在数据量非常大的情况下如何提高分页查询的效率?


回答:
数据量非常大时候的分页查询优化,需要在分库分表的基础上引入数据库中间件和一些其他的技术方案,关于这个后续会有一个专门的专栏,讲海量数据架构的设计实战,也会用订单系统这个案例


问题:

公安局的大数据项目一人一档,job计算前一天抓拍数据的统计结果,和同步抓拍图片,每天图片数上亿张,这个时候用kafka同步每个人的数据,就会较同步工具,来批量统计,性能差些吧?


回答:
是的,这就是你们的核心链路,那么你就可以思考一下,这个核心链路有没有什么性能问题?


问题:

文中说的系统的压力主要是来自高并发和数据库的压力,是不是应该还有其他的压力?除了要考虑系统压力之外,是不是还要考虑系统安全?


回答:
安全性不是压力,通常考虑的压力主要是高并发、大数据量、高性能、高可用这些问题


问题:

QPS和峰值是不是都得考虑 系统的线程池连接数以哪个为准?


回答:
一般要按照峰值的来确定,能抗住峰值的,平时也能抗住


问题:

老师,核心业务都是直接落库吗?不是说数据库容易成为瓶颈吗?所以就会出现读写分离是吗?


回答:
是的,但是数据库这块的东西后面会专门开一个海量数据架构设计实战的专栏来讲


问题:

感谢老师的回答。老师,为啥不要走数据同步的方案呢,利用接口去其他系统取数据过来处理,请问这样有什么好处呢?


回答:
同步数据落地自己这里的一个库,这样一份数据两次冗余存储了,不是增加公司成本么,而且万一同步过程有问题,数据不一致了呢?


问题:

分析了一下我们目前做的物流系统, 物流系统请求处理的时间95%在450ms以内处理完, 其中几次数据库的读写都在20ms左右,主要是请求第三方物流的接口时间耗时在300ms左右


现在系统是4台(4核8G)的容器部署, 按SpringBoot 200的默认线程数计算, 一秒钟可以处理2 * 200 * 4 = 1600个请求,


假如qps增加到5000, 因为线程数是200, 即使QPS达到5000,多余的请求只会在OS中的Epoll模型中排队吧, 所以应该对系统影响不大吧


请问我这么理解对不对? 还有想问一下, 如果Epoll的内存占满了系统操作系统是不是会拒绝后面的请求?


回答:

你的情况是典型的web系统,就是操作数据库。 但是你可以考虑一下,核心请求链路,涉及哪些环节?


比如哪些数据库操作环节?哪些第三方接口环节?这个核心请求链路的性能还有优化的空间吗?


看你描述的,就是第三方接口的请求速度比较慢,那么这个第三方接口你可以关注一下,后续跟着专栏学习后,再做进一步优化



问题:

“高峰期2000左右的QPS,也就是每秒会有2000左右的请求过来”,这句话有误吧,QPS不等于并发数,除非2000请求过来并能1秒内能全部响应。


回答:
看来你对QPS的理解有误,QPS,全称是Query Per Second,意思就是每秒的查询数,现在往往延伸理解为每秒系统的请求数量


问题:

老师,日活百万,高峰QPS过万,这种体量算互联网哪个梯队的公司呀,面试有竞争力嘛


回答:
基本就是个还不错的创业公司


问题:

请问一下, 文章中说系统压力最大的时候是晚上8-9点, 这个时候QPS会达到2000, 那是不是可以理解系统每天只有一个小时在满负荷运转, 余下95%的时间大部分资源都处于闲置的状态, 这是不是也是一种浪费啊, 我这么理解对不对?


回答:
确实是可以这么理解的,所有机器配置都是按照高峰期配置的


问题:

技术文章就得这么讲,有图还有故事,太干的文章真没心情看。但这篇文章干中有湿,真的好湿!😄


回答:
多谢支持!


问题:

老师好,有个疑问,最后这张图,步骤5和步骤6需要走支付系统?


我理解的是获取支付界面后,客户端支付sdk直接和第三方支付服务端交互了,支付系统只需要等待异步回调。


回答:
是的,你的理解没错,其实我也是这个意思


问题:

老师,我还是没搞明白这个预估的问题。每五个小时三五十万,怎么就利用那个半圆计算出来2000每秒的峰值请求?


回答:
那不是计算出来的,是实际线上系统观察出来的


问题:

  1. 公司目前是给便利店做平台,主要给便利店和供应商搭平台,然后我们抽佣金

  2. 目前便利店注册用户大概5W左右

  3. 个人用户量大概20W

  4. 目前采用spring cloud微服务架构

  5. 目前mysql 有读写分离,单表最大7KW数据。最近在弄分库分表

  6. 访问并发目前不高


问题:
  1. 目前在做数据统计时遇到问题,目前采用T+1,领导想改成实时,可是实时需要引入大数据框架Flink 等,需要很多服务器,不知有什么好的方案

  2. 目前公司采用RabbitMQ 中间件,在支付时 计息 等场景都有使用 ,如何对RabbitMQ进行调优


回答:

1、第一个问题: 要做实时数据统计,确实得上kafka、flink等系统,那个也是没有办法的。


如果想要做的简单点,可以基于redis做简单的数据指标统计,把统计代码嵌入到业务逻辑里去,在数据发生变更的时候,就基于redis更新数据指标

2、第二个问题: rabbitmq看来在你们那里已经有很多运用场景了,非常的好,后续可以跟着专栏学一下rocketmq,多拓展一个技术,同时学习一些mq的生产环境的问题解决方案,你可以反过来思考一下rabbitmq如何解决


问题:

老师,就上一个问题,你说线上观察出2000峰值请求,是怎么观察得到的,能具体说下吗?







请到「今天看啥」查看全文