草庐IT

node.js - Nodejs EventLoop(带集群模块)和Golang Scheduler的比较

coder 2024-07-12 原文

在 nodejs 中,主要批评者基于其单线程事件循环模型。

nodejs 最大的缺点是无法在应用程序中执行 CPU 密集型任务。为了演示目的,让我们以 while 循环为例(这可能类似于一个返回十万条记录的 db 函数,然后在 nodejs 中处理这些记录。)

while(1){
    x++
}

此类代码将阻塞主堆栈,因此事件队列中等待的所有其他任务将永远没有机会执行。 (而在 web 应用程序中,新用户将无法连接到该应用程序)。

但是,可以使用像cluster 这样的模块来利用多核系统并部分解决上述问题。 Cluster 模块允许创建一个由独立进程组成的小型网络,这些进程可以共享服务器端口,这使 Node.js 应用程序可以访问服务器的全部功能。 (但是,使用 Cluster 的最大缺点之一是无法在应用程序代码中维护状态)。 但是,如果服务器负载过大,我们很有可能再次陷入同样的​​情况(如上所述)。

当我开始学习 Go 语言并了解它的架构和 goroutine 时,我认为它可能会解决由于 nodejs 的单线程事件循环模型而出现的问题。并且它可能会避免上述 CPU 密集型任务的场景,直到我遇到这段有趣的代码,它阻塞了所有 GO 应用程序并且什么也没有发生,很像 nodejs 中的 while 循环。

func main() {
    var x int
    threads := runtime.GOMAXPROCS(0)
    for i := 0; i < threads; i++ {
        go func() {
            for { x++ }
        }()
    }
    time.Sleep(time.Second)
    fmt.Println("x =", x)
}
//or perhaps even if we use some number that is just greater than the threads.

所以,问题是,如果我有一个负载密集型应用程序,并且还会有很多 CPU 密集型任务,我可能会陷入上述情况。 (其中 db 返回大量行,然后应用程序需要处理和修改这些行中的某些内容)。传入的用户不会被阻止,所有其他任务也会被阻止吗?

那么,如何解决上述问题呢?

附言
或许,我提到的用例没有多大意义? :)

最佳答案

目前(Go 1.11 及更早版本)你所谓的 紧密循环确实会阻塞代码。 发生这种情况仅仅是因为当前 Go 编译器 插入执行“抢占检查”的代码(«我应该放弃吗? 到调度程序,以便它运行另一个 goroutine?») 仅在 它编译的函数的序言(几乎,但我们不要离题)。 如果您的循环不调用任何函数,则不会进行抢占检查 将被制作。

Go 开发者很清楚这一点 和 are working on eventually alleviating this issue .

仍然请注意,您所谓的问题在 最真实的场景:执行很长时间的代码 在不调用任何函数的情况下运行 CPU 密集型工作 很少见,而且介于两者之间。

在某些情况下,您确实拥有这样的代码并且您拥有 检测到它真的让其他 goroutines 饿死 (让我强调一下:你已经通过分析发现了这一点——作为 反对只是想出“它一定很慢”),你可以 应用几种技术来处理这个问题:

  • 插入对 runtime.Gosched() 的调用在某些关键点 长时间运行的 CPU 密集型代码。 这将强制放弃对另一个 goroutine 的控制 而实际上并没有挂起调用者 goroutine(所以它会 一旦再次安排就运行)。
  • 为运行的 goroutines 提供专用的 OS 线程 那些 CPU pig :
    1. 将这样的 CPU 占用集合绑定(bind)到,比如说,N 个“worker goroutines”;
    2. 在他们前面放一个调度员(这叫做 "fan-out" );
    3. 确保 N 明显小于 runtime.GOMAXPROCS 提高后者,这样您就有了 N 个额外的线程。
    4. 通过调度程序将工作单元分配给那些专用的 goroutine。

关于node.js - Nodejs EventLoop(带集群模块)和Golang Scheduler的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51375902/

有关node.js - Nodejs EventLoop(带集群模块)和Golang Scheduler的比较的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  5. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  6. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  7. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  8. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  9. ruby-on-rails - Controller 中的 Rails 辅助模块 - 2

    我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll

  10. ruby-on-rails - 具有同名的模块和类 - 2

    我有一个模块stat存在于目录结构中:lib/stat_creator/stat/在lib/stat_creator/stat.rb中,我在lib/stat_creator/stat/目录中有我需要的文件,以及:moduleStatCreatormoduleStatendend当我使用该模块时,我将这些类称为StatCreator::Stat::Foo.new现在我想要一个存在于应用程序中的根Stat类。我在app/models中制作了我的Stat类,并在routes.rb中进行了设置。但是,如果我转到Rails控制台并尝试在应用程序/模型中使用Stat类,例如:Stat.by_use

随机推荐