花一個周末,掌握 SpringCloud Ribbon 負載均衡原理

2021-02-19 石杉的架構筆記
前言

繼 SpringCloud Feign 之後的第二篇分布式框架文章,同樣秉承單周末一個 SpringCloud 組件的大目標為原則

如果想看 Feign 的小夥伴,猛戳這裡,Feign 核心原理與你不期而遇

在平常使用 SpringCloud 中,一般會使用 Feign,因為 Feign 內部集成了 Ribbon

但是 Ribbon 又是一個不可忽視的知識點,並且比 Feign 要難很多。列舉文章大綱主題

文章使用 SpringCloud Ribbon 原始碼 Hoxton.SR9 版本:2.2.6.RELEASE

另外在文章結尾,說了一些看源碼過程中的感想,以及 Ribbon 中筆者實現不合理的流程說明

概念小貼士負載均衡

負載均衡是指通過負載均衡策略分配到多個執行單元上,常見的負載均衡方式有兩種

獨立進程單元,通過負載均衡策略,將請求進行分發到不同執行上,類似於 Nginx客戶端行為,將負載均衡的策略綁定到客戶端上,客戶端會維護一份服務提供者列表,通過客戶端負載均衡策略分發到不同的服務提供者Ribbon

Ribbon 是 Netflix 公司開源的一款負載均衡組件,負載均衡的行為在客戶端發生,所以屬於上述第二種

一般而言,SpringCloud 構建以及使用時,會使用 Ribbon 作為客戶端負載均衡工具。但是不會獨立使用,而是結合 RestTemplate 以及 Feign 使用,Feign 底層集成了 Ribbon,不用額外的配置,開箱即用

文章為了更貼切 Ribbon 主題,所以使用 RestTemplate 充當網絡調用工具

RestTemplate 是 Spring Web 下提供訪問第三方 RESTFul Http 接口的網絡框架

環境準備

註冊中心選用阿里 Nacos,創建兩個服務,生產者集群啟動,消費者使用 RestTemplate + Ribbon 調用,調用總體結構如下

生產者代碼如下,將服務註冊 Nacos,並對外暴露 Http Get 服務

消費者代碼如下,將服務註冊 Nacos,通過 RestTemplate + Ribbon 發起遠程負載均衡調用

RestTemplate 默認是沒有負載均衡的,所以需要添加 @LoadBalanced

啟動三個生產者實例註冊 Nacos,啟動並且註冊成功如下所示

想要按嚴格的先後順序介紹框架原理,而不超前引用尚未介紹過的術語,這幾乎是不可能的,筆者儘可能介紹明白

如何獲取註冊中心服務實例

先來看一下 Ribbon 是如何在客戶端獲取到註冊中心運行實例的,這個點在之前是我比較疑惑的內容

服務註冊相關的知識點,會放到 Nacos 源碼解析說明

先來舉個例子,當我們執行一個請求時,肯定要進行負載均衡對吧,這個時候代碼跟到負載均衡獲取服務列表源碼的地方

解釋一下上面標黃色框框的地方:

RibbonLoadBalancerClient:負責負載均衡的請求處理ILoadBalancer:接口中定義了一系列實現負載均衡的方法,相當於一個路由的作用,Ribbon 中默認實現類 ZoneAwareLoadBalancerunknown:ZoneAwareLoadBalancer 是多區域負載均衡器,這個 unkonwn 代表默認區域的意思allServerList:代表了從 Nacos 註冊中心獲取的接口服務實例,upServerList 代表了健康實例

現在想要知道 Ribbon 是如何獲取服務實例的就需要跟進 getLoadBalancer()

getLoadBalancer

首先聲明一點,getLoadBalancer() 方法的語意是從 Ribbon 父子上下文容器中獲取名稱為 ribbon-produce,類型為 ILoadBalancer.class 的 Spring Bean

之前在講 Feign 的時候說過,Ribbon 會為每一個服務提供者創建一個 Spring 父子上下文,這裡會從子上下文中獲取 Bean

