centos选择什么版本_有几千个 Dubbo 实例的瓜子二手车,为什么要选择2.7.3版本?...
public void register(URL url) {
super.register(url);
failedRegistered.remove(url);
failedUnregistered.remove(url);
try {
// Sending a registration request to the server side
doRegister(url);
} catch (Exception e) {
Throwable t = e;
// If the startup detection is opened, the Exception is thrown directly.
boolean check = getUrl().getParameter(Constants.CHECK_KEY, true)
&& url.getParameter(Constants.CHECK_KEY, true)
&& !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol());
boolean skipFailback = t instanceof SkipFailbackWrapperException;
if (check || skipFailback) {
if (skipFailback) {
t = t.getCause();
}
throw new IllegalStateException("Failed to register " + url + " to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(), t);
} else {
logger.error("Failed to register " + url + ", waiting for retry, cause: " + t.getMessage(), t);
}
// Record a failed registration request to a failed list, retry regularly
failedRegistered.add(url);
}
}
在繼續(xù)排查問(wèn)題前,我們先普及下這些概念:Dubbo 默認(rèn)使用 curator 作為ZooKeeper 的客戶(hù)端, curator 與 ZooKeeper 是通過(guò) session 維持連接的。當(dāng) curator 重連 ZooKeeper 時(shí),若 session 未過(guò)期,則繼續(xù)使用原 session 進(jìn)行連接;若 session 已過(guò)期,則創(chuàng)建新 session 重新連接。而 Ephemeral 節(jié)點(diǎn)與 session 是綁定的關(guān)系,在 session 過(guò)期后,會(huì)刪除此 session 下的 Ephemeral 節(jié)點(diǎn)。繼續(xù)對(duì) doRegister(url) 的代碼進(jìn)行進(jìn)一步排查,我們發(fā)現(xiàn)在 CuratorZookeeperClient.createEphemeral(path) 方法中有這么一段邏輯:在createEphemeral(path) 捕獲了 NodeExistsException ,創(chuàng)建 Ephemeral 節(jié)點(diǎn)時(shí),若此節(jié)點(diǎn)已存在,則認(rèn)為 Ephemeral 節(jié)點(diǎn)創(chuàng)建成功。這段邏輯初看起來(lái)并沒(méi)有什么問(wèn)題,且在以下兩種常見(jiàn)的場(chǎng)景下表現(xiàn)正常:Session 未過(guò)期,創(chuàng)建 Ephemeral 節(jié)點(diǎn)時(shí)原節(jié)點(diǎn)仍存在,不需要重新創(chuàng)建。
Session 已過(guò)期,創(chuàng)建 Ephemeral 節(jié)點(diǎn)時(shí)原節(jié)點(diǎn)已被 ZooKeeper 刪除,創(chuàng)建成功。
public void createEphemeral(String path) {
try {
client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
} catch (NodeExistsException e) {
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
但是實(shí)際上還有一種極端場(chǎng)景,ZooKeeper 的 Session 過(guò)期與刪除 Ephemeral 節(jié)點(diǎn)不是原子性的,也就是說(shuō)客戶(hù)端在得到 Session 過(guò)期的消息時(shí), Session 對(duì)應(yīng)的 Ephemeral 節(jié)點(diǎn)可能還未被 ZooKeeper刪除。此時(shí) Dubbo 去創(chuàng)建 Ephemeral 節(jié)點(diǎn),發(fā)現(xiàn)原節(jié)點(diǎn)仍存在,故不重新創(chuàng)建。待 Ephemeral 節(jié)點(diǎn)被 ZooKeeper 刪除后,便會(huì)出現(xiàn) Dubbo 認(rèn)為重新注冊(cè)成功,但實(shí)際未成功的情況,也就是我們?cè)谏a(chǎn)環(huán)境遇到的問(wèn)題。此時(shí),問(wèn)題的根源已被定位。定位問(wèn)題之后,經(jīng)我們與 Dubbo 社區(qū)交流,發(fā)現(xiàn)考拉的同學(xué)也遇到過(guò)同樣的問(wèn)題,更確定了這個(gè)原因。問(wèn)題的復(fù)現(xiàn)與修復(fù)定位到問(wèn)題之后,我們便開(kāi)始嘗試本地復(fù)現(xiàn)。由于 ZooKeeper 的 Session 過(guò)期但 Ephemeral 節(jié)點(diǎn)未被刪除的場(chǎng)景直接模擬比較困難,我們通過(guò)修改 ZooKeeper 源碼,在 Session 過(guò)期與刪除 Ephemeral 節(jié)點(diǎn)的邏輯中增加了一段休眠時(shí)間,間接模擬出這種極端場(chǎng)景,并在本地復(fù)現(xiàn)了此問(wèn)題。在排查問(wèn)題的過(guò)程中,我們發(fā)現(xiàn) Kafka 的舊版本在使用 ZooKeeper 時(shí)也遇到過(guò)類(lèi)似的問(wèn)題,并參考 Kafka 關(guān)于此問(wèn)題的修復(fù)方案,確定了 Dubbo 的修復(fù)方案。在創(chuàng)建 Ephemeral 節(jié)點(diǎn)捕獲到 NodeExistsException 時(shí)進(jìn)行判斷,若 Ephemeral 節(jié)點(diǎn)的 SessionId 與當(dāng)前客戶(hù)端的 SessionId 不同,則刪除并重建 Ephemeral 節(jié)點(diǎn)。在內(nèi)部修復(fù)并驗(yàn)證通過(guò)后,我們向社區(qū)提交了 issues 及 pr。Kafka 類(lèi)似問(wèn)題 issues:https://issues.apache.org/jira/browse/KAFKA-1387Dubbo 注冊(cè)恢復(fù)問(wèn)題 issues:https://github.com/apache/dubbo/issues/5125瓜子的 Dubbo 升級(jí)歷程上文中的問(wèn)題修復(fù)方案已經(jīng)確定,但我們顯然不可能在每一個(gè) Dubbo 版本上都進(jìn)行修復(fù)。在咨詢(xún)了社區(qū) Dubbo 的推薦版本后,我們決定在 Dubbo2.7.3 版本的基礎(chǔ)上,開(kāi)發(fā)內(nèi)部版本修復(fù)來(lái)這個(gè)問(wèn)題。并借這個(gè)機(jī)會(huì),開(kāi)始推動(dòng)公司 Dubbo 版本的統(tǒng)一升級(jí)工作。為什么要統(tǒng)一 Dubbo版本?統(tǒng)一 Dubbo 版本后,我們可以在此版本上內(nèi)部緊急修復(fù)一些 Dubbo 問(wèn)題(如上文的 Dubbo 注冊(cè)故障恢復(fù)失效問(wèn)題)。
瓜子目前正在進(jìn)行第二機(jī)房的建設(shè),部分 Dubbo 服務(wù)也在逐漸往第二機(jī)房遷移。統(tǒng)一 Dubbo 版本,也是為 Dubbo 的多機(jī)房做鋪墊。
有利于我們后續(xù)對(duì) Dubbo 服務(wù)的統(tǒng)一管控。
Dubbo 社區(qū)目前的發(fā)展方向與我們公司現(xiàn)階段對(duì) Dubbo 的一些訴求相吻合,如支持 gRPC、云原生等。
我們了解到,在我們之前攜程已經(jīng)與 Dubbo 社區(qū)合作進(jìn)行了深度合作,攜程內(nèi)部已全量升級(jí)為 2.7.3 的社區(qū)版本,并在協(xié)助社區(qū)修復(fù)了 2.7.3 版本的一些兼容性問(wèn)題。感謝攜程的同學(xué)幫我們踩坑~
Dubbo2.7.3 版本在當(dāng)時(shí)雖然是最新的版本,但已經(jīng)發(fā)布了 2 個(gè)月的時(shí)間,從社區(qū) issues 反饋來(lái)看,Dubbo 2.7.3 相對(duì) Dubbo2.7 之前的幾個(gè)版本,在兼容性方面要好很多。
我們也咨詢(xún)了 Dubbo 社區(qū)的同學(xué),推薦升級(jí)版本為 2.7.3。
初步兼容性驗(yàn)證。首先,我們梳理了一些需要驗(yàn)證的兼容性 case ,針對(duì)公司內(nèi)部使用較多的 Dubbo 版本,與 Dubbo 2.7.3 一一進(jìn)行了兼容性驗(yàn)證。經(jīng)驗(yàn)證,除 DubboX 外, Dubbo 2.7.3 與其他 Dubbo 版本均兼容。DubboX 由于對(duì) Dubbo 協(xié)議進(jìn)行了更改,與 Dubbo2.7.3 不兼容。
生產(chǎn)環(huán)境兼容性驗(yàn)證。在初步驗(yàn)證兼容性通過(guò)后,我們與業(yè)務(wù)線合作,挑選了一些重要程度較低的項(xiàng)目,在生產(chǎn)環(huán)境對(duì) Dubbo 2.7.3 與其他版本的兼容性進(jìn)行了進(jìn)一步驗(yàn)證。并在內(nèi)部版本修復(fù)了一些兼容性問(wèn)題。
推動(dòng)公司 Dubbo 版本升級(jí)。在 10 月初,完成了 Dubbo 兼容性驗(yàn)證后,我們開(kāi)始在各個(gè)業(yè)務(wù)線推動(dòng) Dubbo 的升級(jí)工作。截止到 12 月初,已經(jīng)有 30% 的 Dubbo 服務(wù)的完成了版本升級(jí)。按照排期,預(yù)計(jì)于 2020 年 3 月底前完成公司 Dubbo 版本的統(tǒng)一升級(jí)。
org.apache.curator
curator-framework
4.2.0
org.apache.curator
curator-recipes
4.2.0
b. 分布式調(diào)度框架 elastic-job-lite 強(qiáng)依賴(lài)低版本的 curator,與 Dubbo 2.7.3 使用的 curator 版本不兼容,這給 Dubbo 版本升級(jí)工作帶來(lái)了一定阻塞。考慮到 elastic-job-lite 已經(jīng)很久沒(méi)有人進(jìn)行維護(hù),目前一些業(yè)務(wù)線計(jì)劃將 elastic-job-lite 替換為其他的調(diào)度框架。3、OpenFeign 與 Dubbo 兼容性問(wèn)題issues:https://github.com/apache/dubbo/issues/3990Dubbo 的 ServiceBean 監(jiān)聽(tīng) Spring 的 ContextRefreshedEvent,進(jìn)行服務(wù)暴露。OpenFeign 提前觸發(fā)了 ContextRefreshedEvent,此時(shí) ServiceBean 還未完成初始化,于是就導(dǎo)致了應(yīng)用啟動(dòng)異常。參考社區(qū)的 pr,我們?cè)趦?nèi)部版本修復(fù)了此問(wèn)題。4、RpcException 兼容性問(wèn)題Dubbo 低版本 consumer 不能識(shí)別 Dubbo 2.7 版本 provider 拋出的 org.apache.dubbo.rpc.RpcException。因此,在 consumer 全部升級(jí)到 2.7 之前,不建議將 provider 的 com.alibaba.dubbo.rpc.RpcException 改為 org.apache.dubbo.rpc.RpcException。5、QoS 端口占用Dubbo 2.7.3 默認(rèn)開(kāi)啟 QoS 功能,導(dǎo)致一些混部在物理機(jī)的 Dubbo 服務(wù)升級(jí)時(shí)出現(xiàn) QoS 端口占用問(wèn)題。關(guān)閉 QoS 功能后恢復(fù)。6、自定義擴(kuò)展兼容性問(wèn)題業(yè)務(wù)線對(duì)于 Dubbo 的自定義擴(kuò)展比較少,因此在自定義擴(kuò)展的兼容性方面暫時(shí)還沒(méi)有遇到比較難處理的問(wèn)題,基本上都是變更 package 導(dǎo)致的問(wèn)題,由業(yè)務(wù)線自行修復(fù)。7、Skywalking agent 兼容性問(wèn)題我們項(xiàng)目中一般使 Skywalking 進(jìn)行鏈路追蹤,由于 Skywalking agent6.0 的 plugin 不支持 Dubbo 2.7,因此統(tǒng)一升級(jí) Skywalking agent 到 6.1 。Dubbo 多機(jī)房方案瓜子目前正在進(jìn)行第二機(jī)房的建設(shè)工作,Dubbo 多機(jī)房是第二機(jī)房建設(shè)中比較重要的一個(gè)話(huà)題。在 Dubbo 版本統(tǒng)一的前提下,我們就能夠更順利的開(kāi)展 Dubbo 多機(jī)房相關(guān)的調(diào)研與開(kāi)發(fā)工作。初步方案我們咨詢(xún)了 Dubbo 社區(qū)的建議,并結(jié)合瓜子云平臺(tái)的現(xiàn)狀,初步確定了 Dubbo 多機(jī)房的方案。在每個(gè)機(jī)房?jī)?nèi),部署一套獨(dú)立的 ZooKeeper 集群。集群間信息不同步。這樣就沒(méi)有了 ZooKeeper 集群跨機(jī)房延遲與數(shù)據(jù)不同步的問(wèn)題。
Dubbo 服務(wù)注冊(cè)時(shí),僅注冊(cè)到本機(jī)房的 ZooKeeper 集群;訂閱時(shí),同時(shí)訂閱兩個(gè)機(jī)房的 ZooKeeper 集群。
實(shí)現(xiàn)同機(jī)房?jī)?yōu)先調(diào)用的路由邏輯。以減少跨機(jī)房調(diào)用導(dǎo)致的不必要網(wǎng)絡(luò)延遲。
瓜子云平臺(tái)默認(rèn)將機(jī)房的標(biāo)志信息注入容器的環(huán)境變量中。
provider 暴露服務(wù)時(shí),讀取環(huán)境變量中的機(jī)房標(biāo)志信息,追加到待暴露服務(wù)的 url 中。
consumer 調(diào)用 provider 時(shí),讀取環(huán)境變量中的機(jī)房標(biāo)志信息,根據(jù)路由策略?xún)?yōu)先調(diào)用具有相同標(biāo)志信息的 provider。
總結(jié)
以上是生活随笔為你收集整理的centos选择什么版本_有几千个 Dubbo 实例的瓜子二手车,为什么要选择2.7.3版本?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python flask高级编程之res
- 下一篇: Java常用设计模式————外观模式