consul集群、服务发现、常用命令、动态联动

服务发现

微服务的框架体系中,服务发现是不能不提的一个模块。我相信了解或者熟悉微服务的童鞋应该都知道它的重要性。这里我只是简单的提一下,毕竟这不是我们的重点。我们看下面的一幅图片:
在这里插入图片描述
图中,客户端的一个接口,需要调用服务A-N。客户端必须要知道所有服务的网络位置的,以往的做法是配置是配置文件中,或者有些配置在数据库中。这里就带出几个问题:
图中,客户端的一个接口,需要调用服务A-N。客户端必须要知道所有服务的网络位置的,以往的做法是配置是配置文件中,或者有些配置在数据库中。这里就带出几个问题:

  • 需要配置N个服务的网络位置,加大配置的复杂性
  • 服务的网络位置变化,都需要改变每个调用者的配置
  • 集群的情况下,难以做负载(反向代理的方式除外)
    总结起来一句话:服务多了,配置很麻烦,问题多多
    既然有这些问题,那么服务发现就是解决这些问题的。话说,怎么解决呢?我们再看一张图
    在这里插入图片描述
    与之前一张不同的是,加了个服务发现模块。图比较简单,这边文字描述下。服务A-N把当前自己的网络位置注册到服务发现模块(这里注册的意思就是告诉),服务发现就以K-V的方式记录下,K一般是服务名,V就是IP:PORT。服务发现模块定时的轮询查看这些服务能不能访问的了(这就是健康检查)。客户端在调用服务A-N的时候,就跑去服务发现模块问下它们的网络位置,然后再调用它们的服务。这样的方式是不是就可以解决上面的问题了呢?客户端完全不需要记录这些服务网络位置,客户端和服务端完全解耦!
    这个过程大体是这样,当然服务发现模块没这么简单。里面包含的东西还很多。这样表述只是方便理解。
    图中的服务发现模块基本上就是微服务架构中服务发现的作用了。

consul集群

服务器规划

主机名地址作用模式
consul1192.168.43.249consul节点1server
consul2192.168.43.74consul节点2server
consul3192.168.43.253consul节点3server
client1192.168.43.147client节点1client

目录规划

目录作用
/opt/consul/data存放持久化数据目录
/opt/consul/config存放配置文件目录

#节点上均建立上述指定目录(实际环境请自定义)
[root@localhost ~]# mkdir -p /opt/consul/data
[root@localhost ~]# mkdir /opt/consul/config

安装和启动

注意:安装时候用wget命令要加–no-check-certificat,否则会提示无法建立ssl链接

[root@localhost ~]# wget https://releases.hashicorp.com/consul/1.4.0/consul_1.4.0_linux_amd64.zip --no-check-certificat
--2019-01-30 14:44:45--  https://releases.hashicorp.com/consul/1.4.0/consul_1.4.0_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 2a04:4e42:2e::439, 151.101.197.183
Connecting to releases.hashicorp.com (releases.hashicorp.com)|2a04:4e42:2e::439|:443... failed: Connection timed out.
Connecting to releases.hashicorp.com (releases.hashicorp.com)|151.101.197.183|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 34591598 (33M) [application/zip]
Saving to: ‘consul_1.4.0_linux_amd64.zip’

100%[===============================================================>] 34,591,598  98.9KB/s   in 3m 45s 

2019-01-30 14:50:38 (150 KB/s) - ‘consul_1.4.0_linux_amd64.zip’ saved [34591598/34591598]

[root@localhost ~]# unzip consul_1.4.0_linux_amd64.zip 
Archive:  consul_1.4.0_linux_amd64.zip
  inflating: consul                  
[root@localhost ~]# mv ./consul /usr/bin/
[root@localhost ~]# consul -v
Consul v1.4.0
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

参数说明

  • -bootstrap-expect 数据中心预期的服务器数,只有达到指定数量后,才开始进行选举流程。添加此参数后,consul将等待指定数量的服务器可用,然后引导集群。这允许自动选择初始领导者。这不能与传统-bootstrap标志(一般仅有一台服务器时使用,自选为leader,多用于测试)一起使用。此标志需要在服务端模式下运行。
  • -server 以服务端模式运行
  • -data-dir 数据存放位置,这个用于持久化保存集群状态
  • -node 集群中此节点的名字,这在集群中必须是唯一的,默认为主机名
  • -bind 绑定服务器的ip地址
  • -config-dir 指定配置文件服务,这个目录下有.json结尾的文件就会加载进来
  • -enable-script-checks 检查服务是否处于活动状态,类似开启心跳
  • -datacenter 数据中性名称
  • -client 客户端可访问ip,包括HTTP和dns服务器。默认是127.0.0.1,仅允许回环链接
  • -ui 开启web的UI界面
  • -join 加入到已有的集群中
  • -dev 启用开发服务器模式。这对于在关闭所有持久性选项的情况下快速启动consul代理非常有用,从而启用可用于快速原型化或针对API开发的内存服务器。在这种模式下,connect被启用,并且默认情况下会在启动时候创建一个新的ca证书。此模式不打算用于生产,因为它不向磁盘写入任何数据。在此模式下,GRPC端口也默认为8502.

