Spring Cloud系列教程(六):服务注册与发现Consul(Finchley版本)

﹏ヽ暗。殇╰゛Y 2023-07-07 08:02 27阅读 0赞

一、前言

在微服务领域,服务注册与发现是其中很重要的一个模块,主要用于服务治理问题;在分布式Dubbo中常用的服务发现与注册中心是ZookeeperCosul与其类似,在SpringCloud刚占领市场的时候,SpringCloud微服务框架默认使用的注册中心组建是Eureka,总所周知,Eureka已经开始闭源了,那么可以替代Eureka的有:ConsulZookeeper ,这两种比较常用,同样可以很好的与SpringCloud集成,用于替代Eureka,本篇就主要实现SpringCloud整合Consul实现服务注册与发现。

二、Consul是什么

Consul是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,采用 Go 语言开发。Consul内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案。由于出现得晚些,Consul具有功能完善、部署简单、使用方便等特点。

1. 使用Consul 的优势

  • 使用 Raft 算法来保证一致性, 比 ZooKeeper 的 Paxos 算法更简单直接。
  • 支持多数据中心,内外网的服务采用不同的端口进行监听。 ZooKeeper 和 etcd 均不提供多数据中心功能的- 支持。
  • 支持健康检查,etcd 不提供此功能。
  • 支持 http 和 dns 协议接口。ZooKeeper 的集成较为复杂,etcd 只支持 http 协议。
  • 官方提供 web 管理界面,etcd 无此功能。
  • Consul 1.2 新增 Service Mesh 解决方案。

2. Consul默认支持Ribbon负载均衡

在这里插入图片描述

三、Consul的安装

1. 下载安装

ConsulGo语言开发,因此也继承了Go语言跨平台,易安装的特点,支持WindwosLinuxmacOS,解压即可运行使用;以Windwos为例,去官网下载: https://www.consul.io/downloads.html , 解压后只有一个.exe文件。
在这里插入图片描述

2. 运行Consul

a. 启动Consul命令:

consul agent -dev -ui -node=cy

-dev开发服务器模式启动,-node结点名为cy-ui可以用界面访问,默认能访问。
在这里插入图片描述

b. 起始访问地址:
访问地址: http://localhost:8500
在这里插入图片描述

四、实现思路

启动Consul后,创建两个基于Consul的客户端服务工程,一个服务提供者和一个服务消费者,使用Feign进行服务消费,客户端配置连接运行的Consul服务,这里先贴一下项目完整结构图;
在这里插入图片描述

五、搭建服务提供者springcloud-consul-provider

1.引入pom依赖

  1. <!--SpringBoot依赖版本-->
  2. <parent>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-parent</artifactId>
  5. <version>2.0.3.RELEASE</version>
  6. <relativePath/>
  7. </parent>
  8. <!--项目编码、jdk版本、SpringCloud版本定义-->
  9. <properties>
  10. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  11. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  12. <java.version>1.8</java.version>
  13. <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
  14. </properties>
  15. <!--声明管理SpringCloud版本依赖信息-->
  16. <dependencyManagement>
  17. <dependencies>
  18. <dependency>
  19. <groupId>org.springframework.cloud</groupId>
  20. <artifactId>spring-cloud-dependencies</artifactId>
  21. <version>${ spring-cloud.version}</version>
  22. <type>pom</type>
  23. <scope>import</scope>
  24. </dependency>
  25. </dependencies>
  26. </dependencyManagement>
  27. <dependencies>
  28. <!-- SpringBootWeb组件 -->
  29. <dependency>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-starter-web</artifactId>
  32. </dependency>
  33. <!--springcloud整合consul组件-->
  34. <dependency>
  35. <groupId>org.springframework.cloud</groupId>
  36. <artifactId>spring-cloud-starter-consul-discovery</artifactId>
  37. </dependency>
  38. <!-- 引入Feign接口公共层-->
  39. <!--<dependency>-->
  40. <!--<groupId>com.thinkingcao</groupId>-->
  41. <!--<artifactId>springcloud-feign-interface</artifactId>-->
  42. <!--<version>0.0.1-SNAPSHOT</version>-->
  43. <!--</dependency>-->
  44. </dependencies>
  45. <!--maven插件-->
  46. <build>
  47. <plugins>
  48. <plugin>
  49. <groupId>org.springframework.boot</groupId>
  50. <artifactId>spring-boot-maven-plugin</artifactId>
  51. </plugin>
  52. </plugins>
  53. </build>

