SpringCloud入门学习之负载均衡(二)

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: SpringCloud入门学习之负载均衡(二)

负载均衡策略


Ribbon常见的负载均衡策略


// RoundRobinRule 轮询,默认策略,按序获取provider
// RandomRule 随机
// AvailabilityFilteringRule : 可用性敏感策略,会先过滤掉,跳闸,访问故障的服务~,对剩下的进行轮询~
// RetryRule : 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内进行,重试
//WeightedResponseTimeRule 权重轮询策略,根据每个Provider的响应时间分配一个权重,响应时间越长权重越小,被选中的可能性就越低,初次会使用轮询策略,直到分配好权重
//BestAvailableRule 最少并发数策略,选择正在请求中并发数量小的provider,除非这个provider在熔断中
复制代码


如果想要更换负载均衡策略,在本例中,需要修改服务消费者项目中的 MyConfig 配置文件,内容如下:


@Bean
    public IRule getRule(){
        return new RandomRule();
    }
复制代码


增加对 RandomRule 类的注入,使得 Ribbon 优先选择随机策略。


Ribbon自定义负载均衡策略


在实际生产中,我们可能需要根据公司实际需求设计专门的负载均衡策略,接下来我们来设计相关代码。


新建一个文件夹,结构如下:


7.jpg


模仿随机策略的类进行修改,自定义 MyRandomRule 类


public class MyRandomRule extends AbstractLoadBalancerRule {
    private int count = 0;  //每个服务执行次数
    private int providerNum = 0;    //当前哪个服务被执行
    public MyRandomRule(){
    }
    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;
            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
                List<Server> upList = lb.getReachableServers(); //获得活着的服务
                List<Server> allList = lb.getAllServers(); //获得全部的服务
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }
                //核心部分
//                int index = this.chooseRandomInt(serverCount);
//                server = (Server)upList.get(index);
                //我们定义属于自己的执行策略,目前我们有3个provider,那么决定每个provider执行3次,然后接着执行下一个provider
                if(count<3){
                    server = (Server)upList.get(providerNum);
                    count++;
                }else{
                    count = 0;
                    providerNum++;
                    if(providerNum>=serverCount){
                        providerNum = 0;
                    }
                    server = (Server)upList.get(providerNum);
                }
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
                    server = null;
                    Thread.yield();
                }
            }
            return server;
        }
    }
    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}
复制代码


RuleConfig


@Configuration
public class RuleConfig {
    @Bean
    public IRule getRule(){
        return new MyRandomRule();
    }
}
复制代码


最后在入口类上增加注解,启动该策略。


@SpringBootApplication
@EnableEurekaClient
//在微服务启动时去加载我们自定义的负载均衡策略
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = RuleConfig.class)
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}
复制代码


关于上述 myrule 文件夹的位置,原因在于:RuleConfig 不能在主应用程序上下文的@ComponentScan中,否则将由所有@RibbonClients共享。如果您使用@ComponentScan(或@SpringBootApplication),则需要采取措施避免包含(例如将其放在一个单独的,不重叠的包中,或者指定要在@ComponentScan)。


Feign


spring cloud feign 基于Netfix Feign实现,整合了spring cloud Ribbonspring cloud Hystrix, 是声明式的 web service 客户端,它让微服务之间的调用变得更简单了,类似 controller 调用 service。SpringCloud 集成了 Ribbon 和 Eureka,可在使用 Feign 时提供负载均衡的 http 客户端。


Feign能做什么


我们在上一节讲述 Ribbon 的使用时,利用它对 RestTemplate 的请求拦截来实现对依赖服务的接口调用,而 RestTemplate 已经实现了对 http 请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以我们需要针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用,模块化的代码重复出现在每一个客户端中,代码量会比较大。


比如我们之前案例中使用到的 springcloud-consumer-dept-80 项目,其中的 DeptConsumerController 类封装了对 http 请求的处理方法,如果我们此时再新建一个服务消费者,同样需要处理 dept 对象的相关逻辑,则需要复制一份 DeptConsumerController 代码。


而  spring cloud feign在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在spring cloud feign的实现下,我们只需创建一个接口并调用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了使用spring cloud ribbon时自动封装服务调用客户端的开发量。

实现



首先我们需要在 springcloud-api  项目中增加实现了 Feign 的接口类。


1、导入依赖


<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
</dependencies>
复制代码


2、增加一个 service 接口类


DeptFeignService


package com.msdn.service;
import com.msdn.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@Service
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptFeignService {
    @PostMapping("/dept/add")
    boolean addDept(@RequestBody Dept dept);
    @GetMapping("/dept/get/{id}")
    Dept queryDept(@PathVariable("id") long id);
    @GetMapping("/dept/list")
    List<Dept> queryAll();
}
复制代码


参考 springcloud-consumer-dept-80 项目新建一个名为  springcloud-consumer-dept-80-feign 的 maven 项目,大体内容不变,修改少许内容。


1、导入依赖


<dependencies>
    <dependency>
        <groupId>com.msdn</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</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-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
</dependencies>
复制代码


2、DeptConsumerController 文件


@RestController
public class DeptConsumerController {
    @Autowired
    DeptFeignService service;
    @RequestMapping("/consumer/dept/get/{id}")
    public Dept getDept(@PathVariable("id") long id) {
        return service.queryDept(id);
    }
    @RequestMapping("/consumer/dept/list")
    public List<Dept> queryAll() {
        return service.queryAll();
    }
    @RequestMapping(name = "/consumer/dept/add")
    public boolean addDept(Dept dept) {
        return service.addDept(dept);
    }
}
复制代码


3、入口类增加 EnableFeignClients 注解


@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignDeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(FeignDeptConsumer_80.class,args);
    }
} 
复制代码


4、启动3个注册中心,3个服务提供者,然后启动新的服务消费者,访问 http://localhost/consumer/dept/list,多次刷新该页面,发现 consumer 的调用顺序是按序执行的,即轮询策略。



相关实践学习
小试牛刀,一键部署电商商城
SAE 仅需一键,极速部署一个微服务电商商城,体验 Serverless 带给您的全托管体验,一起来部署吧!
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
hresh
+关注
目录
打赏
0
0
0
0
6
分享
相关文章
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
191 2
架构学习:7种负载均衡算法策略
四层负载均衡包括数据链路层、网络层和应用层负载均衡。数据链路层通过修改MAC地址转发帧;网络层通过改变IP地址实现数据包转发;应用层有多种策略,如轮循、权重轮循、随机、权重随机、一致性哈希、响应速度和最少连接数均衡,确保请求合理分配到服务器,提升性能与稳定性。
492 11
架构学习:7种负载均衡算法策略
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全
这篇博客文章详细介绍了Nginx的下载、安装、配置以及使用,包括正向代理、反向代理、负载均衡、动静分离等高级功能,并通过具体实例讲解了如何进行配置。
267 4
nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件,很全
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
358 5
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
nginx学习:配置文件详解,负载均衡三种算法学习,上接nginx实操篇
Nginx 是一款高性能的 HTTP 和反向代理服务器,也是一个通用的 TCP/UDP 代理服务器,以及一个邮件代理服务器和通用的 HTTP 缓存服务器。
296 0
nginx学习:配置文件详解,负载均衡三种算法学习,上接nginx实操篇
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
负载均衡策略:Spring Cloud与Netflix OSS的最佳实践
负载均衡策略:Spring Cloud与Netflix OSS的最佳实践
99 2
Nginx入门 -- 深入了解Nginx负载均衡
Nginx入门 -- 深入了解Nginx负载均衡
63 0
k8s学习--负载均衡器matelLB的详细解释与安装
k8s学习--负载均衡器matelLB的详细解释与安装
448 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等