成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

微服務循環依賴調用引發的血案

開發 架構
微服務之間的耦合性非常強,這嚴重違反了微服務的初衷;這種情況往往是服務之間的調用沒有約束導致的,為了方便取到或更新數據,服務之間可以隨意的調用,以”微服務“為設計目標的系統會逐漸演變成一個分布式大單體?。

最近的迭代轉測后遇到了一個比較有意思的問題。在測試環境整體運行還算平穩,但是過一段時間之后,就開始有接口超時了,日志中出現非常多的 “java.net.SocketTimeoutException: Read timed out”。試了幾次重啟大法,每次都是只能堅持一會之后,再次出現 SocketTimeoutException。

注意:在測試環境于遇到問題重啟服務,并不是一個好的實踐,因為重啟可能會讓不容易出現的問題現場被破壞。如果問題在測試環境不能再重新,卻在發版后出現在生產環境的話,那不僅會造成生產運維事件,還要在巨大的壓力下去解決問題。

初步分析

順著測試匯報的出現問題的場景,跟蹤調用鏈上相關服務的日志,發現出現了微服務之間循依賴調用。大致情況可以抽象如下所示(圖中所有調用都是 http 協議):

圖片

  • Client 調用服務 Foo.hello()
  • Foo.hello() 邏輯中會調用服務 Boo.boo()
  • Boo.boo() 又調用回服務 Foo 的另外一個方法 another()

當然真實的場景要比較這個復雜,調用鏈更長,不過最終形成了環形依賴調用。至于這個環形依賴為什么回導致超時,當時想了多種可能,比如數據庫慢查詢、數據庫鎖、分布式鎖等等。但是整個調用鏈上都是查詢請求,而且查詢相關的數據量也非常小,不會有鎖存在。發生問題的時候也沒有與查詢數據相關的數據庫寫請求。

鑒于這個環形依賴調用確實是這個迭代版本中引入的變更,以及雖然沒有理清其中的因果關系原理,但是這個環性依賴調用還是很可疑的,而且是不必要的環形調用。就抱著將環形依賴調用去掉試試看的態度,做了修復。修復完后,SocketTimeoutException 不再出現了。問題解決了。

探尋原因

問題雖然不再出現,但是憑運氣解決的問題,通常有可能不是真的的解決。只有弄清楚背后的原理,我們才能真正的確認問題是不是這個原因導致的,這樣的修復是不是真的把問題解決了。

通過假設環形調用就是導致調用超時的直接原因。我們看看能不能推出因果關系。通過把Foo 服務容器畫的更詳細一點,如下圖:

圖片

通過這個圖示,我們可以發現,如果容器中接收請求的線程池如果都在等待服務Boo.boo() 的響應,而 Boo 又需要調用回服務 Foo.another()。這個時候,如果所有的線程都處于這樣的狀態,我們就會發現服務 Foo 容器中以及沒有線程來處理 Boo 的請求了。關注公眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部的Java性能調優手冊!某種程度上來說就是死鎖了。到這里,我們就可以很確定了,這個環形依賴調用就是導致出現調用超時的罪魁禍首。當 client 發起的請求速度大于這個環形調用鏈的處理速度的時候,慢慢的就會導致服務 Foo 的所有線程都進入這種死鎖狀態。

驗證

這里只列出關鍵的代碼,具體的代碼可以參考 gitee 工程:https://gitee.com/donghbcn/CircularDependency

Eureka 服務器

建個簡單工程將Eureka server啟動起來。

服務 Foo

創建 SpringBoot 工程實現 Foo 服務。Foo 通過 FeignClient 調用 Boo 服務。設置缺省的容器 Tomcat 的最大線程數為 16,Tomcat 默認配置最大線程數 200,對于驗證這個場景有點了大了,要看到效果需要等的時間有點長。

application.properties

