Consul
Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,采用 Go 语言开发
特性
- 服务发现
- 健康检查
- Key/Value 存储
- 多数据中心
Consul 角色
- client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。
- server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其它数据中心通讯。 每个数据中心的 server 数量推荐为 3 个或是 5 个。
Consul 工作原理:
- producer启动时,回想Consul发送一个post请求,告诉自己的ip和port。
- Consul收到Producer的注册后,每隔10s(默认)向Producer发送一个检查健康的请求。
- consumer发送get请求到producer,会从consul拿到一个ip和port的临时表,拿到ip和port后再请求,这个临时表每10s更新一次,只包含通过检查了producer
consul安装
- 下载
- 命令行输入
consul agent -dev
- 启动 http://localhost:8500
Consul 服务端
创建一个producer项目
引入pom (以下部分重要的依赖)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
-
spring-boot-starter-actuator
健康检查依赖于此包。 -
spring-cloud-starter-consul-discovery
Spring Cloud Consul 的支持。
配置文件
spring.application.name=spring-cloud-consul-producer
server.port=8501
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
#注册到consul的服务名称
spring.cloud.consul.discovery.serviceName=service-producer
启动类上加@EnableDiscoveryClient
表示支持服务发现。
consul消费端
配置如下,pom和服务端相同。
spring.application.name=spring-cloud-consul-consumer
server.port=8503
spring.cloud.consul.host=127.0.0.1
spring.cloud.consul.port=8500
#设置不需要注册到 consul 中
spring.cloud.consul.discovery.register=false
测试
@RestController
public class ServiceController {
@Autowired
private LoadBalancerClient loadBalancer;
@Autowired
private DiscoveryClient discoveryClient;
/**
* 获取所有服务
*/
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("service-producer");
}
/**
* 从所有服务中选择一个服务(轮询)
*/
@RequestMapping("/discover")
public Object discover() {
return loadBalancer.choose("service-producer").getUri().toString();
}
}
远程调用
@RequestMapping("/call")
public String call() {
ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
System.out.println("服务地址:" + serviceInstance.getUri());
System.out.println("服务名称:" + serviceInstance.getServiceId());
String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
System.out.println(callServiceResult);
return callServiceResult;
}
feign服务调用
- 在启动类加上
@EnableDiscoveryClient
和@EnableFeignClients
-
@EnableDiscoveryClient
启用服务注册与发现 -
@EnableFeignClients
启用feign进行远程调用
Feign是一个声明式Web Service客户端。使用Feign能让编写Web Service客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解.Feign也支持可拔插式的编码器和解码器。
feign调用实现
客户端
@FeignClient(name= "spring-cloud-producer")
public interface HelloRemote {
@RequestMapping(value = "/hello")
public String hello(@RequestParam(value = "name") String name);
}
- name:远程服务名,eureka是spring.application.name配置的名称,consul是spring.cloud.consul.discovery.serviceName的名称
- 此类中的方法和远程服务中contoller中的方法名和参数需保持一致。
- @RequestMapping(value = “/hello”)和服务端方法对应
客户端注入接口
@RestController
public class ServiceController {
@Autowired
private HelloRemote helloRemote;
@RequestMapping("/hello/{name}")
public String index(@PathVariable("name") String name) {
return helloRemote.hello(name);
}
}
服务端代码
@RequestMapping("/test")
public String test(@RequestParam(value = "name") String name){
return name;
}
测试 http://localhost:8503/hello/312
参考连接 http://www.ityouknow.com/springcloud/2017/05/12/eureka-provider-constomer.html