• 试试不就知道了

    会往下执行的,除非有 return

  • 分享的想法很好,社区需要这样的文章,就是这排版要好好整理整理

    大量的图、大量的代码不一定是好事情!

  • 当你发现确实是问题的时候,你可以提 Issue,或提 PR 修正

    https://github.com/stefankroes/ancestry

  • 好使,这样就可以 Hash 省略 {}

  • 概念混淆了

    用 jQuery 或其它框架,和前后端是否分离没关系

  • Rolling restart

    app, app_backup 两组 Container

    Nginx proxy 将 app 优先级提高,fallback 到 app_backup

    部署重启的时候先重启 app,断掉的时候会自动切到 app_backup

    等 app 启动好以后再重启 app_backup

  • 都用两个空格,你要用 4 个

    这是病 得治

  • 已修复,并上线

  • 一堆人中标

  • 手动

  • 你 60G 的数据,有多少条记录?

    你要考虑下面的问题:

    • 有没有老的 API 什么的需要向下兼容的?
    • 有没有足够的人一起干这个事情?
    • 如果有老功能,老 API 需要兼容,是否有测试团队帮你验证?
    • 有没有足够能力确保新做一次,比之前好很多,让老板支持?因为这个周期比较长。
    • 等你开发完升级上线的时候,需要做数据迁移,你有没有能力在不停机,或短时间停机快速迁移完成?

    关于老数据迁移

    反正这种大量数据(上百万条)迁移,你要想当然的用 Rails 来写,走 ActiveRecord 的流程是很慢的(因为有各种验证、Callback ... 等等和迁移无关的动作),不适合大量迁移。

    要大量迁移,得写成并发执行(Ruby 也写成可以并发执行的),最好是批量原生 SQL 插入,避免无谓的动作降低速度。

    量更大的时候,你可能需要分布式,例如 (Hadoop 集群)的方式来执行迁移动作,不仅是并发,还多机器并发。

    你还得考虑迁移过程中断(例如开发环境验证没遇到的奇怪数据)以后能增量迁移的问题,这样可以在升级前先把存量的老数据前迁移到新的库里面。等到最终测试完成,要上线的时候再增量跑一次后面新增的少量数据(这样能减少停机时间),完成以后一次切换掉。

  • 不懂别乱说,数据量和框架有毛关系!

  • 关于 Rails 官方文档 at 2018年03月21日
  • nil at 2018年03月20日

    你不可能靠里面自己的物理服务器来做这件事的。

    最大的问题是你们的服务器带宽,例如 Ruby China 只有 5M。

    5M 的概念等于同一时刻最大传输只能 5M。

    上面思路都已经有了,核心就是这个量的上传文件,文件不应该经过应用服务器(不管是 Puma 还是 Nginx),否则你的应用服务器的正常功能会受到这写文件上传影响。

    当然,Nginx 这样的异步 IO 没问题,但 Ruby 的应用服务器是同步 IO 的,意味着上传过程会堵塞,直到上传结束。


    如果你们确实无法使用云存储服务,必须用自己的物理机来存储这些上传文件,那你可以考虑把上传服务独立部署,和应用服务器分开。

    前提是服务器带宽(用户端 -> 你们的上传服务器)得够大。那种 5M 的带宽的云服务器你就别想搞了。

  • nil at 2018年03月20日

    可以做大小限制的一般云服务都有这样的参数支持

  • nil at 2018年03月20日

    直接从客户端提交到云服务哪里,不要经过应用服务器

    http://docs.upyun.com/api/form_api/

    如果你可以使用 Rails 5.2 的话,可以尝试用 Active Storage,我实现的 activestorage-aliyun 已经支持直接从客户端上传文件到阿里云 OSS 了。

    详见 http://edgeguides.rubyonrails.org/active_storage_overview.html#direct-uploads


    然后 Carrierwave 也有 direct upload 的插件 https://github.com/dwilkie/carrierwave_direct

  • 你要用 sudo service mongod start 的方式启动,然后看那个日志文件。

    这个明显是权限的问题,你直接执行 mongod --config /etc/mongod.conf 没问题,不代表 sudo service mongod start 也没问题,两种执行方式权限是不一样的。

  • 看我第二句...

  • 直接执行 mongod --config /etc/mongod.conf 看错误日志

    如果配置里面错误日志没有直接输出,请阅读 /etc/mongod.conf 找到日志文件,就可以找到错误原因。

  • 新增 “挖坟” 列表 at 2018年03月17日

    先用于段时间看看

  • 评论 DHH Callback 的 Video at 2018年03月16日

    而实际上 Ryan 后面 Mention::EavesdropForMentions 的例子,人家 Basecamp 也在用的:

  • 评论 DHH Callback 的 Video at 2018年03月16日

    我认为有点过度解读了!

    Callback 仅仅是一个辅助方式,让你可以在通过 Concern 的方式剥离各种各样复杂业务的时候,能将他们(各种 Concern 实现和基础 Model)组织起来,也可以給 Model 设定必要的基础处理流程。

    Callback 被许多人看作是“Callback Hole”,我觉得是理解不够,或者是没有足够的把握好尺度! 这也是理解不够,组织不好(当前也包括我早些时候的一些项目实现,例如 Quora)。

  • preload 不影响这个,搞出来的都是局部变量

    preload 是 copy on write 在有改变全局变量的时候,copy 到 worker 里面,否则和 master 共享在启动是载入的内容

  • 不是啊 我验证的结果确实是每次调用 GC.start 内存一定能回收降低到 79M 的。

    多进程下你调用 GET /gc 回收的只是其中一个进程。

  • 你用 Linux 试试,我刚才又在 macOS 上验证了一下

    GET /gcGC.start)不会释放,内存还是 GET / 后的样子,单线程 100M 的场景,最后固定在 473MB

  • 我刚才调整了一下配置,Puma 单线程跑,每次请求 100m 内存

    环境:

    • Docker 内的 Ubuntu 14.04 64bit
    • Ruby 2.5, Rails 5.2.0.rc1, Puma 3.11.3
    • 无任何 Ruby GC 配置
    • 最简单的 Controller
    class WelcomeController < ApplicationController
      # GET /
      def index
        foo = '0' * 1024 * 1024 * 100
        memory = `ps -o rss= -p #{$$}`.to_i
        render plain: "hello, #{memory / 1024}MB\n #{GC.stat} \n"
      end
    
      # GET /gc
      # 手动调用 GC.start
      def gc
        GC.start
        memory = `ps -o rss= -p #{$$}`.to_i
        render plain: "hello, #{memory / 1024}MB\n #{GC.stat} \n"
      end
    end
    

    单线程测试

    Puma starting in single mode...
    * Version 3.11.3 (ruby 2.5.0-p0), codename: Love Song
    * Min threads: 1, max threads: 1
    * Environment: production
    * Daemonizing...
    

    并发跑下去,最后稳定在 279M

    /gc 里面有个手动的 GC.start

    $ siege -c 100 http://localhost:3000/
    $ curl http://localhost:3000/
    hello, 279M
    $ curl http://localhost:3000/
    hello, 178MB
    $ curl http://localhost:3000/gc
    hello, 78MB
    $  curl http://localhost:3000/
    hello, 178MB
    $ curl http://localhost:3000/gc
    hello, 78MB
    

    调整为 5 个 threads

    Puma starting in single mode...
    * Version 3.11.3 (ruby 2.5.0-p0), codename: Love Song
    * Min threads: 5, max threads: 5
    * Environment: production
    * Daemonizing...
    

    结果:

    $ curl http://localhost:3000/
    hello, 783MB
    $ curl http://localhost:3000/gc
    hello, 78MB
    $ curl http://localhost:3000/
    hello, 178MB
    $ curl http://localhost:3000/
    hello, 279MB
    $ curl http://localhost:3000/
    hello, 178MB
    $ curl http://localhost:3000/gc
    hello, 78MB
    

    以上测试说明,这是能正确回收的

  • 关于 RoR 内存问题的讨论 at 2018年03月14日

    引入一些相关的讨论,Sidekiq 的作者的分析:

    https://github.com/puma/puma/issues/1047#issuecomment-257904428

  • 做了个例子,在 Linux 上 Rails 5.2,Ruby 2.5, Puma 以及 production 环境。

    配置:

    • Ubuntu
    • Rails 5.2 + Ruby 2.5 + production env
    • Puma 3.11 + 1 worker, 5 threads

    结果

    并发 (10 并) 用工具跑一段时间观察内存

    • 每次 100M,最后内存稳定在 560M 左右,不会变动
    • 每次 10M,最后内存稳定在 300M 左右
    • 什么都不做,最后内存稳定在 80M,无论跑多久
  • 我来实际试试,确实是之前的应用没有发现这样的情况,一些跑了好几个月的应用,内存最终都是稳定在一个位置的。