10x系列之Clay.io的服务发现

【编者的话】Clay.io的Zoli Kahan撰写了“10X”系列博文,分享如何只使用一个很小的团队支撑Clay.io的大规模应用。本文是整个系列的第四篇,介绍如何构建一个服务发现系统。

架构

面向服务的架构 是构建绝大多数产品的最可迭代和可用的软件配置之一。这些系统也遇到过很多问题,其中最大的问题可能就是服务发现问题。服务发现实际定义了你的服务如何与其它服务通信。Docker里也有这个问题。如果你不知道我们如何部署Docker,请参看 Docker at Clay.io (中文翻译)。

教程

Synapse( https://github.com/claydotio/synapse )是一个动态配置本地HAproxy的后台程序。HAproxy负责在集群内将请求转发到服务,它会根据配置文件的定义,寻找Amazon EC2(或其它)服务。我们用的是 ec2tag ,可以很容易地通过标签化服务器并将其添加到集群。

HAProxy

让我们从服务入手。服务之间通过本地的 HAProxy 实例互相通信。因为服务运行在Docker内部,我们需要为服务指定宿主IP在某个特定端口寻找服务。

我们使用 Ansible 将本地IP和端口传给运行在机器上的服务。

SERVICE_API=http://{ ansible_default_ipv4.address }:{ service_port }   

对于要使用其它服务的服务,只需要简单地调用IP/端口。这里的关键点是IP是本地机器的IP,它可以被HAProxy处理。我们发布了一个HAProxy docker容器,它监控挂载着的配置文件,在有变化时自动更新:

https://github.com/claydotio/haproxy

docker run
--restart always
--name haproxy
-v /var/log:/var/log
-v /etc/haproxy:/etc/haproxy
-d
-p 50001:50001
-p 50002:50002
-p 50003:50003
-p 50004:50004
...
-p 1937:1937
-t clay/haproxy

我们默认在 /etc/haproxy 使用 noop config ,它会挂载到Docker容器中并监控变化。我们也会将相同的HAproxy config挂载到Synapse容器。要注意的是,如果这个容器关闭了,机器上的所有服务就不会被其它服务发现。因此,我们给容器也分配了另外的端口以供未来的新服务使用(因为无法被 动态分配 )。

Synapse

好了,现在开始搭建Synapse。

Synapse的运行很简单(归功于公共Docker容器库)。

docker run
--restart always
--name synapse
-v /var/log:/var/log
-v /etc/synapse:/etc/synapse
-v /etc/haproxy:/etc/haproxy
-e AWS_ACCESS_KEY_ID=XXX
-e AWS_SECRET_ACCESS_KEY=XXX
-e AWS_REGION=XXX
-d
-t clay/synapse
synapse -c /etc/synapse/synapse.conf.json

注意我们如何在容器里挂载Synapse config以及HAproxy config。HAProxy配置就是上文提到的noop config(因为其会由Synapse自动生成),我们来看看如何配置Synapse。

配置Synapse有些难,因为 文档 写得不是很好。如下是示例配置,可以解释所有文档里缺失的信息:

{
"services": {
"myservice": {
"discovery": {
// use amazon ec2 tags
"method": "ec2tag",
"tag_name": "servicename",
"tag_value": "true",
// if this is too low, Amazon will rate-limit and block requests
"check_interval": 120.0
},
"haproxy": {
// This is the port other services will use to talk to this service
// e.g. http://10.0.1.10:50003
"port": 50003,
"listen": [
"mode http"
],
// This is the port that the service exposes itself
"server_port_override": "50001",
// This is our custom (non-documented) config for our backup server
// See http://zolmeister.com/2014/12/10x-docker-at-clay-io.html
// for details on how our zero-downtime deploys work
"server_backup_port": "50002",
"server_options": "check"
}
}
},
// See the manual for details on parameters:
// http://cbonte.github.io/haproxy-dconv/configuration-1.5.html
"haproxy": {
// This is never used because HAProxy runs in a separate container
// Reloads happen automatically via the file-watcher
"reload_command": "echo noop",
"config_file_path": "/etc/haproxy/haproxy.cfg",
"socket_file_path": "/var/haproxy/stats.sock",
"do_writes": true,
"do_reloads": true,
"do_socket": false,
// By default, this is localhost, however because HAProxy is running
// inside of a container, we need to expose it to the host machine
"bind_address": "0.0.0.0",
"global": [
"daemon",
"user haproxy",
"group haproxy",
"chroot /var/lib/haproxy",
"maxconn 4096",
"log 127.0.0.1 local0",
"log 127.0.0.1 local1 notice"
],
"defaults": [
"log global",
"mode http",
"maxconn 2000",
"retries 3",
"timeout connect 5s",
"timeout client 1m",
"timeout server 1m",
"option redispatch",
"balance roundrobin",
"default-server inter 2s rise 3 fall 2",
"option dontlognull",
"option dontlog-normal"
],
"extra_sections": {
"listen stats :1937": [
"stats enable",
"stats uri /",
"stats realm Haproxy Statistics"
]
}
}

}

结论

特别感谢Airbnb开源了他们的工具,这使得我们可以以简单可扩展的方式搭建服务发现系统。对于没有使用Amazon EC2的人,可以使用 Zookeeper watcher(我们没有用到),或者即将可以使用的 etcd watcher

一旦代码被合并,我们可能会选择使用 Nerveetcd 替代EC2标签,来发布服务。以下etcd示例的Docker信息仅供参考:

curl https://discovery.etcd.io/new?size=3
docker run
--restart always
--name etcd
-d
-p 2379:2379
-p 2380:2380
-v /opt/etcd:/opt/etcd
-v /var/log:/var/log
-v /etc/ssl/certs:/etc/ssl/certs
quay.io/coreos/etcd:v2.0.0
-data-dir /opt/etcd
-name etcd-unique-name
-listen-client-urls http://0.0.0.0:2379
-listen-peer-urls http://0.0.0.0:2380
-advertise-client-urls http://localhost:2379
-initial-advertise-peer-urls http://localhost:2380
-discovery https://discovery.etcd.io/XXXXXXXXXXXX
-initial-cluster-token cluster-token-here

1.2.3.===========================译者介绍崔婧雯,现就职于VMware,高级软件工程师,负责桌面虚拟化产品的质量保证工作。曾在IBM WebSphere业务流程管理软件担任多年系统测试工作。对虚拟化,中间件技术有浓厚的兴趣。

我来评几句
登录后评论

已发表评论数()