最近在解决探针获取Ruby应用服务器的内存使用的情况,将解决的思路总结一下,希望对此感兴趣的伙伴一起探讨。
先对比应用服务器: Puma 和 Passenger ,下面对比这2个服务器内存统计,
单进程模式:直接获取进程id: Process.pid
cluster模式:以启动2个worker进程为例:
从上面截图可以看到,Puma启动后会出现3个进程:1个master进程和2个worker进程。
内存的使用情况(见 RSS 列):
而对于探针来说,一个探针实例是伴随进程一起启动的,也就说一个探针只能识别自己所在的进程id,那如何获取应用服务器使用的内存?我们用其中1个woker进程所在的进程组[ PGID ]看一下:(为啥不是父进程?, 见下文Passenger)
这3个进程都在相同的进程组里,而且进程组号为master的进程id,那我们就可以用这个信息获取应用服务器的所使用的内存:
4.累加进程组内进程内存和即为应用服务器使用内存:
启动Passenger后的Process信息:
对Passenger架构感兴趣的请移步到 这儿 .
查看一下worker所在进程组和父进程:
通过PPID可以看出
Passenger core —>Passenger AppPreloader —>Passenger RubyApp
三者为爷-父-子关系,当服务器请求量增大时 AppPreloader 会产生新的进程来响应请求,从而新的 RubyApp 进程的 PPID 即为 AppPreloader 的 PID ,这样看来就可以将同一个 PPID 的进程加起来得到应用服务器的内存?
由于Passenger会根据服务器的负载量动态调整进程数,当服务器请求量较小时,Passenger会kill多余的进程,会出现下面的情况:
AppPreloader 也被Passenger杀掉了。原 RubyApp 进程的 PPID 变成了1。这时如果服务器的请求量增大,应用服务器进程会成为这样:
Passenger core 产生新的 AppPreloader 进程,并且 AppPreloader 产生新的 RubyApp 进程,这时如果只用 PPID 统计应用服务器内存就会不准确,所以要统计Passenger的使用的内存还得通过累加在同一个进程组( PGID )的所有进程使用的内存和得到。
由于 Unicorn 和 Rainbows 都与Puma的cluster模式[master+worker模式]类似,内存统计的方式可以参考上文的Puma。
由于 Thin 启动多个server后没有类似的特点,上面方法不适用于Thin,有好方法的伙伴们可以告知:smile:
在解决探针统计应用服务器的内存问题上,摸索出了上面的一条路子,如果小伙伴们有其他更好的方式,可以一起探讨一下。
Ruby,一种为简单快捷的面向对象编程(面向对象程序设计)而创的脚本语言.作用:Ruby 是开源的,在Web 上免费提供,但需要一个许可证。Ruby 是一种通用的、解释的编程语言。Ruby 是一种真正的面向对象编程语言。Ruby 是一种类似于 Python 和 Perl 的服务器端脚本语言。Ruby 可以用来编写通用网关接口(CGI)脚本。Ruby 可以被嵌入到超文本标记语言(HTML)。Ruby 语法简单,这使得新的开发人员能够快速轻松地学习 Ruby。Ruby 与 C++ 和 Perl 等许多编程语言有着类似的语法。Ruby 可扩展性强,用 Ruby 编写的大程序易于维护。Ruby 可用于开发的 Internet 和 Intranet 应用程序。Ruby 可以安装在 Windows 和 POSIX 环境中。Ruby 支持许多 GUI 工具,比如 Tcl/Tk、GTK 和 OpenGL。Ruby 可以很容易地连接到 DB2、MySQL、Oracle 和 Sybase。Ruby 有丰富的内置函数,可以直接在 Ruby 脚本中使用。先定义一下前后端,所谓web前端是指运行在用户浏览器中的内容;而后端则是指运行在应用服务器上的内容。前后端之间通过http协议进行交互:浏览器发起http请求(来源于浏览器的直接发起和前端代码中的ajax请求),后端得到请求后返回数据(可能是html、静态文件或者ajax调用产生的数据)。ruby只能做服务端也就是后端开发,前端依然需要使用javascript+css
不过javascript也可以用作后端开发,那就是nodejs