后端的一些经验与心得

先简单介绍一下我的经历,最早在学校的时候,是在社团里写php和Java,创业时期写js,oc和Ruby,现在是全职用Rails写后端了。

项目简介

我们的主要业务有两块,社区和电商

整体业务的峰值qps大概在3000,也算是pv过10亿的站点了,后端team有4个人,除了一个八年老司机,其他人参加工作的年限都不是太久。

我们面对的是一个巨大的基于Rails的历史遗留系统,最早的开发成员均已离开,导致我们常常面对遗留代码一脸蒙逼,到处是没有人知道的逻辑,丑陋的实现,以及很多性能跟不上的接口。

与巨石应用的斗争

日常工作的重中之重,就是与这个monolith的战斗!

性能篇

以往每年我们搞活动,服务器都会挂,经济损失不少,所以优化性能,保证活动期间的访问是第一要务。

原来的活动整体设计还是比较科学的,活动页面本身是静态化托管到cdn的,从来没有出现过问题,主要瓶颈是商品详情页面。我们利用redis做了三层cache,解决了这个问题。第一层是数据库的缓存,直接把商品信息缓存到redis里,避免了频繁的数据库访问,第二层是单条数据的渲染缓存,可以理解成一小段html,第三层是整个数据集的渲染缓存。第二个瓶颈出现在一些静态资源上,全面迁移到云存储解决。做完这两件事之后,上上次活动是我们有史以来第一次,没有挂。

就在我们觉得,优化做的不错的时候,上次活动却又挂了。

要知道我们特意买了新服务器,美滋滋觉得这下稳了,没想到...

上次活动挂的原因有以下几点

  1. redis hmget,我们通过gem提供的API,缓存了一个巨大的省市区列表,但是没有注意到缓存是分离的,获取整个列表,其实就是一条hmget获取所有独立的缓存片段,这个操作block了redis,导致访问极度缓慢。我们紧急把整个列表转成json,直接贴到代码里返回hotfix了这个问题
  2. 突然无法通过redis sential进行连接,这套sential系统是由已经离职的运维搭建的,我们绕开sential直接连接redis,解决了这个问题
  3. fd limit, 做完以上两点,依然时常502, 发现运维修改的是root用户的fd数量...坑爹....
  4. 在支付回调中有一段用于统计的sql,订单量大了以后slow query,block了数据库,我们直接注释了这段可有可无的老代码,解决。

总结一下,对于web应用的场景来说,大都是读多写少,缓存读请求,异步写请求,是我们经常采用的两种效果不错的方式。在数据库层面,对于遗留代码中效率低下的查询进行重写,重点改写了所有N+1查询,对一些逐条插入的语句用batch insert合并写入操作,也有不错的提升。

替换篇

做的比较有意思的事,是写了我们内部用的个推GEM。原来使用的是github上开源的一个GEM,但是已经很久没更新了,无法适应我们的使用需求。我基于个推最新的HTTPS的API,写了一个Ruby的包装。

这里要吐槽的是个推的技术水平。推送服务是做的不错,但API怎么做的这么low。他们定义了一个叫authorize的http header用来传递身份信息...违背了RFC关于HTTP头必须大写开头的规范。一些语言的标准库(Go、Ruby...)会自动帮你把authorize转化成Authorize,导致个推那边一直返回auth error...而个推的接口又是HTTPS的,抓包调试很困难,浪费了我很长时间调试这个问题。

重构篇
重构的主要方针就是拆分,尽可能把功能从巨石应用中拆出去。如果一时半会难以拆分的,代码上也尽可能让逻辑高度内聚,方便以后迁移。

消息系统的重构
消息系统是一个,出点问题没什么,但做得好会非常出彩的功能。我一直觉得,像知乎这种社区的成功,除了内容,很大一部分要归功于消息的体验。目前,我们几乎所有页面,都会展示新消息的数量,导致每次请求都会去主数据库的消息表做count,计算各种消息的数量返回给前端。我正在着手把整个系统迁移到另一个独立的数据库,以后可以作为单独的服务供内部调用,降级限流什么的都很方便。

搜索的重构

原来的搜索是基于Solr的java工程,是一个我们内部没人维护好多年的烂摊子,虽然各方面表现都不错。我们还是决定未来要用Elasticsearch换掉它。

新系统
我新写了内部的财务系统,过程中遇到很多问题,写的也很痛苦,但最终效果还是不错。因为原来的各种报表都是直接基于生产数据库的,对业务会有冲击,新系统写了一个同步模块,可以增量同步订单数据到财务系统的专用数据库,这样就不会对业务带来影响。

遇到的比较大的坑就是内存爆炸。有一些耗时计算我放到了消息对列里,整个worker进程的内存占用疯狂上升。最终发现是Ruby内存模型的问题。

我通过时间换空间的方式,把之前加载全部数据做计算,改成了加载部分数据做计算,然后汇总结果这样的方式,极大降低了内存占用,并通过每天重启worker进程,解决了最主要的内存问题。

这个项目让我真实感觉到,有些场景真的不是Ruby擅长的领域。Ruby的内存模型,就是尽量分配对象,从不真正回收,只会重用。Ruby VM启动就有大量空对象等着被分配,假如我加载了很多数据,空对象不够用了,VM就向操作系统申请一批内存,用完后也不释放,等着下次重用。而报表计算的最佳场景就是能加载大量数据,算一下结果,算完释放掉内存。

监控
可以看我之前的文章使用ELK构建分布式日志分析系统

代码篇
在日常编码、重构的过程中,经常使用的技术是

  1. 设计模式
  2. 元编程

运用设计模式,写出符合OOP规范的代码。分割每个类的职责,尽量让各个功能的逻辑内聚,只提供彼此间调用的接口,这是我最近才刚领悟的代码整洁之道。

元编程抽象代码,我很早就在使用的奇技淫巧。现在却用的越来越少了,因为它违背了OOP,可维护性比较差,对使用者的水平有很大要求,也容易坑队友。

简单地说,我代码中的if/else越来越少了,类越来越多了,改动起来越来方便了,改动影响的部分越来少了,美滋滋。

结语

用一句古老的名言,软件开发没有银弹。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,513评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,312评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,124评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,529评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,937评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,913评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,084评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,816评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,593评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,788评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,267评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,601评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,265评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,158评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,953评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,066评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,852评论 2 277

推荐阅读更多精彩内容