2. 启动类上加@EnableDiscoveryClient注解

  1. package com.thinkingcao.api;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. @SpringBootApplication
  6. @EnableDiscoveryClient
  7. public class AppMemerProvider {
  8. public static void main(String[] args) {
  9. SpringApplication.run(AppMemerProvider.class, args);
  10. }
  11. }

3. @EnableDiscoveryClient 与@EnableEurekaClient区别

  • @EnableDiscoveryClient注解是基于spring-cloud-commons依赖,并且在classpath中实现; 适合于consulzookeeper注册中心
  • @EnableEurekaClient注解是基于spring-cloud-netflix依赖,只能为eureka作用;

4. 修改application.yml

  1. ##=========服务生产者-会员服务配置========
  2. ##服务在7777端口暴露出来
  3. server:
  4. port: 8764
  5. ##配置Spring相关
  6. spring:
  7. ##应用服务名称,切记不能为下划线consul_member_provider,因为Feign不支持
  8. application:
  9. name: consul-member-provider
  10. ##consul注册中心地址
  11. cloud:
  12. consul:
  13. ##Consul所在主机ip
  14. host: localhost
  15. ##Consul监听的端口
  16. port: 8500
  17. discovery:
  18. ##配置开启服务注册到Consul上
  19. register: true
  20. ##配置注册到Consul的服务实例名称(Consul里Feign是通过此名称调用,而非spring.application.name)
  21. service-name: member-provider
  22. ##配置服务健康检查地址,供Consul调用
  23. healthCheckPath: /health
  24. ##Consul 健康检查频率
  25. healthCheckInterval: 15s

5. 提供会员接口ApiConsulMemberController

  1. package com.thinkingcao.api.controller;
  2. import org.springframework.beans.factory.annotation.Value;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestMethod;
  5. import org.springframework.web.bind.annotation.RequestParam;
  6. import org.springframework.web.bind.annotation.RestController;
  7. /** * @desc: 服务生产者(会员服务) * @author: cao_wencao * @date: 2020-02-22 23:44 */
  8. @RestController
  9. public class ApiConsulMemberController {
  10. @Value("${server.port}")
  11. private String serverPort;
  12. @RequestMapping(value="/getMember", method = RequestMethod.GET)
  13. private String getMember(@RequestParam("userName") String userName){
  14. return "我是会员服务,订单服务调用会员服务成功啦, 姓名为: " + userName + ", 端口为: " + serverPort;
  15. }
  16. }

6. Consul健康检查接口HealthCheckController

  1. package com.thinkingcao.api.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. /** * @desc: 提供给Consul健康检查的controller * @auth: cao_wencao * @date: 2020/2/23 0:08 */
  5. @RestController
  6. public class HealthCheckController {
  7. //RequestMapping中的url地址需和配置文件中保持一致
  8. @RequestMapping("/health")
  9. public String healthCheck() {
  10. return "ok";
  11. }
  12. }

7. 启动会员服务

启动springcloud-consul-provider项目,会发现项目实例 member-provider 注册到了 consul 中

在这里插入图片描述

六、搭建服务消费者springcloud-feign-consumer

