<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringCloud下基于Ribbon的負載均衡實踐

          共 4935字,需瀏覽 10分鐘

           ·

          2021-11-09 06:47

          負載均衡大體可以分為兩類:集中式、進程內(nèi)。前者也被稱為服務端負載均衡,其一般位于服務集群的前端,統(tǒng)一接收、處理、轉(zhuǎn)發(fā)客戶端的請求。典型地包括F5硬件、LVS、Nginx等技術方案;而后者也被稱為客戶端負載均衡,其是在客戶端側(cè)根據(jù)某種策略選擇合適的服務實例直接進行請求,其典型代表有Ribbon

          abstract.png

          環(huán)境搭建

          搭建服務提供者

          我們在服務提供者payment中添加一個Controller,如下所示

          @RestController
          @RequestMapping("pay")
          public?class?PaymentController?{

          ????@GetMapping("/hello")
          ????public?String?hello(@RequestParam?String?name)?{
          ????????String?msg?=?"[Payment?Service-"+?serverPort?+"]:?"?+?name;
          ????????return?msg;
          ????}

          }

          這里使用Consul作為注冊中心。創(chuàng)建三個payment服務的實例,分別使用8004、8005、8006端口。如下所示

          figure 1.jpeg

          搭建服務消費者

          在服務消費者order中,我們同樣也會引入spring-cloud-starter-consul-discovery依賴。由于該依賴間接依賴了spring-cloud-starter-netflix-ribbon,如下圖所示。故無需顯式引入spring-cloud-starter-netflix-ribbon依賴

          figure 2.jpeg

          在服務消費者order中,先聲明一個restTemplate實例,然后通過Controller調(diào)用payment服務

          @Configuration
          public?class?RestTemplateConfig?{

          ????/**
          ?????*?@LoadBalanced?注解作用:
          ?????*???1.?基于服務名調(diào)用的restTemplate實例
          ?????*???2.?支持負載均衡
          ?????*?@return
          ?????*/

          ????@Bean
          ????@LoadBalanced
          ????public?RestTemplate?restTemplate()?{
          ????????return?new?RestTemplate();
          ????}

          }

          ...

          @RestController
          @RequestMapping("order")
          public?class?OrderController2?{

          ????//?使用?注冊中心的服務名
          ????public?static?final?String?PAYMENT_URL?=?"http://payment";

          ????@Qualifier("restTemplate")
          ????@Autowired
          ????private?RestTemplate?restTemplate;

          ????@GetMapping("/test2")
          ????public?String?test2(@RequestParam?String?name)?{
          ????????String?msg?=?restTemplate.getForObject(PAYMENT_URL?+"/pay/hello?name={1}",?String.class,?name);
          ????????String?result?=?"[Order?Service?#test2]:?"?+?msg;
          ????????return?result;
          ????}

          }

          創(chuàng)建order服務的實例,使用82端口。如下所示

          figure 3.jpeg

          本版本Ribbon默認采用ZoneAvoidanceRule區(qū)域敏感性策略,測試效果如下符合預期

          figure 4.jpeg

          負載均衡策略

          Ribbon通過實現(xiàn)IRule接口內(nèi)置了多種負載均衡策略

          figure 5.jpeg
          • RoundRobinRule:隨機策略。隨機選擇服務實例
          • RandomRule:輪詢策略。依次選擇服務實例
          • RetryRule:重試策略
          • BestAvailableRule:最低并發(fā)策略。選擇正在請求的并發(fā)量最小的服務實例。如果服務實例處于熔斷狀態(tài),則忽略該服務實例
          • AvailabilityFilteringRule:可用性敏感策略。過濾掉 處于熔斷狀態(tài) 或 正在請求的并發(fā)量高的服務實例
          • ZoneAvoidanceRule:區(qū)域敏感性策略。復合判斷服務實例所在區(qū)域的性能和服務實例的可用性
          • WeightedResponseTimeRule:響應時間加權策略。根據(jù)各服務實例的響應時間計算權重,響應時間越長,權重越低,選擇該服務實例的概率越低

          策略配置

          全局配置

          在服務消費者order中,我們可以配置全局的負載均衡策略。這里以RoundRobinRule隨機策略為例。首先通過Java配置類聲明一個該策略的實例對象

          @Configuration
          public?class?RandomRuleConfig?{

          ????@Bean
          ????public?IRule?randomRule()?{
          ????????return?new?RandomRule();
          ????}

          }

          需要注意的是,該Java配置類不能被@ComponentScan注解掃描到,否則該配置類就會被所有的Ribbon客戶端所共享。換言之,Ribbon策略實例的Java配置類不要放在@ComponentScan注解所在的當前包及其子包下即可。如下所示,我們所有策略實例的Java配置類均放在ribbon包下,而SpringBoot啟動類在order包下

          figure 6.jpeg

          通過@RibbonClients注解的defaultConfiguration屬性來設置其全局的負載均衡策略,如下所示

          @SpringBootApplication
          //?使用Consul作為注冊中心時使用
          @EnableDiscoveryClient?
          //?設置Ribbon全局負載均衡策略為隨機策略
          @RibbonClients(defaultConfiguration?=?RandomRuleConfig.class)
          public?class?OrderApplication?
          {
          ?
          ????public?static?void?main(String[]?args)?{
          ????????SpringApplication.run(OrderApplication.class,?args);
          ????}

          }

          效果如下所示,符合預期

          figure 7.jpeg

          根據(jù)所調(diào)用的服務進行配置

          可以通過@RibbonClient注解,對所調(diào)用的服務分別配置相應的策略。用法如下所示

          @SpringBootApplication
          //?使用Consul作為注冊中心時使用
          @EnableDiscoveryClient?
          //?調(diào)用payment服務時,采用隨機策略
          @RibbonClient(name?="payment",?configuration?=?RandomRuleConfig.class)
          public?class?OrderApplication?
          {
          ?
          ????public?static?void?main(String[]?args)?{
          ????????SpringApplication.run(OrderApplication.class,?args);
          ????}

          }

          對于多個配置,還可以通過@RibbonClients注解整合到一處

          //?調(diào)用payment服務時,采用隨機策略;?調(diào)用bill服務時,采用響應時間加權策略
          @RibbonClients({
          ????@RibbonClient(name?=?"payment",configuration?=?RandomRuleConfig.class),
          ????@RibbonClient(name?
          =?"bill",configuration?=?WeightedResponseTimeRuleConfig.class)
          })

          基于配置文件的策略配置

          事實上,不僅可以通過注解配置負載均衡策略。還可以直接通過配置文件進行配置,這樣可以直接免去相應均衡策略實例的Java配置類??赏ㄟ^ [調(diào)用的服務名].ribbon.NFLoadBalancerRuleClassName 配置項進行配置。示例如下所示

          #?調(diào)用payment服務時,采用隨機策略
          payment:
          ????ribbon:
          ????????NFLoadBalancerRuleClassName:?com.netflix.loadbalancer.RoundRobinRule

          #?調(diào)用bill服務時,采用響應時間加權策略
          bill:
          ????ribbon:
          ????????NFLoadBalancerRuleClassName:?com.netflix.loadbalancer.WeightedResponseTimeRule

          自定義負載均衡策略

          通過查看IRule接口實現(xiàn)類,不難發(fā)現(xiàn)IRule接口是一個均衡策略接口。而具體的實現(xiàn)類則是通過抽象類AbstractLoadBalancerRule進行拓展的。所以,如果我們期望自定義均衡策略,可以直接繼承實現(xiàn)AbstractLoadBalancerRule類即可,而不用從IRule接口進行拓展。如下即是我們實現(xiàn)的一個負載均衡策略,具體通過實現(xiàn)choose方法完成服務實例的選擇。這里為了簡便起見,我們的目標為總是使用某端口的服務實例

          package?com.aaron.SpringCloud1.ribbon;

          public?class?CustomRule?extends?AbstractLoadBalancerRule?{

          ????@Override
          ????public?void?initWithNiwsConfig(IClientConfig?clientConfig)?{
          ????}

          ????@Override
          ????public?Server?choose(Object?key)?{
          ????????ILoadBalancer?lb?=?getLoadBalancer();
          ????????//獲取服務列表
          ????????List?serverList?=?lb.getAllServers();

          ????????//?獲取端口為8005的服務實例
          ????????Server?target?=?serverList.stream()
          ????????????.filter(?server?->?server.getPort()==8005?)
          ????????????.findAny()
          ????????????.orElse(null);

          ????????return?target;
          ????}

          }

          在使用上,其與Ribbon內(nèi)置的均衡策略使用并無二致。要么通過 Java配置類+注解 的方式,要么通過配置文件的方式。當然對于前者而言,Java配置類不要放在@ComponentScan注解所在的當前包及其子包下

          package?com.aaron.SpringCloud1.ribbon;

          @Configuration
          public?class?CustomRuleConfig?{

          ????@Bean
          ????public?IRule?customRule()?{
          ????????return?new?CustomRule();
          ????}

          }

          測試結(jié)果如下,符合預期

          figure 8.jpeg

          參考文獻

          1. Spring微服務實戰(zhàn) John Carnell著
          2. 鳳凰架構(gòu) 周志明著
          瀏覽 66
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩AV之家 | 日韩午夜在线观看 | 苍井空一区二区三区无码 | 欧美aaa国产aaa亚洲aaa免费看 | 日韩无码操逼 |