看到這裡並沒有解決我們的疑惑,以為方法裡會有拉取服務列表的代碼,然鵝只是返回一個包含了服務實例的 Bean,所以我們只能去跟下這個 Bean 的上下文

我們需要從負載均衡客戶端著手,因為默認是 ZoneAwareLoadBalancer,那我們需要跟進它何時被創建,初始化都做了什麼事情

ZoneAwareLoadBalancer

ZoneAwareLoadBalancer 是一個根據區域(Zone)來進行負載均衡器,因為如果不同機房跨區域部署服務列表,跨區域的方式訪問會產生更高的延遲,ZoneAwareLoadBalancer 就是為了解決此類問題,不過默認都是同一區域

ZoneAwareLoadBalancer 很重要,或者說它代表的 負載均衡路由角色 很重要。進行服務調用前,會使用該類根據負載均衡算法獲取可用 Server 進行遠程調用,所以我們要掌握創建這個負載均衡客戶端時都做了哪些

ZoneAwareLoadBalancer 是在服務第一次被調用時通過子容器創建

@Bean @ConditionalOnMissingBean  // RibbonClientConfiguration 被加載,從 IOC 容器中獲取對應實例填充到 ZoneAwareLoadBalancer
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
                                        ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
                                        IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
    ...
    return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
            serverListFilter, serverListUpdater);
}

public ZoneAwareLoadBalancer(IClientConfig clientConfig, IRule rule,
                             IPing ping, ServerList<T> serverList, ServerListFilter<T> filter,
                             ServerListUpdater serverListUpdater) {
    // 調用父類構造方法
    super(clientConfig, rule, ping, serverList, filter, serverListUpdater);
}

在 DynamicServerListLoadBalancer 中調用了父類 BaseLoadBalancer 初始化了一部分配置以及方法,另外自己也初始化了 Server 服務列表等元數據

public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping,
                                     ServerList<T> serverList, ServerListFilter<T> filter,
                                     ServerListUpdater serverListUpdater) {
    // 調用父類 BaseLoadBalancer 初始化一些配置,包括 Ping(檢查服務是否可用)Rule(負載均衡規則)
    super(clientConfig, rule, ping);  
    // 較重要,獲取註冊中心服務的接口
    this.serverListImpl = serverList;
    this.filter = filter;
    this.serverListUpdater = serverListUpdater;
    if (filter instanceof AbstractServerListFilter) {
        ((AbstractServerListFilter) filter).setLoadBalancerStats(getLoadBalancerStats());
    }
    // 初始化步驟分了兩步走,第一步在上面,這一步就是其餘的初始化
    restOfInit(clientConfig);
}

先來說一下 BaseLoadBalancer 中初始化的方法,這裡主要對一些重要參數以及 Ping、Rule 賦值,另外根據 IPing 實現類執行定時器,下面介紹 Ping 和 Rule 是什麼

方法大致做了以下幾件事情:

獲取每次 Ping 的間隔以及 Ping 的最大時間設置具體負載均衡規則 IRule,默認 ZoneAvoidanceRule,根據 server 和 zone 區域來輪詢設置具體 Ping 的方式,默認 DummyPing,直接返回 True根據 Ping 的具體實現,執行定時任務 Ping Server

這裡會介紹被填入的 IPing 和 IRule 是什麼東東,並且都有哪些實現

IPing 服務探測

IPing 接口負責向 Server 實例發送 ping 請求,判斷 Server 是否有響應,以此來判斷 Server 是否可用

接口只有一個方法 isAlive,通過實現類完成探測 ping 功能

public interface IPing {
    public boolean isAlive(Server server);
}

IPing 實現類如下:

PingUrl:通過 ping 的方式,發起網絡調用來判斷 Server 是否可用(一般而言創建 PingUrl 需要指定路徑,默認是 IP + Port)PingConstant:固定返回某服務是否可用,默認返回 True,表示可用NoOpPing:沒有任何操作,直接返回 True,表示可用DummyPing:默認的類,直接返回 True,實現了 initWithNiwsConfig 方法IRule 負載均衡

