• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • [SpringCloud學習筆記3]SpringCloud服務調用(ribbon,openFeign)

    標簽: 學習筆記  SpringCloud  JAVA  分布式  java  spring  其他

    SpringCloud服務調用

    這次學習的服務調用主要是ribbon和openFeign的應用

    一、ribbon的負載均衡和RestTemplate

    1.負載均衡

    在調用eurake的時候,其pom文件默認幫我們調用了ribbon,所以能實現默認的輪詢方式的負載均衡功能.

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-netflix-ribbon</artifactId>
      <version>2.2.1.RELEASE</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    

    查詢ribbon源碼,其調用規則是IRule

    package com.netflix.loadbalancer;
    
    public interface IRule {
        Server choose(Object var1);
    
        void setLoadBalancer(ILoadBalancer var1);
    
        ILoadBalancer getLoadBalancer();
    }
    

    查看其源碼可以發現其實現類

    在這里插入圖片描述

    • com.netflix.loadbalancer.RoundRobinRule 實現輪詢選擇

    • com.netflix.loadbalancer.RandomRule 實現隨機選擇

    • com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗則在指定時間內會進行重試

    • com.netflix.loadbalancer.WeightedResponseTimeRule 對RoundRobinRule的擴展,響應速度越快的實例選擇權重越大,越容易被選擇

    • com.netflix.loadbalancer.BestAvailableRule 會先過濾掉由于多次訪問故障而處于斷路器跳閘狀態的服務,然后選擇一個并發量最小的服務

    • com.netflix.loadbalancer.AvailabilityFilteringRule 先過濾掉故障實例,再選擇并發較小的實例

    • com.netflix.loadbalancer.ZoneAvoidanceRule 默認規則,復合判斷server所在區域的性能和server的可用性選擇服務器

    默認調用的就是輪詢選擇

    2.RestTemplate的方法區別

    模板獲取對象方法有以下幾種

    getForObject方法/getForEntity方法

    postForObject/postForEntity方法

    其實區別不大,就是object的返回值是json串,entitity返回的是一個帶有很多頭信息等等信息的對象

    3.rule切換

    1.新建子包

    默認規則是輪詢,現在可以把它改成隨機,根據官網所述,不能將新的rule放入到@componetScan注解能夠掃描到的地方,所以先新建一個包.

    2.新建一個Myrule類

    @Component
    public class MyRule {
        @Bean
        public IRule randomRule() {
            return new RandomRule();
        }
    }
    

    3.在主方法上聲明調用

    //必須指定name和configuration
    @RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MyRule.class)
    
    

    4.輪詢算法源碼探究

    輪詢算法底層還是挺簡單的,就是用CAS和一個循環.

    源碼分析如下:

    public class RoundRobinRule extends AbstractLoadBalancerRule {
        //聲明一個AtomicInteger類
        private AtomicInteger nextServerCyclicCounter;
        private static final boolean AVAILABLE_ONLY_SERVERS = true;
        private static final boolean ALL_SERVERS = false;
        private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class);
    	//初始化AtomicInteger參數為0
        public RoundRobinRule() {
            this.nextServerCyclicCounter = new AtomicInteger(0);
        }
    	//初始化ILoadBalancer
        public RoundRobinRule(ILoadBalancer lb) {
            this();
            this.setLoadBalancer(lb);
        }
    
        public Server choose(ILoadBalancer lb, Object key) {
            //如果為空,那就提示沒有ILoadBalancer
            if (lb == null) {
                log.warn("no load balancer");
                return null;
                
            } else {
                //如果ILoadBalancer非空,就開始計數
                Server server = null;
                int count = 0;
    			//開啟一個循環
                while(true) {
                    //默認是10次為上限,每次重啟都會重置count
                    if (server == null && count++ < 10) {
                        //獲取所有可用的服務器
                        List<Server> reachableServers = lb.getReachableServers();
                        //獲取所有服務器
                        List<Server> allServers = lb.getAllServers();
                        //獲取所有可用的服務器數量
                        int upCount = reachableServers.size();
                        //獲取所有服務器數量
                        int serverCount = allServers.size();
                        if (upCount != 0 && serverCount != 0) {
                            //調用下面的incrementAndGetModulo函數來選擇幾號服務器
                            int nextServerIndex = this.incrementAndGetModulo(serverCount);
                            //調用對應編號服務器
                            server = (Server)allServers.get(nextServerIndex);
                            if (server == null) {
                                Thread.yield();
                            } else {
                                if (server.isAlive() && server.isReadyToServe()) {
                                    //如果可以用就返回
                                    return server;
                                }
    
                                server = null;
                            }
                            continue;
                        }
    
                        log.warn("No up servers available from load balancer: " + lb);
                        return null;
                    }
    
                    if (count >= 10) {
                        log.warn("No available alive servers after 10 tries from load balancer: " + lb);
                    }
    
                    return server;
                }
            }
        }
    	//核心算法
        private int incrementAndGetModulo(int modulo) {
            //初始化參數,傳入modulo為總數
            int current;
            int next;
            //每次用一次就+1%總數
            do {
                current = this.nextServerCyclicCounter.get();
                next = (current + 1) % modulo;
            } while(!this.nextServerCyclicCounter.compareAndSet(current, next));
    		//返回服務器編號
            return next;
        }
    
        public Server choose(Object key) {
            return this.choose(this.getLoadBalancer(), key);
        }
    
        public void initWithNiwsConfig(IClientConfig clientConfig) {
        }
    }
    

    二、openFeign的入門

    源碼及說明文檔

    Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations

    Feign是一個聲明式的web服務客戶端,讓編寫web服務客戶端變得非常容易,只需創建一個接口并在接口上添加注解即可

    1.openFeign服務調用

    1.修改pom

    <!--openfeign里面引入了ribbon-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--eureka client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    

    2.編寫appliciation.yml

    server:
      port: 80
    eureka:
      client:
        register-with-eureka: false
        service-url:
          defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
    

    3.編寫主方法

    @SpringBootApplication
    //開啟openfeign
    @EnableFeignClients
    public class FeignOrderMain80 {
        public static void main(String[] args) {
            SpringApplication.run(FeignOrderMain80.class,args);
        }
    }
    

    4.開啟feign注解的接口服務

    @Component
    @FeignClient(name = "CLOUD-PAYMENT-SERVICE")
    public interface FeignOrderService {
        @GetMapping("/payment/get/{id}")
        public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) ;
    }
    

    5.控制層編寫

    @RestController
    @Slf4j
    public class FeignPaymentController {
        @Resource
        FeignOrderService feignOrderService;
        @GetMapping("/consumer/payment/get/{id}")
        public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
            return feignOrderService.getPaymentById(id);
        }
    }
    

    2.openFeign的超時控制

    默認情況下,如果業務不在一秒內完成就會報出timeout的錯誤

    There was an unexpected error (type=Internal Server Error, status=500).
    
    Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/timeout
    
    feign.RetryableException: Read timed out executing GET http://CLOUD-PAYMENT-SERVICE/payment/timeout
    
    

    由于整合了ribbon,可以直接在yaml文件中進行修改

    ribbon:
      ReadTimeout: 5000
      ConnectTimeout: 5000
    

    3.日志增強

    1.新建配置類

    @Configuration
    public class MyFeignConfig {
        @Bean
        Logger.Level feignLoggerLevel(){
            return Logger.Level.FULL;
        }
    }
    

    2.改寫Yml文件

    logging:
      level:
        #以什么級別監視哪個接口
        com.xiaoxiao.springcloud.service.FeignOrderService: debug
    
    版權聲明:本文為qq_41522089原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/qq_41522089/article/details/106924510

    智能推薦

    SpringCloud負載均衡和服務調用之【Ribbon、OpenFeign】

    Ribbon(停更進維) 主要功能是提供客戶端的軟件負載均衡算法和服務調用(RestTemplate) 在Eureka的依賴下,已經自動引入了ribbon的依賴,默認實現了輪詢的負載均衡 更改Ribbon的負載規則為隨機 原理就是自定義一個類,實現IRule接口。官網明確提出自定義的配置類不能放在@ComponentScan所掃描的當前包及子包下,否則我們自定義的這個配置類就會被所有的Ribbon...

    SpringCloud(H版&alibaba)筆記(四)-Ribbon、OpenFeign 負載均衡服務調用

    目錄 一、Ribbon是什么 1.1 LB的分類: 二、再說一次RestTemplate 2.1 getForObject 方法與 getForEntity方法 三、 Ribbon負載均衡架構: 3.1 Ribbon在工作時分成兩步: 3.2 IRule繼承關系 四、代碼演示負載均衡 4.1 替換 4.2 Ribbon負載均衡算法: 4.3 根據RoundRobinRule輪詢的源碼進行編寫 五、...

    SpringCloud框架學習筆記(三)-- Ribbon負載均衡服務調用

    是什么? 總結:Ribbon其實就是一個軟負載均衡的客戶端組件,它可以和其他所需請求的客戶端結合使用,和eureka結合只是其中的一個實例 能干嗎? 負載均衡概念 Ribbon的工作 Ribbon演示: 首先在之前演示的時候,我們已經看到有輪詢的效果,這是因為eureka中已經集成了ribbon: RestTemplate的使用: Irule負載均衡算法 自帶的負載均衡算法: 修改8010的負載均...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    猜你喜歡

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    精品国产乱码久久久久久蜜桃不卡