NATS是CloudFoundry内部的神经系统,是一款基于EventMachine、使用“发布--订阅”机制的轻量级消息中间件。基于EM的特点使得NATS在Ruby环境下有着处理高并发请求的能力。NATS对消息本身不做持久化,所以匹配和订阅的过程比较简洁高效。目前,NATS server是CF中一处需要解决的单点依赖。
NATS主要的依赖gem包包括:eventmachine, json_pure, daemons, thin
NATS的代码结构比较简单:
源码地址: https://github.com/derekcollison/nats/
lib
nats/client.rb NATS的客户端
nats/server.rb 启动NATS server的入口类
nats/server/server.rb NATS server的实际代码
nats/server/connection.rb 网络连接和消息处理的部分
nats/server/sublist.rb 订阅者管理的部分
nats/server/options.rb NATS的启动选项
nats/ext/ 对JRuby和Ruby1.8的补充部分
另外,在github上的cluster分支下,我们还可以看到NATS Cluster的代码:
lib
nats/server/cluster.rb NATS server集群的代码
nats/server/route.rb NATS路由集群的代码
NOTE:在阅读代码之前,我们最好先按照github上readme部分熟悉下NATS的使用。
一、/lib/nats/server.rb
这是是server包装类,它通过EventMachine启动了两个服务。
1、Nats Server,基于EM的核心消息服务器
NATSD::Server.start_http_server
EventMachine::start_server(NATSD::Server.host, NATSD::Server.port, NATSD::Connection)
这里,我们就可以看到NATS与EM的密切关系,请尝试对比一下下面两段代码:
左边部分是我们之前见过的启动一个”Echo server“的简单例子,而右边则是NATS中启动核心NATS server的方法。没错NATS就是基于EM的网络编程的典型例子。在接下来的NATS#connection部分,我们还可以看到更多这样的例子。
2、HTTP Monitor Server,一个基于Thin的监控服务器。跟CF其他组件一样,这个monitor server主要用来响应/varz和/healthz请求。
# Check to see if we need to fire up the http monitor port and server
if NATSD::Server.options[:http_port]
begin
NATSD::Server.start_http_server
rescue => e
log "Could not start monitoring server on port #{NATSD::Server.options[:http_port]}"
log_error
exit(1)
end
end
查看/lib/nats/server/options.rb中关于:http_port的定义,我们可以看到启动monitor的方法:
opts.on("-m", "--http_port PORT", "Use HTTP PORT ")。没错,就是加参数-m。
比如,我们访问localhost:http_port/varz,可以看到这个nats-server的信息。
{
"in_bytes": 0,
"out_bytes": 0,
"cpu": 3.2,
"start": "Tue Oct 09 17:15:54 +0800 2012",
"connections": 0,
"options": {
"max_pending": 2000000,
"users": [
{
"pass": "nats",
"user": "nats"
}
],
... ...
而如果我们访问/healthz,会收到一个“ok”,这与CloudFoundry component的机制也是类似的:
@healthz = "ok\n&