ruby 没有真正的多线程,只能开多线程,对于成熟商业项目是致命的性能弱点。虽然现在有了 ractor,可惜仍然非常难用……
我正好有空,想去看看。现在几个人了?
试了下,确实把 config.cache_classes 设为 true 就正常了。但这样的话 dev 模式下就不能改了代码直接生效了,还有什么别的解法吗
我需要在运行时记录一个状态值,运行过程中值会变化,多个不同的方法都需要用到这个值,而且多个 workers 需要能取到。当然不用全局变量肯定也有别的办法,比如 redis,但全局变量是我能想到的最简单的方法了。
感谢大佬,这么快就找到原因了 能否再请指教一下,应该怎样写这个代码呢?我只是想在 controller/model 使用全局变量而已,如果 dev 和 pro 模式的行为不一样,难道要写两种方法来判断吗?
好像只有在 controller、model 中调用全局变量才会这样,如果在 global_vars 直接判断是正常的。is_a、instance_of、kind_of 我全试过了都一样
做出来了,rails new 一个空白项目,两行代码重现。明天发上来供大家围观,不会真的是 rails 的 bug 吧。。
查了没有,而且用 instance_of?也是一样的
报错啊,启动不了。换成 if-then 启动了
这个问题我解决了。不是什么内存泄露,换 jemalloc 就好了
设成 0,1 个 worker 都没有启动。。。官方文档也看了,好像没有你说的“worker process 没有请求的时候,会自动被干掉”
worker 是固定的数量,设置类似:workers ENV.fetch("WEB_CONCURRENCY") { 4 } 我不知道这个怎么能设置成动态的,请教一下
我用的是 puma,但是没有发现 worker 会自动 kill 啊?有一个 gem puma_worker_killer 可以自动 kill,但是实测发现会影响请求所以没敢用。
观察下来应该是逐渐趋近于一个稳定值。到时试试 GC.compact 有没有效果
考虑过自动重启,但是怕会不会某个 worker 运行到一半突然被自动重启了,那业务数据是不是会丢啊
这段代码一字不差地复制到 ractor.rb,我仍然是崩溃的……
我的环境是 ubuntu 16.04
已经提了。不过现在还没有 assign
试了同样是报错的
我目前对 ractor 的期望不是它快还是慢,适合什么场景,而是能正常运行就好。我测了一段简单代码,ractor 运行 100% 崩溃,请看下:https://ruby-china.org/topics/40902。 任何技术都有优缺点,但底线是能运行,如果同样的代码用 ractor 就报错崩溃,那这个不是场景的问题,就是 ractor 本身的问题。
看完我的第一反应居然是:换了我,不如新买一台笔记本好了……[捂脸]
非常感谢,试了很管用!我有几个想法,如果方便的话,请您指教一下: 1、这个方法每次输出数组的顺序是随机的,最好能够和原数组对应。这个很容易解决,我把 ractor 处理的数据改为 hash,带上原数组 index 就可以了。 2、如果 handler 中含有类方法,如 handler = proc { |x| A.handle(x) },此方法是无效的,因为 A 类没有传到 ractor 里面去。至于怎样修改,我尝试了半天也没解决…… 3、如果 n 个线程中,有 1 个特别慢,其它线程都执行完了它还没完,那么剩余待处理的数据会继续放到 n-1 个线程中继续运行吗?看代码我认为是的,但是不敢确定。
因为某些地方这种相同的代码重复很多次,所以想重构。
多谢,感谢指教!但是,想必您也能看出来,我这样写其实是就是为了跑 benchmark,故意让它的运算次数增加,可以跑得时间长点。否则按您优化后的算法,用任何语言跑都是几毫秒,用作性能对比不太直观。就好比两个人比赛爬楼梯,本来就是为了比体力,结果您在旁边说了一句“干嘛不坐电梯?”……
当然,优化算法往往对性能的提升是最大的,好代码与烂代码之间的性能差距何止千、万倍,这是用任何其它优化手段都做不到的。但是,现实中存在很多复杂计算,算法优化的空间有限,或者即使用了已知理论上最快的算法、用户体验上仍然无法接受,这就不得不想办法在其它方面(包括语言层面)压榨性能了。
至于 java 跑得快是不是因为对烂代码有优化,我对编译器知之甚少,不敢评价;不过,可能暂时持保留意见,原因有二:1、优化过的算法(好代码)只有几 ms,而烂代码 java11 实测 1 秒左右。以 java 编译器的功力,既然做了优化,为何不干脆优化到底?2、烂代码.net 4.8 实测 5s,.net 5.0 实测 2s,明显 5.0 的优化更好,但仍输于 java。而根据网上评测,.net5 的大部分算法 benchmark 小胜 java。如果这种烂代码很容易被优化,为何 2s 离 java 的 1s 仍有不小的差距?
更准确地说,100% 的任何项目最后的结局,都是公司倒闭。 凡人皆有一死……
读文件以后还有一些处理,处理的代码有几百行,这几百行代码又调用了几个 module,每个 module 上千行……
感谢回复。不用 redis 或数据库的主要考虑是,这个全局变量很大,而且调用频繁,如果放在外部内存可能性能不如本地内存,而且多了一项环境依赖。如果不能消除那个警告的话,好像只能先这样用着了。
系统参数已经用 gem config 处理了。这个全局变量实质上是把一个本地文件读取到内存,在 rails 启动时一次性加载。因为后续要不断使用这个文件中的数据,如果每次读一下本地文件太浪费资源了。
这样做是眼不见为净了,但是下一个版本可能就真变成报错了啊……有彻底的办法吗?
如果必须用局部变量,有办法吗