IRule 接口負責根據不用的算法和邏輯處理負載均衡的策略,自帶的策略有 7 種,默認 ZoneAvoidanceRule

BestAvailableRule:選擇服務列表中最小請求量的 ServerRandomRule:服務列表中隨機選擇 ServerRetryRule:根據輪詢的方式重試 ServerZoneAvoidanceRule:根據 Server 的 Zone 區域和可用性輪詢選擇 Server

上面說過,會有兩個初始化步驟,剛才只說了一個,接下來說一下 這個其餘初始化方法 restOfInit,雖然取名叫其餘初始化,但是就重要性而言,那是相當重要

void restOfInit(IClientConfig clientConfig) {
    boolean primeConnection = this.isEnablePrimingConnections();
    // turn this off to avoid duplicated asynchronous priming done in BaseLoadBalancer.setServerList()
    this.setEnablePrimingConnections(false);
    // 初始化服務列表,並啟用定時器,對服務列表作出更新
    enableAndInitLearnNewServersFeature();
    // 更新服務列表,enableAndInitLearnNewServersFeature 中定時器的執行的就是此方法
    updateListOfServers();
    if (primeConnection && this.getPrimeConnections() != null) {
        this.getPrimeConnections()
                .primeConnections(getReachableServers());
    }
    this.setEnablePrimingConnections(primeConnection);
    LOGGER.info("DynamicServerListLoadBalancer for client {} initialized: {}", clientConfig.getClientName(), this.toString());
}

獲取服務列表以及定時更新服務列表的代碼都在此處,值得仔細看著源碼。關注其中更新服務列表方法就闊以了

public void updateListOfServers() {
    List<T> servers = new ArrayList<T>();
    if (serverListImpl != null) {
        // 獲取服務列表數據
        servers = serverListImpl.getUpdatedListOfServers();
        LOGGER.debug("List of Servers for {} obtained from Discovery client: {}",
                getIdentifier(), servers);

        if (filter != null) {
            servers = filter.getFilteredListOfServers(servers);
            LOGGER.debug("Filtered List of Servers for {} obtained from Discovery client: {}",
                    getIdentifier(), servers);
        }
    }
    // 更新所有服務列表
    updateAllServerList(servers);
}

第一個問題兜兜轉轉,終於要找到如何獲取的服務列表了,serverListImpl 實現自 ServerList,因為我們使用的 Nacos 註冊中心,所以 ServerList 的具體實現就是 NacosServerList

public interface ServerList<T extends Server> {
    public List<T> getInitialListOfServers();
    public List<T> getUpdatedListOfServers();
}

ServerList 中只有兩個接口方法,分別是 獲取初始化服務列表集合、獲取更新的服務列表集合,Nacos 實現中兩個調用都是一個實現方法,可能設計如此

相當於 Ribbon 提供出接口 ServerList,註冊中心開發者們誰想和 Ribbon 集成,那你就實現這個接口吧,到時候 Ribbon 負責調用 ServerList 實現類中的方法實現

Ribbon 和各服務註冊中心之間,這種實現方式和 JDBC 與各資料庫之間很像

兜兜轉轉中問題已經明朗,一起總結下註冊中心獲取服務實例這塊內容

負載均衡客戶端在初始化時向 Nacos 註冊中心獲取服務註冊列表信息根據不同的 IPing 實現,向獲取到的服務列表 串行發送 ping,以此來判斷服務的可用性。沒錯,就是串行,如果你的實例很多,可以 考慮重寫 ping 這一塊的邏輯如果服務的可用性 發生了改變或者被人為下線,那麼重新拉取或更新服務列表當負載均衡客戶端有了這些服務註冊類列表,自然就可以進行 IRule 負載均衡策略非健康服務實例如何下線

首先筆者做了兩個 "大膽" 的實驗,第一次是對生產者 SpringBoot 項目執行關閉流程,這時候 Nacos 註冊中心是 實時感知到並將此服務下該實例刪除

