最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Cloud負(fù)載均衡LoadBalance及實(shí)際應(yīng)用

 更新時(shí)間:2026年01月27日 11:48:59   作者:努力也學(xué)不會(huì)Java.  
負(fù)載均衡是一種將流量合理分配到多個(gè)服務(wù)器的技術(shù),可以提高系統(tǒng)的可用性和性能,本文通過(guò)一個(gè)示例展示了如何使用SpringCloudLoadBalancer實(shí)現(xiàn)負(fù)載均衡,負(fù)載均衡的概念、實(shí)現(xiàn)方式以及在SpringCloud中的應(yīng)用,感興趣的朋友跟隨小編一起看看吧

一、負(fù)載均衡介紹

1.1、問(wèn)題描述

上篇文章中遠(yuǎn)程調(diào)用的代碼如下:

List<ServiceInstance> instances =discoveryClient.getInstances("productservice");
//服務(wù)可能有多個(gè), 獲取第?個(gè)
EurekaServiceInstance instance = (EurekaServiceInstance)instances.get(0);
  1. 根據(jù)應(yīng)用名稱獲取了服務(wù)實(shí)例列表
  2. 從列表中選擇了一個(gè)服務(wù)實(shí)例

**思考:**如果一個(gè)服務(wù)對(duì)應(yīng)多個(gè)實(shí)例呢? 流量是否可以合理的分配到多個(gè)實(shí)例呢?
現(xiàn)象觀察:
我們?cè)賳?dòng)2個(gè)product-service實(shí)例
選中要啟動(dòng)的服務(wù), 右鍵選擇 Copy Configuration

在彈出的框中, 選擇 Modify options -> Add VM options

添加 VM options : -Dserver.port=9091

9091 為服務(wù)啟動(dòng)的端口號(hào), 根據(jù)自己的情況進(jìn)行修改

現(xiàn)在IDEA的Service窗口就會(huì)多出來(lái)?個(gè)啟動(dòng)配置, 右鍵啟動(dòng)服務(wù)就可以

同樣的操作, 再啟動(dòng)1個(gè)實(shí)例, 共啟動(dòng)3個(gè)服務(wù)

觀察Eureka, 可以看到product-service下有三個(gè)實(shí)例:

訪問(wèn)日志:
訪問(wèn): http://127.0.0.1:8080/order/1
通過(guò)觀察日志我們發(fā)現(xiàn):請(qǐng)求多次訪問(wèn), 都是同?臺(tái)機(jī)器。這肯定不是我們想要的結(jié)果, 我們啟動(dòng)多個(gè)實(shí)例, 是希望可以分擔(dān)其他機(jī)器的負(fù)荷, 那么如何實(shí)現(xiàn)呢?

解決方案:
我們可以對(duì)上述代碼進(jìn)行簡(jiǎn)單修改:

 private static AtomicInteger atomicInteger = new AtomicInteger(1);
    private static List<ServiceInstance> instances;
    @PostConstruct
    public void init(){
        //根據(jù)應(yīng)?名稱獲取服務(wù)列表
        instances = discoveryClient.getInstances("product-service");
    }
    public OrderInfo selectOrderById(Integer orderId) {
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        //String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();
        //服務(wù)可能有多個(gè), 輪詢獲取實(shí)例
        int index = atomicInteger.getAndIncrement() % instances.size();
        ServiceInstance instance =instances.get(index);
        log.info(instance.getInstanceId());
        //拼接url
        String url = instance.getUri()+"/product/"+ orderInfo.getProductId();
        ProductInfo productInfo = restTemplate.getForObject(url,
                ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }

修改代碼后,我們?cè)俅螁?dòng)發(fā)現(xiàn)請(qǐng)求被均衡的分配在了不同的實(shí)例上, 這就是負(fù)載均衡。

1.2、什么是負(fù)載均衡

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

?個(gè)團(tuán)隊(duì)最開始只有?個(gè)?, 后來(lái)隨著工作量的增加, 公司又招聘了幾個(gè)?. 負(fù)載均衡就是: 如何把工作量均衡的分配到這幾個(gè)人?上, 以提高整個(gè)團(tuán)隊(duì)的效率

