天天看点

服务注册和发现-consulconsul

consul

consul的理论概念自行百度一下,此处不再叙述

1. consul的搭建

此处我们使用

docker

来搭建consul的集群,至于docker不是很熟练的同学,自行恶补一下

1.1 docker拉取consul

拉取的命令很简单

docker pull consul
           

默认下载最新的consul镜像文件,下载完成好之后我们开始启动一个节点,作为集群的一个节点,这里我们搭建三个节点,最终组装成一个集群,因我这里只有一台机器,所以我们部署在一台机器上,分别采用三个端口,这样就是三个节点,实际使用过程中,一般都是三台机器来搭建三个节点。

1.2 搭建第一个节点

执行的命令为:

docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:1.2.2 agent -server -bootstrap-expect 2 -ui -bind=0.0.0.0 -client=0.0.0.0
           

至于里面所使用的命令下面简单介绍一下

–net=host docker参数, 使得docker容器越过了net namespace的隔离,免去手动指定端口映射的步骤
-server consul支持以server或client的模式运行, server是服务发现模块的核心, client主要用于转发请求
-advertise 将本机私有IP传递到consul
-retry-join 指定要加入的consul节点地址,失败后会重试, 可多次指定不同的地址
-client 指定consul绑定在哪个client地址上,这个地址可提供HTTP、DNS、RPC等服务,默认是>127.0.0.1
-bind 绑定服务器的ip地址;该地址用来在集群内部的通讯,集群内的所有节点到地址必须是可达的,>默认是0.0.0.0
allow_stale 设置为true则表明可从consul集群的任一server节点获取dns信息, false则表明每次请求都会>经过consul的server leader
-bootstrap-expect 数据中心中预期的服务器数。指定后,Consul将等待指定数量的服务器可用,然后>启动群集。允许自动选举leader,但不能与传统-bootstrap标志一起使用, 需要在server模式下运行。
-data-dir 数据存放的位置,用于持久化保存集群状态
-node 群集中此节点的名称,这在群集中必须是唯一的,默认情况下是节点的主机名。
-config-dir 指定配置文件,当这个目录下有 .json 结尾的文件就会被加载,详细可参考https://www.consul.io/docs/agent/options.html#configuration_files
-enable-script-checks 检查服务是否处于活动状态,类似开启心跳
-datacenter 数据中心名称
-ui 开启ui界面
-join 指定ip, 加入到已有的集群中
           

1.3 查看第一个节点的地址

执行如下的命令我们来查看第一个节点的地址,这个很重要,因为我们要给节点二和节点三绑定到节点一上。

docker inspect --format ‘{{ .NetworkSettings.IPAddress }}‘ consul1
           

1.4 搭建第二个节点

执行命令:

docker run --name consul3 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
           

1.5 搭建第三个节点

执行命令:

docker run --name consul3 -d -p 8502:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
           

搭建完成之后,我们查看docker容器运行的情况,查看运行状态

服务注册和发现-consulconsul

我们可以看到我们新建的consul集群已经在运行中,我这里是将防火墙关闭了,我们你是启动的防火墙,要是访问我们需要做个防火墙开放端口,开放端口之后,并且重启防火墙。完了才可以执行下面的操作。

1.6 查看集群

通过浏览器访问192.168.1.100:8500之后,如果能看到下面的界面,说明我们的集群搭建完成了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

服务注册和发现-consulconsul

继续访问节点2 节点2我们的端口是8501

服务注册和发现-consulconsul

访问节点3 端口是8502

服务注册和发现-consulconsul

至此我们consul的集群算是搭建完毕了。那我们如何使用它呢?

2. 调用consul

2.1 新建一个服务提供者

新建一个项目名称叫consul-provider,引入如下图所示的

服务注册和发现-consulconsul

2.2 修改服务提供者配置文件

我们在新建的服务提供者的配置文件中加入如下配置:

spring.application.name=consul-provider
server.port=3000
spring.cloud.consul.host=192.168.1.100
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.service-name=consul-provider
           