spring.application.name=demo-foo
server.port=8000
eureka.client.serviceUrl.defaultZnotallow=http://localhost:8080/eureka
server.tomcat.threads.max=16
package com.cd.demofoo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FooController {
@Autowired
BooFeignClient booFeignClient;
@RequestMapping("/hello")
public String hello(){
long start = System.currentTimeMillis();
System.out.println("[" + Thread.currentThread() +
"] foo:hello called, call boo:boo now");
booFeignClient.boo();
System.out.println("[" + Thread.currentThread() +
"] foo:hello called, call boo:boo, total cost:" +
(System.currentTimeMillis() - start));
return "hello world";
}

@RequestMapping("/another")
public String another(){
long start = System.currentTimeMillis();
try {
//通過 slepp 模擬一個耗時調用
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("foo:another called, total cost:" + (System.currentTimeMillis() - start));
return "another";
}
}

服務 Boo

創建 SpringBoot 工程實現 Boo 服務。Boo 通過 FeignClient 調用 Foo 服務。

package com.cd.demoboo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BooController {

@Autowired
FooFeignClient fooFeignClient;

@RequestMapping("/boo")
public String boo(){
long start = System.currentTimeMillis();

fooFeignClient.another();
System.out.println("boo:boo called, call foo:another, total cost:" +
(System.currentTimeMillis() - start));
return "boo";
}
}

Jmeter

采用 Jmeter 來模擬并發 Client 調用。配置了30 個 線程,無限循環。

圖片

很快服務 Foo 日志就卡死了。過一會 Boo 的日志開始出現 SocketTimeoutException,如下圖:

圖片

jstack

通過 jstack 我們可以看到 Foo 進程的所有線程都卡在 hello() 調用上了。

圖片

總結

微服務之間的環形依賴類似于類之間的循環依賴,當依賴關系形成了環,會造成比較嚴重的問題:

  • 微服務直接不能形成環形調用,否則非常容易出現死鎖狀態。
  • 微服務之間的耦合性非常強,這嚴重違反了微服務的初衷;這種情況往往是服務之間的調用沒有約束導致的,為了方便取到或更新數據,服務之間可以隨意的調用,以”微服務“為設計目標的系統會逐漸演變成一個分布式大單體?。
責任編輯:武曉燕 來源: 碼猿技術專欄
相關推薦

2024-07-12 08:52:50

2022-04-12 08:43:04

生產故障Dubbo調用

2021-01-11 05:30:04

Boot 單機片

2022-01-26 10:29:24

微服務循環依賴代碼

2015-02-04 14:36:07

格式串漏洞Ghost漏洞安全漏洞

2011-02-28 09:31:30

HashtableHashMap

2021-07-27 07:12:11

Getter接口Setter

2017-03-20 19:40:29

AndroidSwipeRefres下拉刷新

2011-05-20 12:34:05

大話IT云服務中斷亞馬遜

2021-12-01 06:59:27

架構

2019-09-09 08:30:57

MYSQL代碼數據庫

2012-02-13 09:42:41

備份服務器數據中心

2020-01-06 09:43:14

賠償TSB遷移

2018-11-22 15:50:27

MySQL數據庫雙引號

2021-01-25 08:08:22

APP機器人KOB

2017-05-22 08:35:07

MySQL雙引號錯位

2021-02-01 10:42:47

MySQL雙引號數據庫

2013-08-26 10:19:24

納斯達克數據專線交易暫停

2016-12-01 09:30:03

運維網絡網線

2017-08-25 16:38:05

表達式正則血案
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产高清在线视频 | 成人精品一区二区 | 婷婷亚洲综合 | 国产精品久久久久久久久污网站 | 久久久www成人免费精品 | 国产欧美一区二区久久性色99 | 一区二区免费高清视频 | 五月婷婷激情网 | 天天视频一区二区三区 | 精品国产乱码久久久久久丨区2区 | 亚洲精品视频免费看 | 久久久国产一区二区三区四区小说 | 美女视频久久 | 一区二区三区高清 | 在线视频一区二区 | 超级乱淫av片免费播放 | 国产欧美一区二区在线观看 | 99热精品6| 日韩欧美国产精品 | 精品国产18久久久久久二百 | 91一区二区三区在线观看 | 国产免费一区二区 | 亚洲国产一区二区三区四区 | 艹逼网| av一区二区三区在线观看 | 亚洲精品中文字幕 | 91影库| 午夜播放器在线观看 | 欧美天堂在线观看 | 免费观看一区二区三区毛片 | 国产一区二区自拍 | 三级在线免费 | 日韩视频在线一区 | 成人蜜桃av| 精品产国自在拍 | 日本精品视频 | 一区二区三区中文字幕 | 欧美视频成人 | 婷婷在线视频 | 日韩欧美一区二区在线播放 | 亚洲不卡在线观看 |