1.3、負(fù)載均衡的一些實(shí)現(xiàn)

上面的例子中, 我們只是簡(jiǎn)單的對(duì)實(shí)例進(jìn)行了輪詢, 但真實(shí)的業(yè)務(wù)場(chǎng)景會(huì)更加復(fù)雜. 比如根據(jù)機(jī)器的配置進(jìn)行負(fù)載分配, 配置高的分配的流量高, 配置低的分配流量低等.
類似企業(yè)員工: 能力強(qiáng)的員工可以多承擔(dān)一些工作.服務(wù)多機(jī)部署時(shí), 開發(fā)人員都需要考慮負(fù)載均衡的實(shí)現(xiàn), 所以也出現(xiàn)了?些負(fù)載均衡器, 來(lái)幫助我們實(shí)現(xiàn)負(fù)載均衡.
負(fù)載均衡分為服務(wù)端負(fù)載均衡和客戶端負(fù)載均衡

服務(wù)端負(fù)載均衡
在服務(wù)端進(jìn)行負(fù)載均衡的算法分配.
比較有名的服務(wù)端負(fù)載均衡器是Nginx. 請(qǐng)求先到達(dá)Nginx負(fù)載均衡器, 然后通過(guò)負(fù)載均衡算法, 在多個(gè)服務(wù)器之間選擇一個(gè)進(jìn)行訪問(wèn).

客戶端負(fù)載均衡
在客戶端進(jìn)行負(fù)載均衡的算法分配.
把負(fù)載均衡的功能以庫(kù)的方式集成到客戶端, 而不再是由一臺(tái)指定的負(fù)載均衡設(shè)備集中提供.
比如Spring Cloud的Ribbon, 請(qǐng)求發(fā)送到客戶端, 客戶端從注冊(cè)中心(比如Eureka)獲取服務(wù)列表, 在發(fā)送請(qǐng)求前通過(guò)負(fù)載均衡算法選擇?個(gè)服務(wù)器,然后進(jìn)行訪問(wèn).
Ribbon是Spring Cloud早期的默認(rèn)實(shí)現(xiàn), 由于不維護(hù)了, 所以最新版本的Spring Cloud負(fù)載均衡集成的是Spring Cloud LoadBalancer(Spring Cloud官方維護(hù))

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

二、Spring Cloud LoadBalancer

2.1、快速上手

2.1.1、使用Spring Cloud LoadBalancer實(shí)現(xiàn)負(fù)載均衡

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

@Configuration
public class BeanConfig {
  @Bean
  @LoadBalanced
  public RestTemplate restTemplate(){
     return new RestTemplate();
 }
}

2.修改IP端口號(hào)為服務(wù)名稱

  public OrderInfo selectOrderById(Integer orderId) {
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        //String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();
        String url = "http://product-service/product/"+ orderInfo.getProductId();
        ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }

2.1.2、啟動(dòng)多個(gè)product-service實(shí)例

按照上面的方式,啟動(dòng)多個(gè)實(shí)例。

2.1.3、測(cè)試負(fù)載均衡

啟動(dòng)后,我們觀察日志,發(fā)現(xiàn)請(qǐng)求被分配到三個(gè)實(shí)例上了

2.2、負(fù)載均衡策略

負(fù)載均衡策略是?種思想, ?論是哪種負(fù)載均衡器, 它們的負(fù)載均衡策略都是相似的. Spring CloudLoadBalancer 僅?持兩種負(fù)載均衡策略: 輪詢策略 和 隨機(jī)策略

  1. 輪詢(Round Robin): 輪詢策略是指服務(wù)器輪流處理用戶的請(qǐng)求. 這是?種實(shí)現(xiàn)最簡(jiǎn)單, 也最常用的策略. 生活中也有類似的場(chǎng)景, 比如學(xué)校輪流值日, 或者輪流打掃衛(wèi)?.
  2. 隨機(jī)選擇(Random): 隨機(jī)選擇策略是指隨機(jī)選擇?個(gè)后端服務(wù)器來(lái)處理新的請(qǐng)求.