注意:

spring.cloud.consul.host

中配置的是我们consul的地址,

spring.cloud.consul.port

中配置的是我们consul的端口,此处我们只配置三个节点中的任意一个,我们我们新建的三个节点,本身是带有复制功能,所以随便配置一个,其他两个都能获取到这个服务提供者。这里和zk的用法不太一样。

2.3 服务提供者业务

为了演示我们给服务提供者集群部署,测试一下负载均衡。

我们新建一个controller,内容如下:

服务注册和发现-consulconsul

完了我们开启注册服务,在启动类上加上注解

@EnableDiscoveryClient

服务注册和发现-consulconsul

完成以上配置之后,我们需要打包,完了集群部署。

2.4 集群部署服务提供者

右击服务提供者的target,选择open in terminal

服务注册和发现-consulconsul

之后执行命令

java -jar consul-provider-0.0.1-SNAPSHOT.jar --server.port=3001
           

再次右击服务提供者的target,选择open in terminal,执行命令

java -jar consul-provider-0.0.1-SNAPSHOT.jar --server.port=3002
           
服务注册和发现-consulconsul

我们访问consul,查看服务注册情况。

我们先访问节点1,查看运行情况。

服务注册和发现-consulconsul

再访问节点2

服务注册和发现-consulconsul

最后访问节点3

服务注册和发现-consulconsul

我们可以看出来 我们注册的时候配置文件的地址只写了一个节点的地址,但是我们同样可以看到节点2和节点3的运行情况,完全和节点1一样。

2.5 新建服务消费者

和新建服务提供者是一样的。引入这三个jar包

服务注册和发现-consulconsul

2.6 修改服务消费者的配置文件

这里修改的配置文件和服务提供者的一样,如下图所示:

spring.application.name=consul-consumer
server.port=3100
spring.cloud.consul.host=192.168.1.100
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.service-name=consul-consumer
           

2.7 修改服务消费者的启动类

因为我们这里需要调用服务提供者,所以我们需要新建一个

restTemplate

@SpringBootApplication
@EnableDiscoveryClient 
public class ConsulConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsulConsumerApplication.class, args);
    }

    @Bean
//    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

}
           
注意:这里的restTemplate可以采用轮询,也可以不用再这里设置轮询,我们再具体代码调用的地方再设置

2.8 服务消费者的业务编写

新建一个controller,编写一个简单的参数接受并返回的方法。

@RestController
public class ConsulConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @GetMapping("/consulconsumer")
    public String hello(){
        ServiceInstance choose = loadBalancerClient.choose("consul-provider");
        URI uri = choose.getUri();
        String forObject = restTemplate.getForObject(uri + "/consulprovider?name={1}", String.class,"muyan");
        return forObject;
    }
}
           

上面就是就是再controller中采用的轮询方式,如果我们在启动类的RestTemplate中加上@LoadBalanced,那么此处的代码应该是:

@RestController
public class ConsulConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @GetMapping("/consulconsumer")
    public String hello(){
//        ServiceInstance choose = loadBalancerClient.choose("consul-provider");
//        URI uri = choose.getUri();
        String forObject = restTemplate.getForObject("http://consul-provider/consulprovider?name={1}", String.class, "mumu");
//        String forObject = restTemplate.getForObject(uri + "/consulprovider?name={1}", String.class,"muyan");
        return forObject;
    }
}
           
切记,千万不要在启动类上加上了@LoadBalanced注解之后,再在controller中采用LoadBalancerClient的choose方式来调用远程服务,因为serverid必须是我们访问的服务名称 ,当我们直接输入ip的时候获取的server是null,就会抛出异常。

2.9 测试

启动服务消费者。我们通过浏览器来调用consulconsumer方法。

服务注册和发现-consulconsul

可以看到调用的3001端口的服务提供者,我们再刷新

服务注册和发现-consulconsul

我们可以看到出现的调用时3002的端口服务提供者。