关于 Consul 的安装:https://www.consul.io/docs/install/index.html 
关于 Consul-Template 的安装:https://github.com/hashicorp/consul-template#installation 
关于 Consul 集群搭建:https://book-consul-guide.vnzmi.com/06_setup_cluster.html 
Consul 的 C/S 架构,Consul Agent 安装后可以作为 Client,也可以作为 Server,所谓什么 Raft 算法的作用在于多个 Server 集群选取 master,使用的话不需要关注这些细节。
启动 Consul 测试使用两台,一台作为 Server,一台作为 Client。
在 Server 端,运行:
1 consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=s1 -bind=192.168.221.192 -ui-dir ./consul_ui/ -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0 
启动过程中,可以看到如下输出:
1 2 3 4 5 6 7 2018/02/27 10:06:07 [ERR] agent: failed to sync remote state: No cluster leader 2018/02/27 10:06:08 [WARN] raft: Heartbeat timeout from "" reached, starting election 2018/02/27 10:06:08 [INFO] raft: Node at 192.168.221.192:8300 [Candidate] entering Candidate state in term 10 2018/02/27 10:06:08 [INFO] raft: Election won. Tally: 1 2018/02/27 10:06:08 [INFO] raft: Node at 192.168.221.192:8300 [Leader] entering Leader state 2018/02/27 10:06:08 [INFO] consul: cluster leadership acquired 2018/02/27 10:06:08 [INFO] consul: New leader elected: s1 
开始时没有 consul leader,随后可以看到通过 raft 算法选举了 leader,在此只有一个 server 节点,所以这台 server 就成为了 leader。
在 Client 端,运行:
1 consul agent -data-dir /tmp/consul -node=c1 -bind=192.168.221.193 -config-dir=/etc/consul.d/ -join 192.168.221.192 
在此需要先在 Server 端执行,因为 Client 的 -join 参数制定后找不到 Server 会报错。
执行后再 Server 端看到,已经加入了 Client。
1 2 3 4 [root@localhost ~]# consul members Node  Address               Status  Type    Build  Protocol  DC   Segment s1    192.168.221.192:8301  alive   server  1.0.6  2         dc1  <all> c1    192.168.221.193:8301  alive   client  1.0.6  2         dc1  <default> 
注册服务 在此我们注册三个服务,分别为两个 tomcat 和一个 nginx。
启动 consul 时,在启动命令里指定了配置文件目录为 /etc/consul.d,所以在此目录下通过配置文件注册 service.
建立 tomcat.json 注册 tomcat 服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 {   "services" :  [      {        "id" :  "tomcat_1" ,        "name" :  "tomcat" ,        "tags" :  [          "primary"        ] ,        "address" :  "192.168.221.193" ,        "port" :  8110 ,        "checks" :  [            {                "http" :  "http://192.168.221.193:8110" ,                "interval" :  "10s" ,                "timeout" :  "1s" ,                "method" :  "GET"            }        ]      } ,      {        "id" :  "tomcat_2" ,        "name" :  "tomcat" ,        "tags" :  [          "secondary"        ] ,        "address" :  "192.168.221.193" ,        "port" :  8111 ,        "checks" :  [            {                "http" :  "http://192.168.221.193:8111" ,                "interval" :  "10s" ,                "timeout" :  "1s" ,                "method" :  "GET"            }        ]      }    ]  } 
若 name 重名,则 id 必须唯一,tags 标签指定方便管理。
建立 nginx.json 注册 nginx 服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 {   "service" :       {        "id" :  "nginx" ,        "name" :  "nginx" ,        "tags" :  [          "primary"        ] ,        "address" :  "192.168.221.193" ,        "port" :  80 ,        "checks" :  [            {                "http" :  "http://192.168.221.193:80" ,                "interval" :  "10s" ,                "timeout" :  "1s" ,                "method" :  "GET"            }        ]      }  } 
定义好配置文件后来更新服务:
随后可以看到 consul 的输出显示该 Agent 将载入配置定义并注册到服务目录:
1 2 3 4 5 6 2018/02/27 12:51:53 [INFO] agent: Synced service "nginx" 2018/02/27 12:51:53 [INFO] agent: Synced service "tomcat_1" 2018/02/27 12:51:53 [INFO] agent: Synced service "tomcat_2" 2018/02/27 12:51:57 [INFO] agent: Synced check "service:nginx" 2018/02/27 12:51:59 [INFO] agent: Synced check "service:tomcat_2" 2018/02/27 12:52:02 [INFO] agent: Synced check "service:tomcat_1" 
配置更新 来看目的:实时监测 tomcat 的健康状态,并实施更新 Nginx 代理配置文件。
这里需要用到 consul-template。
建立 nginx.conf.ctmpl 文件,写入模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 worker_processes  1; events {     worker_connections  1024; } http {     include       mime.types;     default_type  application/octet-stream;     sendfile        on;     #tcp_nopush     on;     #keepalive_timeout  0;     keepalive_timeout  65;     #gzip  on;      {{service  "tomcat"  "passing" }}   {{$name  : = .Name}}     upstream  {{$name }}  {        {{range  $service}}         server  {{.Address }} : {{.Port }} ;        {{end }}         session_sticky;         check interval=3000 rise=2 fall=5 timeout=1000 type=http;         check_http_send "HEAD / HTTP/1.0\r\n\r\n";         check_http_expect_alive http_2xx http_3xx;     }     server {         listen       80;         server_name  localhost;         location / {             root    html;             index  index.html index.htm;             proxy_pass http://srm;             client_max_body_size 50m;         }         error_page   500 502 503 504  /50x.html;         location = /50x.html {             root   html;         }     } } 
这里只载入了 tomcat 服务,如果要把所有服务载入,可以遍历服务添加代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ... {{range  services}}   {{$name  : = .Name}}   {{$service  : = service .Name}}     upstream  {{$name }}  {          {{range  $service}}         server  {{.Address }} : {{.Port }} ;          {{end }}         session_sticky;         check interval=3000 rise=2 fall=5 timeout=1000 type=http;         check_http_send "HEAD / HTTP/1.0\r\n\r\n";         check_http_expect_alive http_2xx http_3xx;     }  {{end }} ... {{range  services}}   {{$name  : = .Name}}         location / {{$name }}  {           proxy_pass http:// {{$name }} ;         } {{end }} 
模板语法是 golang 的模板语法,和其它后端模板语法很像。
{{service "tomcat" "passing"}} 这部分采用的是 tomcat 服务,passing 表示只采用健康的 service。
随后执行:
1 consul-template  -consul-addr 192.168.221.192:8500 -template="nginx.conf.ctmpl:/usr/local/nginx/conf/nginx.conf:/usr/local/nginx/sbin/nginx -s reload" -once 
将会生成 nginx.conf 配置文件至 nginx 配置文件目录,并会执行 nginx -s reload 进行重载。
上述命令只能生成一次,官方推荐的做法是写入一个配置文件中。
建立 nginx.hcl 文件,内容如下:
1 2 3 4 5 6 7 8 9 consul {   address = "192.168.221.192:8500" } template {   source = "nginx.conf.ctmpl"   destination = "/usr/local/nginx/conf/nginx.conf"   command = "/usr/local/nginx/sbin/nginx -s reload" } 
然后执行 consul-template -config nginx.hcl,就可以运行为一个服务。
当两个 tomcat 正常时,可以看到配置文件如下:
手动把一个 tomcat 关闭,可以看到 consul 的输出中报失败:
而此时的 nginx 配置文件已经被更新,可以看到内容如下:
至此就完成了目的,注册服务 –> 服务健康检查 –> 实时更新服务配置。
后记 这个使用姿势是很奇葩的使用姿势,正确的使用姿势应该配合 DNS 查询 API 和 HTTP API 等去做更进一步的集成,在 DNS 查询层级做负载均衡和高可用的配置处理。服务的注册现在是手动注册,结合 Docker 可以使用 Registrator,不适用 Docker 就要写脚本去检测服务并注册了。
因而题为“半自动化”,这个半应该再加个半,为”半半自动化”为宜。w(゚Д゚)w
参考 -EOF-