开发者社区> 轩墨> 正文

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

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

synapse.png


架构

面向服务的架构是构建绝大多数产品的最可迭代和可用的软件配置之一。这些系统也遇到过很多问题,其中最大的问题可能就是服务发现问题。服务发现实际定义了你的服务如何与其它服务通信。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. 10x系列之Clay.io的架构
2. 10x系列之Clay.io是如何处理日志的
3. 10x系列之Docker在Clay.io

原文链接:10x: Service Discovery at Clay.io(翻译:崔婧雯 校对:李颖杰)

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

原文发布时间为:2015-03-02 
本文作者:崔婧雯 
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:10x系列之Clay.io的服务发现

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Garden.io:它是什么以及为什么要使用它?
Garden.io:它是什么以及为什么要使用它?
13 0
socket.io 集群版
socket.io 集群版
96 0
PHPSocket.IO 是什么?
PHPSocket.IO 是什么?
57 0
socket&io高性能
最近看到篇好文章《IO多路复用》,记得早期学习时,也去探索过select、poll、epoll的区别,但后来也是没有及时记录总结,也忘记了,学习似乎就是在记忆与忘记中徘徊,最后在心中留下的火种,是熄灭还是燎原就看记忆与忘记间的博弈 socket与io一对兄弟,有socket地方必然有io,io数据也大多来源于socket,回顾这两方面的知识点,大致梳理一下
82 0
IO通信模型(三)多路复用IO
从非阻塞同步IO的介绍中可以发现,为每一个接入创建一个线程在请求很多的情况下不那么适用了,因为这会渐渐耗尽服务器的资源,人们也都意识到了这个 问题,因此终于有人发明了IO多路复用。最大的特点就是不需要开那么多的线程和进程。 多路复用IO是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。
107 0
IO总结
IO总结
90 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
多IO线程优化版
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载