1. 程式人生 > >Ribbon負載均衡自定義實現

Ribbon負載均衡自定義實現

Ribbon簡介
負載均衡框架,支援可插拔式的負載均衡規則
支援多種協議,如HTTP、UDP等
提供負載均衡客戶端

Ribbon子模組
ribbon-core
ribbon-eureka
ribbon-httpclient

負載均衡器元件
一個負載均衡器,至少提供以下功能:
要維護各個伺服器的IP等資訊
根據特定邏輯選取伺服器
為了實現基本的負載均衡功能,Ribbon的負載均衡器有三大子模組:
Rule
Ping
ServerList

第一個Ribbon程式

實現第一個Ribbon程式
https://gitee.com/wangxuewaii/codes/ilk7sgcx2eozpbw04fh8t62

Ribbon負載均衡器

package com.example.demo;

import java.util.ArrayList;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;

@SpringBootApplication
public class RibbonUserApplication { public static void main(String[] args) { SpringApplication.run(RibbonUserApplication.class, args); BaseLoadBalancer lb = new BaseLoadBalancer(); ArrayList<Server> servers = new ArrayList<Server>(); servers.add(new
Server("localhost", 8080)); servers.add(new Server("localhost", 8081)); lb.addServers(servers); for (int i = 0; i < 10; i++) { Server server = lb.chooseServer(null); System.out.println(server); } } }
<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>ribbon-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>ribbon-user</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Edgware.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

自定義負載均衡器

繼承IRule

package com.example.demo;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;

public class MyRule implements IRule {

    private ILoadBalancer lb;

    @Override
    public Server choose(Object arg0) {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public ILoadBalancer getLoadBalancer() {
        // TODO Auto-generated method stub
        return this.lb;
    }
    @Override
    public void setLoadBalancer(ILoadBalancer lb) {
        this.lb=lb;
    }

}
package com.example.demo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;

@SpringBootApplication
public class RibbonUserApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonUserApplication.class, args);

        BaseLoadBalancer lb = new BaseLoadBalancer();
        MyRule rule = new MyRule();
        rule.setLoadBalancer(lb);
        lb.setRule(rule);

        List<Server> servers = new ArrayList<Server>();
        servers.add(new Server("localhost", 8080));
        servers.add(new Server("localhost", 8081));
        lb.addServers(servers);
        for (int i = 0; i < 10; i++) {
            Server s = lb.chooseServer(null);
            System.out.println(s);
        }
    }
}
自定義的隨機數大於7的就使用8081伺服器,小於7就用8080伺服器 
替換上面的MyRule ,別的不變

package com.example.demo;
import java.util.List;
import java.util.Random;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;

public class MyRule implements IRule {

    private ILoadBalancer lb;
    @Override
    public Server choose(Object arg0) {
        //自定義的隨機數大於7的就使用8081伺服器,小於7就用8080伺服器
        Random r = new Random();
        int rNum = r.nextInt(10);
        List<Server> servers = lb.getAllServers();
        if (rNum > 7) {
            return getServerByPort(servers, 8081);
        }
        return getServerByPort(servers, 8080);
    }

    private Server getServerByPort(List<Server> servers, int port) {
        for (Server s : servers) {

            if (s.getPort() == port) {
                return s;
            }

        }
        return null;
    }
    @Override
    public ILoadBalancer getLoadBalancer() {
        // TODO Auto-generated method stub
        return this.lb;
    }
    @Override
    public void setLoadBalancer(ILoadBalancer lb) {
        this.lb = lb;
    }

}

ribbon自定義負載均衡器實現,呼叫真正的服務實現

https://gitee.com/wangxuewaii/codes/knp01ylhsrj7x5miqb3uc49

Ribbon內建的負載均衡規則
RoundRobinRule
AvailabilityFilteringRule
WeightedResponseTimeRule
ZoneAvoidanceRule
BestAvailableRule
RandomRule
RetryRule