您的位置:首页 > 数据库 > Redis

麻雀虽小五脏具全-基于Redis的极简服务发现框架Captain

2016-06-03 00:00 435 查看
摘要: Captain通过牺牲一点点高可用性以达到简单高效。在大多数中小型公司,并没有成千上万台的机器设备,机器宕机可能性很小,N个9的高可用性还没有显得太重要。但是开源市场上只提供了zk/etcd/consul这类强一致性服务发现框架,它们都过于复杂,至少一般人很难理解系统内部到底是怎么回事。

Captain -- 基于Redis的极简服务发现系统

Captain通过牺牲一点点高可用性以达到简单高效。在大多数中小型公司,并没有成千上万台的机器设备,机器宕机可能性很小,N个9的高可用性还没有显得太重要。但是开源市场上只提供了zk/etcd/consul这类强一致性服务发现框架,它们都过于复杂,至少一般人很难理解系统内部到底是怎么回事。

https://github.com/pyloque/captain

架构





Captain系统是无状态的,客户端可以访问多个server

Captain客户端可以同时是服务生产者和消费者

如果所有的Captain server还有redis都宕机了,Captain客户端依然会将服务发现信息保留在内存中

如果只有一个Captain server宕机了,Captain客户端可以从其它Captain server获取服务信息

如果只有redis master宕机了,可以在管理后台动态切换到redis slave

仔细监控redis和captain server的状态,即时恢复,高可用性依然可以得到保证

内部结构

每个服务列表保存在redis的sortedset中,key就是host:port服务地址,score是${now+ttl}

有一个专门负责清理过期服务的线程,它定时扫描所有的服务列表

为了快速检测服务列表的变化,在redis中纪录了一个全局的服务版本号,还为每个服务列表纪录了一个子版本号

客户端会周期性检测全局版本号,如果全局版本号编号,再检测依赖服务的子版本号,然后加载版本号变更了的服务列表

Less Keys, Large Value. 尽管captain提供了keyvalue的api,KeyValue也不可以被随便滥用。Captain缺少处理太多key的能力。请尽量只将keyvalue用于全局配置,将多个配置项聚合到一个kv中

客户端和服务器之间只使用http api进行通讯

服务发现 API

keep service /api/service/keep?name=sample&host=localhost&port=6000&ttl=30 GET

cancel service /api/service/cancel?name=sample&host=localhost&port=6000 GET

get service version /api/service/version?name=sample1&name=sample2 GET

get service list /api/service/set?name=sample GET

KV AP
3ff0
I

set /api/kv/set?key=sample&value={"a": "m", "b": "n", "c": {"a": "m", "b": "n"}} POST

get /api/kv/get?key=sample GET

mget /api/kv/mget?key=sample1&key=sample2 GET

get kv version /api/kv/version?key=sample1&key=sample2 GET

全局 API

get global service & kv version in single api /api/version

安装 Captain Server

install redis
install java8
install maven

git clone github.com/pyloque/captain.git
cd captain
mvn package
java -jar target/captain.jar
java -jar target/captain.jar ${configfile}  # custom config file

open web ui http://localhost:6789/ui/

配置

Default Config File is ${user.home}/.captain/captain.ini

[server]
host = 0.0.0.0
port = 6789
thread = 24 # sparkjava threadpool size

[redis]
host = localhost
port = 6379
db = 0

[watch]
interval = 1000 # service expiring check interval, default 1000ms. server will run in readonly mode if interval=0.

只读模式

不启动服务过期检测线程,服务列表永远不会主动过期

服务保持和取消API也不会提供

动态切换Redis

如果redis master遇到偶然宕机,你应该使用管理后台快速切换到redis slave
切换后,server会立即进入紧急模式,服务过期检测被停止,保持服务列表继续存活
当所有的server都切换成功后,再使用管理后台点击"start watcher",退出紧急模式,进入正常状态

Web管理后台









客户端SDK

Python Client https://github.com/pyloque/pycaptain

Java Client https://github.com/pyloque/captain-java

Golang Client https://github.com/pyloque/gocaptain

Agent Server https://github.com/pyloque/captain-agent

PHP Client https://github.com/pyloque/phpcaptain

饮用

棒棒的SparkJava https://github.com/perwendel/spark/

简单直接的ini4j http://ini4j.sourceforge.net/

注意

Captain还在持续的开发中,稳定性虽尚不明确。不过captain的设计如果简单清晰,如果你不想使用带bug的captain,你可以自己造一个

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息