1.引入pom依赖

  1. <!--SpringBoot依赖版本-->
  2. <parent>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-parent</artifactId>
  5. <version>2.0.3.RELEASE</version>
  6. <relativePath/>
  7. </parent>
  8. <groupId>com.thinkingcao</groupId>
  9. <artifactId>springcloud-feign-consumer</artifactId>
  10. <version>0.0.1-SNAPSHOT</version>
  11. <name>springcloud-feign-consumer</name>
  12. <description>SpringCloud整合Feign客户端组件消费服务</description>
  13. <properties>
  14. <java.version>1.8</java.version>
  15. <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
  16. </properties>
  17. <!--声明管理SpringCloud版本依赖信息-->
  18. <dependencyManagement>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.cloud</groupId>
  22. <artifactId>spring-cloud-dependencies</artifactId>
  23. <version>${ spring-cloud.version}</version>
  24. <type>pom</type>
  25. <scope>import</scope>
  26. </dependency>
  27. </dependencies>
  28. </dependencyManagement>
  29. <dependencies>
  30. <!-- SpringBootWeb组件 -->
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-starter-web</artifactId>
  34. </dependency>
  35. <!-- springcloud整合Feign客户端组件 -->
  36. <dependency>
  37. <groupId>org.springframework.cloud</groupId>
  38. <artifactId>spring-cloud-starter-openfeign</artifactId>
  39. </dependency>
  40. <!-- 引入Feign接口公共层-->
  41. <!--<dependency>-->
  42. <!--<groupId>com.thinkingcao</groupId>-->
  43. <!--<artifactId>springcloud-feign-interface</artifactId>-->
  44. <!--<version>0.0.1-SNAPSHOT</version>-->
  45. <!--</dependency>-->
  46. <!--springcloud整合consul组件-->
  47. <dependency>
  48. <groupId>org.springframework.cloud</groupId>
  49. <artifactId>spring-cloud-starter-consul-discovery</artifactId>
  50. </dependency>
  51. <!-- 健康检查 -->
  52. <dependency>
  53. <groupId>org.springframework.boot</groupId>
  54. <artifactId>spring-boot-starter-actuator</artifactId>
  55. </dependency>
  56. <!--lombok代码简化工具-->
  57. <dependency>
  58. <groupId>org.projectlombok</groupId>
  59. <artifactId>lombok</artifactId>
  60. </dependency>
  61. </dependencies>
  62. <build>
  63. <plugins>
  64. <plugin>
  65. <groupId>org.springframework.boot</groupId>
  66. <artifactId>spring-boot-maven-plugin</artifactId>
  67. </plugin>
  68. </plugins>
  69. </build>

2. 启动类添加注解

  • 在启动类添加@EnableFeignClients@EnableDiscoveryClient注解,表示启用Feign客户端调用和Consul服务注册与发现功能

    package com.thinkingcao.api;

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

    @SpringBootApplication
    @EnableFeignClients
    @EnableDiscoveryClient
    public class AppOrderConsumer {

    1. public static void main(String[] args) {
    2. SpringApplication.run(AppOrderConsumer.class, args);
    3. }

    }

3. 编辑application.yml

  1. ##=========服务消费者-订单服务配置========
  2. #服务端口号
  3. server:
  4. port: 8787
  5. ##配置Spring相关
  6. spring:
  7. ##服务名称
  8. application:
  9. name: consul-order_consumer
  10. ##consul注册中心地址
  11. cloud:
  12. consul:
  13. ##Consul所在主机ip
  14. host: localhost
  15. ##Consul监听的端口
  16. port: 8500
  17. discovery:
  18. ##配置注册到Consul的服务实例名称(Consul里Feign是通过此名称调用,而非spring.application.name)
  19. service-name: order-consumer
  20. ##配置服务健康检查地址,供Consul调用
  21. healthCheckPath: /health
  22. ##Consul 健康检查频率
  23. healthCheckInterval: 15s