證明 Nacos 客戶端是有 類似於鉤子函數的存在,感知項目停止就會向 Nacos 服務端註銷實例。但是這個時候要考慮一件事情,那就是在 暴力 Kill 或者執行關閉操作 的情況下,存在於 Ribbon 客戶端服務列表緩存能不能感知

第二次我這邊測試流程是這樣的,可以極大程度還原生產上使用 Ribbon 可能會遇到的問題

改變客戶端負載均衡策略為 隨機負載 RandomRule,大家自己可以進行測試,不固定負載規則註冊三個生產者服務實例到 Nacos 上,檢查 確保服務組下實例正常註冊操作重點來了,先通過消費方實例請求下對應的生產者接口,保證 Ribbon 將對應 Server 緩存到客戶端停掉一個生產者服務,此時 馬上使用 Jmeter 調用,Jmeter 線程組發起請求 100 次(一定要趕到更新 Server 緩存之前發起 Jmeter 請求)這時就會看到會發生隨機失敗,也就是說停掉一個服務後,最壞結果會有 30 秒的生產服務不可用,這個時間可配置,後面會講到為什麼 30 秒服務列表定時維護

針對於服務列表的維護,在 Ribbon 中有兩種方式,都是通過定時任務的形式維護客戶端列表緩存

使用 IPing 的實現類 PingUrl,每隔 10 秒會去 Ping 服務地址,如果返回狀態不是 200,那麼默認該實例下線Ribbon 客戶端內置的掃描,默認每隔 30 秒去拉取 Nacos 也就是註冊中心的服務實例,如果已下線實例會在客戶端緩存中剔除

這一塊源碼都不貼了,放兩個原始碼位置,感興趣自己看看就行了

+ DynamicServerListLoadBalancer#enableAndInitLearnNewServersFeature
+ BaseLoadBalancer#setupPingTask

如果你面試的時候,面試官問了本小節相關內容,把這兩個點都能答出來,基本上 SpringCloud 源碼就差不多了

Ribbon 底層原理實現

底層原理實現這一塊內容,會先說明使用 Ribbon 負載均衡調用遠端請求的全過程,然後著重看一下 RandomRule 負載策略底層是如何實現

創建 ILoadBalancer 負載均衡客戶端,初始化 Ribbon 中所需的 定時器和註冊中心上服務實例列表從 ILoadBalancer 中,通過 負載均衡選擇出健康服務列表中的一個 Server將服務名(ribbon-produce)替換為 Server 中的 IP + Port,然後生成 HTTP 請求進行調用並返回數據

上面已經說過,ILoadBalancer 是負責負載均衡路由的,內部會使用 IRule 實現類進行負載調用

public interface ILoadBalancer {
    public Server chooseServer(Object key);
   ...
}

chooseServer 流程中調用的就是 IRule 負載策略中的 choose 方法,在方法內部獲取一個健康 Server

public Server choose(ILoadBalancer lb, Object key) {
    ... 
    Server server = null;
    while (server == null) {
        ...
        List<Server> upList = lb.getReachableServers();  // 獲取服務列表健康實例
        List<Server> allList = lb.getAllServers();  // 獲取服務列表全部實例
        int serverCount = allList.size();  // 全部實例數量
        if (serverCount == 0) {  // 全部實例數量為空,返回 null,相當於錯誤返回
            return null;
        }
        int index = chooseRandomInt(serverCount);  // 考慮到效率問題,使用多線程 ThreadLocalRandom 獲取隨機數
        server = upList.get(index);  // 獲取健康實例
        if (server == null) {
            // 作者認為出現獲取 server 為空,證明服務列表正在調整,但是!這只是暫時的,所以當前釋放出了 CPU
            Thread.yield();
            continue;
        }
        if (server.isAlive()) {  // 服務為健康,返回
            return (server);
        }
        ...
    }
    return server;
}

