高性能架构探索

其他

【强力推荐】C++经典之作

标准,对改进模板或与模板交互的特性进行了解释,包括可变参数模板、泛型lambda、类模板参数演绎等。本书在内容编排上分为模板基础概念、深入模板细节、模板设计与编码三个部分。读者只要具备初级的
2023年12月21日
其他

【Modern C++】深入理解左值、右值

你好,我是雨乐!作为C/C++开发人员,在平时的项目开发过程中,或多或少的听过左值和右值的概念,甚至在编译器报错的时候,遇到过lvalue和rvalue等字样;甚至使用过std::move(),但是不知道其含义。作为多年的C++开发人员,一直以来,对左值右值的理解没有一个系统的认识,总感觉似懂非懂。今天,借助本文,详细的介绍下这些知识点,并从代码实例的角度去分析什么是左值或者右值,同时,也算是给自己知识点做一个总结。背景
2022年2月16日
其他

智能指针-使用、避坑和实现

你好,我是雨乐!在上篇文章(内存泄漏-原因、避免以及定位)中,我们提到了用智能指针来避免内存泄漏,今天借助本文,从实践、避坑和实现原理三个角度分析下C++中的智能指针。本文主要内容如下图所示:智能指针的由来auto_ptr为什么被废弃unique_ptr的使用、特点以及实现shared_ptr的使用、特点以及实现weak_ptr的使用、特点以及实现介绍笔者在工作中遇到的一些职能指针相关的坑,并给出一些建议背景内存的分配与回收都是由开发人员在编写代码时主动完成的,好处是内存管理的开销较小,程序拥有更高的执行效率;弊端是依赖于开发者的水平,随着代码规模的扩大,极容易遗漏释放内存的步骤,或者一些不规范的编程可能会使程序具有安全隐患。如果对内存管理不当,可能导致程序中存在内存缺陷,甚至会在运行时产生内存故障错误。换句话说,开发者自己管理内存,最容易发生下面两种情况:申请了内存却没有释放,造成内存泄漏使用已经释放的内存,造成segment
2022年1月20日
其他

内存泄漏-原因、避免以及定位

