消息队列
为什么主要作用: 异步:提高系统响应速度以及吞吐量 削峰填谷:稳定平滑系统流量 解耦:减少服务之间的影响,提高系统整体的稳定性以及扩展性 主要缺点MQ 是基于事件驱动的。消息由生产者发送到MQ进行排队,然后按FIFO的顺序交由消息的消费者进行处理。其主要缺点: 系统可用性降低:外部依赖增加,稳定性变差,要考虑MQ的高可用 系统复杂度提高:消息链路追踪复杂,顺序也要保证 消息一致性问题 怎么用(生产环境关注公有云服务)公有云产品官网消息队列全景:https://www.aliyun.com/product/ons?spm=5176.23056729.J_3207526240.58.3dcc3f06fc3SNi MQTT 是给车联网使用, 适合消息比较小且多的跨端消息传输 rabbit 主要是为了原有使用 rabbit 的项目快速迁移,以及增强了 rabbitMQ 的稳定性,降低了运维的成本 kafka 主要用来给大数据日志分析使用, eventBridge 主要用来给 SaaS 平台提供事件总线的能力,实现不同系统之间的解耦以及数据的事件通知机制。如果平台和 Even...
消息端到端的一致性与可靠性
TCP其实自带超时重传机制,保证了消息可靠性的传输,那么为什么我们还要再去讨论和实现 消息可用 呢? TCP究竟帮助我们做到哪一步? 客户端A 发送 msg1和msg2两个消息给到服务端。 msg1和msg2在一个tcp链接上到达服务端。 理论上来说,msg1 和 msg2 是遵循顺序从客户端 A 发送到服务端的,似乎消息是一定收到的,但是这其实是一个端到端可靠性的问题,TCP 作为传输层协议,只能说消息可靠到达了传输层,但是不能说消息可靠到达了业务层。 问题 在传递给业务层时服务端进程崩溃,但客户端A认为已经送达,服务端业务层无感知, 自然无法发送到客户端 B,因此消息丢失。 msg1和msg2到达应用层, 解析后交由两个线程处理, 可能msg2 消息体小一些,msg1 消息体大一些,导致了m2 先解析完毕,落表后先发送给客户端 B, 造成消息乱序。 msg1消息存储失败,msg2消息存储成功先发送给了客户端B,造成丢失且乱序。 !!! tips 洞见: TCP/UDP是双方通信 (本质上是 C/S 模式),而IM本质上是三方通信。 技术...
用户和系统CPU使用率升高
CPU节拍率和节拍数为了维护 CPU 时间,Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 Jiffies 记录了开机以来的节拍数。每发生一次时间中断,Jiffies 的值就加 1。 节拍率 HZ 是内核的可配选项,可以设置为 100、250、1000 等。不同的系统可能设置不同数值,你可以通过查询 /boot/config 内核选项来查看它的配置值。节拍率设置成了 250,也就是每秒钟触发 250 次时间中断。 12grep 'CONFIG_HZ=' /boot/config-$(uname -r)CONFIG_HZ=250 节拍率 HZ 是内核选项,所以用户空间程序并不能直接访问。为了方便用户空间程序,内核还提供了一个用户空间节拍率 USER_HZ,它总是固定为 100,也就是 1/100 秒。这样,用户空间程序并不需要关心内核中 HZ 被设置成了多少,因为它看到的总是固定值 USER_HZ。 CPU 使用率计算(一段时间内的)数据空闲和总的时间来自于 <font style=...
消灭重复代码的最佳实践
代码重复本身不可怕,可怕的是漏改或改错。消灭重复代码,降低改动可能引入的风险。 学习笔记:https://time.geekbang.org/column/article/228964 工厂模式 + 模板方法 消除 if else 和重复代码假设要开发一个购物车下单的功能,针对不同用户进行不同处理: 普通用户需要收取运费,运费是商品价格的 10%,无商品折扣; VIP 用户同样需要收取商品价格 10% 的快递费,但购买两件以上相同商品时,第三件开始享受一定折扣; 内部用户可以免运费,无商品折扣。 我们的目标是实现三种类型的购物车业务逻辑,把入参 Map 对象(Key 是商品 ID,Value 是商品数量),转换为出参购物车类型 Cart。 原始代码12345678910111213141516171819202122232425262728//购物车@Datapublic class Cart { //商品清单 private List<Item> items = new ArrayList<>(); //总优惠 ...
策略设计模式Strategy
Comparable 是被比较对象和比较策略没有解耦 Comparator 是被比较对象和比较策略解耦了,在真正要比较的时候才会定义比较策略。这就是策略模式****(实现比较策略和被比较对象的解耦) 相比于策略模式,非策略模式不符合开闭原则,比如Comparable想要修改比较方法,必须修改实现类的内部。而使用了策略模式的Comparator就不需要 详细版业务逻辑可能有很多方式都可以实现某个具体的功能。例如,按照购买次数对一个用户购买的全部商品进行排序,从而粗略地得知该用户复购率最高的商品,我们可以使用多种排序算法来实现这个功能,例如,归并排序、插入排序、选择排序等。 之前都是if else,新增的时候直接追加 在策略模式中,我们会将每个算法单独封装成不同的算法实现类(这些算法实现类都实现了相同的接口),每个算法实现类就可以被认为是一种策略实现,我们只需选择不同的策略实现来解决业务问题即可,这样每种算法相对独立,算法内的变化边界也就明确了,新增或减少算法实现也不会影响其他算法。 StrategyUser 是算法的调用方,维护了一个 Strategy 对象的引用,用来选择...
案例分析-DDOS攻击、网络延迟(延迟确认纳格算法)、NAT延迟
DDoS 攻击DDoS 的前身是 DoS(Denail of Service),即**拒绝服务攻击,指利用大量的合理请求, 来占用过多的目标资源,从而使目标服务无法响应正常请求。** DDoS(Distributed Denial of Service) 则是在 DoS 的基础上,采用了分布式架构,利用多台主机同时攻击目标主机。这样,即使目标服务部署了网络防御设备,面对大量网络请 求时,还是无力应对。 DDoS 类型 耗尽带宽。无论是服务器还是路由器、交换机等网络设备,带宽都有固定的上限。 带宽耗尽后,就会发生网络拥堵,从而无法传输其他正常的网络报文。 耗尽操作系统的资源。网络服务的正常运行,都需要一定的系统资源,像是 CPU、内存等物理资源,以及连接表等软件资源。一旦资源耗尽,系统就不能处理其他正 常的网络连接。 消耗应用程序的运行资源。应用程序的运行,通常还需要跟其他的资源或系统交互。如果应用程序**一直忙于处理无效请求,也会导致正常请求的处理变慢,甚至得不到响 应。** 构造大量不同的域名来攻击 DNS 服务器,就会导致 DNS 服务器不停执行迭代查询****,并更新缓存...
简单计算机模型MARIE
CPUCPU中的寄存器 保存数据、地址、控制信息 常见:存储信息的寄存器、数值移位的寄存器、数值比较的寄存器、计数寄存器、存储中间结果的寄存器、控制循环的索引寄存器、管理处理堆栈的堆栈指针寄存器、保持各种工作状态和操作模式溢出进位的寄存器、和给程序员使用的通用寄存器。 CPU中的算数逻辑单元ALU 执行逻辑运算和算数运算 通过控制单元发出的信号,ALU可以执行规定的计算 在ALU执行的操作会影响状态寄存器的某些数据位(状态寄存器存放特殊的操作状态,溢出进位借位等等),指示是否有溢出等发生 CPU中的控制单元 取指令:使用程序计数器PC确定要执行哪一条指令 指令译码:确保数据适合时间出现在正确的地方 通知ALU使用哪一个寄存器,执行哪些中断服务程序 总线多条线路组成,允许多位数据并行传递 总线周期:完成总线信息传送所需的时钟脉冲间隔 总线分类有哪些? 按照对象个数分为:点对点和多点总线 按照功能分为:数据总线、控制总线、地址总线、电源线 按照传输的信息种类黑使用的设备不同分为: 处理器内存总线:比较短,告诉总线,通常是专门设计的,最大限度提高带宽 IO总线:允许多种类型的不同...
系统监控与应用监控
很多应用都是等到用户抱怨响应慢了,或者系统崩 溃了后,才发现系统或者应用程序的性能出现了问题。虽然最终也能发现问题,但显然,这 种方法是不可取的,因为严重影响了用户的体验。要解决这个问题,就要搭建监控系统,把系统和应用程序的运行状况监控起来,并定义一系列的策略,在发生问题时第一时间告警通知。 监控系统要涵盖系统的整体资源使用情况,比如我们前面讲过的 CPU、内 存、磁盘和文件系统、网络等各种系统资源。不仅可以将系统资源的瓶颈快速暴露出 来,还可以借助监控的历史,事后追查定位问题。 而从应用程序来说,监控系统要涵盖应用程序内部的运行状态,这既包括进程的 CPU、磁盘 I/O 等整体运行状况,更需要包括诸如接口调用耗时、执行过程中的错误、内部对象的 内存使用等应用程序内部的运行状况。 系统监控USE 法指标分类专门用于性能监控的 USE(Utilization Saturation and Errors) 法。USE 法把系统资源的性能指标,简化成了三个类别,即**使用率、饱和度以及错误数**。 使用率,表示资源用于服务的时间或容量百分比。100% 的使用率,表示容量已经...
系统软件
编译时绑定Compile time binding :给定明确的代码 装载时绑定Load time binding:装载到内存里面不可以再修改 运行时绑定Run time binding:模块不运行就不会加载 链接:不同的二进制文件形成一个单一的可执行文件,编译的时候先生成一个符号表,之后再替换 动态链接:链接推迟到加载时或者运行时,外部模块通过动态链接库装载 装载时动态链接 运行时动态链接:减少装载时的负担,第一次调用的时候需要链接一下,所以第一次比较慢,但是之后就好了,使得程序的模块的更小一些,每次运行不是所有的模块都会调用,但是程序员不能很好的控制动态链接库,安全性不一定好
缓存和数据库数据的一致性
缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的 问题 Redis 的 qps 可以达到 10 万每秒,对于一般体量的互联网公司,一台机器就够了。但不论是什么业务,都不得不面对一个棘手的问题:那就是 Redis 和源数据的一致性问题。 对高可用、成本、一致性的权衡,进入到了特事特办的场景,甚至要考虑基础设施 读多写少的情况加入缓存提高性能,如果写多读多的情况又不能容忍缓存数据不一致,那 就没必要加缓存了,可以直接操作数据库。放入缓存的数据应该是对实时性、一致性要求不是很高的数据。切记不要为了用缓存,同时又要保证绝对的一致性做大量的过度设计和控制,增加系统复杂性! 整个架构的演进和推演过程与需求息息相关,你需要掌握“推演”能力,并用实践去证明你的方案。 没有最好的设计,只有最合适的设计,和模板化的思考问题的思路。 一致性问题来源缓存:读、写、更新、删除,这些操作可能失败; 数据库:读、写、更新、删除,这些操作可能失败。 getFromDB(key) getFromRedis(key) putToDB(key,value) putToRedis(key,va...
