自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何使用Java可觀(guān)察性進(jìn)行有效編碼

譯文
開(kāi)發(fā) 前端
開(kāi)發(fā)團(tuán)隊(duì)如何使用豐富的代碼運(yùn)行時(shí)數(shù)據(jù)更好地進(jìn)行代碼編寫(xiě)和發(fā)布?可觀(guān)察性能方面的例子有哪些呢?

譯者 | 李睿

審校 | 重樓

多年來(lái),在試圖使可觀(guān)察性計(jì)劃取得成功的過(guò)程中,許多企業(yè)犯了一些常見(jiàn)的錯(cuò)誤。然而,這些企業(yè)的失誤中最關(guān)鍵和最根本的問(wèn)題是對(duì)技術(shù)和工具本身的不可抗拒的迷戀。

這應(yīng)該讓人感到意外。許多“讓我們添加可觀(guān)察性平臺(tái)X”的項(xiàng)目在開(kāi)始時(shí)通常都是大張旗鼓,但其方向感非常模糊,并且成功的標(biāo)準(zhǔn)也非?;靵y。對(duì)于有效的可觀(guān)察性可以做些什么來(lái)幫助開(kāi)發(fā)人員更好地工作,許多供應(yīng)商和預(yù)言者對(duì)于這一愿景的宣傳卻令人懷疑地缺失了。開(kāi)發(fā)人員需要問(wèn)問(wèn)自己:有多少次發(fā)現(xiàn)自己會(huì)把目光從集成開(kāi)發(fā)環(huán)境(IDE)中的代碼上移開(kāi),發(fā)現(xiàn)可以從執(zhí)行數(shù)據(jù)中學(xué)到什么?

不要誤解,開(kāi)發(fā)人員要相信可觀(guān)察性在軟件開(kāi)發(fā)中可以發(fā)揮重要作用。OpenTelemetry發(fā)揮了巨大的作用,可以清楚地看到它如何幫助開(kāi)發(fā)人員編寫(xiě)更好的代碼,引入新的范例,并加快開(kāi)發(fā)周期。它可以啟發(fā)開(kāi)發(fā)人員提出他們甚至還沒(méi)有考慮到的問(wèn)題。然而,無(wú)論人們?cè)诰W(wǎng)上看到什么,其重點(diǎn)似乎仍然是可觀(guān)察性本身,如何啟用它,以及如何開(kāi)始。盡管有著炫酷圖形的儀表板非常棒,但許多開(kāi)發(fā)團(tuán)隊(duì)都不知道該從哪里入手。

本文將討論一個(gè)更有趣的話(huà)題:對(duì)于使用可觀(guān)察性的開(kāi)發(fā)者來(lái)說(shuō),成功是什么樣子的?開(kāi)發(fā)團(tuán)隊(duì)如何期望使用豐富的代碼運(yùn)行時(shí)數(shù)據(jù)更好地編碼和發(fā)布?更重要的是,現(xiàn)在有哪些可觀(guān)察性可以告訴開(kāi)發(fā)人員關(guān)于代碼的事情,以及它如何幫助開(kāi)發(fā)人員改進(jìn)?可以通過(guò)具體的代碼示例來(lái)了解如何利用可觀(guān)察性作為編碼實(shí)踐。

超越監(jiān)控:縮短開(kāi)發(fā)過(guò)程中的反饋循環(huán)

可觀(guān)察性最大的希望在于提供真實(shí)和客觀(guān)的反饋,不受單元測(cè)試的一些偏差和偏見(jiàn)的影響。想象一下,當(dāng)開(kāi)發(fā)人員還在處理代碼更改時(shí),就會(huì)收到有關(guān)任何回歸或問(wèn)題的警報(bào)?;蛘撸冀K了解代碼的哪些部分在生產(chǎn)中實(shí)際使用,并根據(jù)集成測(cè)試結(jié)果輕松識(shí)別需要注意的薄弱環(huán)節(jié)。

