麻雀虽小五脏具全-基于Redis的极简服务发现框架Captain
2016-06-03 00:00
435 查看
摘要: 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中纪录了一个全局的服务版本号,还为每个服务列表纪录了一个子版本号
客户端会周期性检测全局版本号,如果全局版本号编号,再检测依赖服务的子版本号,然后加载版本号变更了的服务列表
Less Keys, Large Value. 尽管captain提供了keyvalue的api,KeyValue也不可以被随便滥用。Captain缺少处理太多key的能力。请尽量只将keyvalue用于全局配置,将多个配置项聚合到一个kv中
客户端和服务器之间只使用http api进行通讯
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
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也不会提供
切换后,server会立即进入紧急模式,服务过期检测被停止,保持服务列表继续存活
当所有的server都切换成功后,再使用管理后台点击"start watcher",退出紧急模式,进入正常状态
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
简单直接的ini4j http://ini4j.sourceforge.net/
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 GETcancel 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"}} POSTget /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/pycaptainJava 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,你可以自己造一个相关文章推荐
- redis安装问题小结
- 使用 Redis 和 Python 构建一个共享单车的应用程序
- Redis偶发连接失败案例实战记录
- Redis中实现查找某个值的范围
- win 7 安装redis服务【笔记】
- redis的hGetAll函数的性能问题(记Redis那坑人的HGETALL)
- Redis和Memcached的区别详解
- 分割超大Redis数据库例子
- Redis总结笔记(一):安装和常用命令
- Redis sort 排序命令详解
- 用Redis实现微博关注关系
- Redis实现信息已读未读状态提示
- redis中修改配置文件中的端口号 密码方法
- 在Ruby on Rails上使用Redis Store的方法
- Redis和Memcache的区别总结
- 在Node.js应用中使用Redis的方法简介
- Redis服务器的启动过程分析
- web 应用中常用的各种 cache详解
- 利用yum安装Redis的方法详解
- 从MySQL到Redis的简单数据库迁移方法