目录
1、Consul简介
Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper 等)。使用起来也较为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。
2、下载
下载地址:https://www.consul.io/downloads.html
我这里下载的是windows版本,下载后之后就只是一个exe文件
将其所在路径配置在windows的环境变量中
启动consul的命令:
consul agent -dev -ui -node=cy
-dev开发服务器模式启动,-node结点名为cy,-ui可以用界面访问,默认能访问。
打开命令行窗口输入命令
consul默认端口是8500,因此在浏览器输入http://localhost:8500 出现如下界面,则表示consul启动成功:
3、搭建环境
在这里搭建consul-order和consul-member两个项目,并且在consul-order项目中远程调用consul-member中的服务。
3.1 consul-member项目搭建
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- consul依赖的核心包 -->
<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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.yml:
##服务名称
spring:
application:
name: consul-member
#连接consul
cloud:
consul:
host: localhost
port: 8500
discovery:
hostname: 127.0.0.1
##本服务在tomcat中运行的端口号
server:
port: 8100
主类:
@SpringBootApplication
@RestController
@EnableDiscoveryClient //适用于zk consul
public class ConsulMemberApplication {
@RequestMapping("/getMember")
public String getMember() {
return "调用会员服务";
}
public static void main(String[] args) {
SpringApplication.run(ConsulMemberApplication.class, args);
}
}
@EnableDiscoveryClient 与@EnableEurekaClient区别
1、@EnableDiscoveryClient注解是基于spring-cloud-commons依赖,并且在classpath中实现; 适合于consul、zookeeper注册中心
2,@EnableEurekaClient注解是基于spring-cloud-netflix依赖,只能为eureka作用;
3.2 consul-order项目搭建
pom.xml与上面相同
application.yml
spring:
application:
name: consul-order
cloud:
consul:
host: localhost
port: 8500
discovery:
hostname: 127.0.0.1
server:
port: 8200
主类:
第一种远程调用方法
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ConsulOrderApplication {
@Autowired
private RestTemplate restTemplate;
//两种调用方式:一种是采用服务别名方式调用,另一种是直接调用,使用别名去注册中心上获取对应的服务调用地址
@RequestMapping("/getOrder01")
public String getOrder01() {
String serviceUrl = "http://consul-member/getMember";
return restTemplate.getForObject(serviceUrl, String.class);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsulOrderApplication.class, args);
}
}
第二种远程调用方法:
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class ConsulOrderApplication {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/getOrder02")
public String getOrder02() {
//根据名称,在注册中心查找到具体url
String serviceUrl = getServiceURL("consul-member") + "/getMember";
String result = restTemplate.getForObject(serviceUrl, String.class);
return result;
}
private String getServiceURL(String appName) {
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances(appName);
if(serviceInstanceList != null && !serviceInstanceList.isEmpty()) {
return serviceInstanceList.get(0).getUri().toString();
}
return null;
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsulOrderApplication.class, args);
}
}
当两个项目搭建完毕后,将这两个项目同时启动,在consul注册中心查看服务列表信息:访问http://localhost:8500
可以看到,已经将consul-member和consul-order服务全都注册到cosul注册中心了。
现在进行测试:通过浏览器访问consul-order暴露出的接口,之后通过RPC调用consul-order的服务。
访问:http://localhost:8200/getOrder01
由图可知,远程调用成功!
4、consul注册中心原理
- 1、当 Producer 启动的时候,会向 Consul 发送一个 post 请求,告诉 Consul 自己的 IP 和 Port
- 2、Consul 接收到 Producer 的注册后,每隔10s(默认)会向 Producer 发送一个健康检查的请求,检验Producer是否健康
- 3、当 Consumer 发送 GET 方式请求 /api/address 到 Producer 时,会先从 Consul 中拿到一个存储服务 IP 和 Port 的临时表,从表中拿到 Producer 的 IP 和 Port 后再发送 GET 方式请求 /api/address
- 4、该临时表每隔10s会更新,只包含有通过了健康检查的 Producer