Consul快速入门

编程

1. Consul 是什么

Consul是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控)解决方案,它是一个一个分布式的,高度可用的系统,而且开发使用都很简便。它提供了一个功能齐全的控制平面,主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心。

Consul是一个服务管理软件:

1.    支持多数据中心下,分布式高可用的,服务发现和配置共享。

2.    consul支持健康检查,允许存储键值对。

3.    一致性协议采用 Raft 算法,用来保证服务的高可用。

4.    成员管理和消息广播 采用GOSSIP协议,支持ACL访问控制。

1.1 Consul 的具体应用场景

1. Docker、coreos 实例的注册与配置共享

2. vitess集群

3. SaaS应用的配置共享

4.与confd服务集成,动态生成nignx与haproxy配置文件

1.2 服务发现

假设有服务A,B,C.服务A需要调用服务B和C,传统的方式我们需要在服务A中记录服务B和C的ip及端口号。这些配置一般写在配置文件等地方存储。

这种做法有两个显而易见的缺点:1.如果将来B的ip改变了就需要修改所有调用者的ip配置。 2.难以做负载均衡

而服务发现就是用来解决这个问题的,怎么解决呢?请看下面这张图

这张图中在服务消费者和服务生产者之间加了一个服务注册中心的模块,用上面的服务器ABC来举例,服务B在发布的时候会在注册中心注册,注册中心会记录服务B的名字及ip地址。当服务A请求服务B的时候,只需要带着服务B的名字来注册中心查询即可。集群情况下,注册中心会有多个服务B。同时注册中心会定期检查每一个服务否可以正常访问,移除不可访问的服务。(健康检查)

总的来说,服务发现就是通过一个标志来获取服务列表,并且服务列表可随着每个服务的上线或下线动态变更

1.3 Consul术语及解释

下面列出几个consul中出现频率较高的术语

  • Agent,Agent是长期运行在每个consul集群成员节点上守护进程。通过命令consul agent启动。Agent有client和server两种模式。由于每个节点都必须运行agent,所有节点要么是client要么是server。所有的Agent都可以可以调用DNS或HTTP API,并负责检查和维护服务同步。

  • client运行client模式的Agent,将所有的RPCs转发到Server。Client是相对无状态的。Client唯一所做的是在后台参与LAN gossip pool。只消耗少量的资源,少量的网络带宽。

  • Server运行Server模式的Agent,参与Raft quorum,维护集群的状态,响应RPC查询,与其他数据中心交互WAN gossip,转发查询到Leader或远程数据中心。

  • datacenter数据中心的定义似乎是显而易见的,有一些细节是必须考虑的。例如,在EC2,多个可用性区域是否被认为组成了单一的数据中心?我们定义数据中心是在同一个网络环境中——私有的,低延迟,高带宽。这不包括基于公共互联网环境,但是对于我们而言,在同一个EC2的多个可用性区域会被认为是一个的数据中心。

  • 关于client和server我搞了好久才搞明白,实际上client不存储数据,发送到client的请求,client都会转发给它绑定的server,也就是说client必须绑定server。server会存储数据,如果只有一个server并在上面注册了一个服务,这个server挂了然后你又重启了,那么这个服务的注册信息仍然保存在server上。

  • 如果你在一台服务器上运行了一个server,它会默认有一个client绑定到server上,并且地址是127.0.0.1

1.4 优势

1. 使用 Raft 算法来保证一致性,比poxes算法更直接。zookeeper采用的时poxes算法。

Raft大概将整个过程分为三个阶段,leader election,log replication和commit(safety)。

每个server处于三个状态:leader,follower,candidate。正常情况下,所有server中只有一个是leader,其它的都是follower。server之间通过RPC消息通信。follower不会主动发起RPC消息。leader和candidate(选主的时候)会主动发起RPC消息。

首先选择一个leader全权负责管理日志复制,leader从客户端接收log entries,将它们复制给集群中的其它机器,然后负责告诉其它机器什么时候将日志应用于它们的状态机。举个例子,leader可以在无需询问其它server的情况下决定把新entries放在哪个位置,数据永远是从leader流向其它机器。一个leader可以fail或者与其他机器失去连接,这种情形下会有新的leader被选举出来。

http://www.jdon.com/artichect/raft.html

http://blog.csdn.net/cszhouwei/article/details/38374603

2. 支持多数据中心,内外网的服务采用不同的端口进行监听。这样可以避免单点故障。