你好,我是雨乐!作为C/C++开发人员,内存泄漏是最容易遇到的问题之一,这是由C/C++语言的特性引起的。C/C++语言与其他语言不同,需要开发者去申请和释放内存,即需要开发者去管理内存,如果内存使用不当,就容易造成段错误(segment
2022年1月12日
其他

GDB调试-从入门实践到原理

你好,我是雨乐!在上篇文章中,我们分析了线上coredump产生的原因,其中用到了coredump分析工具gdb,这几天一直有读者在问,能不能写一篇关于gdb调试方面的文章,今天借助此文,分享一些工作中的调试经验,希望能够帮到大家。写在前面在我的工作经历中,前几年在Windows上进行开发,使用Visual
2022年1月5日
其他

【线上问题】P1级公司故障,年终奖不保

❝对本文有疑问的,可以公众号留言、私信,也可以加笔者微信直接交流(文末留有微信二维码);另外还有批量免费计算机电子书,后台回复[pdf]免费获取。❞大家好,我是雨乐!前段时间,某个同事找我倾诉,说是因为strict
2021年12月16日
其他

【性能优化】lock-free在召回引擎中的实现

❝对本文有疑问的,可以公众号留言、私信,也可以加笔者微信直接交流(文末留有微信二维码);另外还有批量免费计算机电子书,后台回复[pdf]免费获取。❞大家好,我是雨乐!在我们的工作中,多线程编程是一件太稀松平常的事。在多线程环境下操作一个变量或者一块缓存,如果不对其操作加以限制,轻则变量值或者缓存内容不符合预期,重则会产生异常,导致进程崩溃。为了解决这个问题,操作系统提供了锁、信号量以及条件变量等几种线程同步机制供我们使用。如果每次操作都使用上述机制,在某些条件下(系统调用在很多情况下不会陷入内核),系统调用会陷入内核从而导致上下文切换,这样就会对我们的程序性能造成影响。今天,借助此文,分享一下去年引擎优化的一个点,最终优化结果就是在多线程环境下访问某个变量,实现了无锁(lock-free)操作。背景对于后端开发者来说,服务稳定性第一,性能第二,二者相辅相成,缺一不可。作为IT开发人员,秉承着一句话:只要程序正常运行,就不要随便动。所以程序优化就一直被搁置,因为没有压力,所以就没有动力嘛😁。在去年的时候,随着广告订单数量越来越多,导致服务rt上涨,光报警邮件每天都能收到上百封,于是痛定思痛,决定优化一版。秉承小步快跑的理念,决定从各个角度逐步优化,从简单到困难,逐个击破。所以在分析了代码之后,准备从锁这个角度入手,看看能否进行优化。在进行具体的问题分析以及优化之前,先看下现有召回引擎的实现方案,后面的方案是针对现有方案的优化。广告订单以HTTP方式推送给消息系统消息系统收到广告订单消息后将广告订单消息格式化后推送给消息队列kafka(第1步)将广告订单消息持久化到DB(第2步)召回引擎订阅kafka的topic从kafka中实时获取广告订单消息,建立并实时更建立维度索引(第3步)召回引擎接收pv流量,实时计算,并返回满足定向后的广告候选集(第4步)从上面图中可以看出,召回引擎是一个多线程应用,一方面有个线程专门从kafka中获取最新的广告订单消息建立维度索引(此为写线程),另一方面,接收线上流量,根据流量属性,获取广告候选集(此为读线程)。因为召回引擎涉及到同时读和写同一块变量,因此读写不能同时操作。概述在多线程环境下,对同一个变量访问,大致分为以下几种情况:多个线程同时读多个线程同时写一个线程写,一个线程读一个线程写,多个线程读多个线程写,一个线程读多个线程写,多个线程读在上述几种情况中,多个线程同时读显然是线程安全的,而对于其他几种情况,则需要保证其_互斥排他_性,即读写不能同时进行,管他几个线程读几个线程写,代码走起。thread1{
2021年12月13日
其他

【性能优化】高效内存池的设计与实现

❝对本文有疑问的,可以公众号留言、私信,也可以加笔者微信直接交流(文末留有微信二维码);另外还有批量免费计算机电子书,后台回复[pdf]免费获取。❞大家好,我是雨乐!在之前的文章中,我们分析了glibc内存管理相关的内容,里面的是不是逻辑复杂😁,毕竟咱们用几十行代码完成的功能,glibc要用上百乃至上千行代码来实现,毕竟它的受众太多了,需要考虑跨平台,各种边界条件等。其实,glibc的内存分配库ptmalloc也可以看做是一个内存池,出于性能考虑,每次内存申请都是先从ptmalloc中进行分配,如果没有合适的则通过系统分配函数进行申请;在释放的时候,也是将被释放内存先方式内存池中,内存池根据一定的策略,来决定是否进行shrink以归还OS。那么,现一个内存池?我们该怎么实现呢?今天,借助这篇文章,我们一起来设计和实现一个内存池(文末附有github地址)。背景首先需要说明的是,该内存池是笔者在10年前完成的,下面先说下当时此项目的背景。09年,在某所的时候,参与了某个国家级项目,该项目是防DDOS攻击相关,因此更多的是跟IP相关,所以每次分配和释放内存都是固定大小,经过测试,性能不是很满意,所以,经过代码分析以及性能攻击分析,发现里面有大量的malloc/free,所以,当时就决定是否从malloc/free入手,能否优化整个项目的性能。所以,决定实现一个Memory
2021年12月1日
其他

2万字|30张图带你领略glibc内存管理精髓

内存管理内存管理是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。一个好的内存管理器,需要具有以下特点:1、跨平台、可移植
2021年11月1日
其他

【万字长文】吃透负载均衡

大家好,我是雨乐。首先告诉大家一件事,在十一国庆期间,引擎的机器又又。。。又扛不住了流量。经过监控分析,发现某个服务的一个实例所在的虚拟机扛不住了,所以采取临时措施流量控制之后,问题解决了,但还是造成了不小的损失。经过此次故障,以及分析故障的过程中对负载均衡又有了新的更加深入的认识,所以将这部分写出来,算是做个故障总结吧。1写在前面写本文的目的:对负载均衡的理解零零散散,不成体系。阅读这篇文章需要的条件:对OSI模型有些许了解有耐心。本文涉及大量的知识点,且只能用文字才能讲清楚,所以文字比较多。收获:读完此篇文章,从宏观的角度理解了负载均衡的原理以及实现机制。加深对分布式架构的了解主要内容:本文首先从概念开始,讲解什么是负载均衡,以及负载均衡在分布式系统中所承担的角色以及提供的功能。讲解负载均衡的分类。分别从
2021年10月14日
其他

流量控制还能这么搞。。。

一个优秀的RPC框架,流量控制是必不可少的功能之一。在上一篇文章聊聊服务注册与发现中,我们讲了微服务架构中核心功能之一服务注册与发现。在本文中,我们将着重讲下微服务的另外一个核心功能点:流量控制。在微服务系统中,整个系统是以一系列固有功能的微服务组成,如果某一个服务,因为流量异常或者其他原因,导致响应异常,那么同样的也会影响到调用该服务的其他服务,从而引起了一系列连锁反应,最终导致整个系统崩溃。针对此种问题,我们在之前的文章微服务架构之雪崩效应有讲解过解决方案,今天我们针对方案中的限流控制来进行深入讲解。1引言限流这件事,对于微服务架构来说,最直接的就是跟系统承载能力正相关。任何系统都有它服务能力上限,如果在请求链路上,某个子服务的请求量超过其承载能力,那么该链路上的请求将无法正常响应,而此时,如果在client端对于不能返回的请求不断重试(retry),那么对原本已经超过负载上限的子服务来说,无异于雪上加霜。而这一的模式在拖垮了链路上的某个子服务后,可能会影响到其上游服务,导致影响范围持续扩大,进而让其它原本正常的服务也跟着失效,从而引起雪崩,雪崩效应会加速整个系统无法提供服务。解决这个问题的方式,就是限流。如果监测到这个现象时候(错误率增高,rt变大或者是服务负载高于其安全阈值),就直接开启某些策略,在服务负载恢复前,丢弃新的request,以使得整个系统安全可靠。这个就是限流的目的。不过,这个机制困难的不在于要挑选哪种框架或者给某个服务来使用,而是是否有办法精准掌握系统内各个子服务的负载上限,并且有能力做好整合,进一步做到自动化调节限流策略。2概念在解释什么是限流之前,我们先了解一个点,就是服务的请求上限,也可以理解为是服务承载量,即该服务支持一定时间内最多能够支持多少请求。只有将服务承载量进行量化,能够被测量,才能根据这个测量值,采取一定的对应措施。服务承载量,指的是单位时间内的处理量。北京地铁早高峰,地铁站都会做一件事情,就是限流了!想法很直接,就是想在一定时间内把请求限制在一定范围内,保证系统不被冲垮,同时尽可能提升系统的吞吐量。再以我家里的带宽为例,是联通100m的,也就是说,每一秒钟,联通提供最大100m
2021年9月23日
其他

聊聊服务注册与发现

服务发现,作为互联网从业人员,大家应该都不陌生,一个完善的服务集群,服务发现是必不可少的功能之一。最近一直想写这个话题,也一直在构思,但不知道从何入手,或者说不知道写哪方面。如果单纯写如何实现,这个未免太乏味枯燥了;而如果只是介绍现有成熟方案呢,却达不到我的目的。想了很久,准备先从微服务的架构入手,切入
2021年9月13日
其他

技术十年

走过的路,回忆起来是那么曲折,把自己的一些心得体会分享给程序员兄弟姐妹们,虽然时代在变化,但是很可能你也会走我已经走过的10年的路程,有些心得体会你可以借鉴一下。在某一天的某一个时候,突然意识到,自己已经毕业工作十年了,是该写篇东西,来记录下自己的十年,算是给自己一个心理的慰藉,亦算是给自己入职场以来,第一个十年的总结。
2021年9月6日
自由知乎 自由微博
其他

亿级流量实验平台设计实践

ACPE,负反馈率、财务消耗计算等。广告实时流系统还需要日志的关联工作,比如关联广告互动日志,广告负反馈日志。实时流的计算的结果,会落地到druid
2021年9月2日
其他

TCP之深入浅出send&recv

接触过网络开发的人,大抵都知道,上层应用使用send函数发送数据,使用recv来接收数据,而send和recv的实现原理又是怎样的呢?在前面的几篇文章中,我们有提过,TCP是个可靠的、全双工协议。其流量控制或者拥塞控制依赖于滑动窗口和拥塞窗口的滑动来实现,而这两个窗口的滑动实现则是依赖于TCP中的两个buffer,这两个buffer则是TCP
2021年8月13日
其他

TCP之滑动窗口原理

在我们当初学习网络编程的时候,都接触过TCP,在TCP中,对于数据传输有各种策略,比如滑动窗口、拥塞窗口机制,又比如慢启动、快速恢复、拥塞避免等。通过本文,我们将了解滑动窗口在TCP中是如何使用的。滑动窗口实现了TCP流控制。首先明确滑动窗口的范畴:TCP是双工的协议,会话的双方都可以同时接收和发送数据。会话的双方都各自维护一个发送窗口和一个接收窗口。各自的接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的发送窗口则要求取决于对端通告的接收窗口,要求相同。滑动窗口解决的是流量控制的的问题,就是如果接收端和发送端对数据包的处理速度不同,如何让双方达成一致。接收端的缓存传输数据给应用层,但这个过程不一定是即时的,如果发送速度太快,会出现接收端数据overflow,流量控制解决的是这个问题。发送端窗口上图是发送端滑动窗口的简图。我们可以将数据分为4个部分:发送和已确认的字节(蓝色部分)已发送但尚未确认的字节(黄色部分)未发送的字节和接收方准备接收的字节,即在缓冲区buffer中(绿色部分)未发送且接收方未准备接收的字节,即已经在缓冲区,但是该部分数据还未被处理(灰色部分)其中第三部分,也就是绿色部分,也称为可用窗口,因为这是发送方可以使用的窗口。发送窗口由黄色和绿色部分组成。这些字节要么已经发送,要么可以发送。当发送方发送21-25字节并使用可用窗口中的所有字节时,可用窗口可能为空,发送窗口保持不变(如下图)。当发送方收到第16-19字节的
2021年8月2日
其他

权重随机分配器

v[idx];}就地选择(无序)除了像上面使用的方法那样扩展集合,我们还可以保持集合的当前形式,并在循环中简单地模拟集合的扩展。为了做到这一点,我们首先必须知道集合的总权重。int
2021年7月16日
其他

一道面试题引起的...

迭代器前移,指向第一个不大于pivot的元素。在4处的判断,若第一个不小于主元的元素不先序于第一个不大于pivot的元素,则说明分割已经完毕,返回第一个不小于pivot的元素的位置,即
2021年4月6日
其他

I/O多路复用之EPOLL

epoll是一种事件轮询,是Linux特有的。它允许一个进程监视多个文件描述符,并在对它们进行I/O操作时获取通知。它允许边缘触发和级别触发通知。在我们研究epoll的内部之前,首先让我们研究一下语法。1语义与poll不同,epoll本身不是系统调用。它是一种内核数据结构,允许进程在多个文件描述符上复用I/O。这个数据结构可以通过三个系统调用来创建、修改和删除。1、epoll_create通过系统调用epoll_create,可以创建一个epoll实例,该系统调用返回一个指向epoll实例的文件描述符。函数调用如下:#include
2021年3月25日
其他

微服务架构之雪崩效应

Feistel使用,[1]尽管其概念最早可以追溯到克劳德·香农提出的扩散(diffusion)。-
2021年3月2日