摘自:http://www.infoq.com/cn/news/2017/06/freewheel-experience-on-go

Go语言是FreeWheel公司目前主要力推的一个方向,在其看来,面向服务的架构的大环境中,Go非常适合做一些功能相对独立、功能比较明确的微服务的语言。在结合已有的各种编程语言,计算框架(如Hadoop、Java、Ruby、C++)的基础上,FreeWheel把Go语言定位成用来实现轻量级服务或API的缺省编程语言,将之与用来完成更小粒度工作的Python结合在一起,就构成了FreeWheel的整个技术语言栈 。
 
FreeWheel在Go上所经历的“坑”

虽然从2012年Go 1.0发布到团队相继采用Go来编写项目,这中间经历了大致三年左右的时间,但由于在GC等许多问题的克服上需要Go本身去做一部分迭代,FreeWheel也需要把技术对客户的影响控制在一个可控的范围内,因此作为一家B-to-B企业,其采用了更为渐进的方式将Go语言应用到自身的生产平台上。

在这个过程中,FreeWheel也经历过两个较为重要的“坑”。

  • GC的问题

如多数人所知道的一样,Go语言垃圾回收器存在一定的缺陷,特别是容易导致整个进程不可预知的间歇性停顿。像某些大型后台服务程序,如游戏服务器、APP容器等,由于占用内存巨大,其内存对象数量极多,GC完成一次回收周期,可能需要数秒甚至更长时间,这段时间内,整个服务进程是阻塞的、停顿的,在外界看来就是服务中断、无响应。FreeWheel在使用Go 1.4版本时也遇到过类似问题:广告预测团队用Go来实现调度器,平常运行的时候没有问题,但一旦触发1.4版本下GC的时候,该系统的downgrade非常厉害,导致任务的堆积非常严重,触发报警,同时其处理性会下降很多,也会影响其他上下游系统的正常运转。

于是,FreeWheel在当时主要采取了三种对策:一、并不把Go用在非常关键的、对服务进程稳定性要求较高的系统里;二、引入Kafka之类的能够持久化的消息队列,能够缓存和重释这样的方式去解决这个问题,使系统能扛住冲击,并在后面把它消化掉;三、尽量复用已经创建的对象,防止Go频繁的创建了回收对象。

Go 1.5到1.7版本相继出来后,GC的系统性能得到不断改进和持续提升(从秒级到毫秒级)。对于目前FreeWheel内生存环境不太关键的系统来说,Go 1.7之后的GC已经可以达到可接受的范围和程度以内。

  • 内置数据结构的变化

很多人都知道,Go语言提供的字典类型并不是并发安全的,此外由于Go语言发展较快,有些内置的数据结构如Map的行为也发生了变化。因为Map为引用类型,所以即使函数传值调用,参数副本依然指向映射m,所以多个goroutine并发写同一个映射m。例如,如果map由多协程同时读和写就会出现 fatal error:concurrent map read and map write的错误。

Go 1.6版本之前Map可以支持并发读写,但FreeWheel开发的程序在升级到1.6之后也就发现Map产生了读写竞争的问题。

对于这一问题,常用的有两种解决方案,一是如上所说的加锁(包括通用锁和读写锁),二是利用channel串行化处理。FreeWheel的做法也主要靠两方面,其一是将锁粒度设计的更细,使得并发的依赖更少;另外是在不同的数据结构中,选择性能更高的一方。比如array和slice中,前者就是更优选择。

FreeWheel首席架构师刘昊植认为,并发的时候不能假设Go能完美处理所有的工作,工程师需要结合并借鉴传统(成熟)的编程语言,比如Java或者C对并发的经验,在动手之前就想清楚并发的规模、锁的粒度等,并对系统会如何运行有非常明确的设计和理解。

