Synapse

一个用于连接SOA的透明服务发现框架
2,034
作者Igor Serebryany

Synapse是爱彼迎新的服务发现系统。Synapse解决了云环境中自动化故障转移的问题,在云环境中,通过网络重新配置进行故障转移是不可能的。最终结果是能够以可扩展、容错的方式将内部服务连接在一起。

动机

Synapse源于在云中维护高可用性应用程序的需求。传统的基于使用像pacemaker这样的CRM的高可用性技术,在最终用户无法控制网络的环境中不起作用。在像亚马逊EC2这样的环境中,所有可用的变通方法都并非最佳选择。

  • 轮询DNS:收敛速度慢,并且在应用程序缓存DNS查找(这种情况很常见)时不起作用。
  • 弹性IP:收敛速度慢,数量有限,仅面向公众,这使得它们对于内部服务不太有用。
  • ELB:同样,仅面向公众,并且仅适用于HTTP。

解决此问题的一种方法是使用服务发现服务,例如Apache Zookeeper。但是,Zookeeper和类似的服务也有自身的问题。

  • 服务发现嵌入在所有应用程序中;通常,集成并不简单。
  • 发现层本身也可能发生故障。
  • 需要额外的服务器/实例。

Synapse以简单且容错的方式解决了这些难题。

Synapse的工作原理

Synapse运行在您的应用程序服务器上;在爱彼迎,我们只是在我们部署的每个机器上运行它。Synapse的核心实际上是HAProxy,一个稳定且经过验证的路由组件。对于您的应用程序与之通信的每个外部服务,我们都会在localhost上分配一个Synapse本地端口。Synapse从本地端口到服务创建一个代理,您需要重新配置您的应用程序以与代理通信。

Synapse附带许多监视器,它们负责服务发现。Synapse监视器负责重新配置代理,使其始终指向可用的服务器。我们包含了许多默认监视器,包括查询Zookeeper和使用AWS API的监视器。您可以轻松地为您的用例编写自己的监视器,我们鼓励您将它们提交回项目。

迁移示例

假设您的Rails应用程序依赖于一个Postgres数据库实例。database.yaml文件硬编码了DB主机和端口。

production:
  database: mydb
  host: mydb.example.com
  port: 5432

您希望能够在原始数据库失效的情况下故障转移到另一个数据库。假设您的实例运行在AWS中,并且您使用标记“proddb”设置为“true”来指示生产数据库。您将Synapse设置为在synapse.conf.yaml文件中代理localhost:3219上的数据库连接。在services下添加如下所示的哈希值:

---
 services:
  proddb:
   default_servers:
    -
     name: "default-db"
     host: "mydb.example.com"
     port: 5432
   discovery:
    method: "awstag"
    tag_name: "proddb"
    tag_value: "true"
   haproxy:
    port: 3219
    server_options: "check inter 2000 rise 3 fall 2"
    frontend: mode tcp
    backend: mode tcp

然后将您的database.yaml文件更改为如下所示:

production:
  database: mydb
  host: localhost
  port: 3219

启动Synapse。它将使用从localhost:3219到您的数据库的代理配置HAProxy。它将尝试使用AWS API查找数据库;如果失败,它将默认为default_servers中给定的数据库。在最坏的情况下,如果AWS API宕机并且您需要更改应用程序连接的数据库,只需编辑synapse.conf.json文件,更新default_servers并重新启动Synapse。HAProxy将被透明地重新加载,您的应用程序将继续运行而不会出现任何问题。

链接