server 节点1

[root@localhost ~]# consul agent -bootstrap-expect 2 -server -data-dir /opt/consul/data/ -node=consul1 -bind 192.168.43.249 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01
这个命令是以服务端模式启动一个代理,进群需要有两个扩展机器,设置集群持久化数据存放在/opt/consul/data,节点名称是consul1,绑定本机ip,服务配置文件存放在/opt/consul/config(如果有json文件为加载),开启检查心跳,数据中心名称是bdqn01,可访问的客户端地址是0.0.0.0

server 节点2

[root@localhost ~]# consul agent -server -data-dir /opt/consul/data/ -node=consul2 -bind 192.168.43.74 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249

server 节点3

[root@localhost ~]# consul agent -server -data-dir /opt/consul/data/ -node=consul3 -bind 192.168.43.253 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249

server集群验证

输入上述命令后,命令行会阻塞,并输入日志,选手集群状态,如下

 2019/01/30 15:19:52 [INFO] consul: cluster leadership acquired
    2019/01/30 15:19:52 [INFO] consul: New leader elected: consul1
    2019/01/30 15:19:52 [INFO] raft: pipelining replication to peer {Voter c9772032-7f8e-d1d5-1b97-a0d0cf54934a 192.168.43.74:8300}
    2019/01/30 15:19:53 [INFO] memberlist: Suspect consul2.bdqn01 has failed, no acks received

使用命令查看集群成员(任一server节点)

[root@localhost ~]# consul members
Node     Address              Status  Type    Build  Protocol  DC      Segment
consul1  192.168.43.249:8301  alive   server  1.4.0  2         bdqn01  <all>
consul2  192.168.43.74:8301   alive   server  1.4.0  2         bdqn01  <all>
consul3  192.168.43.253:8301  alive   server  1.4.0  2         bdqn01  <all>
[root@localhost ~]# 

使用命令查看集群信息(任一server节点)

[root@localhost ~]# consul info
agent:
	check_monitors = 0
	check_ttls = 0
	checks = 0
	services = 0
build:
	prerelease = 
	revision = 0bddfa23
	version = 1.4.0
consul:
	acl = disabled
	bootstrap = false
	known_datacenters = 1
	leader = false
	leader_addr = 192.168.43.249:8300
	server = true
raft:
	applied_index = 98
	commit_index = 98
	fsm_pending = 0
	last_contact = 14.046772ms
	last_log_index = 98
	last_log_term = 8
	last_snapshot_index = 0
	last_snapshot_term = 0
	latest_configuration = [{Suffrage:Voter ID:c9772032-7f8e-d1d5-1b97-a0d0cf54934a Address:192.168.43.74:8300} {Suffrage:Voter ID:46709fba-6e61-074c-29f3-1d273ea53f44 Address:192.168.43.249:8300} {Suffrage:Voter ID:7144d459-8695-947a-e030-61d332b301fc Address:192.168.43.253:8300}]
	latest_configuration_index = 38
	num_peers = 2
	protocol_version = 3
	protocol_version_max = 3
	protocol_version_min = 0
	snapshot_version_max = 1
	snapshot_version_min = 0
	state = Follower
	term = 8
runtime:
	arch = amd64
	cpu_count = 4
	goroutines = 79
	max_procs = 4
	os = linux
	version = go1.11.1
serf_lan:
	coordinate_resets = 0
	encrypted = false
	event_queue = 0
	event_time = 3
	failed = 0
	health_score = 0
	intent_queue = 0
	left = 0
	member_time = 4
	members = 3
	query_queue = 0
	query_time = 1
serf_wan:
	coordinate_resets = 0
	encrypted = false
	event_queue = 0
	event_time = 1
	failed = 0
	health_score = 0
	intent_queue = 0
	left = 0
	member_time = 4
	members = 3
	query_queue = 0
	query_time = 1
[root@localhost ~]# 

使用HTTP api查看集群状态
#集群server成员
[root@localhost ~]# curl 127.0.0.1:8500/v1/status/peers
[“192.168.43.74:8300”,“192.168.43.249:8300”,“192.168.43.253:8300”]
#集群 raft leader
[root@localhost ~]# curl 127.0.0.1:8500/v1/status/leader
“192.168.43.249:8300”
#注册的所有服务
[root@localhost ~]# curl 127.0.0.1:8500/v1/catalog/srevices
#服务信息
[root@localhost ~]# curl 127.0.0.1:8500/v1/catalog/srevices/nginx
#集群节点详细信息

