SpringCloud+Consul服务注册+服务发现实战

一、介绍

Consul是一个服务网格解决方案,提供了一个功能齐全的控制平面,具有服务发现、配置和分段功能。这些功能中的每一项都可以根据需要单独使用,也可以一起使用来构建一个完整的服务网格。-- 引用自Consul中文文档

在基于SpringCloud的微服务架构中,Consul用来做服务注册、服务发现、配置中心等功能。平替的解决方案还有Nacos、Zookeeper等等。

本文主要是将Consul服务注册+服务发现集成进SpringCloud项目中。

二、下载安装

1、以Windows环境为例,下载压缩包

2、解压后运行命令,启动Consul面板

r 复制代码
PS F:\wwwroot\consul_1.17.1_windows_amd64> .\consul.exe agent -dev

命令行结果如下:

打开浏览器查看面板,链接:http://localhost:8500/

可以看到面板已经成功启动了

三、开始撸代码

新建spring-cloud父工程,工程pom文件如下:

xml 复制代码
<?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>

    <groupId>zhu.bruce.springcloud</groupId>
    <artifactId>spring-cloud</artifactId>
    <version>${revision}</version>
    <packaging>pom</packaging>
    <modules>
        <module>jd-consul</module>
        <module>user-consul</module>
    </modules>

    <properties>
        <revision>1.0-SNAPSHOT</revision>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <lombok.version>1.18.24</lombok.version>
        <maven.spring.boot.verison>2.3.0.RELEASE</maven.spring.boot.verison>
        <spring-boot.version>2.7.14</spring-boot.version>
        <spring-cloud.version>2021.0.5</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${maven.spring.boot.verison}</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

这里,我们选用springboot2.7.14版本、springcloud2021.0.5版本。springboot与springcloud的版本对应关系如下,如果配置错误,会出现意想不到的错误

父工程的依赖包也很简约,主要是把springboot和springcloud组件的依赖清单加入依赖管理。

接下来新建jd-consul和user-consul子模块

jd-consul模块的pom文件如下

xml 复制代码
<?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>zhu.bruce.springcloud</groupId>
        <artifactId>spring-cloud</artifactId>
        <version>${revision}</version>
    </parent>

    <artifactId>jd-consul</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 基于Spring Boot的Web应用程序 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 提供HTTP端点的系统监控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Netflix Ribbon废弃后,SpringCloud官方的负载均衡组件 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>
        <!-- Consul服务注册+发现 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

在jd-consul模块中resources目录下,新建application.yml与application-dev.yml。springboot的配置文件与多环境配置,这里不再赘述。

application.yml

yaml 复制代码
server:
  port: 8040
spring:
  application:
    name: jd-consul-service
  profiles:
    active: dev

application-dev.yml

yaml 复制代码
spring:
  cloud:
    consul:
      host: 127.0.0.1
      # consul面板的默认端口
      port: 8500
      discovery:
        service-name: ${spring.application.name}

接下来新建启动类JDConsulApplication,加载好依赖包后,就可以启动了。jd-consul模块的文件目录结构如下:

启动成功之后,再次打开consul面板,http://localhost:8500/,就可以看到jd-consul服务已经成功注册上去了

同理,user-consul模块也如法炮制即可。到此,consul的服务注册就撸好了。

接下来,我们把jd-consul服务作为服务消费者,user-consul作为服务提供者。也就是jd-consul向user-consul发起服务调用,直白点说就是:user写个api,jd去调用

user-consul写个简单的api,UserConsulController如下:

kotlin 复制代码
package zhu.bruce.springcloud.userConsul.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/userConsul")
@Slf4j
public class UserConsulController {
    @GetMapping(value = "/{id}")
    public String query(@PathVariable("id") String id) {
        return id;
    }
}

jd-consul发起调用:

简单点的话,在jd模块下,可以用ip:port的方式直接访问user的api,比如:127.0.0.1:8030/userConsul/100。但是这样就发挥不了服务发现的作用了,这里我们换个方式,采用springcloud官方的客户端负载均衡器。它支持http://这种方式来访问api

这里我们引入RestTemplate组件作为Http客户端,平替的解决方案还有OkHttp、Apache的HttpClient、以及OpenFeign。OpenFeign是比较流行且优雅的Http客户端,我们后面也会专门开专题讲解。

客户端负载均衡器组件,SpringCloud Loadbalancer在上述pom文件中已经引入。它可以配合RestTemplate组件使用,实现负载均衡,方式也很简单,在RestTemplate组件上添加@LoadBalanced注解即可:

kotlin 复制代码
package zhu.bruce.springcloud.jdConsul.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 JDConsulConfiguration {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

开始发起调用,JDConsulController:

kotlin 复制代码
package zhu.bruce.springcloud.jdConsul.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@RequestMapping("/jdConsul")
public class JDConsulController {
    public static final String USER_CLOUD_URL = "http://user-consul-service/userConsul";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping(value = "/user/{id}")
    public String queryUser(@PathVariable("id") String id) {
        ResponseEntity<String> entity = restTemplate.getForEntity(USER_CLOUD_URL + "/" + id, String.class);
        return entity.getBody();
    }
}

接口调用结果如下:

结束!

一个简单的,SpringCloud+Consul服务注册+服务发现,宣告完成。

源代码已上传Gitee。仓库地址:gitee.com/bruce_chu/s...,分支:develop

千里之行始于足下,每天紧握一颗稻草,最后就会长出参天大树。喜欢的朋友可以关注/赞赏一下,你的鼓励将给我莫大的动力!

相关推荐
Rain的Java大神之路2 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
需要8266 小时前
MySQL 索引 B+ 树与“查询为什么变慢了
java·spring boot·spring·spring cloud·tomcat
需要82610 小时前
Arthas 一个命令排查线上问题
java·jvm·spring·spring cloud
苏渡苇1 天前
Spring Insight 里如何把 Span 画成瀑布时间线
后端·spring·spring cloud·springboot·监控·apm
叶总没有会1 天前
Nacos—注册中心
spring cloud·微服务
苏渡苇3 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring·spring cloud·系统监控·apm
叶总没有会3 天前
微服务--分布式基础
java·spring·spring cloud·微服务
孙启超3 天前
【AI开发之Rust】第 7 课:错误处理 —— panic、Result 与 `?`
人工智能·分布式·后端·爬虫·spring cloud·架构·rust
行百里er4 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring cloud·监控
砍材农夫5 天前
spring|spring web|拦截器、过滤器、aop
java·spring boot·spring·spring cloud