自定義負(fù)載均衡策略:
Spring Cloud LoadBalancer 默認(rèn)負(fù)載均衡策略是輪詢策略, 實(shí)現(xiàn)是 RoundRobinLoadBalancer, 如果服務(wù)的消費(fèi)者如果想采用隨機(jī)的負(fù)載均衡策略, 也非常簡(jiǎn)單.

  1. 定義隨機(jī)算法對(duì)象, 通過(guò) @Bean 將其加載到 Spring 容器中
    此處使用Spring Cloud LoadBalancer提供的 RandomLoadBalancer
 public class LoadBalancerConfig {
        @Bean
        ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment
                      environment,LoadBalancerClientFactory loadBalancerClientFactory) {
            String name =
                    environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
            System.out.println("=============="+name);
            return new
                    RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
                    ServiceInstanceListSupplier.class), name);
        }
    }

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

  1. 使用 @LoadBalancerClient 或者 @LoadBalancerClients 注解在 RestTemplate 配置類上方, 使用@LoadBalancerClient 或 @LoadBalancerClients 注解, 可以對(duì)不同的服務(wù)提供方配置不同的客戶端負(fù)載均衡算法策略.由于項(xiàng)目中只有?個(gè)服務(wù)提供者, 所以使用@LoadBalancerClient
    @LoadBalancerClient(name = "product-service", configuration =LoadBalancerConfig.class)
    @Configuration
    public class BeanConfig {
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }

@LoadBalancerClient 注解說(shuō)明

  1. name: 該負(fù)載均衡策略對(duì)哪個(gè)服務(wù)生效(服務(wù)提供方)
  2. configuration : 該負(fù)載均衡策略 用哪個(gè)負(fù)載均衡策略實(shí)現(xiàn).

2.3、LoadBalancer 原理

LoadBalancer 的實(shí)現(xiàn), 主要是 LoadBalancerInterceptor , 這個(gè)類會(huì)對(duì) RestTemplate 的請(qǐng)求進(jìn)行攔截, 然后從Eureka根據(jù)服務(wù)id獲取服務(wù)列表,隨后利用負(fù)載均衡算法得到真實(shí)的服務(wù)地址信息,替換服務(wù)id
我們來(lái)看看源碼實(shí)現(xiàn):

 public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
        public ClientHttpResponse intercept(final HttpRequest request, final
        byte[] body, final ClientHttpRequestExecution execution) throws IOException {
            URI originalUri = request.getURI();
            String serviceName = originalUri.getHost();
            Assert.state(serviceName != null, "Request URI does not contain a 
                    valid hostname: " + originalUri);
            return (ClientHttpResponse)this.loadBalancer.execute(serviceName,
                    this.requestFactory.createRequest(request, body, execution));
        }
    }

可以看到這里的intercept方法, 攔截了用戶的HttpRequest請(qǐng)求,然后做了幾件事:

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

后續(xù)代碼:

 public class BlockingLoadBalancerClient implements LoadBalancerClient {
        public <T> T execute(String serviceId, LoadBalancerRequest<T> request)
                throws IOException {
            String hint = this.getHint(serviceId);
            LoadBalancerRequestAdapter<T, TimedRequestContext> lbRequest = new
                    LoadBalancerRequestAdapter(request, this.buildRequestContext(request, hint));
            Set<LoadBalancerLifecycle> supportedLifecycleProcessors =
                    this.getSupportedLifecycleProcessors(serviceId);
            supportedLifecycleProcessors.forEach((lifecycle) -> {
                lifecycle.onStart(lbRequest);
            });
            //根據(jù)serviceId,和負(fù)載均衡策略, 選擇處理的服務(wù)
            ServiceInstance serviceInstance = this.choose(serviceId, lbRequest);
            if (serviceInstance == null) {
                supportedLifecycleProcessors.forEach((lifecycle) -> {
                    lifecycle.onComplete(new CompletionContext(Status.DISCARD,
                            lbRequest, new EmptyResponse()));
                });
                throw new IllegalStateException("No instances available for " +
                        serviceId);
            } else {
                return this.execute(serviceId, serviceInstance, lbRequest);
            }
        }
        /**
         * 根據(jù)serviceId,和負(fù)載均衡策略, 選擇處理的服務(wù)
         *
         */
        public <T> ServiceInstance choose(String serviceId, Request<T> request) {
            //獲取負(fù)載均衡器
            ReactiveLoadBalancer<ServiceInstance> loadBalancer =
                    this.loadBalancerClientFactory.getInstance(serviceId);
            if (loadBalancer == null) {
                return null;
            } else {
                //根據(jù)負(fù)載均衡算法, 在列表中選擇?個(gè)服務(wù)實(shí)例
                Response<ServiceInstance> loadBalancerResponse =
                        (Response)Mono.from(loadBalancer.choose(request)).block();
                return loadBalancerResponse == null ? null :
                        (ServiceInstance)loadBalancerResponse.getServer();
            }
        }
    }

三、總結(jié)

以上就是本文全部?jī)?nèi)容,本文主要為大家介紹了負(fù)載均衡-LoadBalance以及實(shí)際應(yīng)用。感謝各位能夠看到最后,如有問(wèn)題,歡迎各位大佬在評(píng)論區(qū)指正,希望大家可以有所收獲!創(chuàng)作不易,希望大家多多支持

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

相關(guān)文章

  • Java如何通過(guò)反射獲取對(duì)象的屬性和值

    Java如何通過(guò)反射獲取對(duì)象的屬性和值

    這篇文章主要介紹了Java如何通過(guò)反射獲取對(duì)象的屬性和值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • java關(guān)于字符串的常用API

    java關(guān)于字符串的常用API

    字符串其實(shí)就是一串連續(xù)的字符,它是由許多單個(gè)字符連接而成的。如多個(gè)英文字母所組成的一個(gè)英文單詞。字符串中可以包含任意字符,這些字符必須包含在一對(duì)雙引號(hào)之內(nèi),今天就來(lái)介紹字符串常用的API
    2023-05-05
  • Java壓縮集合的三種方法

    Java壓縮集合的三種方法

    這篇文章主要介紹了Java壓縮集合的三種方法,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01
  • MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問(wèn)題及解決

    MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問(wèn)題及解決

    這篇文章主要介紹了MyBatis查詢數(shù)據(jù),賦值給List集合時(shí),數(shù)據(jù)缺少的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問(wèn)題

    解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問(wèn)題

    這篇文章主要介紹了解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • Java主鍵生成之@Id和@GeneratedValue使用詳解

    Java主鍵生成之@Id和@GeneratedValue使用詳解

    這篇文章主要介紹了Java主鍵生成之@Id和@GeneratedValue的使用,@Id和@GeneratedValue注解就是JPA中用于定義主鍵和主鍵生成策略的關(guān)鍵注解,理解這兩個(gè)注解的使用和不同的主鍵生成策略,對(duì)于開發(fā)高效、穩(wěn)定的數(shù)據(jù)持久化應(yīng)用至關(guān)重要,需要的朋友可以參考下
    2025-05-05
  • Java連接數(shù)據(jù)庫(kù)的步驟介紹

    Java連接數(shù)據(jù)庫(kù)的步驟介紹

    這篇文章介紹了Java連接數(shù)據(jù)庫(kù)的步驟,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Springboot整合Urule的方法步驟

    Springboot整合Urule的方法步驟

    這篇文章主要介紹了Springboot整合Urule的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實(shí)現(xiàn)

    elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實(shí)現(xiàn)

    這篇文章主要為大家介紹了elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 在spring boot中使用java線程池ExecutorService的講解

    在spring boot中使用java線程池ExecutorService的講解

    今天小編就為大家分享一篇關(guān)于在spring boot中使用java線程池ExecutorService的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03

最新評(píng)論

舞钢市| 云南省| 上蔡县| 山西省| 蒙阴县| 罗源县| 封丘县| 长宁区| 弋阳县| 丹江口市| 平安县| 夏河县| 保亭| 佛冈县| 石楼县| 榆中县| 唐河县| 五峰| 郑州市| 洮南市| 镶黄旗| 武威市| 扶沟县| 邻水| 长子县| 织金县| 固原市| 原平市| 田东县| 寻甸| 陈巴尔虎旗| 桑日县| 禹城市| 正安县| 曲麻莱县| 凉城县| 彰武县| 勃利县| 克什克腾旗| 台北县| 镇远县|