亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

全解析Spring Cloud之負載均衡之LoadBalance

 更新時間:2025年05月08日 10:20:46   作者:新綠MEHO  
這篇文章主要介紹了全解析Spring Cloud之負載均衡之LoadBalance的相關(guān)資料,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧

負載均衡

問題

上面是我們之前的代碼,是根據(jù)應(yīng)用名稱獲取了服務(wù)實例列表,并從列表中選擇了一個服務(wù)實例。

那如果一個服務(wù)對應(yīng)多個實例呢?流量是否可以合理的分配到多個實例呢?

我們再啟動兩個product-service示例。

步驟

打開View->Tool Windows->Services

選中ProductServiceApplication,然后右鍵,選擇Copy Configuration

然后改名,并點擊Modify options

然后點擊Add VM options

然后添加-Dserver.port=9091,然后Apply,OK

然后再重復(fù)上述步驟,再添加一個服務(wù)實例。

現(xiàn)象 

啟動上述所有實例后,可以在Eureka網(wǎng)站頁面看到:

此時多次訪問"http://127.0.0.1:8080/order/1",然后查看IDEA上的日志,可以看到,我們剛剛的多次訪問,都訪問到了同一臺機器上,即第一個注冊到Eureka的服務(wù)實例端口號為9092的機器。

這肯定不是我們想要的結(jié)果,我們啟動多個服務(wù)實例,是希望可以分擔(dān)其它機器的負荷,那么如何實現(xiàn)呢?

我們可以修改一下之前的order-service中的OrderService代碼,把只請求服務(wù)列表第一臺機器修改為輪詢請求服務(wù)列表中的機器。

修改后的order-service中的OrderService代碼如下:

package order.service;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import order.mapper.OrderMapper;
import order.model.OrderInfo;
import order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    //計數(shù)器
    private AtomicInteger count = new AtomicInteger(1);
    private List<ServiceInstance> instances;
    @PostConstruct
    public void init(){
        //從Eureka中獲取服務(wù)列表
        instances = discoveryClient.getInstances("product-service");
    }
    public OrderInfo selectOrderById(Integer orderId){
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        //計算輪流的實例idnex
        int index= count.getAndIncrement() % instances.size();
        //獲取實例
        String uri = instances.get(index).getUri().toString();
        //拼接url
        String url = uri+"/product/"+orderInfo.getProductId();
        log.info("遠程調(diào)用url:{}", url);
        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

重啟order-service,再次多次訪問"127.0.0.1:8080/order/1",可以看到每個服務(wù)實例都有被請求到:

通過?志可以看到, 請求被均衡的分配在了不同的實例上, 這就是負載均衡.

什么是負載均衡?

負載均衡(Load Balance,簡稱 LB) , 是?并發(fā), ?可?系統(tǒng)必不可少的關(guān)鍵組件.
當(dāng)服務(wù)流量增?時, 通常會采?增加機器的?式進?擴容, 負載均衡就是?來在多個機器或者其他資源中, 按照?定的規(guī)則合理分配負載.

負載均衡的一些實現(xiàn)

上?的例?中, 我們只是簡單的對實例進?了輪詢, 但真實的業(yè)務(wù)場景會更加復(fù)雜. ?如根據(jù)機器的配置進?負載分配, 配置?的分配的流量?, 配置低的分配流量低等.

服務(wù)多機部署時, 開發(fā)?員都需要考慮負載均衡的實現(xiàn), 所以也出現(xiàn)了?些負載均衡器, 來幫助我們實現(xiàn)負載均衡.

負載均衡分為服務(wù)端負載均衡和客?端負載均衡.

服務(wù)端負載均衡

在服務(wù)端進?負載均衡的算法分配.
?較有名的服務(wù)端負載均衡器是Nginx. 請求先到達Nginx負載均衡器, 然后通過負載均衡算法, 在多個服務(wù)器之間選擇?個進?訪問.

客戶端負載均衡

在客?端進?負載均衡的算法分配.

把負載均衡的功能以庫的?式集成到客?端, ?不再是由?臺指定的負載均衡設(shè)備集中提供.
?如Spring Cloud的Ribbon, 請求發(fā)送到客?端, 客?端從注冊中?(?如Eureka)獲取服務(wù)列表, 在發(fā)送請求前通過負載均衡算法選擇?個服務(wù)器,然后進?訪問.
Ribbon是Spring Cloud早期的默認(rèn)實現(xiàn), 由于不維護了, 所以最新版本的Spring Cloud負載均衡集成的是Spring Cloud LoadBalancer(Spring Cloud官?維護)。

客?端負載均衡和服務(wù)端負載均衡最?的區(qū)別在于服務(wù)清單所存儲的位置。

Spring Cloud LoadBalance

SpringCloud 從 2020.0.1 版本開始, 移除了Ribbon 組件,使?Spring Cloud LoadBalancer 組件來代替 Ribbon 實現(xiàn)客?端負載均衡。

使用Spring Cloud LoadBalance實現(xiàn)負載均衡

1. 給 RestTemplate 這個Bean添加 @LoadBalanced 注解就可以

package order.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;
@Configuration
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

2.修改后的order-service中的OrderService代碼如下:

修改IP為服務(wù)端名稱。

package order.service;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import order.mapper.OrderMapper;
import order.model.OrderInfo;
import order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RestTemplate restTemplate;
    public OrderInfo selectOrderById(Integer orderId){
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        String url = "http://product-service/product/"+orderInfo.getProductId();
        log.info("遠程調(diào)用url:{}", url);
        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

此時再次多次訪問"127.0.0.1:8080/order/1",可以看到每個服務(wù)實例都有被請求到,且比例差不多:

負載均衡策略

負載均衡策略是?種思想, ?論是哪種負載均衡器, 它們的負載均衡策略都是相似的. Spring Cloud
LoadBalancer 僅?持兩種負載均衡策略: 輪詢策略 和 隨機策略。

1. 輪詢(Round Robin): 輪詢策略是指服務(wù)器輪流處理??的請求. 這是?種實現(xiàn)最簡單, 也最常?的策略. ?活中也有類似的場景, ?如學(xué)校輪流值?, 或者輪流打掃衛(wèi)?.
2. 隨機選擇(Random): 隨機選擇策略是指隨機選擇?個后端服務(wù)器來處理新的請求.

官方介紹

翻譯:

Spring Cloud提供了自己的客戶端負載均衡器抽象和實現(xiàn)。對于負載平衡機制,添加了ReactiveLoadBalancer接口,并為其提供了基于輪轉(zhuǎn)和隨機的實現(xiàn)。為了讓實例從反應(yīng)式ServiceInstanceListSupplier中進行選擇,使用了該接口。目前,我們支持ServiceInstanceListSupplier的基于服務(wù)發(fā)現(xiàn)的實現(xiàn),該實現(xiàn)使用類路徑中可用的發(fā)現(xiàn)客戶端從服務(wù)發(fā)現(xiàn)中檢索可用實例。通過將Spring.Cloud.LoadBalancer.enabled的值設(shè)置為false,可以禁用Spring Cloud LoadBalancer。

1. 定義隨機算法對象, 通過 @Bean 將其加載到 Spring 容器中
此處使?Spring Cloud LoadBalancer提供的 RandomLoadBalancer

package order.config;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
public class CustomLoadBalancerConfiguration {
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

注意: 該類需要滿?:
1. 不? @Configuration 注釋
2. 在組件掃描范圍內(nèi) 

2. 使? @LoadBalancerClient 或者 @LoadBalancerClients 注解

在 RestTemplate 配置類上?, 使? @LoadBalancerClient 或 @LoadBalancerClients 注解, 可以對不同的服務(wù)提供?配置不同的客?端負載均衡算法策略.
由于我們只有?個客戶端服務(wù)提供者, 所以使?@LoadBalancerClient。

package order.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@LoadBalancerClient(name = "product-service", configuration = CustomLoadBalancerConfiguration.class)
@Configuration
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

@LoadBalancerClient 注解說明
1. name: 該負載均衡策略對哪個服務(wù)?效(服務(wù)提供?)
2. configuration : 該負載均衡策略 ?哪個負載均衡策略實現(xiàn). 

此時再次多次訪問"127.0.0.1:8080/order/1",可以看到每個服務(wù)實例都有被請求到,且比例隨機:

LoadBalancer原理

LoadBalancer 的實現(xiàn), 主要是 LoadBalancerInterceptor , 這個類會對 RestTemplate 的請
求進?攔截, 然后從Eureka根據(jù)服務(wù)id獲取服務(wù)列表,隨后利?負載均衡算法得到真實的服務(wù)地址信息,替換服務(wù)id。

我們來看看源碼實現(xiàn):

可以看到這?的intercept?法, 攔截了??的HttpRequest請求,然后做了?件事:

1. request.getURI() 從請求中獲取uri, 也就是 http://product-service
2. service/product/1001 originalUri.getHost() 從uri中獲取路徑的主機名, 也就是服務(wù)id, product-service
3. loadBalancer.execute 根據(jù)服務(wù)id, 進?負載均衡, 并處理請求 

根據(jù)serviceId,和負載均衡策略, 選擇處理的服務(wù): 

 根據(jù)serviceId,和負載均衡策略, 選擇處理的服務(wù):

服務(wù)部署

準(zhǔn)備環(huán)境和數(shù)據(jù)

安裝好JDK17和MySQL,并在MySQL中建表且存放好數(shù)據(jù)信息。

修改配置文件中的數(shù)據(jù)庫密碼。

服務(wù)構(gòu)建打包

采?Maven打包, 需要對3個服務(wù)分別打包:
eureka-server, order-service, product-service

啟動服務(wù)

上傳Jar包到云服務(wù)器

第一次上傳需要安裝 lrzsz

Centos:

yum install lrzsz

Ubantu:

apt install lrzsz 

直接拖動文件到xshell窗口,上傳成功。

啟動服務(wù)

#后臺啟動eureka-server, 并設(shè)置輸出?志到logs/eureka.log
nohup java -jar eureka-server.jar >logs/eureka.log &

#后臺啟動order-service, 并設(shè)置輸出?志到logs/order.log
nohup java -jar order-service.jar >logs/order.log &

#后臺啟動product-service, 并設(shè)置輸出?志到logs/order.log
nohup java -jar product-service.jar >logs/product-9090.log &

再多啟動兩臺product-service實例

#啟動實例, 指定端?號為9091
nohup java -jar product-service.jar --server.port=9091 >logs/product-9091.log &

#啟動實例, 指定端?號為9092
nohup java -jar product-service.jar --server.port=9092 >logs/product-9092.log & 

遠程調(diào)用訪問 

可以看到,能夠正常訪問并響應(yīng)。

到此這篇關(guān)于Spring Cloud之負載均衡之LoadBalance的文章就介紹到這了,更多相關(guān)Spring Cloud負載均衡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring boot @ResponseBody轉(zhuǎn)換JSON 時 Date 類型處理方法【兩種方法】

    spring boot @ResponseBody轉(zhuǎn)換JSON 時 Date 類型處理方法【兩種方法】

    這篇文章主要介紹了spring boot @ResponseBody轉(zhuǎn)換JSON 時 Date 類型處理方法,主要給大家介紹Jackson和FastJson兩種方式,每一種方法給大家介紹的都非常詳細,需要的朋友可以參考下
    2018-08-08
  • 使用Spring來創(chuàng)建一個簡單的工作流引擎

    使用Spring來創(chuàng)建一個簡單的工作流引擎

    這篇文章主要給大家介紹了關(guān)于使用Spring來創(chuàng)建一個簡單的工作流引擎的相關(guān)資料,需要的朋友可以參考下
    2006-12-12
  • Java內(nèi)存映射 大文件輕松處理

    Java內(nèi)存映射 大文件輕松處理

    這篇文章主要介紹了Java內(nèi)存映射 大文件輕松處理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • Java的并發(fā)編程之CyclicBarrier解析

    Java的并發(fā)編程之CyclicBarrier解析

    這篇文章主要介紹了Java的并發(fā)編程之CyclicBarrier解析,CyclicBarrier支持一個可選的Runnable命令,在一組線程中的最后一個線程到達之后(但在釋放所有線程之前),該命令只在每個屏障點運行一次,需要的朋友可以參考下
    2023-11-11
  • 解決mybatis 執(zhí)行mapper的方法時報空指針問題

    解決mybatis 執(zhí)行mapper的方法時報空指針問題

    這篇文章主要介紹了解決mybatis 執(zhí)行mapper的方法時報空指針問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • SpringBoot中l(wèi)ogback日志保存到mongoDB的方法

    SpringBoot中l(wèi)ogback日志保存到mongoDB的方法

    這篇文章主要介紹了SpringBoot中l(wèi)ogback日志保存到mongoDB的方法,
    2017-11-11
  • Java日常練習(xí)題,每天進步一點點(63)

    Java日常練習(xí)題,每天進步一點點(63)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08
  • java計算自冪數(shù)和水仙花數(shù)

    java計算自冪數(shù)和水仙花數(shù)

    對于一個正整數(shù)而言,長度是n,如果它的各位上的數(shù)字的n次方之和正好等于它本身,那么我們稱這樣的數(shù)為自冪數(shù),下面使用JAVA實現(xiàn)這個方法
    2014-03-03
  • 解讀maven項目的打包方式

    解讀maven項目的打包方式

    這篇文章主要介紹了關(guān)于maven項目的打包方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • mybatis?使用concat?模糊查詢方式

    mybatis?使用concat?模糊查詢方式

    這篇文章主要介紹了mybatis?使用concat?模糊查詢方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論