簡單說一下隨機策略 choose 中流程

獲取到全部服務、健康服務列表,判斷全部實例數量是否等於 0,是則返回 null,相當於發生了錯誤從全部服務列表裡獲取下標索引,然後去 健康實例列表獲取 Server如果獲取到的 Server 為空會放棄 CPU,然後再來一遍上面的流程,相當於一種重試機制如果獲取到的 Server 不健康,設置 Server 等於空,再歇一會,繼續走一遍上面的流程

比較簡單,有小夥伴可能就問了,如果健康實例小於全部實例怎麼辦?這種情況下存在兩種可能

運氣比較好,從全部實例數量中隨機了比較小的數,剛好健康實例列表有這個數,那麼返回 Server運氣比較背,從全部實例數量中隨機了某個數,健康實例列表數量為空或者小於這個數,直接會下標越界異常

留下一個思考題:

為什麼不直接從健康實例中選擇實例呢

如果直接從健康實例列表選擇,就能規避下標越界異常,為什麼作者要先從全部實例中獲取 Server 下標?

自定義 Ribbon 負載均衡策略

這種自定義策略,在框架中都支持的比較友好,根據上面提的問題,我們自定義一款策略

@Slf4j
public class MyRule extends AbstractLoadBalancerRule {
    @Override
    public Server choose(Object key) {
        ILoadBalancer loadBalancer = getLoadBalancer();
        while (true && ) {
            Server server = null;
            // 獲取已啟動並且可訪問的服務列表
            List<Server> reachableServers = loadBalancer.getReachableServers();
            if (CollectionUtils.isEmpty(reachableServers)) return null;
            int idx = ThreadLocalRandom.current().nextInt(reachableServers.size());
            server = reachableServers.get(idx);
            if (server == null || server.isAlive()) {
                log.warn("Ribbon 服務實例異常, 獲取為空 || 狀態不健康");
                Thread.yield();
                continue;
            }
            return server;
        }
    }

    ... initWithNiwsConfig 不用實現
}

說一下我們自己實現的 MyRule 負載的邏輯:

IRule 獲取服務列表沒有在調用方實現,而是抽象 AbstractLoadBalancerRule,所以我們要獲取服務列表繼承就好了和隨機負載規則大致相似,只不過這裡簡化了流程,直接從健康的服務實例列表獲取 Server 實例確定 Server 不為空並且節點健康後返回,如果不符合則列印日誌,睡一會再重複如果保險起見,最好在 while 中加入一個循環次數的條件,避免死循環

然後把 MyRule 註冊到 SPring IOC 容器中就好了,在初始化時就會代替默認的 Rule 負載規則

關於 IPing 的思考

在閱讀 Ribbon Ping 這一塊原始碼時,發現了兩處個人認為不太合理的地方

setPingInterval 設置 Ping 間隔時執行設置 Ping 任務無意義BaseLoadBalancer 構造函數中 ping 為 null,又再次調用了 setPingInterval,結果只會返回空

setPingInterval 和 setPing 兩個方法發生在 BaseLoadBalancer 初始化時,相當於接著上面邏輯繼續。先說明執行邏輯,再看下不合理的地方

setupPingTask 用於定期執行對 Server 的 ping 任務,也就是檢測 Server 是否可用

個人覺得在 setPingInterval 中沒有必要執行 setupPingTask 方法

作出上述結論有以下依據:

第一次執行 setPingInterval 時,ping 必然為空,那麼會在 canSkipPing 中返回 True,繼而直接結束 setPingInterval 方法後來想了下,會不會在別的地方引用,需要強制刷新,然鵝全局搜索了下引用,只有在此次初始化時調用,當然不排除別的依賴包會使用此方法綜上所述,setPingInterval 執行設置 Ping 任務的方法無意義

另外還有一點,作者感覺代碼中調用的方法沒有實際意義。和上述類似,都是在 ping 為空時執行了 setPingInterval 方法

