8.Consul服务注册与发现
1.Consul简介
Consul是HashiCorp公司推出的开源工具,Consul由Go语言开发,部署起来非常容易,只需要极少的可执行程序和配置文件,具有绿色、轻量级的特点。
Consul是分布式的、高可用的、 可横向扩展的用于实现分布式系统的服务发现与配置。
2.consul官网:https://www.consul.io/
3.Consul具有特点
1.服务发现(Service Discovery):Consul提供了通过DNS或者HTTP接口的方式来注册服务和发现服务。一些外部的服务通过Consul很容易的找到它所依赖的服务。
2.健康检查(Health Checking):Consul的Client可以提供任意数量的健康检查,既可以与给定的服务相关联(“webserver是否返回200 OK”),
也可以与本地节点相关联(“内存利用率是否低于90%”)。操作员可以使用这些信息来监视集群的健康状况,服务发现组件可以使用这些信息将流量从不健康的主机路由出去。
3.Key/Value存储:应用程序可以根据自己的需要使用Consul提供的Key/Value存储。 Consul提供了简单易用的HTTP接口,结合其他工具可以实现动态配置、功能标记、领袖选举等等功能。
4.安全服务通信:Consul可以为服务生成和分发TLS证书,以建立相互的TLS连接。意图可用于定义允许哪些服务通信。服务分割可以很容易地进行管理,其目的是可以实时更改的,
而不是使用复杂的网络拓扑和静态防火墙规则。
5.多数据中心:Consul支持开箱即用的多数据中心. 这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。
Consul 架构图
图片上 datacenter 分成上下两个部分, 但是这两个部分又不是完全隔离的。他们之间通过 WAN GOSSIP 进行报文交互。
单个 datacenter 中, 节点被划分成两种颜色, 红色的 server, 紫色的 client, 他们之间通过 GRPC 进行通信(业务数据), 除此之外,
Client 和 Server 之间通过还有一条 LAN Gosssip 进行通信,比如,当 Server 节点增加,或者 down 机后,Client 可以获取对应的 Server列表,
去除或者增加 Server 列表。
同一个 Consul agent 程序,启动的时候,通过制定不同的参数来运行 Server 和 Client 模式。也就是说 client 和 server 本质上都是 Client Agent
Server:
参与共识仲裁(raft)
存储机器状态(日志存储)
处理查询
维护周边(LAN/WAN) 节点之间的关系
Client :
负责通过该节点注册到 Consul 微服务的健康检查
将客户端的注册请求和查询转换为 server 的 RPC 请求
维护周边各节点(LAN/WAN) 的关系
consul的安装
windows安装consul
首先去官网下载官网地址:https://www.consul.io/
解压就会得到一个exe可执行文件,在当前目录下新建start.bat文件,在里面输入
consul agent -dev
双击它启动consul.
然后浏览器输入http://127.0.0.1:8500/ui/dc1/services
出现这个页面说明启动成功了。
springcloud整合consul
服务提供者搭建
- 首先新建Module支付服务provider8006
- 修改他的pom文件添加以下的依赖。
<dependencies>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.zhubayi.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
- 修改配置文件
###consul服务端口号
server:
port: 8006
spring:
application:
name: consul-provider-payment
####consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}
- 添加主启动类
package com.zhubayi.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author zhubayi
*/
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class,args);
}
}
- 业务类Controller
package com.zhubayi.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* @author zhubayi
*/
@RestController
@RequestMapping("payment")
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("consul")
public String paymentConsul(){
return "consul:"+serverPort+"\t"+ UUID.randomUUID().toString();
}
}
完整目录结构
启动测试,去consul查看
可以看到consul-provider-payment注册了进来。
可以访问,搭建成功了服务提供模块。
服务消费者搭建
- 新建Module消费服务order80,cloud-consumerconsul-order80
- 修改他的pom文件,添加以下的依赖。
<dependencies>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.zhubayi.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
- 修改配置文件application.yml
###consul服务端口号
server:
port: 80
spring:
application:
name: cloud-consumer-order
####consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}
- 添加主启动类
package com.zhubayi.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author zhubayi
*/
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class,args);
}
}
- 添加配置类,配置Bean
package com.zhubayi.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author zhubayi
*/
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 添加controller类
package com.zhubayi.springcloud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author zhubayi
*/
@RestController
public class OrderConsulController {
重点:此处配置的式服务在consul中的名称
public static final String URL="http://consul-provider-payment";
@Autowired
private RestTemplate restTemplate;
@GetMapping("consumer/payment/consul")
public String paymentInfo(){
return restTemplate.getForObject(URL+"/payment/consul",String.class);
}
}
完整目录结构
启动80端口,浏览器输入:http://127.0.0.1:8500/ui/dc1/services
可以看到服务提供方与服务消费方都注册了进来。
测试服务是否可以调用:http://localhost/consumer/payment/consul
可以看到服务消费方调用服务提供方成功!