同时,刘昊植也坦言,随着Go的快速发展阶段,FreeWheel内部也有多种不同的声音,例如运维团队就会觉得快速发展阶段的语言稳定性不够,它的特性和数据结构会因为版本升级等原因产生很大变化,并且部分变化不能完全保持向前兼容。在这个过程中FreeWheel的总结是:不管Go怎样实现,都要对系统并发做很好的支持,在应用层面做保护和控制,这样才保证这个系统能够正常的运行。

为什么FreeWheel没有全部用系统重写Go

从编程范式的角度来说, Go语言是变革派,而不是改良派。对于C++、Java和C#等语言为代表的面向对象的思想体系,总体来说全球范围内许多公司对Go语言的态度更为保守,多数持有限吸收的观念(这可从下图中Go的热度分布情况看出)。

即使FreeWheel在实践中发现Go比其他类编程语言具有许多更为明显的优势,如在写并行上,相比Python这样的解释语言要高一个数量级;如前期由Python开发的很多轻量级API,因为全局解释锁GIL的关系而面临着进程间通信带来额外开销,所以就把轻量级API迁移到Go上;又比如Go在并发上的优势,适合面向多用户同时上传、同时调用API的场景……但其内部团队也并没有用Go来重写全部系统。原因主要有两点:

第一,FreeWheel有很多已有的算法实现,想全部切入到Go上会面临巨大的开销和成本;第二,相比C或者C++,Go在高性能方面还没有完全的证明自己。在Web服务器端,它目前也没有一个特别好的像RoR、Django、或者PHP的流行框架。对于FreeWheel来说,整个广告服务器是不允许出现明显的downgrade情况(尤其是当GC时),所以对这种非常关键的系统,目前还不能完全用Go去写。所以刘昊植也认为,Go在扩展使用场景层面可能还需要做一些较大变革。

此外,FreeWheel基于Go的Web程序,目前使用的是Gorilla框架。但从Martini、Revel、Gocraft/web等几款主流框架的使用和评价上看(可以下图github上的数据做个参考),Go社区还没有一款处于统治地位的Web框架。如果Go想把它的触角伸得更长,这可能是其未来发力的一个方向。

但总的来说,Go在高并发、开发效率等特性上的优势,决定了Go在FreeWheel内的采用程度会越来越深。刘昊植说:“除了一些已有业务依赖于Hadoop、Spark这样的基础设施,对于新增的业务和功能,Go语言会是我们的首选。”

另外,FreeWheel希望其使用的编程语言是能够得到跨大陆、跨时区、受所有工程师共同认可的,所以Go或许会是其最好的选择。这个过程中,FreeWheel也评估过很多其他语言如Scala、Rust等,但最终因为Go在学习成本、统一实践、社区规模等方面的优势而胜出。

转载于:https://www.cnblogs.com/bonelee/p/6999802.html

