SpringCloud极简入门(十六)consul

阅读次数:3    时间:2018-10-03     作者:陈刚

一.什么是Consul

在前面章节中我们一直使用 Spring Cloud 下的 Netflix Eureka实现服务注册,然而很不幸,Spring Cloud 下的 Netflix Eureka 组件项目居然宣布闭源了。。
https://github.com/Netflix/eureka/wiki

Eureka 2.0 (Discontinued)
The existing open source work on eureka 2.0 is discontinued. The code base and artifacts that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk.
Eureka 1.x is a core part of Netflix’s service discovery system and is still an active project.

大概意思说的是Eureka 2.0 的开源工作已经停止,依赖于开源库里面的 Eureka 2.x 分支构建的项目或者相关代码,风险自负!
但是大家不必惊慌,除了Eureka以外我们还有更多的选择实现服务注册/发现组件,如:consul , zookeeper

而在Spring Cloud 中 Consul 使用也较为广泛,Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。它具有很多优点。包括: 基于 raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows

原理:

image.png

当Producer服务启动的时候,会向 Consul 发送一个请求,注册自己的 服务地址 和 端口 ,Consul 接收到 Producer 的注册后,每隔10s(默认)会向 Producer 发送请求检验Producer是否已经下线等,当 Consumer 发送请求 (REST API) 到 Producer 时,会先从 Consul 中拿到注册的服务的地址清单(服务的ip、端口),然后发起请求。

二.安装consul

安装Consul是非常简单的,首先从 https://www.consul.io/downloads.html 下载对应的安装包,直接解压。如在mac上安装就把解压出来的 consul 文件拷贝到/usr/local/bin/目录中,然后运行:consul agent -dev

image.png
访问:http://127.0.0.1:8500/ui/dc1/services出现以下界面,说明安装成功
image.png

三.服务注册:提供者

我们把consul作为注册中心,创建生产者服务到consul进行注册,创建消费者服务和生产者服务进行通信

  • 创建SpringBoot应用 Producer作为生产者,pom如下
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Finchley.SR1</spring-cloud.version>
  </properties>

  <dependencies>
    <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>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </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>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

spring-cloud-starter-consul-discovery :consul基础依赖包
spring-boot-starter-actuator :健康检查/监控包

#应用名
spring.application.name=consul-producer
#服务端口
server.port=2222
#consul服务地址
spring.cloud.consul.host=localhost
#consul端口
spring.cloud.consul.port=8500
#注册到consul的服务名称
spring.cloud.consul.discovery.serviceName=service-producer
  • 创建 ProducerController ,向外暴露一个方法供消费者服务访问
@RestController
public class ProducerController {

    @RequestMapping("/hello")
    public String hello() {
        return "hello consul";
    }
}

四.服务消费者

  • 创建Consumer服务,pom同 Procuder

  • 应用主程序配置类如下:

@SpringBootApplication
public class ConsumerApplication
{
    public static void main( String[] args )
    {
        SpringApplication.run(ConsumerApplication.class,args);
    }
}
  • 配置文件如下:
spring.application.name=consul-consumer
server.port=3333
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
#设置不需要注册到 consul 中
spring.cloud.consul.discovery.register=false

消费者服务可以选择注册到consul或者不注册到 consul,这个根据业务情况选择

  • 编写ConsumerController,编写方法去访问Producer服务的hello接口
@RestController
public class ConsumerController {

    @Autowired
    private LoadBalancerClient loadBalancer;
    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/consumer")
    public String consumer() {
        //指定请求地址为提供者
        String callServiceResult = new RestTemplate().getForObject("http://192.168.82.187:2222/hello", String.class);
        System.out.println(callServiceResult);
        return callServiceResult;
    }

}

测试

一次启动,consul,服务提供者,服务消费者 ,这次访问consul : http://127.0.0.1:8500/ui/dc1/nodes,点击nodes,可以看到多了一个服务,就是我们的服务提供者:
image.png
访问:http://localhost:3333/consumer 你将会看到 : hello consul,说明已经访问到了 Producer的 hello接口