一篇文章带你详细学习:SpringCloud - Consul服务注册与配置中心以及LoadBalancer的组合使用,实现负载均衡!

本文介绍了如何在SpringBoot项目中集成Consul实现服务注册、配置中心管理和负载均衡,包括Consul的安装与配置、SpringCloud的依赖引入、服务发现机制、配置持久化以及不同负载均衡算法的应用。
摘要由CSDN通过智能技术生成

目录

1. 服务注册

1.1普通调用存在的问题

1.2.为什么要引入Consul服务注册

1.3.Consul的下载与安装

1.4 在SpringBoot中引入Consul

2. 配置中心

2.1 简述

 2.2 引入依赖

2.3 在resource目录下新建一个bootstrap.yml文件

2.4 打开Consul web管理面板建立相关配置

2.5 获取Consul中的配置

2.6 Consul 配置持久化和注册服务

3. Consul+LoadBalancer实现负载均衡

3.1 LoadBalancer介绍

3.2 LoadBalancer支持的远程调用方式

3.3 引入依赖

3.4 创建测试

3.5 手动切换负载均衡算法

3.6 负载均衡算法原理

3.6.1 轮询算法

3.6.2 随机算法


官网地址:Spring Cloud Consul

1. 服务注册

1.1普通调用存在的问题

  1. 当我们采用硬编码的方式(在代码中写死请求路径及访问地址)时,会产生一个问题:单独给我们被调用的服务的端口或者IP地址发生变化的时候,则需要手动修改代码中的内容
  2. 如果有多个同一服务:如多个订单微服务,普通的远程调用则无法实现负载均衡功能
  3. 如果系统需要支持更高的并发,则需要部署很多的微服务,在后续的维护过程中会变得很复杂

1.2.为什么要引入Consul服务注册

  1. 当我们端口或者IP地址变化时不需要手动去修改代码中的内容依旧能够正常访问(前提是微服务的服务名不变,通常是不会变的
  2. Consul可以实现负载均衡的功能,极大程度的提高了我们系统的高可用性和稳定性
  3. 便于后期的维护

1.3.Consul的下载与安装

  1. 下载地址:Consul下载地址

特别说明:

Windows系统的386指的是i386指的是intel80386,32位架构,amd64指的是amd的64位架构,新的指令集,支持64位系统,现在大部分电脑都是64位,所以直接下载AMD64即可

        2. 下载成功之后是一个压缩包,解压即可

       3. 解压之后里面是一个exe文件

        4. 在这里打开命令控制台输入以下命令即可查看consul版本以及启动consul服务

consul -v

consul agent -dev

        3. 为了方便可以在Path环境变量中配置consul的安装路径,即可在任意位置通过cmd打开consul

        4. 成功启动后在浏览器输入http://localhost:8500/

http://localhost:8500/

出现以下界面就表明consul安装成功

1.4 在SpringBoot中引入Consul

  1.  引入依赖,需要远程调用的微服务都需要引入该依赖
<!--SpringCloud consul discovery -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

        2.  在application.yml中编写配置

 服务A cloud-payment-service

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

服务B cloud-consumer-order

server:
  port: 80

spring:
  application:
    name: cloud-consumer-order
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}

        3. 服务B调用服务A

     我这里是使用的RestTemplate来进行远程调用



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

    @Bean
    @LoadBalanced //必须要加因为Consul默认有多个微服务
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

        4. 服务A cloud-payment-service

@RestController
@Tag(name = "支付微服务模块", description = "支付crud")
public class PayController {

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

}

        5. 服务B cloud-consumer-order

@RestController
public class OrderController {

    //    public static final String PaymentSrv_URL = "http://localhost:8001";//先写死,硬编码
    public static final String PaymentSrv_URL = "http://cloud-payment-service";//服务注册中心上的微服务名称

    @Resource
    private RestTemplate restTemplate;

    @GetMapping(value = "/test")
    public String test() {
        return restTemplate.getForObject(PaymentSrv_URL + "/test", String.class);
    }

}

 6. 分别启动服务A和服务B,必须要把consul给启动成功,启动成功之后可以在consul的web面板看到两个服务

        7. 在浏览器输入 http://localhost/test

        8. 至此我们服务注册就大功告成了

2. 配置中心

2.1 简述

微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。比如某些配置文件中的内容大部分都是相同的,只有个别的配置项不同。就拿数据库配置来说吧,如果每个微服务使用的技术栈都是相同的,则每个微服务中关于数据库的配置几乎都是相同的,有时候主机迁移了,我希望一次修改,处处生效。

 2.2 引入依赖

<!--SpringCloud consul config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

2.3 在resource目录下新建一个bootstrap.yml文件

bootstrap.yml的优先级要高于application.yml,当项目启动时会先加载bootstrap.yml中的配置,并且不会application.yml覆盖,所以需要同一管理的配置放在bootstrap.yml中。我这里只是为了演示就写得比较简单

bootstrap.yml

spring:
  application:
    name: cloud-payment-service
    ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
      config:
        profile-separator: '-' # consul默认是使用','分割,这里修改成'-'
        format: YAML
#        watch:
#          wait-time: 1  # consul默认动态刷新配置时间是55秒(当我们在consul中修改了配置之后需要等待55秒钟),不建议修改

 application.yml

server:
  port: 8002

# ==========applicationName + druid-mysql8 driver===================
spring:
  profiles:
    active: dev  # 后缀为dev

2.4 打开Consul web管理面板建立相关配置

consul当中配置文件需要存放在以下目录