以上這兩點是筆者跟源碼時,發現不妥當的地方,所以在這裡佔了一些篇幅說明,主要是想表達兩點自己的想法給讀者朋友

不要對源碼有敬畏之心,應該有敬畏之心的是生產環境! 不要感覺看框架源碼是一件高不可攀的事情,其實有時候你理解不了的代碼,可能只是多人維護後,混亂的產物,條件允許的情況下,還是要多跟進源碼去看一看直言說出自己的見解,如果只有自己去想,那麼很可能沒有答案,通過文章間接的方式讓更多小夥伴看到,指正錯誤言論亦或者得到肯定結言

整體來看,文章更 注重表達設計思想以及源碼分析,所以閱讀文章需要一定的源碼功底。同時文章是針對問題而展開敘述,哪怕源碼不理解也能有所收穫

Ribbon 這塊內容從初始化負載均衡客戶端 ILoadBalancer 說起,講述了初始化過程中具體的內容,包括如何開啟 IPing 定時器以及服務列表更新定時器

另外通過源碼查看到 Ribbon 的服務列表其實是向 Nacos 提供的接口發起服務調用 獲取並保存到本地緩存,繼而牽引出如何保證不健康實例下線:IPing 定時器和服務更新定時器

文末章節說了下請求 Ribbon 負載均衡的全鏈路以及如何自己定義一個負載均衡算法。最最後面也說了下自己看源碼過程中對 SpringCloud IPing 感覺無意義的代碼,當然,不排除是為了別的包集成而留下的

