Soul原始碼分析 —— 初體驗
Soul原始碼分析 —— 初體驗
啥是Soul
soul是一個非同步的, 高效能的, 跨語言的, 響應式的API閘道器。
soul核心Features
提供了諸如限流、熔斷、轉發和路由監控等外掛
Soul是如何做到代理服務
本質上它在服務之前增加了一層代理,在被代理服務啟動時通過環境引數中的adminUrl在Soul-admin服務中插入該服務的元資料,並帶上ContextPath, AppName其它引數。Soul Admin會拼出該服務對應的URl模式。Soul-Admin可以調整各個服務的限流,熔斷等引數。Soul-Bootstrap就是閘道器,會在收到請求是通過呼叫soul-plugin去Soul-Admin的介面去拿到對應的元資料和代理服務的引數,並呼叫URL對應的soul-plugin去呼叫服務或者拒絕請求。
每一個開啟的外掛就會增加soul閘道器對流量的適配。也就是說沒有開啟的外掛時,soul閘道器會拒絕所有的流量。需要對http協議的支援,就有了divide外掛,需要對dubbo協議的支援,就有了dubbo外掛,等等。有些外掛時通用的,比如說rate_limitor是做限流的,monitor是做系統性能監控的,等等。各外掛的作用以後會具體研究。
服務端需要引入的依賴
本質上它引用的Soul的starter的包並通過Annotation的方式往Soul-Admin注入元資料
閘道器需要引入的依賴
本質上它引用的starter依賴會匯入soul-plugin的bean.
Soul管理服務
本質上它提供了被代理服務元資料的資料中心,還提供對具體API的限流、熔斷,負載均衡等等的配置
碰到的幾個坑
啟動異常
如果之前啟動過AlibabaDubbo的應用,在啟動Sofa應用時,soul-admin就會丟擲異常
2021-01-18 23:30:49.178 ERROR 48161 --- [.0-9095-exec-10] o.d.s.admin.exception. ExceptionHandlers : nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
在soul-admin中檢視外掛的metadata,因為interface和MethodName和Dubbo的服務相同,導致報異常,解決辦法是刪除Dubbo的metadata.
測試介面/sofa/insert, 返回響應200但無資料
打斷點在一下方法發現pluginList裡找不到SofaPlugin。我們知道SofaPlugin是通過soul-spring-boot-starter-plugin-sofa注入BeanFactory的,所以它應該在裡面。 這個問題很詭異但是重啟IDEA後神奇的解決了。反過來也能重現這個問題,也就是說當將這個starter依賴刪掉之後,只有重啟IDEA才能將這個外掛從pluginList中刪掉。
@Bean("webHandler")
public SoulWebHandler soulWebHandler(final ObjectProvider<List<SoulPlugin>> plugins) {
List<SoulPlugin> pluginList = plugins.getIfAvailable(Collections::emptyList);
final List<SoulPlugin> soulPlugins = pluginList.stream()
.sorted(Comparator.comparingInt(SoulPlugin::getOrder)).collect(Collectors.toList());
soulPlugins.forEach(soulPlugin -> log.info("load plugin:[{}] [{}]", soulPlugin.named(), soulPlugin.getClass().getName()));
return new SoulWebHandler(soulPlugins);
}
小結
下章再看程式碼