這可能是開(kāi)發(fā)人員可觀(guān)察性的真正潛力,而不是作為“監(jiān)視”解決方案的傳統(tǒng)角色。監(jiān)視器和警報(bào)至關(guān)重要,但不幸的是,它們的重點(diǎn)始終是報(bào)告已經(jīng)發(fā)生的問(wèn)題。也許是因?yàn)樵摷夹g(shù)主要由DevOps/SRE/IT團(tuán)隊(duì)使用,他們主要關(guān)心生產(chǎn)的穩(wěn)定性。

本文作者表示,有一次在發(fā)布一個(gè)產(chǎn)品的階段,他和團(tuán)隊(duì)中的其他開(kāi)發(fā)人員感覺(jué)他們的作用更像是消防隊(duì)而不是開(kāi)發(fā)團(tuán)隊(duì),他開(kāi)玩笑地將匆忙修復(fù)漏洞稱(chēng)為BDD——不是行為驅(qū)動(dòng)設(shè)計(jì),而是漏洞驅(qū)動(dòng)開(kāi)發(fā)。然而,這種描述并非完全不準(zhǔn)確。開(kāi)發(fā)人員沒(méi)有積極主動(dòng)地改進(jìn)代碼,而是極其被動(dòng)地追逐一個(gè)又一個(gè)問(wèn)題,這很快就變得不可持續(xù)。

例舉更實(shí)際的例子

為了說(shuō)明開(kāi)發(fā)人員如何利用可觀(guān)察性來(lái)改進(jìn)的開(kāi)發(fā)周期,在此例舉一個(gè)現(xiàn)實(shí)場(chǎng)景的更實(shí)際的例子:團(tuán)隊(duì)中的高級(jí)開(kāi)發(fā)人員Bob被要求向Spring PetClinic示例添加一些功能。跟蹤寵物的疫苗接種記錄似乎非常重要,Bob被要求與外部數(shù)據(jù)源集成以實(shí)現(xiàn)這一目標(biāo)。對(duì)于最初的最小可行產(chǎn)品MVP),Bob為此創(chuàng)建一個(gè)功能分支,并繼續(xù)實(shí)現(xiàn)一些新的功能。

在閱讀了許多關(guān)于如何從Java應(yīng)用程序中收集可觀(guān)察性數(shù)據(jù)的教程之后,Bob在后臺(tái)運(yùn)行了幾個(gè)OSS和免費(fèi)工具來(lái)幫助他完成任務(wù)。這篇文章并不會(huì)詳細(xì)介紹如何設(shè)置整個(gè)堆棧(因?yàn)樗灿袕V泛的文檔記錄)。但是,可以docker_compose文件的形式找到整個(gè)堆棧。

Bob的基本可觀(guān)測(cè)性堆棧:

  • 用于跟蹤的OpenTelemetry;他還在本地運(yùn)行了一個(gè)OTEL收集器容器,將數(shù)據(jù)路由到各種工具。
  • 用于顯示跟蹤的Jaeger。
  • 用于采集指標(biāo)的Micrometer。
  • 用于保存矩陣的Prometheus和用于可視化它們的開(kāi)源版本Grafana。

需要注意的是,要開(kāi)始使用OTEL收集代碼數(shù)據(jù),Bob不需要進(jìn)行任何代碼更改。在本地運(yùn)行時(shí),他可以安全地使用OTEL代理。在他的例子中,他只是在IDE的運(yùn)行配置中引用代理,以便在本地運(yùn)行/調(diào)試時(shí)可以引用代理。他還添加了一個(gè)docker-compose.override文件,用于使用docker/Podman啟動(dòng)應(yīng)用程序(這也不需要更改源docker-compose文件)。

在一切就緒并運(yùn)行之后,Bob創(chuàng)建了一個(gè)新的功能分支,并開(kāi)始開(kāi)發(fā)新功能。

疫苗API外觀(guān)組件

非常幸運(yùn)的是,有人已經(jīng)編寫(xiě)了一個(gè)Spring組件來(lái)與另一個(gè)模塊的模擬API進(jìn)行通信。Bob的工作很簡(jiǎn)單:將組件注入PetController,并在添加寵物時(shí)使用它檢索數(shù)據(jù)。該組件非常簡(jiǎn)單,使用OKHttp庫(kù)實(shí)現(xiàn)一個(gè)基本的REST調(diào)用,以獲取JSON形式的數(shù)據(jù)。

Java 
 @WithSpan
 public VaccinnationRecord[] AllVaccines() throws JSONException, IOException {
 var vaccineListString = MakeHttpCall(VACCINES_RECORDS_URL);
 JSONArray jArr = new JSONArray(vaccineListString);
 var vaccinnationRecords =
 new ArrayList<VaccinnationRecord>();
 for (int i = 0; i < jArr.length(); i++) {
 VaccinnationRecord record = parseVaccinationRecord(jArr.getJSONObject(i));
 vaccinnationRecords.add(record);
 }
 return vaccinnationRecords.toArray(VaccinnationRecord[]::new);
 }
  @WithSpan
 public VaccinnationRecord VaccineRecord(int vaccinationRecordId) throws JSONException, IOException {
 var idUrl = VACCINES_RECORDS_URL + "/" + vaccinationRecordId;
 var vaccineListString = MakeHttpCall(idUrl);
 JSONObject vaccineJson = new JSONObject(vaccineListString);
 return parseVaccinationRecord(vaccineJson);
 } 

更新寵物模型

接下來(lái),為了保存疫苗接種數(shù)據(jù),而不是每次都檢索它,必須更新模型和數(shù)據(jù)庫(kù)結(jié)構(gòu)。這涉及到很多樣板文件,但為了保存每只寵物的疫苗接種信息,這是必要的措施。Bob適時(shí)地添加了一個(gè)新表,對(duì)類(lèi)中的關(guān)系進(jìn)行建模,還更新了DDL腳本。

Java 
@Entity
@Table(name = "pet_vaccines")
public class PetVaccine extends BaseEntity {
 @Column(name = "vaccine_date")
 @DateTimeFormat(pattern = "yyyy-MM-dd")
 private LocalDate date;
 /**
 * Creates a new instance of Visit for the current date
 */
 public PetVaccine() {
 }
 public LocalDate getDate() {
 return this.date;
 }
 public void setDate(LocalDate date) {
 this.date = date;
 }
}

添加用于檢索和更新新的寵物接種日期字段的域服務(wù)

遵循最佳實(shí)踐,Bob創(chuàng)建了一個(gè)簡(jiǎn)單的域服務(wù),該服務(wù)將被注入PetController中。新服務(wù)編排域邏輯,以便從外部API檢索新寵物的疫苗記錄,并用最新日期更新模型。不幸的是,這也是Bob犯了幾個(gè)錯(cuò)誤的地方,其中一些錯(cuò)誤與facade抽象的泄漏有關(guān),這掩蓋了成本昂貴的HTTP調(diào)用。Bob也沒(méi)有注意到很多邏輯是多余的。

Java 
 @Component
 public class PetVaccinationStatusService {
 @Autowired
 private PetVaccinationService adapter;
 public void UpdateVaccinationStatus(Pet[] pets){
 for (Pet pet: pets){
 try {
 var vaccinationRecords = this.adapter.AllVaccines();
 for (VaccinnationRecord record : vaccinationRecords){
 var recordInfo = this.adapter.VaccineRecord(record.recordId());
 if (recordInfo.petId()==pet.getId()){
 PetVaccine petVaccine = new PetVaccine();
 petVaccine.setDate(recordInfo.vaccineDate());
 pet.addVaccine(petVaccine);
 }
 }
 } catch (JSONException |IOException e) {
 //Fail silently
 Span.current().recordException(e);
 }
 }
 }
 }

更新視圖模板

最后,Bob添加了一個(gè)新字段,用于指示寵物疫苗是否過(guò)期。

HTML 
 ..
<table class="table table-striped" th:object="${owner}">
 <tr>
 <th>Name</th>
 <td><b th:text="*{firstName + ' ' + lastName}"></b></td>
 </tr>
 <tr>
 <th>Address</th>
 <td th:text="*{address}"></td>
 </tr>
 <tr>
 <th>City</th>
 <td th:text="*{city}"></td>
 </tr>
 <tr>
 <th>Telephone</th>
 <td th:text="*{telephone}"></td>
 </tr>
 <tr>
 <th>Needs Vaccine</th>
 <td th:text="*{isVaccineExpired()}"></td>
 </tr>
 </table>

...

就是這樣! 更改已準(zhǔn)備就緒。Bob甚至編寫(xiě)了一些測(cè)試,他對(duì)快速的進(jìn)展感到滿(mǎn)意,并對(duì)本地測(cè)試時(shí)沒(méi)有發(fā)生意外的代碼充滿(mǎn)信心,他轉(zhuǎn)向收集的運(yùn)行時(shí)數(shù)據(jù),看看它能揭示他的更改。他決定擴(kuò)展“完成”的定義,并花費(fèi)額外的精力來(lái)檢查與他的更改相關(guān)的數(shù)據(jù)。

使用可觀(guān)察性

首先,參考某種基準(zhǔn)是很重要的。有兩個(gè)API操作受到了更改的影響,Bob希望了解更改之前和之后它們是如何執(zhí)行的。作為可觀(guān)察性設(shè)置的一部分,Bob還配置了Micrometer和Actuator,以提供有關(guān)API的有用指標(biāo)。在這個(gè)案例中,這些可以通過(guò)執(zhí)行器URL直接訪(fǎng)問(wèn)http://localhost:8082/actuator/metrics。然而,為了更好的可視化和更多的繪圖選項(xiàng),Bob將在他的堆棧中使用本地運(yùn)行的Prometheus和Grafana OSS。

查看一些常見(jiàn)的Grafana儀表板,令人驚訝的是,沒(méi)有用于跟蹤API響應(yīng)時(shí)間的默認(rèn)圖表。也許是因?yàn)榇蠖鄶?shù)儀表板都與Ops相關(guān),關(guān)注CPU/內(nèi)存和堆棧大小,而不是日常開(kāi)發(fā)人員的見(jiàn)解。幸運(yùn)的是,使用Actuator度量很容易配置這樣的儀表板??梢允褂靡韵虏樵?xún)創(chuàng)建一個(gè)以創(chuàng)建新寵物的API為重點(diǎn)的圖表:

HTTP 
1 http_server_requests_seconds{uri="/owners/{ownerId}/pets/new", quantile="0.5", method="POST", outcome="REDIRECTION"} != 0
2

然后可以在代碼更改之前和之后檢查圖。

代碼更改之前:

代碼更改之后:

毫無(wú)疑問(wèn),這些更改導(dǎo)致了嚴(yán)重的性能問(wèn)題。可以通過(guò)查看指標(biāo)立即發(fā)現(xiàn)問(wèn)題,但跟蹤可以揭示更多關(guān)于根本原因和潛在問(wèn)題的信息。現(xiàn)在是調(diào)用Jaeger的時(shí)候了,這是可觀(guān)察性堆棧的另一個(gè)組件。Jaeger習(xí)慣于可視化捕獲的跟蹤,并為Bob提供了一個(gè)機(jī)會(huì),讓他在忙于添加更多邏輯和功能的同時(shí),調(diào)查他的代碼在做什么:

因此,在不添加單個(gè)斷點(diǎn)的情況下,已經(jīng)可以在這個(gè)請(qǐng)求中了解到許多關(guān)于這一代碼的內(nèi)容。到目前為止,Bob還完全沒(méi)有注意到這些信息。雖然他在嘗試新請(qǐng)求時(shí)確實(shí)注意到了一些延遲,但他并沒(méi)有太在意。也許外部API太慢了?既然他已經(jīng)訪(fǎng)問(wèn)了跟蹤,他就可以重新審視引入的代碼了。

精選豐富的語(yǔ)句

第一個(gè)突出的問(wèn)題是作為findById存儲(chǔ)庫(kù)方法的一部分觸發(fā)的許多SQL語(yǔ)句。Spring Data會(huì)自動(dòng)檢測(cè)到這一點(diǎn),并提供一些關(guān)于正在發(fā)生的事情的場(chǎng)景。更仔細(xì)地檢查查詢(xún)會(huì)發(fā)現(xiàn)一個(gè)熟悉的Hibernate陷阱:

看起來(lái)訪(fǎng)問(wèn)關(guān)系是通過(guò)通常稱(chēng)為N+1選擇的方式為每個(gè)寵物獲取的。有趣的是,這個(gè)問(wèn)題似乎是PetClinic應(yīng)用程序特有的,而且似乎早于Bob的更改。實(shí)際上,雖然這會(huì)導(dǎo)致一些放緩,但它并不像其他一些問(wèn)題那樣重要,這一點(diǎn)在Bob進(jìn)一步檢查跟蹤時(shí)變得明顯。

HTTP請(qǐng)求聊天

性能回歸的真正原因似乎與Bob的誤解有關(guān),可能是由于VaccineServiceFacade方法的命名不明確。他似乎不太清楚,每次調(diào)用VaccineRecord函數(shù)時(shí)在后臺(tái)執(zhí)行API調(diào)用。使用更好的命名約定可以緩解這種抽象漏洞,強(qiáng)調(diào)這實(shí)際上是長(zhǎng)時(shí)間同步操作的執(zhí)行。

隱藏的錯(cuò)誤

HTTP請(qǐng)求中還發(fā)生了其他事情。當(dāng)向下滾動(dòng)請(qǐng)求列表時(shí),Bob注意到其中一些請(qǐng)求以錯(cuò)誤結(jié)束,然后在嘗試序列化不存在的響應(yīng)時(shí)出現(xiàn)異常。基于HTTP錯(cuò)誤代碼的根本原因與速率限制或節(jié)流或外部API有關(guān)。這個(gè)問(wèn)題可以通過(guò)優(yōu)化調(diào)用的數(shù)量來(lái)暫時(shí)解決,但是隨著越來(lái)越多的用戶(hù)開(kāi)始同時(shí)使用這個(gè)組件,這個(gè)問(wèn)題可能會(huì)重新出現(xiàn)。此外,這段代碼中的異常處理肯定是錯(cuò)誤的,也許需要一種重試機(jī)制。

就在Bob開(kāi)始糾正通過(guò)檢查可觀(guān)測(cè)性工件發(fā)現(xiàn)的許多問(wèn)題之前,他決定快速查看他修改的另一個(gè)API。在這種情況下,性能似乎沒(méi)有顯著下降,但是檢查跟蹤仍然發(fā)現(xiàn)至少有一個(gè)問(wèn)題需要修復(fù)。

將會(huì)出現(xiàn)哪些問(wèn)題?

數(shù)據(jù)中還可以識(shí)別出其他問(wèn)題,但是回顧一下場(chǎng)景,考慮一下如果Bob在合并更改之前沒(méi)有對(duì)其進(jìn)行分析,會(huì)發(fā)生什么情況:代碼最終被部署。有些問(wèn)題在CR或后期測(cè)試階段被發(fā)現(xiàn),導(dǎo)致更多的更改、額外的延遲和痛苦的合并,因?yàn)樵诖似陂g會(huì)出現(xiàn)更多的更改。其他問(wèn)題也會(huì)轉(zhuǎn)移到生產(chǎn)中,導(dǎo)致進(jìn)一步的問(wèn)題:延遲發(fā)布、匆忙修復(fù)、增加團(tuán)隊(duì)的焦慮和沮喪等等。毫無(wú)疑問(wèn),可以發(fā)現(xiàn)縮短反饋循環(huán)有很多好處。

勝利了嗎?不完全是

在這個(gè)有點(diǎn)幼稚的例子中,能夠演示如何簡(jiǎn)單地打開(kāi)OTEL并通過(guò)一些OSS工具流式傳輸數(shù)據(jù),有可能為Bob和其他開(kāi)發(fā)人員提供額外的保護(hù)。然而,現(xiàn)實(shí)情況是,Bob的團(tuán)隊(duì)很可能無(wú)法以可持續(xù)的方式繼續(xù)應(yīng)用此類(lèi)反饋。之所以會(huì)出現(xiàn)這種情況,有幾個(gè)關(guān)鍵原因:

(1)不連續(xù)的人工過(guò)程:整個(gè)實(shí)驗(yàn)依賴(lài)于Bob的奉獻(xiàn)精神、紀(jì)律和意志來(lái)仔細(xì)檢查他的代碼。隨著釋放壓力的增加,他這么做的可能性越來(lái)越小。特別是如果在相當(dāng)多的情況下,他將花費(fèi)時(shí)間調(diào)查數(shù)據(jù)而沒(méi)有提出任何重要的提示。與測(cè)試類(lèi)似,除非它是連續(xù)的和自動(dòng)的,否則它可能不會(huì)大規(guī)模地發(fā)生。

(2)專(zhuān)家需求:如上所述,這個(gè)例子在強(qiáng)調(diào)一些明確的場(chǎng)景時(shí)有些動(dòng)作。在現(xiàn)實(shí)中,如果沒(méi)有統(tǒng)計(jì)學(xué)、回歸甚至基本的機(jī)器學(xué)習(xí)知識(shí),以這種方式處理數(shù)據(jù)以理解代碼更改的影響是非常困難的。以研究的第一個(gè)圖為例,即“之前”狀態(tài)。這些值之間的差異是否代表僥幸、某種上升成本或其他什么?

(3)場(chǎng)景切換和工具過(guò)載——切換場(chǎng)景很難。為了使這種編程范例能夠工作,它必須是工程團(tuán)隊(duì)可以擁有的解決方案。它不可能是開(kāi)發(fā)人員需要掌握并知道如何正確閱讀的一堆指示板和工具。而需要的認(rèn)知努力減少得越多,這些信息就越有可能被使用。

未來(lái)是持續(xù)的反饋

持續(xù)反饋是一種新的開(kāi)發(fā)實(shí)踐,旨在彌合已經(jīng)確定的差距:擁有大量易于收集的關(guān)于代碼運(yùn)行時(shí)的數(shù)據(jù),但需要人工工作、專(zhuān)業(yè)知識(shí)和時(shí)間來(lái)處理成實(shí)際和可操作的提示。有三個(gè)要素可以使其發(fā)揮作用:持續(xù)管道(反向持續(xù)集成管道)、集成工具和自動(dòng)化數(shù)據(jù)分析的機(jī)器學(xué)習(xí)/數(shù)據(jù)科學(xué)。

注:本文作者表示,作為Digma的構(gòu)建者,這是他創(chuàng)建的一個(gè)免費(fèi)的持續(xù)反饋插件,因?yàn)檫@個(gè)無(wú)法解釋的鴻溝阻止開(kāi)發(fā)人員使用代碼數(shù)據(jù),這讓他感到非常沮喪。他不止一次遇到“Bob”的情況,所有的信息都在公開(kāi)的地方。它可以在調(diào)試/測(cè)試數(shù)據(jù)中找到,甚至可以在關(guān)于代碼的生產(chǎn)數(shù)據(jù)中找到,只是沒(méi)有人會(huì)或無(wú)法檢查它。

這里設(shè)想的是流水線(xiàn)自動(dòng)化,它可以發(fā)現(xiàn)Bob最終發(fā)現(xiàn)的所有不同的問(wèn)題,并使其持續(xù)-只是正常開(kāi)發(fā)周期的一部分。實(shí)際上,從等式中刪除了整個(gè)OTEL配置、樣板文件和工具。將“打開(kāi)”所需的工作減少到一個(gè)簡(jiǎn)單的按鈕切換。通過(guò)這種方式,整個(gè)項(xiàng)目現(xiàn)在只需要Bob做兩件事——啟用可觀(guān)察性,并運(yùn)行他的代碼。這意味著更多的開(kāi)發(fā)人員將能夠開(kāi)始探索代碼運(yùn)行時(shí)數(shù)據(jù)的潛力,而不僅僅是像Bob這樣的頑固派。

啟用了可觀(guān)察性收集之后,以下是Bob在調(diào)試和本地運(yùn)行時(shí)使用Digma插件時(shí)看到的IDE視圖:

從視圖中的會(huì)話(huà)反模式、N+1查詢(xún)、檢測(cè)速度變慢到隱藏錯(cuò)誤,所有這些都成為了開(kāi)發(fā)人員視圖的一部分。當(dāng)Bob繼續(xù)編碼、運(yùn)行和調(diào)試時(shí),它會(huì)不斷地從收集的大量數(shù)據(jù)中解鎖和破譯。

通過(guò)這種方式,類(lèi)似于測(cè)試,最終可以使可觀(guān)察性透明——不需要有意識(shí)的努力。就像管道一樣,可觀(guān)察性的作用應(yīng)該是融入背景。不管數(shù)據(jù)是如何收集的,也不管它是OTEL還是其他技術(shù)。更重要的是扭轉(zhuǎn)了這個(gè)過(guò)程。Bob沒(méi)有在與代碼相關(guān)的指標(biāo)和跟蹤中搜索問(wèn)題,而是從查看代碼問(wèn)題開(kāi)始,這些代碼問(wèn)題本身包含到相關(guān)指標(biāo)和跟蹤的鏈接,以便進(jìn)行進(jìn)一步研究。

在考慮持續(xù)反饋時(shí),最讓人大開(kāi)眼界的方法就是把它關(guān)掉。知道所有的問(wèn)題仍然存在,除了完全看不見(jiàn)之外,這讓人抓狂,這感覺(jué)就像在黑暗中編碼。

許多開(kāi)發(fā)人員評(píng)論說(shuō),與采用測(cè)試類(lèi)似,轉(zhuǎn)換部分是技術(shù)上的,部分是文化上的。誰(shuí)知道如果用基于證據(jù)的指標(biāo)來(lái)檢驗(yàn)它們,會(huì)有什么編碼恐怖事件出現(xiàn),或者會(huì)有多少假設(shè)被推翻?也許有些人更喜歡在黑暗中編碼?

在作者看來(lái),它只會(huì)給代碼庫(kù)帶來(lái)問(wèn)題:技術(shù)債務(wù)提供更多的形式和方法。了解延遲代碼更改的差距、影響和系統(tǒng)范圍的后果,將有望幫助推動(dòng)更改,并消除許多企業(yè)所遭受的一些前瞻性偏見(jiàn)。

還有更多的例子和細(xì)微差別可以作為未來(lái)博客文章的素材,這里幾乎沒(méi)有觸及使用CI/Prod數(shù)據(jù)的主題,這可能會(huì)產(chǎn)生巨大的影響。

原文標(biāo)題:Effective Coding With Java Observability,作者:Roni Dover

責(zé)任編輯:華軒 來(lái)源: 51CTO
相關(guān)推薦

2021-09-26 09:50:21

開(kāi)發(fā)技能程序

2023-06-12 16:45:20

數(shù)據(jù)管理

2022-07-18 13:37:56

云計(jì)算云原生可觀(guān)察性

2021-06-06 22:39:48

網(wǎng)絡(luò)安全監(jiān)控網(wǎng)絡(luò)攻擊

2023-01-28 13:42:16

2021-01-26 09:11:16

數(shù)字體驗(yàn)DEM網(wǎng)絡(luò)可觀(guān)察性

2021-11-14 22:14:08

人工智能機(jī)器學(xué)習(xí)工具

2022-08-12 06:26:54

微服務(wù)架構(gòu)

2023-02-23 19:28:09

ODD測(cè)試

2021-06-27 17:18:23

網(wǎng)絡(luò)可觀(guān)察性網(wǎng)絡(luò)網(wǎng)絡(luò)運(yùn)營(yíng)

2021-07-12 11:24:00

流利說(shuō)可觀(guān)察性平臺(tái)阿里云

2024-03-19 15:02:28

云原生工業(yè)4.0

2022-12-29 10:16:12

觀(guān)察性系統(tǒng)監(jiān)視

2024-06-18 10:16:49

2023-03-10 14:03:57

2023-03-23 13:48:00

工具應(yīng)用場(chǎng)景選型

2021-10-26 10:26:25

云計(jì)算云計(jì)算環(huán)境云應(yīng)用

2023-11-16 17:14:16

數(shù)字化轉(zhuǎn)型

2021-10-29 19:22:16

可觀(guān)察性IT基礎(chǔ)設(shè)施監(jiān)控

2022-12-01 15:36:44

數(shù)字化轉(zhuǎn)型
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)