相關焦點

  • spring cloud中RestTemplate網絡請求框架和Ribbon負載均衡器
    本片主要是介紹spring cloud構建微服務系統的RIbbon負載均衡器和網絡請求框架RestTemplate的介紹。下一篇文章將會通過實例帶領大家如何通過Ribbon和RestTemplate相結合實現負載均衡。
  • spring cloud如何使用RestTemplate和Ribbon相結合實現負載均衡
    下面我們啟動eureka-server和eureka-client,如下圖:接下來我們再新建一個eureka-ribbon-client工程,創建完成eureka-ribbon-client的module工程之後,在其pom文件中引入相關的依賴,包括繼承了主maven工程的pom文件,引入了eureka-client的起步依賴spring-cloud-starter-eureka
  • 圖靈學院:「微服務架構」SpringCloud之Ribbon(四)
    我們也很容易使用Ribbon實現自定義的負載均衡算法。3 秒鐘);列印出負載均衡器記錄的伺服器統計信息。-- lookup parent from repository --></parent><dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon
  • 從零搭建 Spring Cloud 服務(超詳細)
    +ribbon ribbon是一種負載均衡的客戶端,它是什麼呢?請詳讀https://www.jianshu.com/p/1bd66db5dc46可以看見其中的一段如下:而客戶端負載均衡和服務端負載均衡最大的不同點在於上面所提到服務清單所存儲的位置。
  • SpringCloud服務間通信方式
    總結:在springcloud中服務間調用方式主要是使用 http restful方式進行服務間調用1|0 1.總結rest Template是直接基於服務地址調用沒有在服務註冊中心獲取服務,也沒有辦法完成服務的負載均衡如果需要實現服務的負載均衡需要自己書寫服務負載均衡策略。
  • 擁抱Kubernetes,再見了Spring Cloud
    Spring Cloud 官方提供的解決方案為解決該問題,官方在 Github 上提供了開源方案,說明如何以 Spring Cloud 整合 Kubernetes 生態下的元件,主要討論從原本組件架構過度並一直到 Kubernetes 原生環境後的處理方法https://github.com/spring-cloud/spring-cloud-kubernetes
  • springcloud五大組件
    首先我們來看springcloud是什麼?它是微服務架構集大成者,基於springboot構建,可以將一系列優秀組件進行完美整合。對熟悉的程式設計師來說,上手不麻煩,對新手來說,就需要了解springcloud架構再去學習。
  • SpringCloud Gateway動態路由
    一個環境新版本,一個環境舊版本,通過負載均衡進行切換與回滾,目的是為了減少服務停止時間。滾動部署就是在升級過程中,並不一下子啟動所有新版本,是先啟動一臺新版本,再停止一臺老版本,然後再啟動一臺新版本,再停止一臺老版本,直到升級完成。基於 k8s 的升級方案默認就是滾動部署。
  • Spring Cloud 2020.0.0 正式發布,移除大量模塊
    代號"Ilford",伊爾福德)版本正式發布,目前已可以從 maven 中央倉庫獲取,坐標如下:<dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud
  • springcloud的五大組件是什麼?讀完這篇就懂了
    概括而言,springcloud的五大組件包括Netflix Eurek,Netflix Ribbon,Netflix Hystrix,Netflix Zuul和Spring Cloud Config。
  • Spring Cloud Hoxton.RELEASE 版本發布!異步即未來
    <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies
  • 阿里巴巴SpringCloud開源教程、文檔合集,趕緊收藏
    終章不是最後一篇,它是一個匯總,未來還會寫很多篇。不要問我為什麼?你們要學習我也要學習啊,共享讓人快了,缺點總是要有被人指點出來的!cloud config將配置存儲在資料庫中Spring Cloud Sleuth 之Greenwich版本全攻略Spring Boot Admin 2.1.0 全攻略阿里分布式事務框架GTS開源了!
  • 4年 46 個版本,一文讀懂 Spring Cloud 發展歷史
    Spring Cloud Circuit Breaker 用於統一熔斷操作的編程模型和 Spring Cloud LoadBalanacer 用於處理客戶端負載均衡並代替 Netflix Ribbon)。
  • springcloud實踐二:gateway網關詳解
    微服務框架當前大行其道,網關在微服務架構中是一個非常重要的部分,網關一般作為項目的統一請求入口提供給前端開發人員,前端開發人員不用知道每個微服務的請求地址。網關可以統一對所有請求做過濾、限流、負載均衡、監控等處理,而不必在每個微服務項目重複處理請求。
  • 什麼是SpringCloud?
    其實SpringCloud也支持的負載均衡功能,只不過它是客戶端的負載均衡,這個功能實現就是Ribbon!負載均衡又區分了兩種類型:客戶端負載均衡(Ribbon)服務端負載均衡(Nginx)所以,我們的圖可以畫成這樣:
  • SpringCloud常見面試題(2020最新版)
    它利用Spring Boot的開發便利性巧妙地簡化了分布式系統基礎設施的開發,如服務發現註冊、配置中心、智能路由、消息總線、負載均衡、斷路器、數據監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。
  • Spring Cloud 中 Zuul 網關到底有何牛逼之處?竟然這麼多人在用!
    Zuul是spring cloud中的微服務網關。網關:是一個網絡整體系統中的前置門戶入口。請求首先通過網關,進行路徑的路由,定位到具體的服務節點上。Zuul是一個微服務網關,首先是一個微服務。也是會在Eureka註冊中心中進行服務的註冊和發現。也是一個網關,請求應該通過Zuul來進行路由。Zuul網關不是必要的。是推薦使用的。
  • 基於 Spring Boot 和 Spring Cloud 實現微服務架構
    Spring Boot:旨在簡化創建產品級的 Spring 應用和服務,簡化了配置文件,使用嵌入式web伺服器,含有諸多開箱即用微服務功能,可以和spring cloud聯合部署。Spring cloud子項目目前來說spring主要集中於spring boot(用於開發微服務)和spring cloud相關框架的開發,我們從幾張圖著手理解,然後再具體介紹:
  • 基於Spring Boot和Spring Cloud實現微服務架構
    Spring Framework:即通常所說的spring 框架,是一個開源的Java/Java EE全功能棧應用程式框架,其它spring項目如spring boot也依賴於此框架。Spring cloud子項目目前來說spring主要集中於spring boot(用於開發微服務)和spring cloud相關框架的開發,我們從幾張圖著手理解,然後再具體介紹: