java consul服务发现_现有系统如何集成Consul服务发现

适宜读者人群

准备使用Consul, 或者对服务发现感兴趣的开发者

追求高质量高可用的服务架构体系的人群

本文目录

Consul 简介

**Consul Glossary(术语) **

Consul Architecture(架构图)

Consul 与 应用集成的几种姿势

Docker registrator详解

Consul 与 Nginx集成的几种姿势

Consul 搭建配置中心

Consul 简介

Consul 四大特性

Service Discovery (服务发现)

Health Check (健康检查)

Multi Datacenter (多数据中心)

Key/Value Storage

Consul Glossary(术语)

Agent

Agent 是一个守护进程

运行在Consul集群的每个成员上

有Client 和 Server 两种模式

所有Agent都可以被调用DNS或者HTTP API,并负责检查和维护同步

Client

Client 将所有RPC请求转发至Server

Client 是相对无状态的

Client 唯一做的就是参与LAN Gossip Pool

Client 只消耗少量的资源和少量的网络带宽

Server

参与 Raft quorum(一致性判断)

响应RPC查询请求

维护集群的状态

转发查询到Leader 或 远程数据中心

Datacenter

顾名思义其为数据中心, 如何定义数据中心呢? 需要以下三点

私有的

低延迟

高带宽

故: 可以简单的理解为同属一个内网环境, 如北京机房和香港机房就不一定满足以上三个条件

Consensus (一致性)

Consul 使用consensus protocol 来提供CAP(一致性,高可用,分区容错性)

Gossip

一种协议: 用来保证 最终一致性 用来向集群广播消息

LAN Gossip

Local Area Network Gossip, 位于同一个局域网或者数据中心的节点

WAN Gossip

Wide Area Network Gossip, 只用于Server之间, 分部在不同的数据中心或广域网

上面说了那么多名词, 可能有点晕, 下面来看Consul集群的架构图

Consul Architecture 架构图

image.png

如上架构图可以看出几个关键点

Client和Client之间的LAN Gossip

Client将RPC请求发至Server, Follower Server将请求转发至Leader节点

Server之间的选举行为

Datacenter之间的WAN Gossip

Consul 与应用集成的几种姿势

首先来说说完整集成服务发现需要做哪些事:

应用启动时需要向Consul 注册服务

定时上报当前服务的状态

应用销毁时需要De-Register 注销自身服务

当Consul数据变化时需要修改本地配置

看上去很麻烦, 那么下面我们具体介绍三种姿势

应用本身作为一个Agent , 适用于SDK相对完善的语言, 如有Spring-Cloud-Consul 的Java

应用旁边(同一台主机)跑一个Client Agent

使用Docker registrator

以上三种方式该如何选择呢?

使用了Docker的话, 就用Docker registrator, 优点: 不用修改程序代码

如果没有用Docker的话, 尽量选择同一台主机下起一个Client模式的Consul agent, 程序本身集成的话, 可能会造成一些不良的反应, 同时有可能还得为服务宕掉背黑锅

Docker registrator详解

下面来说说Docker registrator 是怎么一回事, registrator 自身为一个Container, 运行在其他容器身边(可以理解为同一台主机)

首先是运行时有这么三个步骤:

启动Consul Server集群

启动registrator container

启动应用container

Docker Registrator 原理

Registrator is designed to be run once on every host, 也就是说同一台主机上只需要运行一个registrator即可, 并不用为每一个container起一个registrator

Registrator 会向consul集群register,deregister等操作

Registrator 通过读取同主机其他container的环境变量进行服务注册, 健康检查定义等操作

Docker Registrator 使用

集成方式很简单, 就是为你的应用添加需要的环境变量, 注意不是Registrator 的环境变量哦

Service Definition (服务定义)

环境变量Key

环境变量Value

说明

SERVICE_ID

web-001

可以为GUID或者可读性更强变量, 保证不重复

SERVICE_NAME

web

如果ID没有设置, Consul会将name作为id, 则有可能注册失败

SERVICE_TAGS

nodejs,web

服务的标签, 用逗号分隔,开发者可以根据标签来查询一些信息

SERVICE_IP

内网IP

要使用Consul 可访问的IP

SERVICE_PORT

50001

应用的IP, 如果应用监听了多个端口, 理应被视为多个应用

SERVICE_IGNORE

Boolean

是否忽略本Container, 可以为一些不需要注册的Container添加此属性

Health Check Definition (健康检查定义)

配置原则为: SERVICE_XX_* , 如果你的应用监听的是5000端口, 则改为SERVICE_5000_CHECK_HTTP, 其他变量同理

环境变量Key

环境变量Value

说明

--- 以下为HTTP模式

---

---

SERVICE_80_CHECK_HTTP

/path_to_health_check

你的健康状态检查的路径如 /status

SERVICE_80_CHECK_INTERVAL

15s

15秒检查一次

SERVICE_80_CHECK_TIMEOUT

2s

状态检查超时时间

--- 以下为HTTPS模式

---

---

SERVICE_443_CHECK_HTTPS

/path_to_health_check

你的健康状态检查的路径如 /status

SERVICE_443_CHECK_INTERVAL

15s

15秒检查一次

SERVICE_443_CHECK_TIMEOUT

2s

状态检查超时时间

--- 以下为TCP模式

---

---

SERVICE_443_CHECK_TCP

/path_to_health_check

你的健康状态检查的路径如 /status

SERVICE_443_CHECK_INTERVAL

15s

15秒检查一次

SERVICE_443_CHECK_TIMEOUT

2s

状态检查超时时间

--- 使用脚本检查

---

---

SERVICE_CHECK_SCRIPT

curl --silent --fail example.com

如官方例子中的check_redis.py

-- 其他

---

---

SERVICE_CHECK_INITIAL_STATUS

passing

Consul默认注册后的服务为failed

Consul 与 Nginx集成的几种姿势

目标: 添加 或移除 后端实例时, 不需要运维人员再去手动去修改Nginx.conf文件

DNS

consul-template

nginx-upsync-module

Lua实现

1. DNS模式

如你的应用name=myweb, 再次*强调* 如果id不配置, consu会将name作为默认id, 所以定义服务时id务必要设置

upstream backend {

server myweb.service.consul:20000; #Service Name为myweb, 端口为20000

}

server {

resolver consul_host:8600; # 告诉Nginx DNS解析使用consul的DNS查询

listen 80;

location / {

proxy_pass http://myweb/;

}

}

DNS模式配置简单, 但在运行时会损耗一定性能

2. consul-template

首先consul-template是一个可执行程序, 而不是简单的模板

consul-template的特点

可监听consul的事件, 当已注册service列表或key/value 发生变化时, consul-template会修改配置文件同时可执行一段shell, 如 nginx reload

如下模板文件:

apache {{range services}} upstream {{.Name}} { least_conn;{{range service .Name}} server {{.Address}}:{{.Port}};{{end}} } {{end}}

如下执行consul-template命令

consul-template \

-template "/tmp/nginx.hcl:/var/nginx/nginx.conf:service nginx reload" \

consul-template模式配置相对复杂, 性能相对较好, 仅需要reload nginx, 如果连接量小的话, 不会造成性能影响

3. 使用 nginx-upsync-module

nginx-upsync-module 可以同步consul的服务列表或key/value存储

安装步骤如下, 需要重新编译nginx

wget 'http://nginx.org/download/nginx-1.8.0.tar.gz'

tar -xzvf nginx-1.8.0.tar.gz

cd nginx-1.8.0/

./configure --add-module=/path/to/nginx-upsync-module

make

make install

完成以上步骤后, nginx配置如下

http {

upstream test {

# 先占个位子, 否则nginx在启动时会报错

server 127.0.0.1:11111;

# 所有的后端服务列表会从consul拉取, 并删除上面的占位server

upsync 127.0.0.1:8500/v1/catelog/service/test upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;

# 备份的地址, 保证nginx不强依赖consul

upsync_dump_path /usr/local/nginx/conf/servers/servers_test.conf;

}

server {

listen 8080;

location = /proxy_test {

proxy_pass http://test;

}

# 输出目前指定的所有后端服务

location = /upstream_show {

upstream_show;

}

}

}

使用nginx-upsync-module 不需要reload nginx, 所以性能有保障, 同时配置相比consul-template相对简单

4. Lua实现

此方式适合熟悉openresty的同学, 相对nginx-upsync-module, 可以加入更多自己的逻辑, 毕竟lua语法普通程序员学习一两天就可以写, 具体步骤如下:

init_*_by_lua 阶段通过http api 获取服务列表载入Nginx 内存, 并设置timer轮训更新列表

balancer_by_lua 阶段 读取内存的列表, 设置后端服务器

Lua实现 同样可以不reload nginx, 相比nginx-upsync-module 来说更加可扩展, 但缺点就是目前的版本的openresty中init_by_lua 和 init_worker_by_lua只能使用luasocket(阻塞), 不能使用cosocket, 所以在timer轮训时, 会造成一定性能下降

Consul 搭建配置中心

目标: 配置统一管理, 无需运维人员手动修改应用配置

方式: Consul + consul-template

第一步: 将应用配置分类

调用其他服务的URL,如内部短信接口API, 配置为Service列表,这里还需要分两种情况

有API网关(如Nginx), consul-template 应配置为网关service

无API网关, 则需要程序内随机访问service列表

应用自身配置参数, 如七牛key, 每天找回密码限制次数等

利用consul 的key/value 作为存储

第二步: 另外程序本身需要提供一个url, 用来刷新配置

如应用的配置为json文件, 则模板类似如下:

{

sms_url: [

{{range service "myweb"}}

"{{.Address}}: {{ .Port }}",

{{end}}

,

app: {{ key "myweb" }}

}

可利用consul提供的web ui 来管理配置, 可自由控制配置的颗粒度, 可以按需要将整个配置文件作为value或者某个单独的配置项作为value, 如下图:

image.png

参考链接:

你可能感兴趣的:(java,consul服务发现)