Spring cloud入门-7:服务注册中心-Consul单机环境构建

Spring cloud入门-7:服务注册中心-Consul单机环境构建

  • 1、consul简介
    • 1.1 what is consul
    • 1.2 Common use cases for Consul
  • 2、安装consul
  • 3、构建服务提供模块
    • 3.1、建module
    • 3.2、改pom
    • 3.3、写yml
    • 3.4、主启动
    • 3.5、业务类
    • 3.6、测试
  • 4、构建服务消费模块
    • 4.1、建module
    • 4.2、写pom
    • 4.3、改yml
    • 4.4、主启动
    • 4.5、业务类
    • 4.6、测试
  • 5、三个注册中心的异同点
    • 5.1、测试consul服务宕机
    • 5.2、CAP定理

1、consul简介

1.1 what is consul

  Consul uses service identities and traditional networking practices to help organizations securely connect applications running in any environment.
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第1张图片

1.2 Common use cases for Consul

1、Discover Services with Consul:服务发现,提供http和dns两种发现方式。
2、Health Monitoring with Consul:实时的健康检查
3、Observability with Consul:可视化界面
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第2张图片

2、安装consul

首先是下载linux版的consul:https://www.consul.io/downloads
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第3张图片
我的系统是Ubuntu16.04,按照官网命令安装即可。
安装完成后,查看是否安装成功:consul --version

koping@koping-HP:~$ consul --version
Consul v1.11.1
Revision 2c56447e
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

接下来使用开发模式启动:。数据是存储在内存中,重启之后数据将丢失

consul agent -dev
koping@koping-HP:~$ consul agent -dev
==> Starting Consul agent...
           Version: '1.11.1'
           Node ID: '9b6e4720-3b08-49a1-427e-a81fe2aa0634'
         Node name: 'koping-HP'
        Datacenter: 'dc1' (Segment: '')
            Server: true (Bootstrap: false)
       Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
      Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
           Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false

==> Log data will now stream in as it occurs:

2022-01-13T12:18:16.880+0800 [INFO]  agent.server.raft: initial configuration: index=1 servers="[{Suffrage:Voter ID:9b6e4720-3b08-49a1-427e-a81fe2aa0634 Address:127.0.0.1:8300}]"
2022-01-13T12:18:16.880+0800 [INFO]  agent.server.raft: entering follower state: follower="Node at 127.0.0.1:8300 [Follower]" leader=
2022-01-13T12:18:16.880+0800 [INFO]  agent.server.serf.wan: serf: EventMemberJoin: koping-HP.dc1 127.0.0.1
2022-01-13T12:18:16.881+0800 [INFO]  agent.server.serf.lan: serf: EventMemberJoin: koping-HP 127.0.0.1
2022-01-13T12:18:16.881+0800 [INFO]  agent.router: Initializing LAN area manager
2022-01-13T12:18:16.881+0800 [INFO]  agent.server: Adding LAN server: server="koping-HP (Addr: tcp/127.0.0.1:8300) (DC: dc1)"
2022-01-13T12:18:16.881+0800 [INFO]  agent: Started DNS server: address=127.0.0.1:8600 network=udp
2022-01-13T12:18:16.881+0800 [INFO]  agent.server: Handled event for server in area: event=member-join server=koping-HP.dc1 area=wan
2022-01-13T12:18:16.881+0800 [WARN]  agent: grpc: addrConn.createTransport failed to connect to {dc1-127.0.0.1:8300 0 koping-HP <nil>}. Err :connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:0->127.0.0.1:8300: operation was canceled". Reconnecting...
2022-01-13T12:18:16.881+0800 [INFO]  agent: Started DNS server: address=127.0.0.1:8600 network=tcp
2022-01-13T12:18:16.881+0800 [INFO]  agent: Starting server: address=127.0.0.1:8500 network=tcp protocol=http
2022-01-13T12:18:16.881+0800 [WARN]  agent: DEPRECATED Backwards compatibility with pre-1.9 metrics enabled. These metrics will be removed in a future version of Consul. Set `telemetry { disable_compat_1.9 = true }` to disable them.
2022-01-13T12:18:16.881+0800 [INFO]  agent: started state syncer
2022-01-13T12:18:16.881+0800 [INFO]  agent: Consul agent running!
2022-01-13T12:18:16.881+0800 [INFO]  agent: Started gRPC server: address=127.0.0.1:8502 network=tcp
2022-01-13T12:18:16.941+0800 [WARN]  agent.server.raft: heartbeat timeout reached, starting election: last-leader=
2022-01-13T12:18:16.941+0800 [INFO]  agent.server.raft: entering candidate state: node="Node at 127.0.0.1:8300 [Candidate]" term=2
2022-01-13T12:18:16.941+0800 [DEBUG] agent.server.raft: votes: needed=1
2022-01-13T12:18:16.941+0800 [DEBUG] agent.server.raft: vote granted: from=9b6e4720-3b08-49a1-427e-a81fe2aa0634 term=2 tally=1
2022-01-13T12:18:16.941+0800 [INFO]  agent.server.raft: election won: tally=1
2022-01-13T12:18:16.941+0800 [INFO]  agent.server.raft: entering leader state: leader="Node at 127.0.0.1:8300 [Leader]"
2022-01-13T12:18:16.942+0800 [INFO]  agent.server: cluster leadership acquired
2022-01-13T12:18:16.942+0800 [INFO]  agent.server: New leader elected: payload=koping-HP
2022-01-13T12:18:16.946+0800 [INFO]  agent.leader: started routine: routine="federation state anti-entropy"
2022-01-13T12:18:16.946+0800 [INFO]  agent.leader: started routine: routine="federation state pruning"
2022-01-13T12:18:16.946+0800 [DEBUG] agent.server.autopilot: autopilot is now running
2022-01-13T12:18:16.946+0800 [DEBUG] agent.server.autopilot: state update routine is now running
2022-01-13T12:18:16.947+0800 [DEBUG] connect.ca.consul: consul CA provider configured: id=fb:50:9b:45:1a:65:15:c1:68:57:73:5f:da:cd:b8:0d:0f:e2:26:eb:68:66:43:11:85:9d:67:a9:7a:56:9c:b9 is_primary=true
2022-01-13T12:18:16.949+0800 [INFO]  connect.ca: initialized primary datacenter CA with provider: provider=consul
2022-01-13T12:18:16.949+0800 [INFO]  agent.leader: started routine: routine="intermediate cert renew watch"
2022-01-13T12:18:16.949+0800 [INFO]  agent.leader: started routine: routine="CA root pruning"
2022-01-13T12:18:16.949+0800 [INFO]  agent.leader: started routine: routine="CA root expiration metric"
2022-01-13T12:18:16.949+0800 [INFO]  agent.leader: started routine: routine="CA signing expiration metric"
2022-01-13T12:18:16.949+0800 [INFO]  agent.leader: started routine: routine="virtual IP version check"
2022-01-13T12:18:16.949+0800 [DEBUG] agent.server: successfully established leadership: duration=7.187553ms
2022-01-13T12:18:16.949+0800 [INFO]  agent.server: member joined, marking health alive: member=koping-HP partition=default
2022-01-13T12:18:16.949+0800 [DEBUG] agent.leader: stopping routine: routine="virtual IP version check"
2022-01-13T12:18:16.949+0800 [DEBUG] agent.leader: stopped routine: routine="virtual IP version check"
2022-01-13T12:18:16.964+0800 [INFO]  agent.server: federation state anti-entropy synced
2022-01-13T12:18:17.138+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
2022-01-13T12:18:17.139+0800 [INFO]  agent: Synced node info
2022-01-13T12:18:17.139+0800 [DEBUG] agent: Node info in sync
2022-01-13T12:18:18.014+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
2022-01-13T12:18:18.014+0800 [DEBUG] agent: Node info in sync

显示Consul agent running!后,再访问consul的前端界面,端口号是默认的8500:http://localhost:8500/
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第4张图片

3、构建服务提供模块

和之前eureka、zookeeper一样,现在需要构建服务提供者模块注册进consul中。

3.1、建module

在cloud2021父工程下,构建cloud-provider-payment-consul-8006模块:
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第5张图片

3.2、改pom

  依赖文件参考上一节博文的zookeeper的依赖包,只是将spring-cloud-starter-zookeeper-discovery给替换为了:spring-cloud-starter-consul-discovery。


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2021artifactId>
        <groupId>org.example.springcloudgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>cloud-provider-payment-consul-8006artifactId>

    <properties>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-consul-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>org.example.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
            <version>1.14.0version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

project>

3.3、写yml

配置文件与之前也一致,需要填写服务端口号,服务注册中心IP地址,端口号,注册服务名称等:

server.port=8006

spring.application.name=consul-provider-payment
# consul服务注册中心地址
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.hostname=127.0.0.1
spring.cloud.consul.discovery.service-name=${spring.application.name}

3.4、主启动

在主启动类上面还是要添加@SpringBootApplication和@EnableDiscoveryClient这2个注解。
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第6张图片

package com.example.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8006 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8006.class, args);
    }
}

3.5、业务类

业务类与上一节的zookeeper一致,只是返回consul的端口信息+一个随机UUID字符串:
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第7张图片

