consul是什么?
关于consul实质上跟springcloud的Eureka一样,作为微服务架构中的服务注册和发现的角色出现在我们的面前,至于它具体的内部架构东西,大家可以看看它的官网consul官网,大家也可以跟eureka进行对比,怎么说了各有千秋,虽然官方停止了对Eureka的维护,但作为新手,值得去学习它,话不多说了,接着看.
consul本地安装过程
进入consul官网之后,选择对应系统的进行下载如图所示:
我这里下载的win64位的,然后在对应保存的目录下直接解压如图:
至于图中的consul.bat大家忽略,这是我写的consul启动脚本,主要是为了方便而已,不影响,接着用cmd命令来进行操作consul,如图:
注意:在consul的安装目录下进行cmd命令操作,输入图中命令:
consul agent -dev
启动成功之后直接访问:http://localhost:8500后来到consul的管理界面如图:
看到该页面说明我们的consul启动成功了,接下来我们来进入今天的主题就是如何用springboot来整合consul的过程
consul整合过程
首先用我们的开发工具idea来创建一个emptyProject,我这里的项目名为consul-server,接着在该项目的下面创建字模块项目,我这里服务的提供者为consul-producer,(注意在创建的过程中使用springboot来搭建,我这里服务的发现选择consul),然后一路next即可
- 接下来是需要导入我们相关依赖,代码如下:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
接着看我们的启动类,代码如下:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author cb */ @SpringBootApplication @EnableDiscoveryClient public class ConsulProducerApplication { public static void main(String[] args) { SpringApplication.run(ConsulProducerApplication.class, args); }
我们需要在启动类上添加注解@EnableDiscoveryClient,其目的是为了让consul能够发现自己的服务,接着来看我们的配置文件,代码如下:
server.port=8080 spring.cloud.consul.host=localhost spring.cloud.consul.port=8500 spring.application.name=consul-producer #注册到consul的服务名称 spring.cloud.consul.discovery.service-name=${spring.application.name}
上述是简单的配置,一般自己玩只需要这几个即可,在实际的开发中有需求的可以自己去加,我们启动一下来看一下在consul管理页面中是否存在我们的服务,运行结果如图所示:
如我们想象的一样,在管理界面中出现了我们的服务,接着我们来创建一个接口来测试一下,代码如下:
package com.consul.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author cb */ @RestController @RequestMapping("producer") public class ProducerController { @RequestMapping("hello") public String hello(){ return "hello consul"; }
在浏览器上输入地址http://localhost:8080/producer/hello,在页面中会打印hello consul的字样,就这样我们的服务提供者完成了创建,很简单吧,为了让我们体验下注册时的负载均衡效果,我们在来创建一个跟上一个一模一样的服务提供者我这里的服务名为consul-producer1,创建过程和pom文件一样,唯一区别在于配置文件的端口配置,配置代码如下:
server.port=8081 spring.cloud.consul.host=localhost spring.cloud.consul.port=8500 spring.application.name=consul-producer #注册到consul的服务名称 spring.cloud.consul.discovery.service-name=${spring.application.name}
接着我们来启动下我们的子模块consul-producer1,然后在我们的consul管理界面台中进行查看,如图:
在管理台界面中看到了我们的两个服务,虽然服务名相同,但port不一样,总之使我们想要的结果,接下来我们需要创建一个服务的消费方来对我们的服务进行随机轮询访问,这也体现了微服务的负载均衡策略.
服务消费方
首先创建一个名为consul-consumer的子项目,同样在pom文件需要引入对应的依赖,实际跟我们consul-producer的pom依赖一样,直接cv即可,这里就不重复了,接着看我们的启动类,代码如下:
package com.consul; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author cb */ @SpringBootApplication public class ConsulConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsulConsumerApplication.class, args); }
接着看配置文件,代码如下:
server.port=8082 spring.application.name=consul-consumer spring.cloud.consul.discovery.service-name=${spring.application.name} spring.cloud.consul.host=localhost spring.cloud.consul.port=8500 #消费端不需要注册到consul中 spring.cloud.consul.discovery.register=false
作为服务的消费者,这里我们就不必将它作为服务进行注册,接着写个测试接口进行测试,代码如下:
com.consul.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; /** * * @author cb */ @RestController public class ServiceController { @Autowired private LoadBalancerClient loadBalancerClient; @Autowired private DiscoveryClient discoveryClient; /** * 获取所有的服务 * @return */ @RequestMapping("services") public Object getServices(){ List<ServiceInstance> instances = discoveryClient.getInstances("consul-producer"); System.out.println(instances.toString()); return instances; } /** * 轮训获取服务中的其中一个 * @return */ @RequestMapping("discover") public String discover(){ return loadBalancerClient.choose("consul-producer").toString(); }
我们访问http://localhost:8082/services来获取所有的服务实例,运行结果如下:
DefaultServiceInstance{instanceId='consul-producer-8080', serviceId='consul-producer', host='DESKTOP-NSAK1VJ', port=8080, secure=false, metadata={secure=false} DefaultServiceInstance{instanceId='consul-producer-8081', serviceId='consul-producer', host='DESKTOP-NSAK1VJ', port=8081, secure=false, metadata={secure=false}}
上面的结果使我们进行接口访问之后的结果,可以看到的是我们此时有两个服务名为consul-producer的服务实例,再一次通过访问我们http://localhost:8082/discover,会发现两个服务轮询访问,如图: