springcloud负载均衡Ribbon

springcloud负载均衡Ribbon

Ribbon的作用

​ 我们知道,微服务之间可以进行相互调用,我们一般把服务调用端称为消费者,而对于被调用端(提供者),可能存在多个,这时候需要一套算法去决定具体调用哪个服务,而Ribbon就起着这个作用,它能够把消费者请求分散在不同的服务上,起到负载均衡的作用。

1.定义三个微服务提供者,一个消费者,一个注册中心

image-20201014173228169

2.8001的代码如下

image-20201014173546943

@RestController
public class DeptController {

    @Autowired
    DeptService deptService;

    @Autowired
    DiscoveryClient discoveryClient;

    @RequestMapping("/dept/add")
    public boolean addDept(Dept dept) {
        return deptService.addDept(dept);
    }

    @RequestMapping("/dept/get/{id}")
    public Dept queryDeptById(@PathVariable("id") int id) {
        return deptService.queryDeptById(id);
    }

    @RequestMapping("/dept/list")
    public List<Dept> queryAllDept() {
        return deptService.queryAllDept();
    }

    @RequestMapping("/dept/discovery")
    public Object discovery() {
        //获取注册的服务列表清单
        List<String> services = discoveryClient.getServices();
        System.out.println("所有注册的服务为:"+services);

        List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-provider-dept");

        for (ServiceInstance instance : instances) {

            System.out.println(
                    instance.getHost()+"/t"+
                    instance.getPort()+"/t"+
                    instance.getUri()+"/t"+
                    instance.getServiceId() );
        }

        return this.discoveryClient;
    }
}
@Mapper
@Repository
public interface DeptDao {

    public boolean addDept(Dept dept);

    public Dept queryDeptById(int id);

    public List<Dept> queryAllDept();
}
public interface DeptService {

    public boolean addDept(Dept dept);

    public Dept queryDeptById(int id);

    public List<Dept> queryAllDept();
}
@Service
public class DeptServiceImpl implements  DeptService {

    @Autowired
    DeptDao deptDao;

    public boolean addDept(Dept dept) {
        return deptDao.addDept(dept);
    }

    public Dept queryDeptById(int id) {
        return deptDao.queryDeptById(id);
    }

    public List<Dept> queryAllDept() {
        return deptDao.queryAllDept();
    }
}
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class Provider_dept_8001 {
    public static void main(String[] args) {
        SpringApplication.run(Provider_dept_8001.class,args);
    }

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huang.dao.DeptDao">


    <insert id="addDept" parameterType="Dept">

        insert into dept(dname,db_source)
        values (#{dname},DATABASE())
   </insert>

    <select id="queryDeptById" resultType="Dept" parameterType="int">
       select * from  dept where  dno = #{dno}
    </select>


    <select id="queryAllDept" resultType="Dept" >
       select * from  dept
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
      </settings>
</configuration>
server:
  port: 8001

mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml
  type-aliases-package: com.huang.pojo
  config-location: classpath:mybatis/mybatis-config.xml

spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    username: root
    password: 123456
    url: jdbc:mysql://192.168.43.155:3306/db01?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true

#配置注册中心
eureka:
  client:
    service-url:
       defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept8001  #修改eureka上的默认描述信息


info:
   app.name: testProvider
   company.name: testProvider
<?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>spring-cloud</artifactId>
        <groupId>com.huang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-provider-dept-8001</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.huang</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--日志-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>

        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>

        </dependency>
        <!--数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <!--jetty-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
    </dependencies>
</project>

2.消费者和注册中心代码已经在springcloud注册中心eureka和SpringCloud 消费者和提供者这两篇文章中给出,这里不在提供。对于消费者需要改动的地方如下图

image-20201014174741596

image-20201014174931458

3.测试

image-20201014175134813

每次访问发现页面数据随机来源于不同的库,说明负载均衡成功了

自定义负载均衡算法

​ springcloud已经提供了很多中负载均衡算法,也可以自定义算法

系统提供的算法

image-20201014175627254

自定义算法

1.自定义算法相关代码不能放在和启动类相同的包下

image-20201014175850616

2.代码如下(每个服务访问五次再访问下一个)

public class MyRule extends AbstractLoadBalancerRule {


    public MyRule() {
    }

    private  int total=0;
    private int indexCur=0;

    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;
                }

                if(total<=5){
                    server=allList.get(indexCur);
                    total++;
                }else {
                    total=0;
                    indexCur++;
                    if(indexCur>allList.size()-1){
                        indexCur=0;
                    }
                    server=allList.get(indexCur);
                }

                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) {
    }
}
@Configuration
public class MyRuleConfig {

    @Bean
    public IRule myRule(){
        return  new MyRule();
    }
}

3.启动类上需要加上相关注解

image-20201014180105963

4测试访问就会走自定义的负载均衡算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Cloud负载均衡Ribbon是一种客户端负载均衡工具,它可以将请求分发到多个服务提供者实例中,从而提高系统的可用性和性能。Ribbon可以根据不同的负载均衡策略来选择服务提供者,例如轮询、随机、加权轮询等。同时,Ribbon还支持服务发现和服务注册,可以自动地从服务注册中心获取可用的服务实例列表。在Spring Cloud微服务架构中,Ribbon是非常重要的一部分,它可以帮助我们构建高可用、高性能的微服务系统。 ### 回答2: Spring Cloud 负载均衡Ribbon 是一个在客户端上运行的组件,可以在目标服务之间分配传入请求,以降低每个服务的负载。Ribbon 提供了多种负载均衡策略,包括简单轮询、随机、使用可用性统计数据等。 在实践中,Ribbon 可以轻松地集成到 Spring Cloud 应用中,通过配置文件中的特殊前缀“@LoadBalanced”来激活负载均衡服务。Spring Cloud 应用可以使用 Ribbon 来调用其他 REST 服务,而不用担心网络瓶颈和性能问题。 使用 Ribbon 进行负载均衡的最大好处是其透明的实现,使得客户端无需感知分配策略的变化。具体来说,当使用 Ribbon 负载均衡时,客户端可以轮流使用不同的目标服务,而无需编写特定的代码。Ribbon 为开发人员提供了一致的抽象层,以便简化分配策略和请求转发的实现。 Ribbon 作为 Spring Cloud 的核心组件之一,可以与其他重要的云基础设施服务进行集成,例如 Eureka 服务注册、Zookeeper 服务发现和 Consul 网格。通过这种方式,Ribbon 可以很容易地在多个云基础设施服务之间进行切换和部署。此外,Ribbon 还支持快速故障转移和自动重试机制,以确保应用程序可以在单个节点或整个系统故障时保持高可用性。 ### 回答3: Spring Cloud是一个基于Spring Boot实现的云原生应用开发框架,其中Spring Cloud Ribbon是其核心组件之一,提供了负载均衡的功能。 在传统的架构中,为了保证高可用性和可扩展性,常常需要多个相同的应用实例来处理用户请求,这时候就需要使用负载均衡来将请求均匀地分配到各个实例上。Spring Cloud Ribbon就是为了实现这个目的而设计的。 Ribbon可以将所有服务实例看作是一个整体,通过算法(一般为轮询算法)将请求分配给各个实例,从而实现负载均衡Ribbon内部维护了一个可用服务实例列表,当有服务实例启动或宕机时,它会实时更新列表,保证了服务的动态感知和适应。 Ribbon还提供了一些负载均衡策略,比如轮询(Round Robin)、随机(Random)、最少连接(Least Connection)等,可以根据具体业务来选择不同的策略。 在Spring Cloud中,使用Ribbon进行负载均衡非常简单,只需要加上@LoadBalanced注解,就可以实现自动的负载均衡。具体步骤如下: 1. 引入spring-cloud-starter-ribbon依赖 2. 创建RestTemplate实例,并添加@LoadBalanced注解 3. 像普通的RestTemplate一样使用其get、post等方法发起请求即可 最后,需要注意的是,Ribbon只是一种负载均衡的实现方式,而且还有其它的负载均衡框架可以选择,比如Nginx、HAProxy等。选择哪种负载均衡框架,需要根据具体业务需求、系统规模等综合考虑。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值