本篇主要阐述了为什么需要服务发现功能,对几种服务发现工具进行了比较。同时,在 CentOS 上,对 Etcd、Confd 、Nginx 实现服务发现功能进行了实践。
1. 服务注册与发现
1.1 为什么需要注册和发现服务
随着微服务的兴起,大量接口服务化。当新的微服务加入或微服务的信息发生变更时,服务方如何通知周边系统、使用方如何知道这些变更呢?
这时就需要服务的注册配置和发现功能。
- 服务注册配置——存储的信息至少包括正在运行的服务的主机和端口信息
- 服务发现——允许其他用户可以发现在服务注册配置阶段存储的信息。
1.2 几种服务发现工具的比较
Feature | Consul | Zookeeper | Etcd | Euerka |
---|---|---|---|---|
服务健康检查 | 服务状态,内存,硬盘等 | (弱)长连接,keepalive | 连接心跳 | 可配支持 |
多数据中心 | 支持 | — | — | — |
kv存储服务 | 支持 | 支持 | 支持 | — |
一致性 | raft | paxos | raft | — |
cap | ca | cp | cp | ap |
使用接口(多语言能力) | 支持http和dns | 客户端 | http/grpc | http(sidecar) |
watch支持 | 全量/支持long polling | 支持 | 支持 long polling | 支持 long polling/大部分增量 |
自身监控 | metrics | — | metrics | metrics |
安全 | acl /https | acl | https支持(弱) | — |
spring cloud集成 | 已支持 | 已支持 | 已支持 | 已支持 |
注:
- C,强一致性 (Consistency)
- A,可用性 (Availability)
- P,网络分区故障的容错性 (Partition Tolerance)
Consul 是使用 Go 语言开发的分布式协调系统,对业务发现的管理提供很好的支持,它的 HTTP API 也能很好的和不同的语言绑定,并支持跨数据中心的应用。缺点是相对较新,适合喜欢尝试新事物的用户。
ZooKeeper 功能全,社区活跃,用户群体很大,对所有典型的用例都有很好的封装,支持不同语言的绑定。缺点是,整个应用比较重,依赖于 Java,不支持跨数据中心。
Etcd 是一个更轻量级的分布式协调的应用,更适合一些轻量级的应用来使用,同时 Etcd 也提供 HTTP API 操作接口。值得注意的是,Kubernetes 采用了 Etcd 作为配置中心。
Eureka 是 Netflix 开源的一个 RESTful 服务,主要用于服务的注册发现。Eureka 由两个组件组成:Eureka 服务器和 Eureka 客户端。Eureka 服务器用作服务注册服务器。Eureka 客户端是一个 Java 客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。
2. Etcd
2.1 简介
Etcd 是一个分布式、使用 Raft 算法维护一致性的 key-value 存储系统,与其类似产品有 Zookeeper、Consul 等,Etcd 相对 Zookeeper,更加轻量、易运维。同时,Etcd 支持 TLS 通信,具备高性能的写入能力。
2.2 Raft 算法
很多的分布式系统都会采用 Paxos 协议,但是 Paxos 协议难以理解,并且在实际实现中差别比较大。所以 Etcd 选择了 Raft 作为它的一致性协议。Raft 是 Diego Ongaro 和 John Ousterhout 在 In Search of an Understandable Consensus Algorithm
中提出的。它在牺牲很少可用性,达到相似功能的情况下,对 Paxos 做了很大的优化,并且比 Paxos 简单易懂很多。
它主要集中在解决两个问题:
领导者选举(Leader Election)
Raft 先通过领导选举选出一个 Leader,后续的一致性维护都由 Leader 来完成,这就简化了一致性的问题。Raft 会保证一个时间下只会有一个 Leader,并且在超过一半节点投票的情况下才会被选为 Leader。当 Leader 挂掉的时候,新的 Leader 将会被选出来。日志复制 (Log Replication)
为了维护状态,系统会记录下来所有的操作命令日志。Leader 在收到客户端操作命令后,会追加到日志的尾部。然后 Leader 会向集群里所有其它节点发送 AppendEntries RPC 请求,每个节点都通过两阶段提交来复制命令,这保证了大部分的节点都能完成。
3. Etcd + Confd + Nginx
在进行应用部署时,服务运行起来后,通过接口向 Etcd 注册相关 key-value 信息,Confd 检测到 Etcd 的 key-value 变化后,立即触发程序通过模板形成新的 Nginx 配置文件。
Nginx 先做离线语法测试,如果没问题就覆盖原配置,进而 reload,测试不通过就不覆盖原配置,整个过程安全可控。
3.1 Nginx 安装配置
- 安装以 CentOS 为例
|
|
include /etc/nginx/conf.d/*.conf;
这句配置会将 conf.d 目录下 .conf 后缀的文件配置载入 Nginx。
3.2 Confd 安装配置
直接从 github 下载 Confd 的 Linux 编译版本,然后将可执行文件移动到 /usr/sbin/
目录即可。
|
|
3.3 Etcd 安装配置
- 安装以 CentOS 为例
|
|
- 配置文件目录,/etc/etcd/etcd.conf
|
|
- 启动服务
|
|
3.4 Confd 安装配置
- 创建配置目录
|
|
在 conf.d 下创建 .toml 配置文件
/etc/confd/conf.d/app1.toml
|
|
|
|
在 templates 下创建 .tmpl 模板文件
/etc/confd/templates/subdomain.conf.tmpl
|
|
Nginx 模板配置
/etc/confd/templates/subdomain-nginx.conf.tmpl
upstream {{getv "/subdomain"}} {
{{range getvs "/upstream/*"}}
server {{.}};
{{end}}
}
server {
server_name {{getv "/subdomain"}}.example.com;
location / {
proxy_pass http://{{getv "/subdomain"}};
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
监听 Etcd 的 key-value 值的变化
|
|
3.5 注册服务
可以通过 etcdctl
命令,也可以通过 Etcd 提供的 HTTP API,在 Etcd 插入 subdomain 和 upstream 数据。下面以 etcdctl
为例:
|
|
由于在本地 5601 端口,启动了 ELK 服务,通过访问 http://app1.example.com 打开 Kibana 。
如果需要 Nginx 进行负载均衡,可以在 upstream 上配置多个键值。同时,需要在 /etc/confd/conf.d 目录下新建两个文件 app2-nginx.toml 和 app2.toml,内容上只需要将 app1-nginx.toml 和 app1.toml 中的 app1 修改为 app2 即可。
|
|