config是文件夹,testApp,dev也是文件夹,consul默认是以‘,'分割,我在bootstrap.yml配置中修改成了‘-’,而testapp或者application就是我们项目名称,注意不是服务名称而是配置文件中的spring.application.name:,因为我们是激活的dev配置文件所以我们需要在consul中建立cloud-

config/payment-service-dev/文件夹

①建立config文件夹

②在config文件夹中建立cloud-payment-service-dev文件夹

③接下来就是需要在cloud-payment-service-dev文件夹中建立data的key-value键值对了key为data,value就是我们的配置信息

study:
 consul: very happy

配置就到此写完了,接下来我们就需要在服务中获取配置了

2.5 获取Consul中的配置


@RestController
@Tag(name = "支付微服务模块", description = "支付crud")
public class PayController {

    @GetMapping("/testGetInfo")
    public String testGetInfo(@Value("${study.consul}") String info) {
        return info;
    }

}

成功获取到配置信息

修改consul中的配置信息

然后等待55秒,或者修改bootstrap.yml中的

spring:
  application:
    name: cloud-payment-service
    ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
      config:
        profile-separator: '-' # default value is ",",we update '-'
        format: YAML
        watch:
          wait-time: 1  # consul默认动态刷新配置时间是55秒(当我们在consul中修改了配置之后需要等待55秒钟),不建议修改

然后再此访问即可看到动态更新了我们的配置信息(不需要重启我们的微服务)

至此我们配置中心就搭建好了

2.6 Consul 配置持久化和注册服务

当我们重启Consul服务的时候,会发现我们的配置全消失了,这肯定不是我们想要的那么如何将我们的配置进行持久化呢?如何让我们的Consul开机就启动呢?详细内容请见博主的另外一篇博客:

Consul 详细安装教程,以及配置持久化以及注册为服务详细教程-CSDN博客

3. Consul+LoadBalancer实现负载均衡

3.1 LoadBalancer介绍

LoadBalancer官网网址:Spring Cloud LoadBalancer :: Spring Cloud Commons

LoadBalancer是一个本地负载均衡客户端,Nginx是一个服务端负载均衡,他俩有什么区别呢?

  1. Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的。
  2. loadbalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

3.2 LoadBalancer支持的远程调用方式

LoadBalancer支持以下4中远程调用方式分别是

  1. RestTemplate
  2. RestClient
  3. WebClient
  4. WebFlux WebClient

3.3 引入依赖

在我们的调用者服务B中引入依赖(因为是客户端的负载均衡,我们这里的服务B cloud-consumer-order 就是我们的客户端

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

3.4 搭建多个微服务

在我们的项目中搭建两个服务A,这里就不一一演示了,把搭建的服务A复制一份改一下端口号即可,注意不能修改配置文件中的服务名称,不然就不认为是同一个服务了

3.4 创建测试

在两个服务A中添加以下代码

@RestController
@Tag(name = "支付微服务模块", description = "支付crud")
public class PayController {

    @Value("${server.port}")
    private String port;  //因为两个服务A的端口不一样则可以判断是调用了哪一个服务

    @GetMapping("/testGetPort")
    public String testGetPort() {
        return port;
    }

}
    

在服务B中添加以下代码

@RestController
public class OrderController {

    //    public static final String PaymentSrv_URL = "http://localhost:8001";//先写死,硬编码
    public static final String PaymentSrv_URL = "http://cloud-payment-service";//服务注册中心上的微服务名称

    @Resource
    private RestTemplate restTemplate;

     @GetMapping("/testGetPortOrder")
    public String testGetPort() {
        return restTemplate.getForObject(PaymentSrv_URL+ "/testGetPort", String.class);
    }

}

 RestTemplateConfig.java

@Configuration
public class RestTemplateConfig {

    
    @Bean
    @LoadBalanced //负载均衡算法 //默认轮询
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

多次请求 http://localhost:80/testGetPortOrder 发现一次8001端口,一次是8002端口这样轮询。因为LoadBalancer默认采用轮询的负载均衡算法

3.5 手动切换负载均衡算法

将轮询负载均衡算法切换成随机算法

修改RestTemplateConfig

@Configuration
@LoadBalancerClient(value = "cloud-payment-service",configuration = RestTemplateConfig.class)
public class RestTemplateConfig {

    //负载均衡算法
    //默认轮询
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    //随机
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);

        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }

}

重复3.4的操作发现每次返回的端口号是随机的,表明是随机访问两个服务A的

3.6 负载均衡算法原理

3.6.1 轮询算法

接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标  ,每次服务重启动后rest接口计数从1开始。

List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
如:   List [0] instances = 127.0.0.1:8002
   List [1] instances = 127.0.0.1:8001
8001+ 8002 组合成为集群,它们共计2台机器,集群总数为2, 按照轮询算法原理:

当总请求数为1时: 1 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001

当总请求数位2时: 2 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002

当总请求数位3时: 3 % 2 =1 对应下标位置为1 ,则获得服务地址为127.0.0.1:8001

当总请求数位4时: 4 % 2 =0 对应下标位置为0 ,则获得服务地址为127.0.0.1:8002

如此类推......

3.6.2 随机算法

随机算法的实现通常涉及使用随机数生成器来选择服务器。例如,可以通过生成一个随机数,然后使用这个数作为索引来从服务器列表中选择一个服务器。随机算法是一种简单的负载均衡策略,但需要通过改进,如引入服务器权重,来更有效地处理不同性能的服务器,以达到更均衡的负载分布。

立志用功如种树然,方其根芽,犹未有干;及其有干,尚未有枝;枝而后叶,叶而后花!!!!

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值