• SpringCloud无介绍快使用,Ribbon负载均衡工具与OpenFeign的使用(十五)


    SpringCloud无介绍快使用,Ribbon负载均衡工具与OpenFeign的使用(十五)

    问题背景

    从零开始学springcloud微服务项目
    注意事项:

    • 约定 > 配置 > 编码
    • IDEA版本2021.1
    • 这个项目,我分了很多篇章,每篇文章一个操作步骤,目的是显得更简单明了
    • controller调service,service调dao
    • 项目源码以及sentinel安装包

    Ribbon负载均衡

    1 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具

    • Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用
    • Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等
    • 在配置文件中列出LoadBalancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法

    2 集中式LB

    • 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方

    3 进程内LB

    • 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后再从这些地址中选择出一个合适的服务器
    • Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址

    4 Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别

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

    5 Ribbon在工作时分成两步

    • 第一步先选择 EurekaServer ,它优先选择在同一个区域内负载较少的server
    • 第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权
    • Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例

    6 前面几个篇章就是使用了Ribbon负载均衡,RestTemplate+@LoadBalanced实现负载均衡,使用依赖包含在Eureka-client中

    <!--eureka-client-->
    <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    OpenFeign默认使用Ribbon做负载均衡

    1 OpenFeign集成了Ribbon

    • 利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
      2 新增module

      3 选择jdk1.8

      4 输入服务名:cloud-consumer-feign-order80

    5 复制cloud-consumer-order80到cloud-consumer-feign-order80
    更改pom依赖

    <?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">
        <parent>
            <artifactId>springcloud2022</artifactId>
            <groupId>com.yg</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-consumer-feign-order80</artifactId>
    
        <dependencies>
            <!--openfeign-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            <!--eureka-client-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
                <groupId>com.yg</groupId>
                <artifactId>cloud-api-commons</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    更改application文件,添加超时连接控制和日志增强

    server:
      port: 80
    
    
    spring:
      application:
        name: cloud-consumer-order
    
    
    eureka:
      client:
        #表示是否将自己注册进EurekaServer默认为true。
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
        fetchRegistry: true
        service-url:
          #defaultZone: http://localhost:7001/eureka
          defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
      instance:
        instance-id: order80
        prefer-ip-address: true     #访问路径可以显示IP地址
    
    #设置feign客户端超时时间(OpenFeign默认支持ribbon)
    ribbon:
      #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
      ReadTimeout: 5000
      #指的是建立连接后从服务器读取到可用资源所用的时间
      ConnectTimeout: 5000
    
    logging:
      level:
        # feign日志以什么级别监控哪个接口
        com.yg.springcloud.service.PaymentFeignService: debug
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    更改启动类

    package com.yg.springcloud;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    /**
     * @Author suolong
     * @Date 2022/6/15 15:10
     * @Version 2.0
     */
    @EnableEurekaClient
    @EnableFeignClients
    @SpringBootApplication
    public class FeignMainApp80 {
    
        public static void main(String[] args) {
            SpringApplication.run(FeignMainApp80.class);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    添加openFeign的日志打印配置

    package com.yg.springcloud.config;
    
    import feign.Logger;
    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;
    
    /**
     * @Author suolong
     * @Date 2022/6/15 20:53
     * @Version 2.0
     */
    @Configuration
    public class ApplicationContextConfig {
    
        @Bean
        @LoadBalanced // 使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
        public RestTemplate restTemplate()
        {
            return new RestTemplate();
        }
    
    
        @Bean
        Logger.Level feignLoggerLevel()
        {
            return Logger.Level.FULL;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    更改controller

    package com.yg.springcloud.controller;
    
    import com.yg.springcloud.entities.CommonResult;
    import com.yg.springcloud.entities.Payment;
    import com.yg.springcloud.service.PaymentFeignService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import javax.annotation.Resource;
    
    /**
     * @Author suolong
     * @Date 2022/6/15 20:54
     * @Version 2.0
     */
    
    @RestController
    public class OrderController {
    
    
        //public static final String PaymentSrv_URL = "http://localhost:8001";
        public static final String PaymentSrv_URL = "http://CLOUD-PAYMENT-SERVICE";
    
    
        @Autowired
        private RestTemplate restTemplate;
    
    
        @Resource
        private PaymentFeignService paymentFeignService;
    
        @GetMapping(value = "/consumer/feign/get/{id}")
        public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id)
        {
            return paymentFeignService.getPaymentById(id);
        }
    
        @GetMapping("/consumer/payment/create") //客户端用浏览器是get请求,但是底层实质发送post调用服务端8001
        public CommonResult create(Payment payment) {
            return restTemplate.postForObject(PaymentSrv_URL + "/payment/create", payment, CommonResult.class);
        }
    
    
        @GetMapping("/consumer/payment/get/{id}")
        public CommonResult getPayment(@PathVariable Long id) {
            return restTemplate.getForObject(PaymentSrv_URL + "/payment/get/" + id, CommonResult.class, id);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    添加feign调用

    package com.yg.springcloud.service;
    
    import com.yg.springcloud.entities.CommonResult;
    import com.yg.springcloud.entities.Payment;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     * @Author suolong
     * @Date 2022/6/19 15:06
     * @Version 2.0
     */
    @Component
    @FeignClient(value = "cloud-payment-service")
    public interface PaymentFeignService {
    
        @GetMapping(value = "/payment/get/{id}")
        CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6 整体目录结构

    7 postman测试:http://localhost/consumer/feign/get/1

    • 8001和8002服务器交替出现,说明openfeign自带ribbon负载均衡
    • 消费方也打印详细feign调用的日志
    2022-06-19 15:25:02.356 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] ---> GET http://cloud-payment-service/payment/get/1 HTTP/1.1
    2022-06-19 15:25:02.356 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] ---> END HTTP (0-byte body)
    2022-06-19 15:25:02.469  INFO 34144 --- [p-nio-80-exec-2] c.netflix.config.ChainedDynamicProperty  : Flipping property: cloud-payment-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    2022-06-19 15:25:02.496  INFO 34144 --- [p-nio-80-exec-2] c.n.u.concurrent.ShutdownEnabledTimer    : Shutdown hook installed for: NFLoadBalancer-PingTimer-cloud-payment-service
    2022-06-19 15:25:02.496  INFO 34144 --- [p-nio-80-exec-2] c.netflix.loadbalancer.BaseLoadBalancer  : Client: cloud-payment-service instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=cloud-payment-service,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
    2022-06-19 15:25:02.501  INFO 34144 --- [p-nio-80-exec-2] c.n.l.DynamicServerListLoadBalancer      : Using serverListUpdater PollingServerListUpdater
    2022-06-19 15:25:02.518  INFO 34144 --- [p-nio-80-exec-2] c.netflix.config.ChainedDynamicProperty  : Flipping property: cloud-payment-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    2022-06-19 15:25:02.518  INFO 34144 --- [p-nio-80-exec-2] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client cloud-payment-service initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=cloud-payment-service,current list of Servers=[10.2.0.85:8001, 10.2.0.85:8002],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;	Instance count:2;	Active connections count: 0;	Circuit breaker tripped count: 0;	Active connections per server: 0.0;]
    },Server stats: [[Server:10.2.0.85:8002;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
    , [Server:10.2.0.85:8001;	Zone:defaultZone;	Total Requests:0;	Successive connection failure:0;	Total blackout seconds:0;	Last connection made:Thu Jan 01 08:00:00 CST 1970;	First connection made: Thu Jan 01 08:00:00 CST 1970;	Active Connections:0;	total failure count in last (1000) msecs:0;	average resp time:0.0;	90 percentile resp time:0.0;	95 percentile resp time:0.0;	min resp time:0.0;	max resp time:0.0;	stddev resp time:0.0]
    ]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@27468f17
    2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] <--- HTTP/1.1 200 (219ms)
    2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] connection: keep-alive
    2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] content-type: application/json
    2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] date: Sun, 19 Jun 2022 07:25:02 GMT
    2022-06-19 15:25:02.575 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] keep-alive: timeout=60
    2022-06-19 15:25:02.576 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] transfer-encoding: chunked
    2022-06-19 15:25:02.576 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] 
    2022-06-19 15:25:02.577 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] {"code":200,"message":"查询成功哈: 8001","data":{"id":1,"serial":"abc"}}
    2022-06-19 15:25:02.577 DEBUG 34144 --- [p-nio-80-exec-2] c.y.s.service.PaymentFeignService        : [PaymentFeignService#getPaymentById] <--- END HTTP (77-byte body)
    2022-06-19 15:25:03.519  INFO 34144 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: cloud-payment-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    SpringCloud无介绍快使用,Seata处理分布式事务(二十五)
    SpringCloud无介绍快使用,sentinel服务熔断功能(二十四)
    SpringCloud无介绍快使用,sentinel注解@SentinelResource的基本使用(二十三)
    SpringCloud无介绍快使用,sentinel热点key限流与系统规则的基本使用(二十二)
    SpringCloud无介绍快使用,sentinel熔断降级和限流的基本使用(二十一)
    SpringCloud无介绍快使用,Nacos集群和Nginx代理(二十)
    SpringCloud无介绍快使用,nacos配置中心的基本使用(十九)
    SpringCloud无介绍快使用,nacos注册中心的基本使用(十八)
    SpringCloud无介绍快使用,gateway通过微服务名实现动态路由(十七)
    SpringCloud无介绍快使用,gateway的基本使用(十六)
    SpringCloud无介绍快使用,Ribbon负载均衡工具与OpenFeign的使用(十五)
    SpringCloud无介绍快使用,使用Zookeeper替换Eureka服务注册与发现(十四)
    SpringCloud无介绍快使用,服务发现Discovery和Eureka自我保护(十三)
    SpringCloud无介绍快使用,集群cloud-provider-payment8002搭建(十二)
    SpringCloud无介绍快使用,集群Eureka服务注册中心cloud-eureka-server7002搭建(十一)
    SpringCloud无介绍快使用,单机Eureka服务注册中心cloud-eureka-server7001搭建(十)
    SpringCloud无介绍快使用,新建cloud-api-commons公共模块module(九)
    SpringCloud无介绍快使用,新建子module消费者订单模块(八)
    SpringCloud无介绍快使用,热部署devtools配置(七)
    SpringCloud无介绍快使用,子module提供者支付微服务业务开发(六)
    SpringCloud无介绍快使用,新建子module提供者支付微服务yml整合和新建启动类(五)
    SpringCloud无介绍快使用,新建子module提供者支付微服务pom整合(四)
    SpringCloud无介绍快使用,springcloud父工程pom文件整理(三)
    SpringCloud无介绍快使用,IDEA新建springcloud父工程(二)
    SpringCloud无介绍快使用,与Spingboot之间的兼容版本选择(一)




    作为程序员第 182 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha …

    Lyric: 土耳其冰淇淋 就像是女人的心

  • 相关阅读:
    【Verilog教程】2.1基本语法
    死锁的常见例子及 Python 模拟
    什么是研发效能DevOps?研发效能方程式又是什么?
    不要只成为PID调参工程师
    一文读懂——全局注意力机制(global attention)详解与代码实现
    安全 开发 自己想搭建一个靶场
    Python集合类型详解(二)——集合处理方法与应用场景
    kotlin使用教程
    HTML问题
    Web UI自动化测试框架
  • 原文地址:https://blog.csdn.net/cucgyfjklx/article/details/125434831