这段代码明明很简单,日常跑的都没问题,怎么一大促就卡死甚至进程挂掉?大多是因为设计时,就没针对高并发、高吞吐量case考虑过内存管理。1 自动内存管理机制的实现原理内存管理主要考虑:1.1 申请内存计算要创建对象所需要占用的内存大小在内存中找一块儿连续并且是空闲的内存空间,标记为已占用把申请的内存地址绑定到对象的引用上,这时候对象就能使用1.2 内存回收内存回收大概做这俩事:找出所有可回收对象,将
工作中,你可能经常遇到Page Cache相关场景,如:服务器load飙升服务器I/O吞吐飙升业务响应时延出现突出的毛刺业务平均访问时延明显增加这些都可能由于Page Cache使用不当导致,其不当使用不仅会增加系统I/O吞吐,还会引起业务性能抖动。但很多 crud boy对Page Cache理解仅停留在概念上,完全不知道Page Cache怎么和应用系统联系。要理解Page Cache,最直观
物理网卡明明是块小板子,为何跟和eth0对应?为何还能给物理网卡配置IP地址?1 类比人=》物理网卡人的姓名=》网卡接口名称人的档案信息(保存在公安机构)=》网卡接口的配置信息公安机构=》内核你的朋友知道这名字对应你,但对派出所,不能依赖你名字识别你,因为人可能改名,也可能重名,所以人都有身份证号。派出所会根据你的档案信息做出对应处理,如户籍是杭州,某些事就得交给杭州办。网卡也一样,用户可通过网卡
分布式系统中的许多事情可能出错,最简单方法是让整个服务失效,并向用户显示错误消息。若无法接受,就得找到容错方法:即使某些内部组件出现故障,服务也能正常运行。本文讨论构建容错分布式系统的算法和协议的一些案例。假设所有问题都可能发生:网络中的数据包可能会丢失、重新排序、重复推送或任意延迟;时钟只是尽其所能近似;节点可以暂停(如GC)或随时崩溃。构建容错系统的最好方法,是找到一些带有实用保证的通用抽象,
websocket出现是因为浏览器不给开后门,不是WebSocket基于HTTP,相反可看成是HTTP基于WebSocket。1984年,人们使用TCP协议通讯,那时还没网页浏览器,都通过各种软件直接通讯。到1986,人们使用浏览器浏览网页,当时电脑时100MHz,100M内存。早年TCP链接数量有限制,不是内存,主要是select函数效率问题,select要轮询所有连接才能确定有哪些已就绪。引入
1 定义来个需求就改一次代码,似乎都习惯了,甚至觉得理所当然。反正修改也容易,只要按之前的代码再CV一份,不费脑子。但每人每次改一点点,日积月累,再来个新需求,后人改动量就很大了。每个人都很无辜,都只是简单修改一点点。但最终导致伤害后来接盘侠,代码已无法维护,直接推翻老系统,写新系统了。既然“修改”会带来这么多问题,那可以不修改吗?开放封闭原则就是一种值得努力的方向。Software enti
RC 和 快照隔离 级别可防止某些竞争条件,但并非全部。一些棘手案例,如写偏斜 和 幻读,会发现可悲情况:隔离级别难理解,且不同DB实现不一(如RR含义天差地别)若检查应用层代码很难判断特定隔离级别下是否安全,尤其是大型系统,无法预测各种并发无检测竞争条件的好工具。理论上,静态分析可能有所帮助,但更多技术还没法实际应用。并发问题测试也很难,一切取决于时机而这些还不是新问题,1970s引入了较弱隔离
表面看,RC已满足事务所需的一切特征:支持中止(原子性),防止读取不完整的事务结果,并防止并发写的混乱。这点很关键!为我们的开发省去一大堆麻烦。但此隔离级别仍有很多地方可能产生并发错误。如图-6说明RC可能发生的问题。Alice在银行有1000存款,分为两个账户,每个500。现有一笔转账交易从账户1转移100到账户2。若她在提交转账请求后、银行DB系统执行转账的过程中间,查看两个账户的余额,她可能
1.1 服务注册中心是啥?用来实现微服务实例的自动注册与发现。1.2 没有注册中心时若服务依赖如下:服务还不是很多,于是很多人就把各服务节点直接放进一个全局的配置文件 A 服务的全部 host B 服务的全部 host ...将该文件放在每个服务的远程配置中心或者本地配置文件中维护。当变更时,只有确实需要改变的服务团队才会修改其配置文件,最后就变成:需全局配置文件各模块各自维护变更时就很不方便,
复制的重要可选项:同步复制,synchronously异步复制,asynchronously关系型DB 中,这通常是个可配置项,而其他系统通常是硬性指定或只能二选一。如图-1案例,网站用户更新个人头像图片的流程:客户向主节点发送更新请求主节点收到请求。某刻,主节点又将数据更新转发给从节点最后,主节点通知客户更新完成图-2显示了系统各模块间通信情况。请求或响应标记为粗箭头。图-2中:从节点1是同步复
若两个事务不触及相同数据,即无数据依赖关系,则它们能安全并行运行。只有当:某事务读取由另一个事务同时修改的数据时或两个事务同时修改相同数据才会出现并发问题。并发 BUG 很难通过测试找到,因为这样的错误只有在特殊时序下才会触发。这样的时序问题可能非常少发生,通常很难重现 [^译注i]。并发性也很难推理,特别是在大型应用中,你不一定知道哪些其他代码正在访问DB。只有一个用户访问数据时,应用开发就够麻
苛刻的数据存储系统中,很多可能出错的case:数据库软件、硬件可能随时失效(包括正在执行写操作的过程中)应用程序可能随时崩溃(包括一系列操作的中间某步)网络中断可能会意外切断数据库与应用的连接,或数据库之间的连接。多个客户端可能同时写入DB,导致数据覆盖客户端可能读到无意义的、部分更新的数据客户端之间由于边界条件竞争所引入的各种奇怪问题为实现高可靠,系统必须处理这些问题。但完善容错机制工作量巨大,
从最基本层面看,数据库只需做两件事:向它插入数据肘,它就保存数据之后查询时,返回那些数据本文讨论如何存储输入的数据,并在收到查询请求时,如何重新找到数据。为何关注数据库内部的存储和检索呢?你不可能从头开始实现存储引擎,往往需要从众多现有的存储引擎中选择适合业务的存储引擎。 为针对特定工作负载而对数据库调优时,就得对存储引擎底层机制有所了解。针对事务型工作负载、分析型负载的存储引擎优化存在很大差异。
软件大部分成本其实不在最初开发阶段,而是在于整个生命周期内的持续投入,包括维护与bug修复,监控系统来保持正常运行、故障排查、适配新平台、搭配新场景、技术缺陷完善及增加新功能。可惜许多程序员不喜欢维护这些所谓的遗留系统,例如修复他人埋下的bug或使用过时的开发平台或被迫做不喜欢的工作。每个遗留系统总有过期理由,所以很难给出通用建议该如何对待它们。但换个角度,可从软件设计时就开始考虑,尽可能减少维护
即使系统现在可靠,不代表将来一定可靠。发生退化的最常见原因是负载增加:并发用户从最初的10,000 增长到 100,000或系统目前处理数据量超出之前很多倍。可扩展性,描述系统应对负载增加的能力。它不是衡量一个系统的一维指标, 谈论“系统X是可扩展 ”或“不扩展”无太大意义。相反,讨论可扩展性通常得考虑:“若系统以某种方式增长,应对措施有啥”, “该如何添加计算资源来处理额外的负载”3.1 描述负
1 简介Flyweight Design Pattern,结构型模式。享元模式中的“享元”指被共享的单元。享元模式通过复用对象,以达到节省内存的目的。用于减少创建对象的数量,以减少内存占用和提高性能。尝试复用现有的同类对象,如果未找到匹配的对象,则创建新对象。意图:运用共享技术有效地支持大量细粒度的对象。主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务
1 简介一般有两种方式给一个类或对象新增行为:继承 子类在拥有自身方法同时还拥有父类方法。但这种是静态的,用户无法控制增加行为的方式和时机关联 将一个类的对象嵌入另一个对象,由另一个对象决定是否调用嵌入对象的行为以便扩展自身行为,这个嵌入的对象就叫做装饰器(Decorator)2 定义结构型模式。动态给一个对象增加额外功能,装饰器模式比生成子类实现更为灵活。装饰模式以对用户透明的方式动态给一个对象
1 定义Bridge Design Pattern,将抽象部分与它的实现部分分离,使之任意删减,而无需受其它约束。Decouple an abstraction from its implementation so that the two can vary independently,将抽象和实现解耦,让它们可以独立变化。2 结构Abstraction: 定义抽象类的接口,维护一个指向Imple
1 前言有时一个对象的行为取决于一或多个动态变化的属性(状态),这样的对象称为有状态(stateful)对象,其对象状态是从事先定义好的一系列值中取出。当这样的对象与外部事件产生互动时,内部状态就会改变,对象行为也随之变化。在UML中可使用状态图描述对象状态的变化。在状态模式中,创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。2 定义该模式下,类的行为基于其状态而改
看着自己每次根据设计原则及模式的代码重构,虽然效果还不错,但你肯定也自省过:如果我的每段代码都这么写,是不是过度设计了?把握设计的度,确需长久锤炼。行业也总结了很多原则,帮助我们把握设计的度。它们是一种思考方法、一种行为准则。KISSKeep it simple, stupid,保持简单、愚蠢。提醒我们大多数系统,与其变得复杂,保持简单能让系统运行更好。越资深的人,越觉得这大有道理。因为大佬们见识
若 Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖。所以通过让bean 实现 Aware 接口,则能在 bean 中获得相应的 Spring 容器资源。Aware接口是回调,监听器和观察者设计模式的混合,它表示bean有资格通过回调方式被Spring容器通知。 有时,我们得在 Bean 的初始化中使用 Spring 框架自身的一些对象来执行一些操作,比如获取 Se
间隙锁+行锁,很容易判断是否会出现锁等待。而间隙锁在可重复读隔离级别(RR)下才有效,因此本文默认RR。1 加锁规则原则1 加锁的基本单位:next-key lock,前开后闭原则2 查找过程中,【访问到的对象】才会加锁,加的默认的next-key lock优化1 索引上的等值查询,给【唯一索引】加锁时,next-key lock退化为行锁(记录锁)优化2 索引上的等值查询,【非唯一索引】向右遍历
基于贫血模型的传统开发模式基于充血模型的DDD开发模式如何分别用这两种开发模式,设计实现一个钱包系统。1 业务分析具有支付、购买功能的应用(如京东、哈啰出行)都支持钱包功能。应用为每个用户开设一个系统内的虚拟钱包账户,支持用户充值、提现、支付、冻结、透支、转赠、查询账户余额、查询交易流水。钱包功能界面:每个虚拟钱包账户都对应用户的一个真实的支付账户,如银行卡账户、三方支付账户(支付宝、微信钱包)。
“这代码真烂”或“代码写得真好”。这描述太笼统,具体怎么烂了、怎么就好了?也有一些工程师对如何评价代码质量有所认识,如好代码易扩展、易读、简单、易维护,但更深入的,“怎么算可读性好?代码怎么算易扩展、易维护?可读、可扩展与可维护之间有什么关系?可维护中‘维护’两字该如何理解?”如果连啥是好代码、烂代码,都分不清,又谈何写好代码?如何评价代码质量的高低?对代码质量的一种描述:“好”笼统地表示代码质量
看了很多基础的书籍,比如操作系统、组成原理、编译原理等,但还是觉得很迷茫,觉得在开发中用不上,起码在平时的CRUD业务开发中用不上。实际上,这些基础的知识确实很难直接转化成开发“生产力”。但是,它能潜移默化地、间接地提高你对技术的理解。不过,我觉得,设计模式和操作系统、组成原理、编译原理等这些基础学科是不一样的。它虽然也算是一门基础知识,但是它和数据结构、算法更像是一道儿的,相比那些更加基础的学科
开始日期:"2021-08-31"结束日期:"2021-11-30"在上述两个日期之间的91天持续时间,期望代码返回3个月的持续时间,但是以下方法仅返回2个月。这是Java 8中的bug 吗?日期为91天,却仅返回2个月。Period diff = Period.between(LocalDate.parse("2021-08-31"), LocalDate.parse("2021-11-
1 Scenario 场景电商系统的促销手段(Electronic Commerce Systems):优惠券拼团砍价老带新优惠券的种类满减券直减券折扣券优惠券系统的核心流程发券 发券的方式:同步发送 or 异步发送领券谁能领?所有用户 or 指定的用户 领取上限一个优惠券最多能领取多少张? 领取方式用户主动领取 or 自动发放被动领取用券作用范围商品、商户、类目 计算方式是否互斥、是否达到门
案例demo 类 起俩线程分别执行add、compare 乍一看,a、b“同时”自增,应该一直相等,compare中的判断不会为true。但是看日志:不仅有a<b成立,a>b有时也为 true。 评论里肯定有人在这里就笑了,这是你的代码太垃圾,操作两个字段a和b,有线程安全问题,应该为add方法加上锁,确保a和b的++是原子性的,就不会错了。那么,就在add方法加锁看看?public
通过监控的报表和一些报警规则的设置,你能实时跟踪和解决垂直电商系统中出现的问题。但监控只能发现目前系统中已存问题,对未来可能发生性能问题无能为力。一旦你的系统流量有大长,比如大促活动流量,那你在面临性能问题时就可能手足无措。你需要了解在流量增长若干倍时,系统的哪些组件或者服务会成为整体系统的瓶颈点,这时你就需要做一次全链路压测。1 压力测试是啥?1.1 错误的压测姿势搭建一套与生产环境功能相同的测
Redis事务和乐观锁原理详解得益于Redis单线程模型的内存处理,没有并发事务,所以无隔离级别概念。1 事务命令1.1 MULTIMUIIT命令执行,标识一个事务的开始,它总返回 OK 。收到该命令后,Redis就知道,接下来再收到的命令需要放到一个内部队列,当EXEC命令被调用时,所有队列中的命令才会被执行,保证原子性。1.2 EXEC表示一系列原子性操作的结束。Redis收到该命令,表示所有
Copyright © 2005-2025 51CTO.COM 版权所有 京ICP证060544号