4. 定义 Feign 接口IFeignClientService

  • 定义Feign接口时,其中@FeignClientvalueprovide 注册在 consul中的服务名。RequestMapping 对应 provider的具体映射。

    package com.thinkingcao.api.Feign;

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

    /* @desc: Feign声明式客户端调用工具 @author: cao_wencao @date: 2020-02-22 12:23 */
    @FeignClient(value = “member-provider”)
    public interface IFeignClientService {

    1. //通过userId查询会员信息数据
    2. @RequestMapping("/getMember")
    3. public String getOrderToMemberInfo(@RequestParam("userName") String userName);

    }

5. 定义Controller调用Feign接口

  1. package com.thinkingcao.api.controller;
  2. import com.thinkingcao.api.Feign.IFeignClientService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.cloud.client.discovery.DiscoveryClient;
  5. import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestMethod;
  8. import org.springframework.web.bind.annotation.RequestParam;
  9. import org.springframework.web.bind.annotation.RestController;
  10. /** * @desc: 服务消费者(订单服务) * @author: cao_wencao * @date: 2020-02-22 12:30 */
  11. @RestController
  12. public class ApiFeignOrderController {
  13. @Autowired
  14. private LoadBalancerClient loadBalancerClient;
  15. @Autowired
  16. private DiscoveryClient discoveryClient;
  17. // @Autowired
  18. // private OrderService orderService;
  19. @Autowired(required = false)
  20. private IFeignClientService feignClientService;
  21. //基于Feign实现订单调用会员 ,并且实现本地负载均衡
  22. @RequestMapping(value ="/getMemberInfo",method = RequestMethod.GET)
  23. public String getMemberInfo(@RequestParam("userName") String userName) {
  24. String memberInfo = feignClientService.getOrderToMemberInfo(userName);
  25. return memberInfo;
  26. }
  27. /** * 获取服务实例 */
  28. @RequestMapping(value = "/discover",method = RequestMethod.GET)
  29. public String discover(){
  30. String instance = loadBalancerClient.choose("member-provider").getUri().toString();
  31. return instance;
  32. }
  33. /** * 获取所有服务 */
  34. @RequestMapping("/services")
  35. public Object services() {
  36. return discoveryClient.getInstances("member-provider");
  37. }
  38. }

6. Consul健康检查接口HealthCheckController

  1. package com.thinkingcao.api.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. /** * @desc: 提供给Consul健康检查的controller * @auth: cao_wencao * @date: 2020/2/23 0:08 */
  5. @RestController
  6. public class HealthCheckController {
  7. //RequestMapping中的url地址需和配置文件中保持一致
  8. @RequestMapping("/health")
  9. public String healthCheck() {
  10. return "ok";
  11. }
  12. }

7. 启动订单服务

启动springcloud-feign-consumer项目,会发现项目实例 order-consumer注册到了 consul 中,这时候有两个服务都注册其中

在这里插入图片描述

七、测试

实现订单调用会员服务接口,为了测试Feign+Ribbon+Cosul实现负载均衡效果,需要启动两个会员提供者服务实例;启动会员服务两个实例后,稍等片刻。
在这里插入图片描述

  • 访问接口: http://127.0.0.1:8787/getMemberInfo?userName=“Thinkingcao”

这是浏览器交替显示结果:

我是会员服务,订单服务调用会员服务成功啦, 姓名为: “Thinkingcao”, 端口为: 8764
我是会员服务,订单服务调用会员服务成功啦, 姓名为: “Thinkingcao”, 端口为: 8765

在这里插入图片描述
在这里插入图片描述

  • 访问接口: http://127.0.0.1:8787/services ,获取服务列表信息在这里插入图片描述

八、项目源码

1. 项目源码: https://github.com/Thinkingcao/SpringCloudLearning/tree/master/springcloud-consul

七、SpringCloud系列教程

1.Spring Cloud系列教程(七): Spring Cloud系列教程(七):服务注册与发现ZooKeeper(Finchley版本)

SpringCloud教程汇总: Spring Cloud系列教程(汇总篇):专栏汇总篇(持续更新中)

发表评论

表情:
评论列表 (有 0 条评论,27人围观)

还没有评论,来说两句吧...

相关阅读