1. 程式人生 > >淺談SpringCloud (三) Ribbon負載均衡

淺談SpringCloud (三) Ribbon負載均衡

就會 rul back alt build 算法 實例 app creat

什麽是負載均衡

當一臺服務器的單位時間內的訪問量越大時,服務器壓力就越大,大到超過自身承受能力時,服務器就會崩潰。為了避免服務器崩潰,讓用戶有更好的體驗,我們通過負載均衡的方式來分擔服務器壓力。

我們可以建立很多很多服務器,組成一個服務器集群,當用戶訪問網站時,先訪問一個中間服務器,在讓這個中間服務器在服務器集群中選擇一個壓力較小的服務器,然後將該訪問請求引入該服務器。如此以來,用戶的每次訪問,都會保證服務器集群中的每個服務器壓力趨於平衡,分擔了服務器壓力,避免了服務器崩潰的情況。

Ribbon

  Spring Cloud Ribbons是基於Netflix Ribbon實現的一套客戶端負載均衡的工具。

  Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API網關那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因為微服務間的調用,API網關的請求轉發等內容,實際上都是通過Ribbon來實現的,包括後續我們將要介紹的Feign,它也是基於Ribbon實現的工具。所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。技術分享圖片

SpringCloud使用Ribbon

1.修改客戶端的pom.xml文件

<?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>springclouddemo</artifactId> <
groupId>com.aomeibox</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>customer-order</artifactId> <name>customer-order</name> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>1.4.0.RELEASE</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> <!-- Ribbon 相關--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>1.1.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> </dependencies> </project>

2.修改客戶端的MyConfig類

package com.aomeibox.config;

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;

/**
 * Created by jl on 2018/12/27.
 */
@Configuration
public class MyConfig {

    @Bean
    @LoadBalanced  //負載均衡工具
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

3.修改客戶端的controller,通過在Eureka中註冊的ApplicaitonName進行訪問

package com.aomeibox.con;

import com.aomeibox.pojo.User;
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;

/**
 * Created by leo on 2018/12/24.
 */
@RestController
public class OrderController {

    @Autowired
    private RestTemplate template;//spring提供的一個用於訪問rest接口的模板對象
    private static final String url = "http://PROVIDER-USER";

//    @Autowired
//    private EurekaClient eurekaClient;

    @GetMapping("/order/{id}")
    public User getUser(@PathVariable Integer id){

//        InstanceInfo eureka = eurekaClient.getNextServerFromEureka("PROVIDER-USER", false);

        //訪問提供者獲取數據
//        User user = template.getForObject(eureka.getHomePageUrl()+"/user/"+ id, User.class);//通過訪問rest 獲取到json數據,然後轉換成User對象

        User user = template.getForObject(url+"/user/"+ id, User.class);

        return user;
    }
}

4.運行項目

技術分享圖片

Ribbon負載均衡策略

使用負載均衡帶來的好處很明顯:

  • 當集群裏的1臺或者多臺服務器down的時候,剩余的沒有down的服務器可以保證服務的繼續使用
  • 使用了更多的機器保證了機器的良性使用,不會由於某一高峰時刻導致系統cpu急劇上升

負載均衡有好幾種實現策略,常見的有:

  • 隨機 (RandomRuler)
  • 輪詢 (RoundRobinRuler) (默認)
  • 一致性哈希 (ConsistentHashRuler)
  • 哈希 (HashRuler)
  • 加權(WeightedRuler)

  RoundRobinRule輪詢策略表示每次都取下一個服務器,比如一共有5臺服務器,第1次取第1臺,第2次取第2臺,第3次取第3臺,以此類推。

  WeightedResponseTimeRule繼承了RoundRobinRule,開始的時候還沒有權重列表,采用父類的輪詢方式,有一個默認每30秒更新一次權重列表的定時任務,該定時任務會根據實例的響應時間來更新權重列表,choose方法做的事情就是,用一個(0,1)的隨機double數乘以最大的權重得到randomWeight,然後遍歷權重列表,找出第一個比randomWeight大的實例下標,然後返回該實例。

   BestAvailableRule策略用來選取最少並發量請求的服務器。

如果需要改變輪訓的策略,需要修改自己的配置類。

package com.aomeibox.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
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;

/**
 * Created by leo on 2018/12/27.
 */
@Configuration
public class MyConfig {//@Configuration + 本類  = applicationContext.xml文件

    @Bean
    @LoadBalanced  //負載均衡工具
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    public IRule myRule(){
        return new RandomRule();//隨機策略
    }

}

自定義負載均衡策略

1.主啟動類新增註解。註意,自己編寫的Rule類,不能和主啟動類放在同一個包下

package com.aomeibox;

import com.aomei.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

/**
 *
 * 消費者
 */
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "PROVIDER-USER",configuration = MySelfRule.class)//MySelfRule.class不能在本類的包或者子包下
public class CustomerOrder
{
    public static void main( String[] args )
    {
        SpringApplication.run(CustomerOrder.class);
    }
}

2.新增MyRule類。

package com.aomei;

import com.netflix.loadbalancer.BestAvailableRule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by leo on 2018/12/29.
 */
@Configuration
public class MySelfRule {

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

Feign負載均衡

  上述的Ribbon功能很強大,可以自定義算法。

  Feign 是一個聲明web服務客戶端,這便得編寫web服務客戶端更容易,使用Feign 創建一個接口並對它進行註解,它具有可插拔的註解支持包括Feign註解與JAX-RS註解,Feign還支持可插拔的編碼器與解碼器,Spring Cloud 增加了對 Spring MVC的註解,Spring Web 默認使用了HttpMessageConverters, Spring Cloud 集成 Ribbon 和 Eureka 提供的負載均衡的HTTP客戶端 Feign。

  上述大部分,我們通常是以微服務的ApplicaitonName進行訪問的。但是在開發編程過程中,我們通常是面向接口編程。因此出現了Feign。Feign可以使用接口+註解,調用其他項目的接口。

@FeignClient("provider-user")
public interface UserClient {
 
    @RequestMapping(method = RequestMethod.GET, value = "/getuser")
    public User getuserinfo();
     
    @RequestMapping(method = RequestMethod.GET, value = "/getuser")
    public String getuserinfostr();
     
    @RequestMapping(method = RequestMethod.GET, value = "/info")
    public  String  info();
 
}
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
    }
 
} 
@RestController
public class UserController {
 
    @Autowired
    UserClient userClient;
 
    @RequestMapping(value = "/getuserinfo", method = RequestMethod.GET)
    public User getuserinfo() {
        return userClient.getuserinfo();
    }
     
    @RequestMapping(value = "/getuserinfostr", method = RequestMethod.GET)
    public String getuserinfostr() {
        return userClient.getuserinfostr();
    }
     
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public String info() {
        return userClient.info();
    }
 
 
}

淺談SpringCloud (三) Ribbon負載均衡