- 博客(111)
- 资源 (12)
- 问答 (1)
- 收藏
- 关注
原创 [即时通讯]千人群组消息管理
消息时序 理想状态下,客户端和服务端数据是一致的。实际情况,涉及到用户上线或下线。(详见下图) 用户在线:服务实时发送消息。 用户离线:服务保存消息;用户重新上线后,向服务获取离线消息。 群组离线消息数据(分页获取)。 如上图:client 每条消息都是有时序的,像链表一样,串联起来,每个 node 都可以通过 next 指向上一条消息: 如果上一条消息 msg_id 是 0,说明...
2019-11-14 09:52:58
786
原创 mysql 脚本(*.sql)自动代码(C/C++)工具
使用 protobuf,写个 *.proto 脚本文件,就能通过工具生成相应的代码。 这个自动代码工具太有用了: 1、数据操作面向对象,操作人性化。 2、利于团队代码风格统一。 3、直接减少了团队开发的工作量。 同理,mysql 导出 sql 的数据库结构文件,其实这也是一个脚本。 我们能否通过这个 sql 脚本,像 protobuf 那样,生成类似的自动代码呢。答案是肯定的。 网上...
2018-05-26 15:02:39
1090
原创 深入探索 C++ 多态 ③ - 虚析构
前两章探索了 C++ 多态的虚函数调用链路和继承关系,本章将探索虚析构的工作原理。具有虚析构多态特征的类对象,被释放时:有继承关系的多态类,会先析构派生类,再析构基类,与它的构造顺序刚好相反。类的析构函数被调用时,对象的 this 指针和虚指针会在对应的类内部被重新设置,this 指针指向当前类对象对应的内存位置,虚指针也会被重置指向当前类对应的虚表。释放当前派生类对象内存。深入探索 C++ 多态 ① - 虚函数调用链路深入探索 C++ 多态 ② - 继承关系深入探索 C++ 多态 ③ - 虚析构。
2023-10-31 14:39:31
397
原创 深入探索 C++ 多态 ② - 继承关系
封装,继承,多态是 C++ 的三大特性,其中多态与继承有密切关系。C++ 语言支持三种继承关系:单一继承,多重继承,虚拟继承:图片来源:《多型与虚拟》
2023-10-31 14:34:09
233
原创 深入探索 C++ 多态 ① - 虚函数调用链路
最近翻阅侯捷先生的两本书:(翻译)《深度探索 C++ 对象模型》 和 《C++ 虚拟与多态》,获益良多。虚函数虚函数表虚函数指针、以及对象的内存布局。深入探索 C++ 多态 ① - 虚函数调用链路深入探索 C++ 多态 ② - 继承关系深入探索 C++ 多态 ③ - 虚析构多态是 C++ 中的一个重要概念,它允许在派生类中重写基类中的函数,并以不同的方式处理相同的数据类型;多态的实现依赖于虚函数和动态绑定。虚函数是一种特殊的成员函数,它允许在派生类中重写基类中的函数。
2023-10-31 14:20:11
435
原创 浅析 TLS(ECDHE)协议的握手流程(图解)
通过 wireshark 抓取 HTTPS 包,理解 TLS 1.2 安全通信协议的握手流程。TLS 握手流程:通过 wireshark 抓取 HTTPS 包理解。协商加密:双方通过 ECDHE 椭圆曲线的密钥交换算法,协商出共享的会话密钥进行内容对称加密通信,避免传输会话密钥被中间人窃取。CA 证书:证书用来验证服务端的合法性。证书类似于身份证,可以证明某人是某人,当然身份证可以伪造,一般人可能识别不出来,但是国家相关部门可以验证你的身份合法性。
2023-10-31 14:08:47
1507
原创 探索惊群 ①
惊群比较抽象,类似于抢红包 ????。它多出现在高性能的多进程/多线程服务中,例如:nginx。 探索惊群 系列文章将深入 Linux (5.0.1) 内核,透过 多进程模型 去剖析惊群现象、惊群原理、惊群的解决方案。 文章来源:探索惊群 ① 探索惊群 ① 探索惊群 ② - accept 探索惊群 ③ - nginx 惊群现象 探索惊群 ④ - nginx - accept_mutex 探索惊群 ⑤ - nginx - NGX_EXCLUSIVE_EVENT 探索惊群 ⑥ - nginx - reus
2021-11-16 21:03:10
1721
原创 [libco] libco mysql 连接池
基于 libco 的 mysql 连接池,支持基本的 mysql 读写访问,支持多个连接,多个节点,支持空闲连接回收。 文章来源: [libco] libco mysql 连接池 1. 设计 mysql 连接池,每个链接被分配到一个协程里运行。主要有几部分组成,详见下图: 当用户协程访问 mysql 时,这个请求以任务形式,添加 manager 的任务队列,然后用户协程切出去等待唤醒。 manager 协程主要负责链接调度,还有任务分派,它将一定数量的任务分配给比较空闲的连接处理。 任务处理协程,被
2021-11-10 17:59:36
909
原创 [libco] co_kimserver 简介
co_kimserver 是基于 libco 的高性能 TCP 网络通信框架。 详细请查看:github 。 文章来源:[libco] co_kimserver 简介 1. 简述 co_kimserver 是高性能 TCP 网络通信框架。 多进程工作模式(manager/workers)。 基于腾讯开源的轻量级协程库 libco。 主要使用 C/C++11 语言开发。 支持 tcp 协议。 使用 protobuf 封装通信协议。 支持访问 mysql, redis (client: hiredi
2021-11-10 17:58:11
3018
8
原创 [libco] 删除协程的正确姿势
如果你认为只需要简单调用 co_release 就能将 libco 的协程删除,那等待你的可能就是定时炸弹 ????。 文章来源:* [libco] 删除协程的正确姿势 1. 正确姿势 如何才能安全删除一个协程? 禁止删除一个正在工作的协程,删除已经停止工作(stCoRoutine_t.cEnd == 1)的协程是比较安全的。 /* 协程数据结构。 */ struct stCoRoutine_t { ... char cEnd; /* 协程是否结束。 */ ... };
2021-11-10 17:46:14
462
原创 [libco] libco 定时器(时间轮)
libco 定时器核心数据结构:数组 + 链表,有点像哈希表,通过空间换时间。libco 定时器也被称为时间轮,我们看看这个 “轮” 是怎么转的。 文章来源: [libco] libco 定时器(时间轮) 1. 概述 libco 定时器核心数据结构:数组 + 双向链表(左图)。 数组以毫秒为单位,默认大小 60 * 1000,主要保存一分钟以内到期的事件数据。相同到期时间的事件,会保存在双向链表里,当时间到期时,到期事件链表会一起取出来。 当然超过一分钟的到期事件也支持保存,通过取模路由,有
2021-11-10 17:45:32
654
原创 [libco] 协程栈空间
协程“栈”空间,有独立栈和共享栈,重点理解一下协程共享栈。 文章来源:* [libco] 协程栈空间 1. 概述 libco 虽然支持海量协程,但是单线程,同一时刻只支持一个协程在工作。在一个时间段内,它通过调度,使多个协程不停切换,从而实现协程“并发”功能。 协程“栈”空间,有独立栈,也有共享栈。这个“栈”添加了引号,其实它是在堆上分配的,因为它的协程函数工作原理与普通函数工作原理差不多,所以才叫“栈”。 普通函数运行原理:《x86_64 函数运行时栈帧内存布局》 2. 独立栈 协程独立栈
2021-11-10 17:44:54
690
原创 [libco] libco 不干活也费 CPU
在 Linux 系统,libco 调用 epoll_wait 有点用力过猛,虽然 libco 针对高并发,但是小问题的处理,略显粗糙。 文章来源: [libco] libco 不干活也费 CPU 1. 问题 co_epoll_wait 的 timeout 这里默认为 1,在循环里,每毫秒执行事件处理。 void co_eventloop(stCoEpoll_t *ctx, pfn_co_eventloop_t pfn, void *arg) { ... for (;;) {
2021-11-10 17:44:16
336
原创 [libco] libco 工作流程
libco 设计初衷:为了方便编写 C++ 高性能网络服务。 高性能网络服务主要有两个点:IO 非阻塞 + 多路复用技术。 libco 使用 hook 技术解决阻塞问题。 libco 事件驱动使用 (epoll/kevent)。 但是 非阻塞 + 多路复用技术 这个是异步回调实现方式,对用户开发非常不友好,所以协程的引入就是为了解决这个问题:用同步写代码方式实现异步功能,既保证了系统性能,又避免了复杂的异步回调逻辑。 libco 有三大模块:协程管理模块,hook 模块,多路复用事件驱动模块,我们看看
2021-11-10 17:43:39
978
原创 [libco] 协程调度
libco 通过 co_resume 和 co_yield 交替调度协程。 文章来源:[libco] 协程调度 1. 协程调度 设计图来源:libco 协程调度 1.1. 协程数组 pCallStack 协程数组,保存当前正在执行协程(注意:并不是所有协程)。 pCallStack[0] 是主协程,env->pCallStack[env->iCallStackSize - 1] 是当前协程。 一般情况下数组大小为 2,子协程在主协程里创建。除非在子协程里嵌套创建唤醒新的协程,这个协
2021-11-10 17:42:56
358
原创 [libco] 协程切换理解思路
程切换,可以理解为函数运行时上下文切换。 文章来源:[libco] 协程切换理解思路 1. 协程切换 正常情况下,函数代码从头到尾串行执行,直到函数生命期结束。而协程切换却能将当前运行的函数,切换到另外一个函数运行,这是协程的神奇之处。 2. 划重点 理解协程切换原理,首先需要理解函数的运行原理。(《x86-64 下函数调用及栈帧原理》) 协程是啥?它本质上就是一个函数体,与普通函数相比,它只是特殊一点而已。 协程函数上下文:寄存器数据 + 内存数据。 协程切换(yield/resume)本质是
2021-11-10 17:42:15
453
原创 [libco] 协程库学习,测试连接 mysql
历史原因,一直使用 libev 作为服务底层;异步框架虽然性能比较高,但新人使用门槛非常高,而且串行的逻辑被打散为状态机,这也会严重影响生产效率。 用同步方式实现异步功能,既保证了异步性能优势,又使得同步方式实现源码思路清晰,容易维护,这是协程的优势。带着这样的目的学习微信开源的一个轻量级网络协程库:libco 。 文章来源: [libco] 协程库学习,测试连接 mysql 1. 概述 libco 是轻量级的协程库,看完下面几个帖子,应该能大致搞懂它的工作原理。 微信开源C++协程库Libco—原
2021-11-10 17:41:07
722
原创 深入理解 epoll 回调用户数据
epoll 多路复用驱动是异步事件处理,在用户层它提供了用户数据(epoll_data),方便事件触发后回调给用户处理。 glibc /* sys/epoll.h */ typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll events */ epoll_
2021-09-02 12:08:26
924
原创 [hiredis 源码走读] 异步回调机制剖析
hiredis 是 redis 的一个 c - client,异步通信非常高效。单链接异步压测,轻松并发 10w+,具体请参考《hiredis + libev 异步测试》。本章主要剖析 hiredis 异步回调机制原理,围绕三个问题,展开描述。 异步回调原理。 异步回调如何保证 request/response 时序。 单链接异步读写 redis,为何能并发 10w+。 文章来源????:《[hiredis 源码走读] 异步回调机制剖析》 1. 异步回调原理 先看看异步通信流程。 设计图来源:
2021-09-02 11:09:22
608
原创 剖析 stl + glibc “内存泄漏” 原因
最近项目增加了一个模块,在 Centos 系统压测,进程一直不释放内存。因为新增代码量不多,经过排查,发现 stl + glibc 这个经典组合竟然有问题,见鬼了! 通过调试(Centos 调试 glibc 视频)和查阅 glibc 源码,好不容易才搞明白它 “泄漏” 的原因。 问题在于:ptmalloc2 内存池的 fast bins 快速缓存和 top chunk 内存返还系统的特点导致。 ???? 文章来源:剖析 stl + glibc “内存泄漏” 原因 1. 现象 上测试源码看看: /*
2021-08-14 07:21:14
1625
1
原创 剖析 TCP - SO_REUSEPORT 使用
1. 概述 在 TCP 应用中,SO_REUSEPORT 是 TCP 的一个选项设置,它能开启内核功能:网络连接分配负载均衡。 该功能允许多个进程/线程 bind/listen 相同的 IP/PORT,提升了新连接的分配性能。 nginx 开启 reuseport 功能后,性能有立竿见影的提升,我们结合 nginx 分析一下 reuseport 功能。 文章来源:剖析 TCP - SO_REUSEPORT 使用 1.1. what 从下面这段英文提取一些关键信息: SO_REUSEPORT 是网络的一
2021-08-07 00:19:15
1438
原创 vscode + gdb 远程调试 linux (EPOLL) 内核源码
配套视频:vscode + gdb 远程调试 linux (EPOLL) 内核源码。 前段时间才搭建起来 gdb 调试 Linux 内核网络源码(视频 ),但是 gdb 命令调试效率不高。磨刀不误砍柴工,所以折腾一下 vscode,使调试人性化一点。 1. 搭建调试环境 要搭建 vscode + gdb 调试 Linux 内核环境,首选要搭建:gdb 调试 Linux 内核源码(视频),然后再配置 vscode 进行测试调试。 2. vscode 配置 2.1. vscode 插件 ms-vscod
2021-06-28 08:30:01
869
1
原创 gdb 调试 Linux 内核网络源码(附视频)
最近在看 Linux 内核的网络部分源码,在 MacOS 上搭建调试环境(windows 应该也支持),通过 gdb 调试,熟悉内核网络接口的工作流程。 调试环境搭建视频:gdb 调试 Linux 内核网络源码。 ????文章来源:gdb 调试 Linux 内核网络源码 1. 目标 目标:gdb 调试 Linux 内核网络部分源码。 环境:macos + vmware + ubuntu + qemu + gdb + linux kernel。 参考:构建调试Linux内核网络代码的环境MenuO
2021-06-21 14:51:12
466
原创 [shell] sed 插入多行文本
用 sed 命令插入多行文本,感觉这个操作有点费劲,所以在这记录一下。 ???? 文章来源:《[shell] sed 插入多行文本》 1. 脚本意图 删除 2 - 7 行的文本。 从第 2 行插入多行文本。 2. 脚本使用 ./script your_path 3. 脚本源码 #!/bin/sh work_path=$(dirname $0) cd $work_path work_path=$(pwd) if [ $# -ne 1 ]; then echo "./script
2020-12-15 21:47:07
2418
1
原创 高性能服务异步通信逻辑
最近整理了一下服务程序异步通信逻辑思路。异步逻辑与同步逻辑处理差别比较大,异步逻辑可能涉及多次回调才能完成一个完整的请求处理,逻辑被碎片化,切分成串行的步骤。习惯了写同步逻辑的朋友,有可能思维上转不过来。 ????文章来源:《高性能服务异步通信逻辑》 1. 逻辑 高性能异步非阻塞服务,底层一般用多路复用 I/O 模型对事件进行管理,Linux 平台用 epoll。 epoll 支持异步事件逻辑。epoll_wait 会将就绪事件从内核中取出进行处理。 服务处理事件,每个 fd 对应一个事件处理器
2020-12-05 12:15:10
244
原创 软件性能检测--火焰图
火焰图是 svg 格式的矢量图,基于 perf 软件性能分析工具。通过对软件在系统上的工作行为记录进行采样。并将数据进行图形化,从而得出比较直观的可视化数据矢量图。 ???? 文章来源 《软件性能检测–火焰图????程》 1. perf 采样 基于 Linux 平台的 perf 采样脚本(fg.sh - github 源码),对指定进程(pid)进行采样,生成火焰图 perf.svg。 #!/bin/sh if [ $# -lt 1 ]; then echo 'input pid'
2020-12-02 16:38:17
465
原创 [redis 源码走读] raft 一致性算法
raft 一致性算法,它是分布式系统中一种高可用算法策略。只单纯看论文算法,很难掌握它的工作流程,在 redis 里 raft 算法主要体现在:redis 主从数据复制 和 sentinel 故障转移,如果你有兴趣,可以研究对应 redis 源码,当这两个点理解了,raft 算法自然就理解了。 ???? 文章来源 《[redis 源码走读] raft 一致性算法》 1. 算法文档 raft 算法官网《The Raft Consensus Algorithm》(连接可能需要翻墙) raft 算法中文翻
2020-12-02 15:12:32
1044
原创 [redis 源码走读] sentinel 哨兵 - 故障转移
接上一章投票选举 《[redis 源码走读] sentinel 哨兵 - 选举投票》。前面几章已经讲了:各个角色的通信,主客观下线,投票选举,当 sentinel 的 leader 被选出来后,由它来完成 redis 实例的角色转换。 1. 故障转移 故障转移有很多个环节组成,集群中每个 sentinel 都有机会执行,但是只有在选举过程中,赢得选票的人,才能完整完成整个故障转移流程。 1.1. 流程 sentinel 的故障转移流程有几个环节组成,主要可以看它源码定义的几个宏: /* 初始状态。*/ #
2020-12-02 14:59:14
516
原创 [redis 源码走读] sentinel 哨兵 - 选举投票
在 sentinel 故障转移的流程上,当 sentinel 确认 master 客观下线(《[redis 源码走读] sentinel 哨兵 - 主客观下线》)后,那么它要进入 选举投票 环节。 多个 sentinel 有可能在同一个时间段内一起发现某个 master 客观下线,如果多个 sentinel 同时执行故障转移,有可能会乱套,也可能出现“脑裂”现象(《[redis 源码走读] sentinel 哨兵 - 脑裂处理方案》),所以在一个集群里,多个 sentinel 需要通过投票选出一个代表,由代
2020-12-02 14:47:55
1124
原创 [redis 源码走读] sentinel 哨兵 - 主客观下线
redis 哨兵集群有 3 个角色:sentinel/master/slave,每个角色都可能出现故障,故障转移主要针对 master,而且故障转移是个复杂的工作流程。在分布式系统中,多个节点要保证数据一致性,需要相互通信协调,要经历几个环节: master 主观下线 --> master 客观下线 --> 投票选举 leader --> leader 执行故障转移。 本章重点走读 redis 源码,理解 sentinel 检测 master 节点的主客观下线流程。 1. 故障转移流
2020-12-02 14:43:43
637
原创 [redis 源码走读] sentinel 哨兵 - 节点发现流程
承接上一章 《[redis 源码走读] sentinel 哨兵 - 原理》,本章通过 strace 命令从底层抓取 sentinel 工作日志,熟悉节点通信流程,阅读相关源码。 1. 工作流程 1.1. 命令 下面两个命令都可以启动 sentinel 进程。 redis-sentinel /path/to/your/sentinel.conf redis-server /path/to/your/sentinel.conf --sentinel 通信命令。 struct redisCommand
2020-12-02 14:37:31
670
原创 [redis 源码走读] sentinel 哨兵 - 原理
redis 有主从数据复制功能。多个实例通过读写分离,使得单进程的 redis 可以充分利用多核性能。 当某些 redis 实例出现故障怎么办,服务还能正常工作吗?这时候故障管理者 sentinel 应运而生。它负责 redis 集群管理工作:检查故障,发现故障,转移故障,从而保证集群高可用。 1. sentinel 作用 监控: 检查 redis 节点健康状况。 故障转移:当 redis 集群节点出现故障时,及时自动进行故障转移。 通知:检测到 redis 实例出现故障,通过 api 进行通知用户。
2020-12-02 14:17:51
178
原创 redis 为啥这么快
天下武功,唯快不破。redis 为什么那么快?redis 单进程并发 10w+ (hiredis + libev 异步测试)。本章从这几个角度进行分析:单进程,单线程,多线程,多进程,多实例。 ????文章来源:《redis 为啥这么快》 1. 单进程 redis 核心逻辑在单进程主线程里实现。 1.1. 单线程 数据存储在内存。 redis 的应用场景,一般作为缓存,它的数据存储在内存,而 cpu 访问内存速度非常快。 哈希表。 redis 数据库是 Nosql 数据库,它的数据访
2020-11-16 00:12:30
157
原创 [redis 源码走读] 异步通信流程-单线程
重点 描述 服务异步通信核心 非阻塞 + 异步事件驱动。 事件驱动核心源码 ae.c 网络通信核心源码 connection.h / connection.c,networking.h / networking.c 读/写数据核心函数 readQueryFromClient / writeToClient 本文主要讲述 Linux 平台下的 redis 客户端与服务端异步通信(单线程),不包括 redis 集群间的通信。 ???? 文章来源:《[redis 源码走读] 异步通.
2020-11-16 00:09:37
271
原创 [redis 源码走读] 主从数据复制(下)
redis 主从模式主要作用:读写分离,提高系统的负载能力;保证服务高可用。 本章走读 redis 6.0 源码 github,理解 redis 主从数据复制流程。 ????文章来源:《[redis 源码走读] 主从数据复制(下)》 1. PSYNC 1.1. slave 发送 PSYNC 命令,处理 master 回复。 void syncWithMaster(connection *conn) { ... if (server.repl_state == REPL_STAT
2020-11-16 00:07:18
229
原创 [redis 源码走读] 主从数据复制(上)
阅读源码前,先了解 redis 主从复制的基本知识。 详细源码分析,请参考下一章:[redis 源码走读] 主从数据复制(下) ????文章来源:《[redis 源码走读] 主从数据复制(上)》 1. 复制模式 # Master-Replica replication. Use replicaof to make a Redis instance a copy of # another Redis server. A few things to understand ASAP about Re
2020-11-16 00:04:52
385
原创 [epoll 源码走读] epoll 源码实现-预备知识
epoll 源码涉及到很多知识点:(socket)网络通信,进程调度,等待队列,socket 信号处理,VFS(虚拟文件系统),红黑树算法等等知识点。有些接口的实现,藏得很深,参考了不少网上的帖子,在此整理一下。 本文主要为 《[epoll 源码走读] epoll 实现原理》,提供预备知识。 1. 网络数据传输流程 网络数据是如何从网卡传到内核,内核如何将数据传到用户层的。 参考 Linux网络包收发总体过程 参考 epoll源码分析 2. 内核进程调度 网络通信过程中,进程什么时候睡眠,什么时
2020-11-11 21:20:27
223
原创 epoll 多路复用 I/O工作流程
从业务逻辑上,了解一下 epoll 多路复用 I/O 的工作流程。 有兴趣了解 epoll 源码实现,可以参考: 《[epoll 源码走读] epoll 实现原理》 1. epoll epoll 是一个 Linux 系统的一个事件驱动。简单点来说,是一个针对系统文件的事件管理器,可以高效管理大量网络链接下的数据并发。研发人员根据业务需要,通过事件管理器,监控对应文件描述符的读写事件。(详细解析请参考: 百度百科) ???? 文章来源:《epoll 多路复用 I/O工作流程》 1.1. 事件结构
2020-11-11 21:18:05
254
原创 [epoll 源码走读] LT 与 ET 模式区别
走读内核源码,看看 epoll 的 LT 和 ET 模式区别。 详细信息可以参考文章《[epoll 源码走读] epoll 实现原理》,现在将部分代码提取出来。 1. 原理 核心逻辑在 ep_send_events_proc 函数里实现,关键在 就绪列表。 epoll 监控的 fd 产生事件,fd 信息被添加进就绪列表。 epoll_wait 发现有就绪事件,进程持续执行,或者被唤醒工作。 epoll 将 fd 信息从就绪列表中删除。 fd 对应就绪事件信息从内核空间拷贝到用户空间。 拷贝完成后,检
2020-11-11 21:16:08
262
visual studio 新建C++文件为 UTF8 文件解决方案
2016-09-01
mysql sql 脚本C++自动代码
2018-05-26
easyui ajax http 测试客户端
2017-06-06
QT 入门资料和 windos 配置环境设置
2011-11-29
WTL 入门学习资料
2013-11-11
WTL 学习资源(整合了不少东西,希望对初学者有用)
2009-02-27
easyui + django 进度条
2017-06-19
C++ 内存泄漏问题。
2021-04-04
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