zookeeper等不支持多数据中心功能的支持

3. 支持健康检查

4. 提供web界面

5. 支持http协议与dns协议接口

 

2 Consul实践

2.1 安装Consul

这里提供两台Centos:local12,local13
安装方式:

[root@local13 ~]# wget https://releases.hashicorp.com/consul/1.2.2/consul_1.2.2_linux_amd64.zip

[root@local13 ~]# unzip consul_1.2.2_linux_amd64.zip

[root@local13 ~]# ./consul

Usage: consul [--version][--help]<command>[<args>]

# local12同上

2.2 运行Agent

安装Consul后必须运行Agent,可以选择服务器或客户端模式。每个数据中心至少有一个服务器(推荐3~5个服务器集群)。

简单起见,先启动一个Agent的开发模式:

# Agent的开发模式

[root@local13 ~]# ./consul agent -dev

==>StartingConsul agent...

==>Consul agent running!

# 查看集群成员

[root@local13 ~]# ./consul members

NodeAddressStatusTypeBuildProtocolDCSegment

local13 127.0.0.1:8301 alive server 1.2.22 dc1 <all>

# 使用 HTTP API 查看

[root@local13 ~]# curl localhost:8500/v1/catalog/nodes

[

{

"ID":"796b14fe-1332-4aa0-d96f-8f287a4ccc7e",

"Node":"local13",

"Address":"127.0.0.1",

"Datacenter":"dc1",

"TaggedAddresses":{

"lan":"127.0.0.1",

"wan":"127.0.0.1"

},

"Meta":{

"consul-network-segment":""

},

"CreateIndex":9,

"ModifyIndex":10

}

]

# 还可以使用 DNS 接口来查询节点(默认端口:8600)

[root@local13 ~]# yum install bind-utils

[root@local13 ~]# dig @127.0.0.1-p 8600 local13.node.consul

...

;;QUESTION SECTION:

;local13.node.consul.IN A

;;ANSWER SECTION:

local13.node.consul.0INA127.0.0.1

...

  • consul agent:启动consul的命令,要么是server要么是client
  • -bootstrap-expect:期望的server节点数目,如果集群中的server节点小于这个数据,集群则失效,并且该server也失效,一直等到集群中的数目达到相应的数量才生效,如果是1的话,代表一个server就可以了
  • -data-dir:data存放的目录,server会保存一些配置缓存等信息,存在此目录下
  • -node:该节点的名称,急群众名称必须唯一
  • -client:代表该server对外暴漏的client地址,0.0.0.0代表我可以通过:127.0.0.1和192.168.3.233访问,不设置的话默认是:127.0.0.1
  • -bind:这是设置集群中server之间互相通信的地址,必须可以互相访问到
  • -ui-dir:设置webui的界面,理论上通过命令可以查看到我们需要的任何信息,但是通过ui来查看更直观

2.3 注册服务

1、定义一个服务

[root@local13 ~]# mkdir /etc/consul.d

[root@local13 ~]# echo "{"service": {"name": "web", "tags": ["rails"], "port": 80}}"| sudo tee /etc/consul.d/web.json

[root@local13 ~]# ./consul agent -dev -config-dir=/etc/consul.d

2、查询一个服务

# 使用 DNS API

[root@local13 ~]# dig @127.0.0.1-p 8600 web.service.consul

...

;;QUESTION SECTION:

;web.service.consul.IN A

;;ANSWER SECTION:

web.service.consul.0INA127.0.0.1

# 使用 DNS API 查找 SRV 记录

[root@local13 ~]# dig @127.0.0.1-p 8600 web.service.consul SRV

...

;;QUESTION SECTION:

;web.service.consul.IN SRV

;;ANSWER SECTION:

web.service.consul.0INSRV1180 local13.node.dc1.consul.

;;ADDITIONAL SECTION:

local13.node.dc1.consul.0INA127.0.0.1

...

# 使用 HTTP API 查询

[root@local13 ~]# curl http://localhost:8500/v1/catalog/service/web

# 健康检查

[root@local13 ~]# curl "http://localhost:8500/v1/health/service/web?passing"

2.4 Consul集群

1、创建node1,consul server

[root@local12~]# ./consul agent -server -bootstrap-expect=1

-data-dir=/tmp/consul

-node=agent-one -bind=192.168.56.112

-enable-script-checks=true-config-dir=/etc/consul.d

-client 0.0.0.0-ui

# -node:节点的名称

