Sentinel原始碼解析之一次請求走進Sentinel
原創不易,轉載請註明出處
前言
本篇開始,我們就正式進入Sentinel原始碼解析了,本篇主要是介紹下Sentinel與SpringMVC整合,傳送批量請求去Sentinel控制檯看看效果,最後我們就要揭祕一下Sentinel是怎樣做到能夠統計請求的。
1.整合Sentinel與Spring MVC
這裡是用的springboot 然後匯入spring-boot-starter-web 快速整合的Spring mvc
這裡貼一下我的pom 引用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.6.0</version>
</dependency>
這裡需要 sentinel與servlet的適配專案sentinel-web-servlet
,這個專案主要是適配的, 然後還需要通訊專案sentinel-transport-simple-http
,這個主要是用來與控制檯sentinel-dashboard 網路通訊的。
接下來我們就得配置了
@Configuration
public class SentinelServletConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
registration.setName("sentinelFilter");
registration.setOrder(1);
//logger.info("Sentinel servlet CommonFilter registered");
return registration;
}
}
這裡就是個配置類,然後註冊一下CommonFilter 這個元件,想都不用想,sentinel就是通過這個filter 來進行流控的,這裡配置所有的請求都走這個filter
然後就是再隨便寫個Controller。
@RestController()
@RequestMapping("/test")
public class TestController {
@RequestMapping("/getName")
public String getName(){
System.out.println("getName");
return null;
}
}
2.批量請求看看效果
啟動sentinel-dashboard 這個專案,它就是個springboot 專案,你可以隨心所欲改動,我這裡是8000 埠啟動的。
賬號密碼都是sentinel,這可以在配置檔案中配置。
登陸進去就是這個樣子,現在只有它一個。
然後在啟動上面整合的那個專案, 啟動引數設定
-Dcsp.sentinel.dashboard.server=localhost:8000
-Dproject.name=consumer_app
csp.sentinel.dashboard.server 這個引數就是 sentinel-dashboard 的地址,因為你那個專案啟動的時候就要向這個dashboard 專案傳送心跳啥的,然後dashboard 定時管你要Metric資訊,不然它怎麼實時展示。
project.name 專案名稱,這個向dashboard 傳送心跳的時候,會帶上,用來區分專案的。
我們啟動整合的那個專案。
啟動完成後,再來看看sentinel 的dashboard, 發現還是沒有變化,不是應該向sentinel傳送心跳嗎?其實,我們們專案啟動並沒有初始化這個sentinel,當我們發起請求的時候,經過這個CommonFilter 元件,就會進行sentinel的初始化,到時候我們再來看下 sentinel dashboard的效果。
先來傳送一次請求,用什麼工具隨意,我這裡用postman
ok,我這裡傳送完成了,看下效果,可以看到,這個dashboard 已經有我那個project了。
來組批量請求,看下sentinel dashboard 實時效果。我這裡使用postman 傳送1000次請求
在這裡可以看到我某個請求的實時通過qps與拒絕qps ,響應時間。
在sentinel的世界中, 我們/test/getName 就是一個資源,你可以把一個介面看作一個資源。
3.走進Sentinel的Servlet適配專案
我們來看下 sentinel 與servlet適配專案的這個CommonFilter都幹了些啥,簡單看一下這個CommonFilter 的原始碼,在sentinel-web-servlet這個子專案中
首先是解析了一下 requset ,得到一個target,這裡其實就是解析出來你的請求路徑,接著就是使用UrlCleaner 把這個路徑清理了一下,可以看下這個註釋,就是這個意思,接著就是parseOrigin 方法來解析origin
這個originParser 是個null ,所以就不走了,這塊其實就是解析源的,也就是這個請求的上層,你可以通過某種方式帶過來,然後自己寫個parser 再把這個源解析出來,這裡我們就不看了。
接著就是
ContextUtil.enter(target, origin);
entry = SphU.entry(target, EntryType.IN);
這兩行了我們這裡重點 看下ContextUtil.enter(target, origin);
,後面這個更重要,我們後面天天打交道。
判斷name是不是sentinel_default_context
,很顯然不是,執行trueEnter 方法
先是從contextHolder 中獲取一個context ,這個contextHolder 就是個threadLocal,也就是一個執行緒一個context,如果沒有的話,接著就是contextNameNodeMap 中獲取 你這個name的 DefaultNode ,關於 DefaultNode 先不要管,如果node是null的話,這個map中快取的是不是大於2000了,超過2000的話就往這個執行緒對應的threadLocal 設定一個空的context,下面就是加鎖再來檢查一遍,建立一個EntranceNode,你可以認為這個EntranceNode 是這個資源(就是你傳過來的那個name)的起始 node, 然後根結點新增這個node為位元組點,將name 對應node放入 map中快取起來。建立context,然後將這個context 設定到treadLocal中。
好了,先解析到這裡,其實這個name 你就可以認為一個資源,在servlet中就是/test/getName這種形式的,一個介面就是一個資源。一個資源對應一個EntranceNode,到後面還對應一個ClusterNode。
總結
本文主要是介紹了一下 sentinel 與我們springboot 的web 專案整合,其實什麼web專案都是一樣,配置一下CommonFilter,請求經過這個Filter ,sentinel就能發揮作用,然後就是批量請求了一下,感受了一下sentinel的實時監控功能,通過qps,拒絕qps,rt,最後就是看看這個CommonFilter 到底幹了啥,這裡並沒有深入解析,而是簡單看看,後面會有若干的篇章進行解析原始碼。
相關文章
- Sentinel 原理-全解析
- Sentinel基本使用與原始碼分析原始碼
- Sentinel-Go 原始碼系列(一)|開篇Go原始碼
- Retrofit網路請求原始碼解析原始碼
- SpringCloud使用Sentinel,Sentinel持久化,Sentinel使用nacos持久化SpringGCCloud持久化
- Retrofit原始碼解析之網路請求原始碼
- Volley 原始碼解析之圖片請求原始碼
- Volley 原始碼解析之網路請求原始碼
- Sentinel Dashboard(基於1.8.1)流控規則持久化到Nacos——涉及部分Sentinel Dashboard原始碼改造持久化原始碼
- sentinel流控規則校驗之原始碼分析原始碼
- Redis——SentinelRedis
- springcloud~SentinelSpringGCCloud
- Sentinel 特性
- OkHttp3原始碼解析(一)之請求流程HTTP原始碼
- Redis哨兵sentinelRedis
- Redis sentinel搭建Redis
- sentinel-ProcessorSlot
- sentinel入門
- Sentinel實戰
- Sentinel高階
- Netty原始碼分析之一次請求是如何到達channelRead的?Netty原始碼
- Spring Cloud Alibaba SentinelSpringCloud
- Sentinel 原理-呼叫鏈
- SpringCloud-Alibaba-SentinelSpringGCCloud
- Sentinel原理一覽
- sentinel接入記錄
- Redis高可用 SentinelRedis
- 【Redis】Sentinel 哨兵模式Redis模式
- SpringCloud——Sentinel入門SpringGCCloud
- 阿里開源限流元件 Sentinel 叢集流控全解析阿里元件
- 阿里巴巴開源限流系統 Sentinel 全解析阿里
- tomcat原始碼分析(第三篇 tomcat請求原理解析--Connector原始碼分析)Tomcat原始碼
- 【PHP】一次請求過程的解析PHP
- 阿里 雙11 同款,流量防衛兵 Sentinel go 原始碼解讀阿里Go原始碼
- 阿里雙11同款,流量防衛兵 Sentinel go 原始碼解讀阿里Go原始碼
- 一起向歐洲空間局請求 繼續執行Sentinel-2A衛星
- Laravel 請求類原始碼分析Laravel原始碼
- 原始碼分析Retrofit請求流程原始碼