[root@localhost ~]# curl 127.0.0.1:8500/v1/catalog/nodes
[{"ID":"46709fba-6e61-074c-29f3-1d273ea53f44","Node":"consul1","Address":"192.168.43.249","Datacenter":"bdqn01","TaggedAddresses":{"lan":"192.168.43.249","wan":"192.168.43.249"},"Meta":{"consul-network-segment":""},"CreateIndex":5,"ModifyIndex":9},{"ID":"c9772032-7f8e-d1d5-1b97-a0d0cf54934a","Node":"consul2","Address":"192.168.43.74","Datacenter":"bdqn01","TaggedAddresses":{"lan":"192.168.43.74","wan":"192.168.43.74"},"Meta":{"consul-network-segment":""},"CreateIndex":6,"ModifyIndex":8},{"ID":"7144d459-8695-947a-e030-61d332b301fc","Node":"consul3","Address":"192.168.43.253","Datacenter":"bdqn01","TaggedAddresses":{"lan":"192.168.43.253","wan":"192.168.43.253"},"Meta":{"consul-network-segment":""},"CreateIndex":33,"ModifyIndex":34}]

client 节点

[root@localhost ~]# consul agent -ui -data-dir /opt/consul/data -node=client1 -bind=192.168.43.147 -client 0.0.0.0 -config-dir /opt/consul/config -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249

这个命令是以客户端模式启动一个代理,设置集群持久化数据存放在/opt/consul/data,节点名称是client1,绑定本机地址,服务配置文件存放在/opt/consul/config,开启检测心跳,数据中心的名称是bdqn01,可访问客户端地址是0.0.0.0并加入节点1 的集群,并且开启web-ui管理界面

访问web-ui 只有client开启了web-ui,只有访问client ip才行 http://192.168.43.147:8500/ui/
[root@localhost ~]# firefox http://192.168.43.147:8500/ui/
在这里插入图片描述

命令行中对键值对的操作

创建:put —在consul的kv存储中创建或者更新名为“redis/config/connections”的键值为5

[root@localhost ~]# consul kv put redis/config/connections 5
Success! Data written to: redis/config/connection

获取值:get

[root@localhost ~]# consul kv get redis/config/connections
5

查询详情:-detailed

[root@localhost ~]# consul kv get -detailed redis/config/connections
CreateIndex      262
Flags            0
Key              redis/config/connections
LockIndex        0
ModifyIndex      262
Session          -
Value            5
[root@localhost ~]# 

删除key:delete


[root@localhost ~]# consul kv delete redis/config/connections
Success! Deleted key: redis/config/connections

删除一个指定索引的key,指定-cas或者-modify-index

[root@localhost ~]# consul kv get -detailed redis/config/connections | grep ModifyIndex
ModifyIndex      370
[root@localhost ~]# consul kv delete -cas -modify-index=370 redis/config/connections
Success! Deleted key: redis/config/connections

递归删除指定前缀的所有key,使用-recurse

[root@localhost ~]# consul kv delete -recurse redis/
Success! Deleted keys with prefix: redis/

递归删除中,尾随斜杠很重要,因为consul对所提供的前缀执行贪婪的匹配。如果是有foo作为键,则会递归删除以foo food football等字母开头的所有键,而不仅仅是foo。

导出key为config/的树

[root@localhost ~]# consul kv export config/
[]

列出以指定前缀开头的键: -keys
[root@localhost ~]# consul kv get -keys config/

分隔符: -separator=“string”

默认情况下,-keys使用分隔符为/ 这意味着它不会递归超出分隔符。可以通过设置-separator来设置分隔符,如果分隔符为"" 也即分隔符为空,可以完全禁用分隔符。-separator必须和-keys配合使用

列出所有key,省略前缀即可
[root@localhost ~]# consul kv get -keys

从文件中导入
[root@localhost ~]# consul kv import @value.json
其中value为文件名

从stdin导入,使用-作为数据参数
cat values.json | consul kv import -

consul对json格式的文档也有格式要求 使用consul kv export导出的才可以使用import导入

结合springcloud做注册中心

使用consul作为springcloud的注册中心 下边的操作以上边操作为基础,总的来说还是需要四个节点相连接,但是又有不同,具体来说,consul1和consul2和之前的命令一样,253主机的命令为
consul agent -ui -data-dir /opt/consul/data/ -node=client1 -bind 192.168.43.253 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249
147的主机的命令为
consul agent -server -ui -data-dir /opt/consul/data -node=consul3 -bind=192.168.43.147 -client 0.0.0.0 -config-dir /opt/consul/config -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249

服务器规划

地址作用注册到consul应用名端口
192.168.43.249提供者节点1service-producer8501
192.168.43.74提供者节点2service-producer8502
192.168.43.253消费者节点18503
192.168.43.147注册中心client8500

注册演示

演示说明:

  • 两个服务提供者注册到consul注册中心
  • 消费者通过链接consul注册中心获取到提供者信息,进行通信,并请求验证
  • 为方便区分不同提供者,连个服务提供者相应内容显示不同
