zoukankan      html  css  js  c++  java
  • (转载)服务发现系统etcd介绍

    • 服务发现系统etcd介绍

    最近在折腾服务发现系统,在这之前折腾过一段时间CoreOS,那时候就接触etcd了,不过当时只是把etcd看做一个K/V存储系统来使用的,觉得和redis没什么区别,后来才知道etcd主要也是用于服务发现的。etcd 的灵感来自于 ZooKeeper 和 Doozer,侧重于:
    简单:支持 curl 方式的用户 API (HTTP+JSON)
    安全:可选 SSL 客户端证书认证
    快速:单实例可达每秒 1000 次写操作
    可靠:使用 Raft 实现分布式
    etcd是用Go语言编写的,使用raft一致性算法来管理高可用日志。etcdctl是一个简单的命令行工具,使用起来就和curl一样。etcd已经托管在github上了,我们下载一个稳定版的(0.4.6),不要下载0.5.0版本,0.5.0是基于开发版的,在折腾kubernetes的时候直接下载的0.5.0,可被坑惨了。部署环境还是三台ubuntu14.04机器,都是部署在/opt/etcd目录下
    192.168.1.100  Docker-1  server
    192.168.1.101  Docker-2  client
    192.168.1.102  Docker-3  client
    我们先在Docker-1上练练手,首先安装etcd,etcd用Go语言编写,安装时需要go环境,我这三台机器运行Docker,go环境都已经部署ok了,所以直接编译即可
    cd /opt/etcd
    ./build
    执行完上述命令后,会在源码目录发现生成了一个bin目录,里面有两个文件bench、etcd。先在我们来启动etcd
    ./bin/etcd
    
    
    
    etcd启动后,会监听在4001端口,用来和client进行通讯,而监听的7001端口则是服务端和服务端之间进行通讯的端口。下面我们来设置一个key
    #set
    curl http://127.0.0.1:4001/v2/keys/guol -XPUT -d value='test etcd'
    #get
    curl http://127.0.0.1:4001/v2/keys/guol
    
    
    
    操作起来很简单,现在我们已经启动了一个单节点的etcd服务,并且初步尝试了etcd的api,下面我们看看一些具体的内容。
    etcd api
    etcd的api系统是一个空间层次分明的系统,key space是由目录和密钥构成的。我们先启动一个etcd系统,并查看该etcd的版本
    #start
    ./bin/etcd -data-dir /tmp/etcd/ -name Docker-1
    #get version
    curl  http://127.0.0.1:4001/version
    在启动etcd时,多了两个参数,-data-dir指定etcd系统存储etcd配置、日志和快照的目录,-name该节点在集群中的名称。
    接下来,我们设置第一对K/V,key=message1,value='hello world'
    curl -s http://127.0.0.1:4001/v2/keys/message1 -XPUT -d value='hello world'
    
    
    
    我们看看返回的对象都包含了哪些值:action,action反映当前请求的模式(get/set/delete),因为当前的请求是通过HTTP的PUT方法修改节点的值,所以action是set。node对象中有四个元素:node.key,HTTP请求设置的key名称,etcd使用类似文件系统的结构来表示K/V对,所以所有的key前面都以'/'开头。node.value,设置的key的值。node.createdIndex,一个唯一的索引,在每次etcd变更时一个单调递增的整数,这个特性可以反映出etcd系统已经创建了多少个key,你可以看到索引的值是8,那是因为之前我已经插入了几对K/V值了,在etcd有变更后,也有一些内部命令在幕后做一些变更,例如增加或者同步servers。node.modifiedIndex,和node.createdIndex很像,该属性也是一个索引,set、delete、update、create、compareAndSwap、compareAndDelete等动作都会引起value值的改变,get、watch动作不会引起已经存储的值的改变,因此这两个特性不会改变node.modifiedIndex的值。
    获取一个key的值,我们获取key(message1)的值
    curl -s http://127.0.0.1:4001/v2/keys/message1
    
    你也可以用HTTP的PUT方法改变一个key的值,我们改变message1的value为'hello etcd'
    curl -s http://127.0.0.1:4001/v2/keys/message1 -XPUT -d value='hello etcd'
    
    
    
    这次我们看到返回值中多了一个prevNode属性,prevNode属性根据名称一看就知道是返回的该key在改变前的值,prevNode的格式和node一样,你也会看到index都会递增。
    我们也可以用HTTP的DELETE方法删除一个key,我们删除key(message1)
    curl -s http://127.0.0.1:4001/v2/keys/message1 -XDELETE
    
    
    
    这时候再查看message1的值会发现已经没有该key了
    
    你也可以在etcd系统中给key设置一个过期时间,只需要在设置key时加上一个ttl参数即可
    curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd' -d ttl=5
    
    
    
    看到设置的message2的生存期只有5s,过期后会自动删除。在node的输出中多了一个expiration属性,该属性提示多久后key会过期并被删除。ttl属性显示key的ttl值。后面多余的输出是使用以下命令测试的:
    curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd' -d ttl=5|jq .;echo 'sleep....';sleep 6;curl -s http://127.0.0.1:4001/v2/keys/message2 |jq .
    我们也可以监视key的变更,在key有改变后,我们会收到相关通知。在调用HTTP请求时,提供wait=true参数,即可监控一个key。
    #窗口1
    curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd 1'
    curl -s http://127.0.0.1:4001/v2/keys/message2?wait=true
    新开一个终端,执行以下命令
    curl -s http://127.0.0.1:4001/v2/keys/message2 -XPUT -d value='hello etcd 2'
    再看看窗口1有什么变化
    
    
    自动的创建顺序key,在一个目录中使用POST方法,你可以创建一些key,使key的名字看起来是顺序的,执行以下测试命令:
    curl -s http://127.0.0.1:4001/v2/keys/message3 -XPOST -d value='hello etcd 1'
    curl -s http://127.0.0.1:4001/v2/keys/message4 -XPUT -d value='hello etcd 1'
    curl -s http://127.0.0.1:4001/v2/keys/message5 -XPUT -d value='hello etcd 1'
    curl -s http://127.0.0.1:4001/v2/keys/message3 -XPOST -d value='hello etcd 2' | jq .
    
    
    
    可以看到我们已经针对message3这个key使用了POST方法,在插入两个新key之后,再次更新message3的value,发现messages3在etcd中的key已经变了(key/index),下面我们看看message3这个key中到底存储什么信息,为了使输出的key是顺序的,我们加了sorted参数
    curl -s 'http://127.0.0.1:4001/v2/keys/message3?recursive=true&sorted=true'
    
    可以看到存有message3的历史值记录,在某些情况下,需要自动创建key的目录,但在某些情况下,你希望创建或者删除一个目录。创建一个目录就像创建key一样简单,但是你不能提供一个value,而是要增加一个参数dir=true
    curl -s http://127.0.0.1:4001/v2/keys/message7 -XPUT -d dir=true
    
    
    
    看到没有value属性,而是多了一个dir属性。有创建目录的需求,就有删除目录的需求,我们现在删除刚刚创建的message7目录,和删除key的方法一样,也是使用HTTP的DELETE方法,只不过要再添加一个dir=true参数
    curl -s 'http://127.0.0.1:4001/v2/keys/message7?dir=true' -XDELETE
    
    
    
    如果director里面已经包含keys了,则必须增加recursive=true参数
    curl -s 'http://127.0.0.1:4001/v2/keys/message7?recursive=true' -XDELETE
    在etcd系统中,我们可以存储两种类型的东西:keys和directors。keys存储的是单个字符值,directors存储的是一组keys或者存储其他directors。下面我们创建一个key(message_key),在创建该key之前,我们先看看etcd系统已经存在哪些key了,要查看整个系统的key,只要增加recursive=true参数即可。
    curl -s http://127.0.0.1:4001/v2/keys/?recursive=true
    
    
    
    因为我已经清空etcd系统了,现在创建key:message_key
    curl -s http://127.0.0.1:4001/v2/keys/message_key -XPUT -d value='this is a key'
    
    
    
    创建directory:message_directory
    curl -s http://127.0.0.1:4001/v2/keys/message_directory -XPUT -d dir=true
    
    
    
    现在我们看看整个etcd系统中有多少key
    curl -s http://127.0.0.1:4001/v2/keys/?recursive=true
    
    
    
    可以看到整个etcd中只有一个key和一个directory,现在我们在message_directory目录下面创建一个key(message_key)
    curl -s http://127.0.0.1:4001/v2/keys/message_directory/message_key -XPUT -d value='this is a key in directory'
    
    
    
    我们现在看看etcd系统都有哪些key了
    curl -s http://127.0.0.1:4001/v2/keys/?recursive=true
    
    可以看到整个etcd中有一个key和一个directory,而directory中又包含了一个key。
    如何创建一个隐藏的节点(隐藏key/隐藏directory),我们创建一个隐藏key时使用'_'作为key的前缀即可,当你发送HTTP GET请求时,隐藏key并不会被显示出来
    curl -s http://127.0.0.1:4001/v2/keys/_message -XPUT -d value='a hidden key'
    
    
    
    etcd系统中也可以存储一些小的配置文件、json文档、xml文档等等。
    curl -s http://127.0.0.1:4001/v2/keys/file -XPUT --data-urlencode value@upfile
    
    
    
    etcd会跟踪一些集群使用的统计信息,比如带宽、启动时间之类的。
    Leader Statistics:leader有查看整个etcd集群视图的能力,而且会跟踪两个有趣的统计信息:到集群中同等机器的延迟和rafr rpc请求失败和成功的数量。
    curl -s http://127.0.0.1:4001/v2/stats/leader
    
    
    
    Self Statistics:每个节点内部的统计信息
    curl -s http://127.0.0.1:4001/v2/stats/self
    
    
    
    Store Statistics:存储统计信息包含了在该节点上的所有操作信息
    curl -s http://127.0.0.1:4001/v2/stats/store
    
    如何查询集群的配置
    curl -s http://192.168.1.100:7001/v2/admin/config
    
    
    
    看看整个集群中有多少成员
    curl -s http://192.168.1.100:7001/v2/admin/machines
    
    
    
    在集群中删除Docker-2节点
    curl -s http://192.168.1.100:7001/v2/admin/machines/Docker-2 -XDELETE
    再次查看整个集群的成员
    
    

    etcd节点的配置文件可以有三种设置方法:命令行、环境变量、配置文件,命令行优先级最高,环境变量的又高于配置文件。

    下面我们看看etcd的命令都支持哪些命令行参数:
    Options:
      --version         显示版本号
      -f -force         强制使用新的配置文件
      -config=<path>    指定配置文件的路径
      -name=<name>      该节点在etcd集群中显示的名称
      -data-dir=<path>  etcd数据的存储路径
      -cors=<origins>   Comma-separated list of CORS origins.
      -v                开启verbose logging.
      -vv               开启very verbose logging.
    
    Cluster Configuration Options:
      -discovery=<url>                Discovery service used to find a peer list.
      -peers-file=<path>              包含节点信息的文件列表
      -peers=<host:port>,<host:port>  逗号分割的节点列表,这些节点应该匹配节点的-peer-addr标记指定的信息
    
    Client Communication Options:
      -addr=<host:port>         客户端进行通讯的公共地址端口
      -bind-addr=<host[:port]>  监听的地址端口,用来进行客户端通讯
      -ca-file=<path>           客户端CA文件路径
      -cert-file=<path>         客户端cert文件路径
      -key-file=<path>          客户端key文件路径
    
    Peer Communication Options:
      -peer-addr=<host:port>  节点间进行通讯的地址端口
      -peer-bind-addr=<host[:port]>  监听的地址端口,节点间来进行通讯
      -peer-ca-file=<path>    节点CA文件路径
      -peer-cert-file=<path>  节点cert文件路径
      -peer-key-file=<path>   节点key文件路径
      -peer-heartbeat-interval=<time> 心跳检测的时间间隔,单位是毫秒
      -peer-election-timeout=<time> 节点选举的超时时间,单位是毫秒
    
    Other Options:
      -max-result-buffer   结果缓冲区的最大值
      -max-retry-attempts  节点尝试重新加入集群的次数
      -retry-interval      Seconds to wait between cluster join retry attempts.
      -snapshot=false      禁止log快照
      -snapshot-count      发布快照前执行的事物次数
      -cluster-active-size 集群中的活跃节点数
      -cluster-remove-delay 多少秒之后再删除集群中的节点
      -cluster-sync-interval 在备模式下,两次同步之间的时间差
    配置文件方式,etcd默认从/etc/etcd/etcd.conf读取配置
    addr = "127.0.0.1:4001"
    bind_addr = "127.0.0.1:4001"
    ca_file = ""
    cert_file = ""
    cors = []
    cpu_profile_file = ""
    data_dir = "."
    discovery = "http://etcd.local:4001/v2/keys/_etcd/registry/examplecluster"
    http_read_timeout = 10.0
    http_write_timeout = 10.0
    key_file = ""
    peers = []
    peers_file = ""
    max_cluster_size = 9
    max_result_buffer = 1024
    max_retry_attempts = 3
    name = "default-name"
    snapshot = true
    verbose = false
    very_verbose = false
    
    [peer]
    addr = "127.0.0.1:7001"
    bind_addr = "127.0.0.1:7001"
    ca_file = ""
    cert_file = ""
    key_file = ""
    
    [cluster]
    active_size = 9
    remove_delay = 1800.0
    sync_interval = 5.0
    

  • 相关阅读:
    16进制颜色转普通RGB
    (null)
    GIT配置
    -other linker flags
    cocoapods使用问题集锦(2017-04)
    关于@property与@syntheszie的使用问题
    iOS端一次视频全屏需求的实现(转)
    用C语言进行最基本的socket编程
    http和socket之长连接和短连接区别(转)
    socket,TCP/IP的理解(转)
  • 原文地址:https://www.cnblogs.com/wtf0215-golang/p/5054436.html
Copyright © 2011-2022 走看看