之前呢。反正多多少少了解过一些。
- 从java基础起家,到了SSM,由于需求从而接触到一些架构方面的东西,然后接触到水平扩展—>垂直扩展—>扩完了之后出现了四个问题—>不同的公司提出了自己不同的解决方法,那里面东西好多呀。
- 然后呢,不知道为什么,就感觉服务注册与发现这几个字印象很深,只对这几个子有了感觉,那就看看呗,看完记录一下笔记。
- 然后呢,由于Spring Cloud与Dubbo的相爱相杀、爱恨情仇,不知不觉把Dubbo也了解了一下
嘶…,要进了公司后,有这么一天。
老板说:小胡呀,你明天先去跟客户群交流调研一下,确定一下需求
胡:(内心独白)。这是让干啥去呀,如果说是可以延长我职业生涯的活的话,那不就是…
基础软件开发
方面的:操作系统、计算机网络、数据库、编程语言… 这些领域需要长期的积累,并且技术变化很慢,只要技术不断精进不断积累,可以越老越吃香。- 就另外一种情况就是:我可以用的继续,让我自己或者带着一群人去解决客户的业务需求
- 客户的业务问题多种多样,需要不同的架构、不同的技术方案来应对,对于咱们年轻人来说,需要不断地积累经验,利用自己学的东西成功解决问题的次数越多,经验就越丰富。那这样以来,首先咱们
需要和客户面对面的进行顺畅的沟通,帮助他把真正的需求提取出来,然后做出架构设计,详细设计,最终写代码给实现了,写出代码后还得能测试,并且会重构,使得项目的架构能够不断演进以便能够应对不同的多样的变化
。小项目自己写,大项目带一帮人写。
老板:小胡,小胡,…
- 客户的业务问题多种多样,需要不同的架构、不同的技术方案来应对,对于咱们年轻人来说,需要不断地积累经验,利用自己学的东西成功解决问题的次数越多,经验就越丰富。那这样以来,首先咱们
胡:哎老板,你继续说吧,我在听,老板一脸疑惑,这小伙得是还没睡醒。
老板:然后的事就是,我需要你模仿你们封装底层技术,向上层提供一个接口或者一个访问点(因为我觉得往大了说不一定都是提供一个方法或者一个类供别人调用,也可以提供一个其他的什么,虽然我不知道有什么,hahaha)这种思想。总结一下咱们公司关于系统设计与实现的文档,然后新进来的选手们可以以此文档作为学习,上手工作或者遇到问题也可以思考,而不是这百度一下那百度一下…整起。
- 那如果系统设计的话,不能只限于某一个系统吧,多参考一点,就像写毕业论文一样,先看好多论文横纵向比较,然后再提取出自己的点去下手。整整整。
- 第一步:首先明确使用场景、人家给的条条框框约束
- 给谁用呀
- 系统的目标群体是什么
- 用的人会怎样用
- 用多少用户
- 要处理多少数据。后面对应乱七八糟的数据表,用户表、xxx表…
- 系统要发挥的作用是啥呀
- 系统的输入输出是啥
- 我们系统的对手是谁,或者说我们要处理什么数据,处理多少数据,咋处理,用啥方式处理,一秒处理多少个请求
- 读写比率
- 给谁用呀
- 第二步:就像DB中设计数据库一样,是不是得先设计出表之间的关系,画一画呗,咱们Java中不是也有UML类图啥的嘛,我感觉都是一个道理。咱们画出主要的组件和连接
- 例如按类别功能设计亚马逊的销售排名或者在云平台上设计一个可扩展到数百万用户的系统,这个是个完整的架构图,在这一步只需要画出一个抽象的架构图即可,不需要这么具体。
- 例如按类别功能设计亚马逊的销售排名或者在云平台上设计一个可扩展到数百万用户的系统,这个是个完整的架构图,在这一步只需要画出一个抽象的架构图即可,不需要这么具体。
- 第三步:然后分组或者分队,或者你是一个人的话分时间对每一个核心组件进行详细深入的分析。例如让你设计一个url短网址,你需要考虑这些问题:
- 数据库查找怎么进行、加密方面的MD5和 Base62、Hash碰撞产生了怎么办、用SQL还是NoSQL还是一起用、生成并存储一个完整URL的hash如何实现、API和面向对象设计。
- 第四步:扩展设计或者说对系统进行优化。当然,咱们古人已经就发现了,鱼和熊掌不可兼得,所以可能的解决办法或者会有取舍,具体问题具体分析呗。
- 要不要水平扩展或者垂直扩展(因为你要高可用啥的)
- 其中涉及到:
- 服务注册与发现,你服务提供者太多,人家服务消费者咋知道我找你那个要我找的东西呢,那你是不是得搞个负载均衡,帮助人家服务消费者从服务提供者的列表中选择出一个唯一的URL供我发请求进行调用
- 然后呢,为了稍微快一点,我是不是得搞个缓存,Redis缓存还是其他什么的,我觉的缓存的话可以这样理解。比如我想到我媳妇家去,但是路太远,所以由于主观和客观的两方面因素制约,我指定的两种出行方案:总之不管是主观还是客观,反正就是用缓存了。
- 首先,中间搞个缓存,然后我先把这次过去要带的东西,比如我自己啦、一只能唱能跳能rap,还经过两年实习生训练的狗狗、一些吃的、几瓶饮料等。分批先送到缓存中,再从缓存中递送过去。比如这个缓存就是我的一个亲戚家
- 其次的方案就是带的东西其实不多,但我就是想走走逛逛,也是先短时间赶过去有些类,所以就是因为路太长这个客观因素,我选择分段过去,有多个缓存,
- 其中涉及到:
- 后端跟数据分不开,数据又跟数据库分不开,数据库中数据多了那就跟分库分表分不开咯。
- 除了分库分表啥的,你索引用多用少是不是得不能乱来、
- SQL优化啥的是不是要多注意下。除了SQL优化,数据库中还有很多能够提高查询效率或者说增删改查的效率的注意事项或者说操作,也就是那些
这些个场景下这个能用那个不能用、这个不能用太多、那个不能用太少、要注意把这俩结合起来、把那个拆分开来、搞个中间层或者中间件或者代理啥的、选静态还是选动态的、编译期来干还是运行期来干...
- 要不要水平扩展或者垂直扩展(因为你要高可用啥的)
- 当然啦,优化都是有标准的,咱们设计的系统肯定也有衡量他的一些性能指标:ctrl+F搜搜,衡量网站的性能指标
- 这个https://github.com/donnemartin/system-design-primer网站中给了一些例子,不过我觉得例子结合知识点玩起来会更好一点,或者说落地性更强一点:
- 第一步:首先明确使用场景、人家给的条条框框约束
- 比如,到了午饭时间,几个同事或者好朋友在一起聊天:
PART:MQ我只知道下面这些理论,确实没用过:
- 为啥使用MQ?
- 使用MQ的场景很多,主要有三个:解耦、异步、削峰。
- 解耦:假设现在,日志不光要插入到数据库里,还要在硬盘中增加文件类型的日志,同时,一些关键日志还要通过邮件的方式发送给指定的人。那么,如果按照原来的逻辑,
A可能就需要在原来的代码上做扩展
,除了B服务,还要加上日志文件的存储和日志邮件的发送。但是,如果你使用了MQ,那么,A服务是不需要做更改的
,它还是将消息放到MQ中即可,其它的服务,无论是原来的B服务还是新增的日志文件存储服务或日志邮件发送服务,都直接从MQ中获取消息并处理即可,这不就相当于替代了扩展了嘛【通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。】
。这就是解耦,它的好处是提高系统灵活性,扩展性。
- 异步:可以将一些非核心流程,如日志,短信,邮件等,通过MQ的方式异步去处理。这样做的好处是缩短主流程的响应时间,提升用户体验。
- 削峰:MQ的本质就是业务的排队。所以,面对突然到来的高并发,MQ也可以不用慌忙,先排好队,不要着急,一个一个来。削峰的好处就是避免高并发压垮系统的关键组件,如某个核心服务或数据库等。
- 解耦:假设现在,日志不光要插入到数据库里,还要在硬盘中增加文件类型的日志,同时,一些关键日志还要通过邮件的方式发送给指定的人。那么,如果按照原来的逻辑,
- MQ的分类及优缺点:
- 芋道源码老师的实操经验:一个线上服务OOM的问题的分析定位排查过程,他们有个mq消费者服务,在某一天下午,出现OOM了,导致服务直接挂掉。---->dump了当时的内存快照----->查看了prometheus上的服务监控----->锁定了excel文件导入导出功能
如果出现了线上OOM问题,为了不影响用户的正常使用,最快的解决办法就是重启服务,但重启服务治标不治本,只能临时解决一下问题,如果不找到真正的原因,难免下次在某个不经意的时间点,又会出现OOM问题,所以,有必要定位一下具体原因
。
未完待续…
- 使用MQ的场景很多,主要有三个:解耦、异步、削峰。
巨人的肩膀:
github.com/donnemartin/system-design-primer
码农翻身老师的文章
设计模式之禅
Head First设计模式
程序员库森
javaguide
SpringForAll老师的文章