提供者节点1

代码克隆:

[root@localhost ~]# git clone https://github.com/luojunyong/spring-cloud-examples.git
Cloning into 'spring-cloud-examples'...
remote: Enumerating objects: 700, done.
remote: Total 700 (delta 0), reused 0 (delta 0), pack-reused 700
Receiving objects: 100% (700/700), 67.17 KiB | 96.00 KiB/s, done.
Resolving deltas: 100% (208/208), done.
[root@localhost ~]# ls
anaconda-ks.cfg                Desktop               jdk-8u201-linux-x64.tar.gz  spring-cloud-examples
apache-maven-3.6.0-bin.tar.gz  Documents             Music                       Templates
apache-tomcat-8.5.35.tar.gz    Downloads             Pictures                    Videos
consul_1.4.0_linux_amd64.zip   initial-setup-ks.cfg  Public
[root@localhost ~]# cd spring-cloud-examples/spring-cloud-consul/spring-cloud-consul-producer

修改配置:

[root@localhost spring-cloud-consul-producer]# vim src/main/resources/application.properties 
spring.application.name=spring-cloud-consul-producer #应用名
server.port=8501  #监听端口
spring.cloud.consul.host=192.168.43.147   #要连接的consul地址
spring.cloud.consul.port=8500  #要连接的consul端口
#\u6CE8\u518C\u5230consul\u7684\u670D\u52A1\u540D\u79F0   
spring.cloud.consul.discovery.serviceName=service-producer  #注册到consul注册中心的服务名

运行:
mvn spring-boot:run
运行之后会阻塞在下边的字样处,这是正常的,如果需要其他操作再开一个终端就好