# -bind:绑定的一个地址,用于节点之间通信的地址,可以是内外网,必须是可以访问到的地址

# -server:这个就是表示这个节点是个SERVER

# -bootstrap-expect:这个就是表示期望提供的SERVER节点数目,数目一达到,它就会被激活,然后就是LEADER了

# -dc:指明数据中心的名字

# -client 0.0.0.0 -ui:启动UI(为了方便后续的UI访问)

2、创建node2,consul client

[root@local13 ~]# ./consul agent -data-dir=/tmp/consul

-node=agent-two

-bind=192.168.56.113 -enable-script-checks=true

-config-dir=/etc/consul.d

-ui

3、加入集群

[root@local13 ~]# ./consul join192.168.56.112

Successfully joined cluster by contacting 1 nodes.

[root@local13 ~]# ./consul members

NodeAddressStatusTypeBuildProtocolDCSegment

agent-one 192.168.1.13:8301 alive server 1.2.22 dc1 <all>

agent-two 192.168.1.12:8301 alive client 1.2.22 dc1 <default>

4、查询节点

[root@local13 ~]# dig @127.0.0.1 -p 8600 agent-two.node.consul

...

;; QUESTION SECTION:

;agent-two.node.consul. IN A

;; ANSWER SECTION:

agent-two.node.consul. 0 IN A 192.168.1.12

2.5 KV数据

类似Redis,一般也就用来做服务配置。
简单了解下命令就好:

consul kv put redis/config/minconns 1

consul kv put redis/config/minconns 2 # 更新

consul kv get redis/config/minconns

consul kv delete redis/config/minconns

consul kv delete -recurse redis # 批量删除

2.6 WEB UI

访问下:http://192.168.56.112:8500/ui

WEB UI

 

栏目解析:就是上面操作生成的一些东西

1、services:放置服务
2、nodes:放置consul节点
3、key/value:放置一些配置信息
4、dc1:配置数据中心

 

2.7 netcore实践

可以通过命令来注册服务,因为最终是要在.net core上使用,所以我就直接贴上.net core中的相关代码

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifeTime)

{

string ip = Configuration["ip"];

string port = Configuration["port"];

string serviceName = "MsgService";

string serviceId = serviceName + Guid.NewGuid();

Action<ConsulClientConfiguration> ConsulConfig = (config) =>

{

config.Address = new Uri("http://192.168.3.201:8500"); //服务注册的地址,集群中任意一个地址

config.Datacenter = "dc1";

};

using (var consulClient = new ConsulClient(ConsulConfig))

{

AgentServiceRegistration asr = new AgentServiceRegistration

{

Address = ip,

Port = Convert.ToInt32(port),

ID = serviceId,

Name = serviceName,

Check = new AgentServiceCheck

{

DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),

HTTP = $"http://{ip}:{port}/api/Health",//健康检查访问的地址

Interval = TimeSpan.FromSeconds(10), //健康检查的间隔时间

Timeout = TimeSpan.FromSeconds(5), //多久代表超时

},

};

consulClient.Agent.ServiceRegister(asr).Wait();

}

//注销Consul

appLifeTime.ApplicationStopped.Register(() =>

{

using (var consulClient = new ConsulClient(ConsulConfig))

{

consulClient.Agent.ServiceDeregister(serviceId).Wait(); //从consul集群中移除服务

}

});

if (env.IsDevelopment())

{

app.UseDeveloperExceptionPage();

}

else

{

app.UseHsts();

}

app.UseHttpsRedirection();

app.UseMvc();

}

运行程序后向consul集群注册了一个服务,访问集群的任何一个ip都可取到该服务的ip。客户端查询服务的代码如下:

static void Main(string[] args)

{

using (var consul = new Consul.ConsulClient(c =>

{

c.Address = new Uri("http://192.168.3.233:8500"); //Consul地址

}))

{

var services = consul.Catalog.Service("MsgService").Result.Response;

foreach (var s1 in services)

{

Console.WriteLine($"ID={s1.ServiceID},Service={s1.ServiceName},Addr={s1.Address},Port={s1.ServicePort}");

}

}

}

这样我们一个基本的consul集群就可以正常使用了

 

参考资料

https://blog.csdn.net/viewcode/article/details/45915179

https://blog.csdn.net/younger_china/article/details/79462530

https://www.jianshu.com/p/7d20dc58c9fc

 

 

以上是 Consul快速入门 的全部内容, 来源链接: utcz.com/z/517220.html

回到顶部