package com.example.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
@Slf4j
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    @RequestMapping(value = "/payment/consul")
    public String paymentConsul() {
        return "Spring cloud with consul: " + serverPort + "\t" + UUID.randomUUID();
    }
}

3.6、测试

启动服务提供模块的主启动类:PaymentMain8006。
启动成功后,刷新consul的监控主页面,可以看到服务提供模块已经成功注册进入consul中:
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第8张图片
然后,通过postman调用服务接口,可以得到consul端口号和一个随机的uuid字符串结果:
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第9张图片

4、构建服务消费模块

4.1、建module

在cloud2021父工程下新建服务消费模块:cloud-consumer-order-consul-80
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第10张图片

4.2、写pom


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2021artifactId>
        <groupId>org.example.springcloudgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>cloud-consumer-order-consul-80artifactId>

    <properties>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-consul-discoveryartifactId>
        dependency>
        
        <dependency>
            <groupId>org.example.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
            <version>1.14.0version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>
project>

4.3、改yml

server.port=8080

# 服务别名--注册到consul的服务名称
spring.application.name=cloud-consumer-order
# consul服务注册中心地址
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.hostname=127.0.0.1
spring.cloud.consul.discovery.service-name=${spring.application.name}

4.4、主启动

Spring cloud入门-7:服务注册中心-Consul单机环境构建_第11张图片

package com.example.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderConsulMain80.class, args);
    }
}

4.5、业务类

首先还是要配置restTemplate远程调用bean,然后调用服务提供模块得到结果:

Spring cloud入门-7:服务注册中心-Consul单机环境构建_第12张图片
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第13张图片

package com.example.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;

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}
package com.example.springcloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderConsulController {
    public static final String INVOKE_URL = "http://consul-provider-payment";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping(value = "/consumer/payment/consul")
    public String paymentInfo() {
        String result = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
        return result;
    }
}

4.6、测试

启动消费服务模块,查看consul注册中心,发现已成功注册消费服务模块:
cloud-consumer-order。
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第14张图片
其次,通过消费服务模块8080端口调用服务提供者的8006的接口,发现可以获取到服务提供者返回的数据:
Spring cloud入门-7:服务注册中心-Consul单机环境构建_第15张图片

5、三个注册中心的异同点

5.1、测试consul服务宕机

  在前几篇博文中,介绍了当服务宕机后,eureka会在一段时候(默认90s)之后才会移除服务,并且具有自我保护机制。而zookeeper在规定心跳时间后未收到心跳,则直接移除了。那么consul是哪种情况?
  接下来,将服务提供者停掉进行测试。如下图,当服务提供者宕机后,provider服务几秒后就被移除。
  Spring cloud入门-7:服务注册中心-Consul单机环境构建_第16张图片

5.2、CAP定理

  经过测试可以发现,当服务不可用时,eureka很在一段时间后,才会将服务移除。而zookeeper和consul则是在心跳周期内未收到心跳就会很快移除服务。
  接下来引出CAP定理:CAP定理指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可同时获得
  Spring cloud入门-7:服务注册中心-Consul单机环境构建_第17张图片

  • 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(所有节点在同一时间的数据完全一致,节点越多,数据同步越耗时)
  • 可用性(A):负载过大后,集群整体是否还能响应客户端的读写请求。(服务一直可用,而且是正常响应时间)
  • 分区容错性(P):分区容忍性,一个节点崩了,并不影响其它的节点(100个节点,挂了几个,不影响服务,机器越多越好)

  CAP定理提出三者不可同时获得的原因如下:

  • C A 满足的情况下,P不能满足的原因
    数据同步(C)需要时间,还要在正常的时间内响应(A),那么机器数量就要少,所以P就不满足
  • C P 满足的情况下,A不能满足的原因
    数据同步(C)需要时间,机器数量也多§,但是同步数据需要时间,所以不能在正常时间内响应,所以A就不满足
  • A P 满足的情况下,C不能满足的原因
    机器数量多§,正常的时间内响应(A),那么数据就不能及时同步到其他节点,所以C不满足

  在分布式系统中(机器数量多),由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡
  因此之前博文中介绍的Eureka注册中心就属于AP,即服务明明已经不可用了,但Eureka并没有移除,而是继续返回数据,保证了服务的可用性,但是降低了数据的一致性。
  而Zookeeper,Consul则属于CP,即心跳周期内检测到服务不可用了,就立刻移除服务。保证了数据一致性,但是服务可用性降低了。
  Eureka,Zookeeper,Consul三者的异同点如下:
  Spring cloud入门-7:服务注册中心-Consul单机环境构建_第18张图片

你可能感兴趣的:(spring,cloud,spring,cloud,consul,spring)