2019-01-30 20:02:49.361  INFO 45742 --- [           main] c.neo.consul.ConsulProducerApplication   : Started ConsulProducerApplication in 13.214 seconds (JVM running for 22.243)
2019-01-30 20:02:53.425  INFO 45742 --- [nio-8502-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-01-30 20:02:53.426  INFO 45742 --- [nio-8502-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2019-01-30 20:02:53.459  INFO 45742 --- [nio-8502-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 33 ms

提供者节点2

代码克隆:

[root@localhost ~]# git clone https://github.com/luojunyong/spring-cloud-examples.git
Cloning into 'spring-cloud-examples'...
remote: Enumerating objects: 700, done.
remote: Total 700 (delta 0), reused 0 (delta 0), pack-reused 700
Receiving objects: 100% (700/700), 67.17 KiB | 96.00 KiB/s, done.
Resolving deltas: 100% (208/208), done.
[root@localhost ~]# ls
anaconda-ks.cfg                Desktop               jdk-8u201-linux-x64.tar.gz  spring-cloud-examples
apache-maven-3.6.0-bin.tar.gz  Documents             Music                       Templates
apache-tomcat-8.5.35.tar.gz    Downloads             Pictures                    Videos
consul_1.4.0_linux_amd64.zip   initial-setup-ks.cfg  Public
[root@localhost ~]# cd spring-cloud-examples/spring-cloud-consul/spring-cloud-consul-producer-2

修改配置:

[root@localhost spring-cloud-consul-producer]# vim src/main/resources/application.properties 
spring.application.name=spring-cloud-consul-producer #应用名
server.port=8502  #监听端口
spring.cloud.consul.host=192.168.43.147   #要连接的consul地址
spring.cloud.consul.port=8500  #要连接的consul端口
#\u6CE8\u518C\u5230consul\u7684\u670D\u52A1\u540D\u79F0   
spring.cloud.consul.discovery.serviceName=service-producer  #注册到consul注册中心的服务名

运行:
mvn spring-boot:run

消费者节点1

克隆代码-修改配置

[root@localhost ~]# git clone https://github.com/luojunyong/spring-cloud-examples.git
Cloning into 'spring-cloud-examples'...
remote: Enumerating objects: 700, done.
remote: Total 700 (delta 0), reused 0 (delta 0), pack-reused 700
Receiving objects: 100% (700/700), 67.17 KiB | 13.00 KiB/s, done.
Resolving deltas: 100% (208/208), done.
[root@localhost ~]# cd spring-cloud-examples/spring-cloud-consul/spring-cloud-consul-consumer/
[root@localhost spring-cloud-consul-consumer]# vim src/main/resources/application.properties 
spring.application.name=spring-cloud-consul-consumer
server.port=8503
spring.cloud.consul.host=192.168.43.147
spring.cloud.consul.port=8500
#\u8BBE\u7F6E\u4E0D\u9700\u8981\u6CE8\u518C\u5230consul\u4E2D
spring.cloud.consul.discovery.register=false  #设置不需要注册到consul中

运行:
mvn spring-boot:run

消费节点运行完之后会阻塞在下边的语句

2019-01-30 20:20:33.321  INFO 45589 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2019-01-30 20:20:33.625  INFO 45589 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8503 (http) with context path ''
2019-01-30 20:20:33.638  INFO 45589 --- [           main] c.neo.consul.ConsulConsumerApplication   : Started ConsulConsumerApplication in 13.525 seconds (JVM running for 819.005)

查看状态

可以在consul注册中心查看状态
firefox 192.168.43.147:8500/ui/
在这里插入图片描述

两个服务提供者均存活,消费者使用有轮询,以下是在消费者上的显示结果

[root@localhost spring-cloud-consul-consumer]# curl 192.168.43.253:8503/call
helle consul
[root@localhost spring-cloud-consul-consumer]# curl 192.168.43.253:8503/call
helle consul two

结合nginx动态联动

服务器规划

地址作用注册到consul应用名端口
192.168.43.249提供者节点1service-producer8501
192.168.43.74提供者节点2service-producer8502
192.168.43.253consul-clientconsu-client8500
192.168.43.147负载均衡联动(nginx+consul-template)80

目录规划

第四台负责联动的主机建立三个目录

  • /opt/consul/config 生成nginx配置文件的ctmpl文件目录
  • /usr/local/nginx/conf/vhost 生成nginx配置文件的ctmpl文件目录
  • /opt/consul/logs 生成consul-template进程(后台运行)产生的consul-template.log日志

演示说明

  1. 开启consul注册中心,服务提供者通过consul client注册到注册中心
  2. 服务提供者注册时候使用真是IP地址注册(在不适合hosts方式的环境)
  3. nginx和consul-template服务装在一台服务器上
  4. 当注册中心服务提供者有变更(新增或失败)的时候,nginx能动态加载upstream列表

操作提示
在上边实验的基础上操作:
249主机启动consul命令不变,74主机启动consul命令不变,253主机启动consul命令不变,147主机断开consul,249主机和74主机修改代码文件配置,把注册中心ip改成253。253主机需要克隆代码,并修改配置,然后再运行

249和74主机修改代码文件,修改ip,并添加一行内容在最后
spring.cloud.consul.discovery.preferIpAddress=true

253主机修改配置的操作如下所示:

[root@localhost ~]# cd spring-cloud-examples/spring-cloud-consul/spring-cloud-consul-consumer/
[root@localhost spring-cloud-consul-consumer]# vim src/main/resources/application.properties 
spring.application.name=spring-cloud-consul-consumer
server.port=8503
spring.cloud.consul.host=192.168.43.253
spring.cloud.consul.port=8500
#\u8BBE\u7F6E\u4E0D\u9700\u8981\u6CE8\u518C\u5230consul\u4E2D
spring.cloud.consul.discovery.register=false
spring.cloud.consul.discovery.preferIpAddress=true

以上三台主机都修改完毕,可以运行
mvn spring-boot:run

服务配置

最后一台主机自己安装nginx

过程略

配置consul-template服务
[root@localhost ~]# mkdir -p /opt/consul/{config,logs}
[root@localhost ~]# mkdir -p /usr/local/nginx/conf/vhost
[root@localhost ~]# wget https://releases.hashicorp.com/consul-template/0.19.5/consul-template_0.19.5_linux_amd64.tgz --no-check-certificat
[root@localhost ~]# tar -zxf consul-template_0.19.5_linux_amd64.tgz 
[root@localhost ~]# mv consul-template /usr/bin/
配置consul-template模板
  • range service要和服务提供者注册在consul应用名相同
  • 具体nginx配置可根据环境自定义配置
[root@localhost ~]# vim /opt/consul/config/nginx-consul-web1.ctmpl  #这部分内容手写
upstream web1 {
    ip_hash;
{{range service "service-producer"}}
    server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=30s;
   {{end}}
}

server {
    listen 80;
    server_name web1.luojunyong.com;
    location / {
        proxy_connect_timeout 300s;
        proxy_send_timeout    900;
        proxy_read_timeout    900;
        proxy_buffer_size     32k;
        proxy_buffers        4 32k;
        proxy_busy_buffers_size 64k;
        proxy_redirect         off;
        proxy_set_header       Host              $host;
        proxy_set_header       Referer           $http_referer;
        proxy_set_header       X-Real-IP         $remote_addr;
        proxy_set_header       X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_pass             http://web1/;
}
}

配置nginx引用方式

以include方式加载由consul-template生成的nginx配置目录

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
http模块和server模块之间添加一行内容:   include /usr/local/nginx/conf/vhost/*.conf;
生成nginx配置文件

测试模板状态
consul-template --consul-addr 192.168.43.253:8500 -template /opt/consul/config/nginx-consul-web1.ctmpl:/usr/local/nginx/conf/vhost/web1.conf:"/usr/local/nginx/sbin/nginx -s reload" -dry

-dry表示仅运行此命令,但不实际执行写入文件的命令,此处是指不根据模板修改文件,不执行nginx -s reload命令。第一个冒号前是模板文件位置,第二个冒号前是输出配置文件到哪里,第二个冒号后是需要运行的命令。

生成nginx配置和运行
通过nohup命令可以将consul-template放到后台执行
[root@localhost ~]# nohup consul-template --consul-addr 192.168.43.253:8500 -template /opt/consul/config/nginx-consul-web1.ctmpl:/usr/local/nginx/conf/vhost/web1.conf:"/usr/local/nginx/sbin/nginx -s reload" --log-level=info >/opt/consul/logs/consul-template.log 2>&1 &

2>&1 的意思就是将标准错误重定向到标准输出。这里标准输出已经重定向到了consul-template.log文件,那么标准错误也会输出到consul-template.log文件

可通过以下方式查看运行情况

[root@localhost ~]# ps -elf | grep consul
4 S root      52027  45465  0  80   0 -  2969 futex_ 22:33 pts/2    00:00:00 consul-template --consul-addr 192.168.43.253:8500 -template /opt/consul/config/nginx-consul-web1.ctmpl:/usr/local/nginx/conf/vhost/web1.conf:/usr/local/nginx/sbin/nginx -s reload --log-level=info
0 S root      52061  45465  0  80   0 - 28165 pipe_w 22:35 pts/2    00:00:00 grep --color=auto consul
或者
[root@localhost ~]# cat /opt/consul/logs/consul-template.log 
nohup: ignoring input
2019/01/30 14:33:42.149784 [INFO] consul-template v0.19.5 (57b6c71)
2019/01/30 14:33:42.149831 [INFO] (runner) creating new runner (dry: false, once: false)
2019/01/30 14:33:42.150385 [INFO] (runner) creating watcher
2019/01/30 14:33:42.150672 [INFO] (runner) starting

验证效果

测试模板生成验证(之前的步骤已实现)
[root@localhost ~]# consul-template --consul-addr 192.168.43.253:8500 -template /opt/consul/config/nginx-consul-web1.ctmpl:/usr/local/nginx/conf/vhost/web1.conf:"/usr/local/nginx/sbin/nginx -s reload" -dry
> /usr/local/nginx/conf/vhost/web1.conf
upstream web1 {
    ip_hash;

    server 192.168.43.249:8501 max_fails=3 fail_timeout=30s;

    server 192.168.43.74:8502 max_fails=3 fail_timeout=30s;

}

server {
    listen 80;
    server_name web1.luojunyong.com;
    location / {
	proxy_connect_timeout 300s;
	proxy_send_timeout    900;
	proxy_read_timeout    900;
	proxy_buffer_size     32k;
	proxy_buffers        4 32k;
	proxy_busy_buffers_size 64k;
	proxy_redirect         off;
	proxy_set_header       Host              $host;
	proxy_set_header       Referer           $http_referer;
        proxy_set_header       X-Real-IP         $remote_addr;
	proxy_set_header       X-Forwarded-For   $proxy_add_x_forwarded_for;
	proxy_pass             http://web1/;
}
}
验证nginx配置
[root@localhost ~]# cat /usr/local/nginx/conf/vhost/web1.conf 
upstream web1 {
    ip_hash;

    server 192.168.43.249:8501 max_fails=3 fail_timeout=30s;

    server 192.168.43.74:8502 max_fails=3 fail_timeout=30s;

}

server {
    listen 80;
    server_name web1.luojunyong.com;
    location / {
	proxy_connect_timeout 300s;
	proxy_send_timeout    900;
	proxy_read_timeout    900;
	proxy_buffer_size     32k;
	proxy_buffers        4 32k;
	proxy_busy_buffers_size 64k;
	proxy_redirect         off;
	proxy_set_header       Host              $host;
	proxy_set_header       Referer           $http_referer;
        proxy_set_header       X-Real-IP         $remote_addr;
	proxy_set header       X-Forwarded-For   $proxy_add_x_forwarded_for;
	proxy_pass             http://web1/;
}
}

两个服务提供者均运行(consul-template主机上验证)

[root@localhost ~]# nginx
[root@localhost ~]# curl http://192.168.43.147:80/hello
helle consul
[root@localhost ~]# curl http://192.168.43.147:80/hello
helle consul

因为nginx配置有ip_hash,所有请求会一直在一个节点(可关闭一个服务提供者进行验证)

由于上边的访问提示的是第一个节点的 返回信息(第一个consul返回helle consul 第二个返回helle consul two),所以我们关闭第一个节点后再进行验证。关闭方法是去终端ctrl+c,让mvn spring-boot:run的命令停止

[root@localhost ~]# curl http://192.168.43.147:80/hello
helle consul two[root@localhost ~]# curl http://192.168.43.147:80/hello
helle consul two[root@localhost ~]# 
动态列表验证

当服务提供者有变更(此处演示停了一个服务提供者)的时候,通过consul-template和nginx日志均可发现服务重载

[root@localhost ~]# tail -100f /opt/consul/logs/consul-template.log 
动态监控日志文件,当停掉服务提供者1的时候新增加如下信息:
2019/01/30 15:24:46.556339 [INFO] (runner) rendered "/opt/consul/config/nginx-consul-web1.ctmpl" => "/usr/local/nginx/conf/vhost/web1.conf"
2019/01/30 15:24:46.556453 [INFO] (runner) executing command "/usr/local/nginx/sbin/nginx -s reload" from "/opt/consul/config/nginx-consul-web1.ctmpl" => "/usr/local/nginx/conf/vhost/web1.conf"
2019/01/30 15:24:46.592771 [INFO] (child) spawning: /usr/local/nginx/sbin/nginx -s reload
再次开启服务提供者1的时候增加如下信息:
2019/01/30 15:27:15.113516 [INFO] (runner) rendered "/opt/consul/config/nginx-consul-web1.ctmpl" => "/usr/local/nginx/conf/vhost/web1.conf"
2019/01/30 15:27:15.113948 [INFO] (runner) executing command "/usr/local/nginx/sbin/nginx -s reload" from "/opt/consul/config/nginx-consul-web1.ctmpl" => "/usr/local/nginx/conf/vhost/web1.conf"
2019/01/30 15:27:15.116804 [INFO] (child) spawning: /usr/local/nginx/sbin/nginx -s reload
说明这个是在动态刷新,当发现有不能用的节点,即使执行命令把可用的节点ip和端口生成到web1.conf文件中,人后重载nginx,当发现不能用的节点再次能用的时候也会执行相同的操作

[root@localhost ~]# tailf /usr/local/nginx/logs/error.log 
当停掉服务提供者1的时候,新增信息如下:
2019/01/30 23:29:03 [notice] 53369#0: signal process started
当再次开启服务提供者1的时候,新增信息如下:
2019/01/30 23:29:36 [notice] 53373#0: signal process started
说明服务提供者的生与死,都可以被动态监控到

日志和配置文件变更时间一直,并且nginx自动reload,实现了后端服务的动态刷新

多配置文件

在多个配置文件(不同微服子站点)或多服务的时候,可以指定多个template模板文件
consul-template -template "/opt/consul/config/nginx.ctmpl:/var/nginx/nginx.conf:nginx -s reload" -template "/opt/consul/config/redis.ctmpl:/var/redis/redis.conf:service redis restart" -template "/opt/consul/config/haproxy.xtmpl:/var/haproxy/haproxy.conf"

Consul Config Server

  • 如果采用consul作为spring-cloud的注册中心的话,其实configserver(版本库钩子+队列+bus总线,架构太重)也没有必要继续使用了,consul自带kv存储,可以取代configserver的功能
  • consul作为注册中心的时候,spring cloud会自动使用远程配置覆盖本地配置(本地优先级低于远程配置)。配置加载策略是,首先从远程加载,远程存在则覆盖本地,远程不存在,再从本地配置查找,若果本地也不存在,则抛出异常。

config server的逻辑如下图
在这里插入图片描述

Spring Cloud Bus会向外提供一个http接口,即图中的/bus/refresh。我们将这个接口配置到远程的git的webhook上,当git上的文件内容发生变动时,就会自动调用/bus-refresh接口。Bus就会通知config-server,config-server会发布更新消息到消息总线的消息队列中,其他服务订阅到该消息就会信息刷新,从而实现整个微服务进行自动刷新。

下面的操作是把consul作为spring cloud注册中心的操作,它可以实现远程配置覆盖本地配置

服务器规划

ip地址角色端口
192.168.43.253(节点3)注册中心8500
192.168.43.147(节点4)spring cloud8055

实现过程

consul连接
节点1
[root@localhost ~]# consul agent -bootstrap-expect 2 -server -data-dir /opt/consul/data/ -node=consul1 -bind 192.168.43.249 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01
节点2
[root@localhost ~]# consul agent -server -data-dir /opt/consul/data/ -node=consul2 -bind 192.168.43.74 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249
节点3
[root@localhost ~]# consul agent -server -ui -data-dir /opt/consul/data/ -node=consul3 -bind 192.168.43.253 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249
节点4
[root@localhost consulservice2]# consul agent -server -data-dir /opt/consul/data/ -node=consul4 -bind 192.168.43.147 -client=0.0.0.0 -config-dir /opt/consul/config/ -enable-script-checks=true -datacenter=bdqn01 -join 192.168.43.249

如果不做集群,curl的命令会提示no cluster leader报错
spring cloud端的操作
克隆代码
[root@localhost ~]# git clone https://github.com/luojunyong/spring_cloud_learn.git
Cloning into 'spring_cloud_learn'...
remote: Enumerating objects: 290, done.
remote: Total 290 (delta 0), reused 0 (delta 0), pack-reused 290
Receiving objects: 100% (290/290), 30.55 KiB | 12.00 KiB/s, done.
Resolving deltas: 100% (57/57), done.
[root@localhost ~]# cd spring_cloud_learn/discover_server_with_consul/springcloudlearn/consulservice2/

代码说明:

  1. 在resources文件夹下创建bootstrap.properties和application.properties两个配置文件
  2. bootstrap.properties在程序引导其间加载,应用于更早期配置信息读取
  3. application.properties相当于系统级别的配置,优先加载
  4. 将配置条目使用consul的kv存储进行存储,bootstrap.properties在程序引导其间进行远程调用测试
  5. 演示项目在启动的时候将加载到的配置条目在启动过程中打印出来
  6. 为方便区分,consul存储的值为username=aaa,password=123,本地配置文件中存储的为username=bbb,password=456
配置文件/启动
[root@localhost consulservice2]# vim src/main/resources/bootstrap.properties
spring.application.name=consul-service2 #springboot应用名
server.port=8055  #监听端口

spring.cloud.consul.host=192.168.43.253 #consul注册中心地址
spring.cloud.consul.port=8500  #注册中心端口
spring.cloud.consul.discovery.serviceName=${spring.application.name} #注册到consul注册中心的服务名
spring.cloud.consul.discovery.preferIpAdress=true  #开启真实ip注册

spring.cloud.consul.config.prefix=config  #指定consul配置的文件夹前缀为config
spring.cloud.consul.config.data-key=configuration  #指定consul配置的配置文件为configuration
spring.cloud.consul.config.format=properties  #指定consul配置的配置文件格式properties(maven),gradle为YAML
spring.cloud.consul.config.defaultContext=${spring.application.name}  #指定consul配置的配置文件的父路径

[root@localhost consulservice2]# vim src/main/resources/application.properties 
jdbc.username=bbb
jdbc.password=456

consul配置键值

#添加config/consul-service2/configuration 值,必须对应bootstrap.properties指定的目录树结构和key配置文件

[root@localhost consulservice2]# curl -X PUT "http://192.168.43.253:8500/v1/kv/config/consul-service2/configuration" -H 'Content-Type: applicatoin/json' -d'{ "jdbc.username": "aaa", "jdbc.password": "123"}'
true

去注册中心的主机,也就是253主机,访问ui,找到key并调整成如下图所示的样式,点击save
firefox 192.168.43.253:8500/ui/
在这里插入图片描述

配置文件和consul的键值配置完成后,进行项目

[root@localhost consulservice2]# mvn spring-boot:run
执行命令后,终端在最后的部分会输出如下信息
01-31 14:17:28.093 [main] INFO  o.s.c.c.s.ConsulServiceRegistry - Registering service with consul: NewService{id='consul-service2-8055', name='consul-service2', tags=[], address='192.168.43.147', port=8055, enableTagOverride=null, check=Check{script='null', interval='10s', ttl='null', http='http://192.168.43.147:8055/actuator/health', tcp='null', timeout='null', deregisterCriticalServiceAfter='null', tlsSkipVerify=null, status='null'}, checks=null}
01-31 14:17:28.145 [main] INFO  com.yyh.ConsulService2App - Started ConsulService2App in 13.47 seconds (JVM running for 1604.546)
username:"aaa", 
password:"123"
01-31 14:17:38.075 [http-nio-8055-exec-1] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
01-31 14:17:38.076 [http-nio-8055-exec-1] INFO  o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
01-31 14:17:38.112 [http-nio-8055-exec-1] INFO  o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 36 ms
从这里可以看出默认加载的是远程consul服务器上的设定的键值,并且本地配置没有生效

此时去注册用心查看service,如下图,可以看到8055端口的
在这里插入图片描述

在spring客户机上远程删除consul上的值,再重新启动项目试试

[root@localhost consulservice2]# curl -X DELETE "http://192.168.43.253:8500/v1/kv/config/consul-service2/configuration"
true[root@localhost consulservice2]# 
[root@localhost consulservice2]# mvn spring-boot:run
运行项目后,关键部分输出结果如下:
01-31 14:23:41.301 [main] INFO  o.s.c.c.s.ConsulServiceRegistry - Registering service with consul: NewService{id='consul-service2-8055', name='consul-service2', tags=[], address='192.168.43.147', port=8055, enableTagOverride=null, check=Check{script='null', interval='10s', ttl='null', http='http://192.168.43.147:8055/actuator/health', tcp='null', timeout='null', deregisterCriticalServiceAfter='null', tlsSkipVerify=null, status='null'}, checks=null}
01-31 14:23:41.466 [main] INFO  com.yyh.ConsulService2App - Started ConsulService2App in 16.862 seconds (JVM running for 25.546)
username:bbb
password:456
01-31 14:23:49.410 [http-nio-8055-exec-1] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
01-31 14:23:49.410 [http-nio-8055-exec-1] INFO  o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
01-31 14:23:49.439 [http-nio-8055-exec-1] INFO  o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 28 ms
可以看出,在没有加载到consul远程的键值时,使用本地配置
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值