1. 程式人生 > >SpringCloud 學習(5):第一個Ribbon程式

SpringCloud 學習(5):第一個Ribbon程式

一、簡介

Ribbon是netflix公司的一個負載均衡框架,負載均衡就是分發請求,緩解單臺伺服器壓力。

二、Ribbon hello world

這篇文章主要通過寫一個簡單Ribbon程式,來了解一下Ribbon的原理。
第一個Ribbon程式包括以下內容:

  • 2個簡單的服務,埠分別為1001和1002
  • 1個client程式用來向伺服器傳送請求,測試負載均衡的效果

1.首先,新建專案Ribbon-service
pom.xml

     <dependencies>
         <dependency>
             <groupId
>
org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.3.RELEASE</version> </dependency> </dependencies>

2.配置檔案(這一步是為了啟動兩個不同埠的服務)
application.properties

spring.profiles.active
=dev #spring.profiles.active=pro

application-dev.properties:

server.port=1001

application-pro.properties:

server.port=1002

3.服務實現(這裡返回RequestURL是為了區分請求的伺服器):RibbonServiceControl.java

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController
; import javax.servlet.http.HttpServletRequest; @RestController public class RibbonServiceControl { @RequestMapping("hello") public String helloWorld(HttpServletRequest request){ return "Hello World Ribbon--"+request.getRequestURL(); } }

4.最後是sprongBoot啟動程式:Application.java

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}

5.新建專案:Ribbon-client
直接寫一個測試類:

import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.niws.client.http.RestClient;


public class test {

    public static void main(String[] args) throws Exception {
        ConfigurationManager.getConfigInstance().setProperty(
                "my-client.ribbon.listOfServers", "localhost:1001,localhost:1002");  //設定服務列表
        RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
        HttpRequest request = HttpRequest.newBuilder().uri("/hello").build();
        for(int i = 0; i < 10; i++) {
            HttpResponse response = client.executeWithLoadBalancer(request);
            String json = response.getEntity(String.class);
            System.out.println(json);
        }
    };
}

6.最後,先啟動2個服務,再執行測試類,可以看到如下效果,說明預設的負載均衡規則就是輪詢。
這裡寫圖片描述

7.當然,我們也可以修改負載均衡的規則
可選的策略如下:

策略型別 描述
RoundRobinRule 這條規則簡單地通過迴圈法選擇伺服器。它通常用作預設規則
BestAvailableRule 選擇一個最小的併發請求的server
AvailabilityFilteringRule 過濾掉那些因為一直連線失敗的被標記為circuit tripped的後端server,並過濾掉那些高併發的的後端server(active connections 超過配置的閾值)
WeightedResponseTimeRule 根據響應時間分配一個weight,響應時間越長,weight越小,被選中的可能性越低。
RetryRule 對選定的負載均衡策略機上重試機制。
RandomRule 隨機選擇一個server
ZoneAvoidanceRule 複合判斷server所在區域的效能和server的可用性選擇server

那麼,我們如何修改策略呢?
只需要修改5的測試程式碼即可:

import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.niws.client.http.RestClient;

public class test {

    public static void main(String[] args) throws Exception {
        ConfigurationManager.getConfigInstance().setProperty(
                "my-client.ribbon.listOfServers", "localhost:1001,localhost:1002");  //設定服務列表
        ConfigurationManager.getConfigInstance().setProperty(
                "my-client.ribbon.NFLoadBalancerRuleClassName", AvailabilityFilteringRule.class.getName()); //設定負載均衡規則

        RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
        HttpRequest request = HttpRequest.newBuilder().uri("/hello").build();
        for(int i = 0; i < 10; i++) {
            HttpResponse response = client.executeWithLoadBalancer(request);
            String json = response.getEntity(String.class);
            System.out.println(json);
        }
    };
}

8.當然,我們也可以自定義負載均衡規則,只需要實現IRule 介面即可:

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;

    public Server choose(Object key) { //自定義規則
        Random rm = new Random();
        int number = rm.nextInt(10);
        if(number < 2) {
            return lb.getAllServers().get(0);
        }else {
            return lb.getAllServers().get(1);
        }
    }

    public void setLoadBalancer(ILoadBalancer lb) {
        this.lb=lb;

    }

    public ILoadBalancer getLoadBalancer() {
        // TODO Auto-generated method stub
        return this.lb;
    }

}

然後測試類修改如下:


import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.niws.client.http.RestClient;

/**
 * @author:
 * @description:
 * @program: ribbon_service
 * @create: 2018-06-22 11:39
 **/
public class test {

    public static void main(String[] args) throws Exception {
        ConfigurationManager.getConfigInstance().setProperty(
                "my-client.ribbon.listOfServers", "localhost:1001,localhost:1002");  //設定服務列表
        ConfigurationManager.getConfigInstance().setProperty(
                "my-client.ribbon.NFLoadBalancerRuleClassName", Myrule.class.getName()); //自定義負載均衡規則

        RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
        HttpRequest request = HttpRequest.newBuilder().uri("/hello").build();
        for(int i = 0; i < 10; i++) {
            HttpResponse response = client.executeWithLoadBalancer(request);
            String json = response.getEntity(String.class);
            System.out.println(json);
        }
    };
}