
s2: 后台开发
涛歌依旧
毕业后就职于华为和腾讯
展开
-
写了一个聊天软件,带超时的connect功能哦
大家好,我是涛哥。最近,写了一个简单的聊天软件,在局域网内玩得很溜,涉及到网络编程,其中一个场景是要实现超时connect功能。什么意思呢?我来举个例子,你就明白了。一个男孩想追求一个女孩,但这个女孩迟迟不响应,男孩却默默傻傻等待,直到地老天荒。然而,现实情况是,很多男孩耐心有限,最多等三年,过期就不等了。涛哥手绘在网络编程中也是如此,默认情况下,建立TCP连接的connect是阻塞的,如果对方无回应,则会一直等待。那么,怎样才能给connect动作设置超时时间呢?思路是:把sock原创 2022-02-13 21:50:40 · 1049 阅读 · 0 评论 -
写了一个网络聊天软件(Windows版TCP程序)
大家好,我是涛哥。最近,一位读者对网络编程很感兴趣,想写一个网络聊天软件,问我如何下手。对于网络编程,我是很熟悉的,而且也写过很多网络相关的程序。对于想学网络编程的人而言,我的建议是:写程序,调试,修改。据我所知,很多人为了面试而背诵了八股文,熟知TCP三次握手、四次挥手,用过网络调用,但却没写过socket编程,哎,哎,哎。今天,我们以最简单的TCP编程为例,来实战一下网络编程,实现一个简单的聊天软件,有兴趣的朋友可以基于本文程序进行修改。由于读者用的是Windows,所以我打开了几年原创 2021-11-15 22:31:24 · 1197 阅读 · 1 评论 -
为了钱袋安全,得懂点CSRF
大家好。今天,我们来聊编程中很重要的安全问题,即CSRF,英语全称是:Cross-Site Request Forgery(跨站请求伪造)。产品的安全性,是第一位的,也是很多公司的红线要求。离开安全性,便一无是处。在这里,顺便友情提醒大家: 遇到不明链接,不要随意乱点。 在登录银行网站后,要记得退出登录,而不是直接关闭网页。 A的正常转账操作A登录银行账户后,给B转账100元,银行后台会校验登录态skey, 最后转账成功,http请求如下(本文全部用http来描述):原创 2021-08-14 15:32:29 · 1014 阅读 · 0 评论 -
用valgrind定位内存泄漏
如果准备得不成功,那就要准备失败了。在笔试面试中,遇到内存泄漏的定位问题,如果连valgrind都说不出来,那就很容易歇菜了。总之,无论是为了找工作,还是为了实际工作中的问题,都很有必要熟练使用valgrind,那么,我们一起来看看这玩意儿是怎么回事。原创 2021-02-28 18:44:32 · 2595 阅读 · 4 评论 -
用Little‘s Law理解系统的QPS、耗时、并发数
我们先看Little's Law: 在一个稳定的系统中,设长时间观察到的平均顾客数量为L,长时间观察到的有效到达速率为λ,平均每个顾客在系统中花费的时间是W,则有如下关系式: L= λW原创 2020-01-31 20:26:36 · 3079 阅读 · 1 评论 -
多进程、多线程、多协程对单核、多核CPU的消耗
搞后台开发,不仅需要关注服务的功能,还需要关注服务的性能。在本文中,我们简要地来看看多进程、多线程、多协程对单核、多核CPU的消耗。在多核情况下,采用多进程、多线程、多协程,能更好地利用CPU, 它们不仅能并发执行,而且能并行执行。原创 2020-01-31 20:14:56 · 5252 阅读 · 2 评论 -
深入理解linux free命令及内存含义
对于软件开发(尤其是后台开发)工程师而言,不仅需要关注服务器的CPU,还需要经常关注服务器的内存。 在之前的文章中,我们探讨了CPU的参数,并且弄清了CPU核相关的一些概念。在本文中,我们来聊内存。原创 2020-01-31 20:09:51 · 6066 阅读 · 4 评论 -
深入理解计算机CPU的参数: CPU主频、多个CPU、多核CPU、逻辑核(超线程)、 大小端
对软件开发(尤其是后台服务开发)工程师来说,这几个概念几乎是必须要缕清的:CPU主频、多个CPU、多核CPU、逻辑核(超线程)、大小端。本文我们会逐一来聊聊。 在之前的文章中,我们见过古老的4004CPU,也分析过古老的8086CPU,并对它进行了汇编语言编程。它们都是单核的(每个CPU只有1个运算器&控制器)。 那么,现代CPU长啥样子呢?原创 2020-01-08 21:46:51 · 14271 阅读 · 4 评论 -
最近碰到mysql覆盖写的低概率问题
最近碰到一个低概率问题: 10 加40 加60 预期结果是110, 但最终实际结果是50 单机单进程场景,来看下:func proc() { amount := queryAmountFromDb() begin lock begin transaction amount +=...原创 2019-10-18 22:52:11 · 2913 阅读 · 4 评论 -
几种软负载均衡策略分析
转自:http://blog.youkuaiyun.com/erlib/article/details/50994209公司去年上了F5,好用是好用,但是费用太高昂了,所以最近一直在研究软负载均衡这一块儿,恰巧今年年初谷歌开源了seesaw,让自己可以绕过很多弯路。特此总结下之前了解的负载均衡策略。 -Sunface在分布式系统中,负载均衡是非常重要的环节,通过负载均衡将请求派发到网络转载 2016-04-10 22:10:07 · 12047 阅读 · 1 评论 -
外网全量机器抓包/日志
外网的一些服务, 通常需要多台机器来承担(有时候是数百台), 机器之间受到负载均衡机制的制约, 某一请求过来后, 无法准确知道会到哪台机器上, 所以感觉是无法抓包的,很多时候就放弃了在外网机器上去抓某一请求的包。 但是, 如果该服务的机器不多, 那就可以在外网所有机器上抓包。 最近遇到一个问题, 在外网全量机器上抓包(4台, 还好), 最后抓到了包, 解决了问题原创 2016-07-10 11:02:46 · 8072 阅读 · 0 评论 -
自己生成随机序列号, 便于串起来
我们知道, 后台基本上可以大致分为接入层, 逻辑层, 存储层。 现在要在三层都记录流水操作。 每次请求对应3条流水信息, 但是, 当多次请求在很短时间内进行时, 流水的顺序会被打乱(网络流水涉及到网络操作, 先发送的, 不一定先到达流水机器), 那怎么办呢? 我的思路是: 在每次之间透传序列号, 这个序列号可以认为随机生成, 请直接看上篇文章讲述的linux下生成随机数的方法,原创 2016-06-29 23:39:23 · 11395 阅读 · 1 评论 -
在服务的入口req处报流水还是在出口rsp处报流水?
req处报流水的优点: 1. 直接, 不担心后续修改了某些变量; 2. 解释在后续过程中程序core dump了, 流水也不会丢失。 rsp处报流水的优点: 信息更全, 可以获取rsp的值和返回值。 我更喜欢后种!原创 2016-07-03 10:38:36 · 7595 阅读 · 0 评论 -
so又被strip掉, core文件又没法分析出代码行号
最近, 相册同学搞出来一个低概率的core, 发到外网后, 不断有core, 于是打算回滚版本, 但core问题还是要定位啊。 抓到了core, 保存起来, 用gdb去分析的时候发现, 呵呵哒, 居然没有行号, 用file命令查了一下so, 果然是被strip掉了, 于是, 我索性把makefile中的strip去掉, 大就大一点, 笨重就笨重一遍, 反正能方便咱们去定位问题原创 2016-08-13 23:46:24 · 9969 阅读 · 0 评论 -
google protobuf 在Linux下安装与使用 (亲自测了一下, 确定可用!)
转载地址:http://blog.youkuaiyun.com/codeheng/article/details/42744875 转载说明: 我本人亲自试了一下, 原文方法完全OK, 感谢原作者。 一、介绍 首先,protobuf是一个开源项目,而且是后台很硬的开源项目。网上现有的大部分(至少80%)开源项目,要么转载 2016-11-04 01:57:13 · 11755 阅读 · 1 评论 -
无protobuf协议情况下的反序列化------貌似无解, 其实有解!
用过protobuf的人都知道, protobuf的序列化过程是: 协议文件(.proto) + 原始数据 ====》 buffer 反序列化的过程是: buffer + 协议文件(.proto) ===>原始数据 那有没有办法实现:buffer ===》原始数据 呢? 这是一个貌似无解的问题, 其实有解。原创 2016-11-05 21:36:42 · 15846 阅读 · 15 评论 -
该用配置的时候, 就不要宏定义
我们经常需要调节网络服务的超时时间设置, 如果把这个超时时间放在代码中, 则很笨重, 不灵活。 万一需要调整, 那就蛋疼了, 说不定就会编译不过, 编译过了, 发布也是风险重重。总之, 是一个重操作, 费时费力。 写代码的时候, 还是考虑下扩展性吧, 该配置的时候, 就不要偷懒地宏定义! 尤其对于哪些经常变化的设定参数。原创 2016-12-11 00:57:02 · 7385 阅读 · 0 评论 -
万恶的crontab -r命令
大家对linux中的crontab不陌生, 今天强调的是, 使用crontab命令时, 一定要慢, 要小心小心再小心。 crontab -e是编辑 crontab -r 是删除 crontab -l是查看 其中crontab -r的r和e, 在键盘上是邻居的, 很容易敲错了, 没有提示啊, 难以恢复啊!!! 当多原创 2016-09-15 00:39:15 · 18426 阅读 · 7 评论 -
系统中负负得正的兼容逻辑也许暂时能跑起来, 但迟早会坑人!
客户端发布后, 一直运行良好, 但实际上有个bug(需要特定时间段才重现)。 后来, 真的就出现bug了, 没办法, 后台兼容处理吧。 两边产生负负得正的效果, 跑起来没问题, 看起来爽得很呢。 但是, 某天, 后台有新同学接手业务, 不知道之前的负负得正的兼容逻辑, 于是在后台代码中写了个正逻辑, 于是产生了负正得负的效果, 然后采坑, 呵呵哒。 我就踩了这个坑!原创 2016-11-19 11:07:45 · 7260 阅读 · 0 评论 -
用配置文件字段区分外网机器和测试机器!
以前联调需求的时候, 经常跟别人说, 你请求到我的测试环境, 我来抓个包和log。 这种方式是很低效的, 因为他类似于单步调试。 现在直接用配置区分测试环境和外网, 对于测试环境, 把请求到全量上报, 以后爱怎么重放就怎么重放, 爽爽哒! 这样一来, 不管你什么时候请求, 我都有记录, 效率倍增。原创 2016-12-08 00:18:18 · 7056 阅读 · 0 评论 -
戏说年末盘点后台数据的获取思路------很多时候, 思路比执行更重要!
首先说明, 我不是做微信的, 和微信也没有半毛钱的关系, 本文仅仅是用大家熟悉的微信举例。 文中所有数据并非真实数据, 仅为用作举例得意得意 年末的时候, 微信经常会搞一些年末盘点类的页面活动, 上面写着: 今年发了多少条朋友圈, 赞了多少个好友, 被多少个好友点赞等众多数据, 实际上可以简化为:微信号------>微信数据 (key--->value) 这里有个问题, 根据key来获取value是一个比较耗时的过程, 尤其是对于一些微信重度用户, 天天发朋友圈,原创 2016-12-24 10:11:40 · 7661 阅读 · 4 评论 -
协议头格式不兼容怎么办?------再套一个兼容的头吧!
google protocol buffer(简称pb)是大家常见常用的序列化工具, 有的公司还有自己的私有序列化工具(xxx工具). 我们平常用的就是xxx工具。 在很多情况下, 序列化出buffer后, 通常会加一个header, 这个header里面有这段buffer的相关信息, 还可能有命令字之类的附带信息。原创 2017-03-04 23:46:32 · 7281 阅读 · 1 评论 -
本地调用, “本地调用”和远程调用!
本地调用很简单, 比如我们调用printf函数, 这类调用很少会失败! 大家平常说的本地运算, 也大概就是这个意思。 最近接到一个需求, 要对接外部门的一个服务接口, 去调用他们拉取数据。 据他们文档介绍, 他们服务提供两种接口调用: C++本地调用; HTTP远程调用。 我当时就纳闷了, 明明是一个网络操作, 怎么可能是本地调用呢? 思前想后觉得不对, 再看了原创 2017-03-05 11:40:43 · 8766 阅读 · 0 评论 -
oom和oom-killer实例简介(内存用完和进程杀死)------顺便说说linux下的两个重要目录:/proc/kmsg和/var/log/messages
oom就是out of memory, 意思就是内存用完了(内存泄漏可能导致这种现象)。 在linux中, 如果linux机器的内存用完了, 会怎样呢? 很显然, 系统肯定无法正常工作。 linux当然要考虑这种问题, linux会杀死占用内存很大的进程(这些进程后续可能被重新拉取), 从而释放出一些内存, 来保证整个系统的的正常运行, 这就是linux oom-killer的机制。 在oom期间, 系统经常会遇到一些莫名其妙的异常, 这是能理解的, 因为内存吃紧啊。 过一会儿, 经历o原创 2017-03-11 21:29:54 · 18300 阅读 · 5 评论 -
实例介绍利用valgrind定位内存异常释放问题(double free 和wrong free)
之前介绍过利用valgrind来定位内存泄漏(慢性病, 会导致程序在某个不确定的时刻异常), 本文我们来简要介绍利用valgrind来定位内存的重复释放(急性病, 会报纸程序崩溃)。 看程序:#include #include #include int main(){ char *p = (char *)malloc(30); free(p); free(p); re原创 2017-03-12 18:48:53 · 12709 阅读 · 2 评论 -
实例介绍利用valgrind定位memcpy内存重叠问题------顺便再次说说memcpy和memmove的区别
继续介绍valgrind的使用, 看程序:#include #include #include int main(){ char a[] = "abcdefghijk"; memcpy(a + 1, a, 5); printf("%s\n", a); return 0;} 先看看结果:[root@xxx ~/valgrind-3.8.1/bin]原创 2017-03-12 19:25:40 · 8773 阅读 · 1 评论 -
实例介绍利用valgrind定位strcpy/strncpy/strcat/strncat内存重叠问题
和前面的memcpy类似, strcpy/strncpy/strcat/strncat都存在内存重叠问题, 为了简便示意起见, 我用strcpy做例子来说明。 值得注意, 有时候, 在你的环境下, strcpy没有出现如下的问题, 不表明他真的没有问题。 看程序:#include #include int main(){ char str[100] = "abcdefghijklmn"原创 2017-03-12 19:55:39 · 7725 阅读 · 3 评论 -
实例介绍利用valgrind定位变量未初始化的问题
继续介绍valgrind的用途, 看程序:#include #include int main(){ int i; if(i == 0) { printf("[%d]\n", i); } return 0;} 一眼就能看出程序的问题, valgrind分析如下:[root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cp原创 2017-03-12 20:07:35 · 8350 阅读 · 4 评论 -
强大的linux tool------valgrind的简介以及安装
valgrind是linux下的一个强大工具, 其子工具(通过toolname参数来控制)主要有: 1、memcheck:检查众多内存问题,如泄漏、越界、非法指针, 我们将一一介绍。 (如果省略toolname, 则默认是memcheck, 比如执行: ./valgrind ./a.out) 2、callgrind: 分析程序性能。 3、cachegrind:分析cache. 4、helgrind: 分析多线程竞争。原创 2017-03-12 17:05:56 · 22947 阅读 · 4 评论 -
用kill -6 pid 主动杀死进程, 使进程abort/coredump, 有哪些用处?
在实际开发中, 要灵活处理各种问题, 今天我们来说说kill -6 命令的使用, 它可以让主动让进程abort/coredump, 来看看一个例子:#include #include using namespace std;struct Point{ int x; int y;};int main() { Point po; po.x = 1; po.y = 2原创 2017-03-25 15:27:04 · 22199 阅读 · 2 评论 -
gdb attach到已经存在的进程进行在线调试------能获取当前栈的所有变量值!
不久前, 我们玩过valgrind定位程序的各类内存问题, 当时非常希望valgrind能对一个已经存在的进程进行attach在线调试, 后来看了valgrind的原理, 发现这样不可行。 只能让valgrind重新拉取新进程进行调试。 在前面的文章中, 也介绍了kill -6和abort函数, 让程序core dump来获取当时栈的值, 其实, 这样似乎没有必要。 ...原创 2017-03-26 13:21:02 · 57757 阅读 · 1 评论 -
“undefined reference to“ 问题汇总及解决方法 ------非常非常好的一篇文章
转载地址:https://segmentfault.com/a/1190000006049907?utm_source=tuicool&utm_medium=referral在实际编译代码的过程中,我们经常会遇到"undefined reference to"的问题,简单的可以轻易地解决,但有些却隐藏得很深,需要花费大量的时间去排查。工作中遇到了各色各样类似的问题,按照以下几转载 2017-06-15 21:40:02 · 234247 阅读 · 23 评论 -
log没有打出, rz -bye时提示core dump, scp上传文件失败, 今天是怎么了!!!------都是磁盘满了惹的火
开发调试的时候, 经常会遇到一些异常, 有的很棘手。 但如果每次尝试去解决问题, 积累多了, 总结多了, 自然就有能快速知道原因了, 这就是所谓的经验吧。 今天, 该打的log没有打出, log戛然而已, 我开始以为core dump呢, 但看进程号, 不是。 rz -bye上传文件, 提示core dump, 我擦! 然后用scp也原创 2017-03-04 23:22:06 · 8557 阅读 · 0 评论 -
运行程序出现Illegal instruction的定位和思考------又是printf string惹的火
最近写了一个程序, 运行的时候出现了Illegal instruction错误, 觉得非常纳闷, 而且该打印的log并没有打印出来。 当时并没有报core dump错误(因为我的机器的core开关没有打开), 经过一段时间排查, 发现是程序出了问题。 下面, 我们看看最简化的程序(简化后, 一眼就可以看出问题):#include using namespace std;int main(原创 2017-06-16 22:20:58 · 28536 阅读 · 2 评论 -
API_INIT_XXX多次初始化导致后台服务成功率不高的bug的定位
最近前端同学反馈, 后台某服务的成功率不高, 我查了一下log, 发现很多错误发生在API_INIT_XXX中, 当时有点纳闷, 这个初始化函数是别的部门提供的, 所以就找赌赢的文档看了下, 发现文档上有备注: 这个初始化函数是进程级别的, 在每个进程中只初始化一次。 原来如此。 于是加了判断, 编译, 验证, 发布, 再check, 成功率就上来了。原创 2017-06-17 19:40:45 · 7230 阅读 · 0 评论 -
为什么飞机上要安装黑匣子呢? 也谈程序中log和debugger的应用场景
最近飞机出了不好的事,我表示深深地哀悼。实时监控系统出了问题, 大家都在急忙找黑匣子这个black box, 因为black box中有飞机飞行的一些记录。 下面,我从软件开发的角度来探讨一下log(black box)和debugger的应用场景。 最开始学C语言的时候,经常用printf函数来打印变量的值。后来学会了单步调试,便了此不疲, 彻底爱上原创 2014-03-26 23:40:09 · 8482 阅读 · 0 评论 -
什么是抓包?为什么要抓包?
前面讲了抓日志,现在来聊聊抓包。这里讲的抓包,并不是说用手去挠你头上的包包。 我们来看一个初三的物理实验题目: 现在灯泡不亮, 请定位分析。 这个很好办啊,无非就是搞个电压表和电流表呗。 在与网络相关的问题中,也会经常遇到类似的网络问题,遇到问题后, 该怎么办呢?猜测?估计?推脱? 我晕原创 2014-03-27 23:04:19 · 96380 阅读 · 21 评论 -
用实际程序来测试udp sendto函数的最大发包大小------为什么是65507?
我们知道, IP包头有一个16bit的长度, 对应的二进制最大值是2^16 -1,也就是说一个IP包整个长度的最大值是2^16 - 1 字节, 如果考虑UDP通信, 那么除去IP头的20个字节, 除去UDP头的8个字节, 还剩2^16 - 1 - 20 - 8 字节。 我们来玩玩程序(本文只以客户端发数据为例)。原创 2017-06-29 22:16:15 · 10886 阅读 · 2 评论 -
connect函数与karn算法
先看connect函数:#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(){ int sockClient = s原创 2017-07-01 00:06:09 · 7635 阅读 · 3 评论 -
为什么tcp建立连接是三次握手而不是两次握手或者四次握手?(笔试面试常考)
先说说tcp三次握手, 不细说了, 也就是syn, ack/syn, ack. 为什么不能是两次呢? 先假设是两次吧。我们知道, tcp的连接过程中有一个超时重传算法(karn算法是比较典型的), 如果client发出syn包后, 由于网络原因, 没有立即收到ack/syn包, 那么client会再次发起syn包, 这一点, 我们已经多次实验过。原创 2017-07-01 00:29:37 · 12468 阅读 · 3 评论