(十二)spring-cloud入门学习:服务注册中心Consul

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/guangcaiwudong/article/details/96999533

由于eureka2.x停止维护了,当前spring cloud eureka使用的eureka 1.9.8,所以对当前一些spring cloud系统影响不大,但是spring cloud发展迅速,更新频率低或停更的组件注定会被淘汰。当然也有其他组件可以作为spring cloud注册中心,比如:Consul,Zookeeper,Kubernetes(k8s)。

Eureka与Consul最大的区别在于CAP:

  • Eureka是AP,强调可用性,尽可能的提供服务,不需要等注册信息 replicate 到其它节点,也不保证注册信息是否replicate成功当数据出现不一致时,虽然 A, B 上的注册信息不完全相同,但每个 Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求 A 查不到,但请求 B 就能查到。如此保证了可用性但牺牲了一致性。
  • Consul则是CP,强调一致性,服务注册相比 Eureka 会稍慢一些,Consul的raft协议要求必须过半数的节点都写入成功才认为注册成功 Leader 挂掉时,重新选举期间整个 Consul不可用。保证了强一致性但牺牲了可用性。

一、consul下载、安装、启动

下载地址:https://www.consul.io/downloads.html

单机启动命令:
consul agent -dev

可对端口进行修改:
{
“ports” : {
“dns” : 8600,
“http” : 8500,
“https” : -1,
“grpc” : -1,
“serf_lan” : 8301,
“serf_wan” : 8302,
“server” : 8300
}
}

指定配置文件目录启动:会自动加载配置目录下的json文件
consul agent -dev -config-dir=D:\software\consul\config

常用启动参数:
consul agent -server 表示以服务器模式启动代理。
-bootstrap-expect=3 表示节点个数为3个。
-node=consul-server-1 表示节点名称
-client=0.0.0.0 表示客户端 IP
-bind=10.0.0.1 表示服务端 IP
-datacenter=dc1 数据中心名称
-data-dir=/opt/consul 表示临时数据存储路径
-retry-join “10.0.0.1:8301” 加入集群,端口对用serf_lan

二、服务注册

1. 创建consul_producer工程,pom.xml引入consul,actuator用于心跳健康检查

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kevin</groupId>
    <artifactId>consul_producer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consul_producer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

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

</project>

2. application.properties

spring.application.name=consulProducer
server.port=9105

# consul地址
spring.cloud.consul.host=localhost
# consul端口
spring.cloud.consul.port=8500
# 服务注册到consul中的服务名,用于消费
spring.cloud.consul.discovery.serviceName=consulProducerName

3. ConsulProducerApplication.java开启服务发现

package com.kevin.consul_producer;

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

@SpringBootApplication
@EnableDiscoveryClient
public class ConsulProducerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsulProducerApplication.class, args);
    }

}

4. HelloController.java提供接口服务

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Value("${server.port}")
    private Integer serverPort;

    @RequestMapping("/sayHello")
    public String sayHello(){
        return "Hello consul, " + serverPort;
    }
}

5. 启动两个服务,端口分别为9106和9106,查看consul ui,发现服务已成功注册
在这里插入图片描述

三、服务消费

1. 创建consul_consumer工程,pom.xml引入

<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>

2. application.properties

spring.application.name=consulConsumer
server.port=9210

spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
# 不注册服务
spring.cloud.consul.discovery.register=false

3. ConsulConsumerApplication.java

package com.kevin.consul_consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsulConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsulConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

4. 调用服务HelloController.java

package com.kevin.consul_consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class HelloController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private LoadBalancerClient loadBalancer;

    @Autowired
    private RestTemplate restTemplate;

    // 通过服务名查询所有的服务信息
    @RequestMapping("/getProducer")
    public Object getProducer(){
        return discoveryClient.getInstances("consulProducerName");
    }

    // 通过服务名查询一个服务地址
    @RequestMapping("/getProducerUrl")
    public String getProducerUrl(){
        return loadBalancer.choose("consulProducerName").getUri().toString();
    }

    // 调用服务
    @RequestMapping("/sayHello")
    public String sayHello(){
        return restTemplate.getForObject("http://consulProducerName/sayHello", String.class);
    }
}

5. 启动测试

1)访问 http://127.0.0.1:9210/getProducer
在这里插入图片描述
2) 访问http://127.0.0.1:9210/getProducerUrl 会自动负载均衡
在这里插入图片描述
在这里插入图片描述
3)访问http://127.0.0.1:9210/sayHello 会自动负载均衡
在这里插入图片描述
在这里插入图片描述
四、使用Feign消费

1. pom.xml引入feign

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2. 启动Feign

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

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

3. 使用Feign调用远程服务

package com.kevin.consul_consumer.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(name="consulProducerName")
public interface HelloFeignService {

    @RequestMapping(value = "/sayHello")
    public String sayHello();
}

4. 对外接口

@RestController
public class HelloController {
    @Autowired
    private HelloFeignService helloFeignService;

    @RequestMapping("/sayHelloFeign")
    public String sayHelloFeign(){
        return helloFeignService.sayHello() + ", call by feign";
    }
}

5. 测试http://127.0.0.1:9210/sayHelloFeign
多次请求返回:
Hello consul, 9105, call by feign
Hello consul, 9106, call by feign

参考:
https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/multi/multi_spring-cloud-consul-discovery.html
http://www.ityouknow.com/springcloud/2018/07/20/spring-cloud-consul.html

猜你喜欢

转载自blog.csdn.net/guangcaiwudong/article/details/96999533
今日推荐