FreeWheel基于Go的实践经验漫谈——GC是大坑(关键业务场景不用),web框架尚未统一,和c++性能相比难说...相关推荐

  1. TiDB 在金融关键业务场景的实践

    TiDB 作为一款高效稳定的开源分布式数据库,在国内外的银行.证券.保险.在线支付和金融科技行业得到了普遍应用,并在约 20 多种不同的金融业务场景中支撑着用户的关键计算.本篇文章将为大家介绍分布式关 ...

  2. TiDB 在金融行业关键业务场景的实践(下篇)

    TiDB 作为一款高效稳定的开源分布式数据库,在国内外的银行.证券.保险.在线支付和金融科技行业得到了普遍应用,并在约 20 多种不同的金融业务场景中支撑着用户的关键计算.在TiDB 在金融行业关键业 ...

  3. 【云原生|实践指北】5:真实业务场景下云原生项目落地实践学习

    真实业务场景下云原生项目落地实践学习 写在前面的话 1.容器化的落地实践 搜题APP的云上之旅 2.Serverless的落地实践 某电商APP的Serverless改造之旅 3.云原生TKE的落地实 ...

  4. 【观察】新华三:融合技术优势和实践经验,推动智慧医疗驶入快车道

    众所周知,随着"健康中国"上升至国家战略,以及在新兴数字化技术的双重推动下,中国的医疗行业迎来了一个发展的新时期. 一方面,一系列医疗健康政策的密集发布和医疗卫生体制改革的不断深化 ...

  5. 1688 复杂业务场景下的 Serverless 提效实践

    前言 首先为大家简单介绍一下我们的业务场景,1688 隶属于阿里集团的国内贸易事业部(CBU),是阿里最早起家的业务,已有十几年的历史.我们主要负责 PC 端 1688.com 以及手机端阿里巴巴 A ...

  6. CaaS环境下实践经验总结(二):监控系统部署

    为什么80%的码农都做不了架构师?>>>    [编者按]监控系统对于云平台的维护团队起着至关重要的作用.Docker的出现对整个生态系统产生了巨大的印象,如何对短暂存在的Docke ...

  7. 【推荐】如何使用好阿里云的网络安全隔离?深入分享阿里云ECS安全组实践经验...

    近期针对安全的话题非常火爆.特别邀请阿里云专家撰写一组文章,深入分享阿里云ECS安全组实践经验. 阿里云的ECS有经典网络和专有网络(VPC)两种网络类型.经典网络基于阿里云基础网络,通过安全组(类似 ...

  8. 从平台到中台:Elaticsearch 在蚂蚁金服的实践经验

    https://www.infoq.cn/article/IfwCVj-qJ4TU0dmBZ177 本文根据他在 2018 Elastic 中国开发者大会的分享整理. 大家好,我是来自蚂蚁金服中间件团 ...

  9. (课程)基于Spark的机器学习经验

     (课程)基于Spark的机器学习经验 祝威廉 2016-09-07 16:48:36 浏览837 评论0 机器学习 spark 摘要: 这篇内容基于我去年的一些感悟写的,但是今年才在Stuq 的 ...

最新文章

  1. 微信小程序获取用户收货地址 完整代码
  2. java弹出网页alter_JavaScript三种弹出框(alert,confirm和prompt)用法举例
  3. 【HIMI转载推荐之三】基于Cocos2dx引擎UI扩展引擎包[cocos2d-x-3c]
  4. C++常用数据结构入门
  5. python如何分成两行_python将文本分每两行一组并保存到文件
  6. css两栏式布局示例
  7. HEC-RAS如何修改SA/2D Connection的名称
  8. 本周进步要点(第3周1.9--1.15)
  9. 结直肠癌呈年轻化趋势,与肠道微生物群密不可分
  10. Egret Wing 项目结构
  11. android手机控制家用电器,手机遥控电脑!教你用手机控制家里电脑
  12. BES2300x笔记(4) -- TWS组对与蓝牙配对(Peer or Pair傻傻分不清)
  13. 关于django外键设置的问题
  14. Daily record-October
  15. 麻将胡牌算法带癞子 python实现
  16. 前端日期选择器--只选择年或者年月的My97
  17. Linux篇面试宝典
  18. 苹果桌面主题_看腻了手机自带的桌面主题,试试这个
  19. 985大学计算机考研难度排名2015,你可能不知道计算机考研985院校也分三六九等...
  20. Unity3D初级工程师面试指导

热门文章

  1. 【转】关于Apache与Nginx的优势比较
  2. 快应用 - 应用签名校验失败
  3. 计算机表格计算总积分,Excel函数教程: 根据条件计算成绩表-excel技巧-电脑技巧收藏家...
  4. java 对象 方法_java——类、对象、方法
  5. c语言程序窗口后台持续监测,用c语言实现后台运行的、每隔30s检查一次的、带有日志功能的断网重新连接程序...
  6. C语言程序设计蔺德军,C语言程序设计上机实验与习题解答(第2版)
  7. java算法题常用到的一些api,含面试题+答案
  8. java并发编程详解,Java架构师成长路线
  9. java常用技术栈,HR的话扎心了
  10. python【数据结构与算法】红黑树概念辨析