啟動 soul-admin成功后, 啟動soul-bootstrap
soul-admin下列印幾行資訊
2021-01-13 23:00:42.047 INFO 16544 --- [0.0-9095-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-01-13 23:00:42.047 INFO 16544 --- [0.0-9095-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2021-01-13 23:00:42.113 INFO 16544 --- [0.0-9095-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 65 ms
2021-01-13 23:00:42.267 INFO 16544 --- [0.0-9095-exec-1] o.d.s.a.l.websocket.WebsocketCollector : websocket on open successful....
說明網關與配置后臺建立websocket通信, soul-admin 的 WebsocketCollector 列印出關鍵資訊
@Slf4j
@ServerEndpoint("/websocket")
public class WebsocketCollector {
private static final Set<Session> SESSION_SET = new CopyOnWriteArraySet<>();
private static Session session;
/**
* On open.
*
* @param session the session
*/
@OnOpen
public void onOpen(final Session session) {
log.info("websocket on open successful....");
SESSION_SET.add(session);
}
...
}
初步判斷, 配置的同步, 默認下是借由websocket協議完成.
再繼續看soul-bootstrap這邊, 由WebsocketSyncDataConfiguration與WebsocketSyncDataService 完成websocket協議建立, 之后也可能借此進行配置通信, 先暫時標記, 以后研究配置同步時繼續鉆研.
2021-01-13 23:00:41.679 INFO 21212 --- [ main] b.s.s.d.w.WebsocketSyncDataConfiguration : you use websocket sync soul data.......
2021-01-13 23:00:42.244 INFO 21212 --- [ main] o.d.s.p.s.d.w.WebsocketSyncDataService : websocket connection is successful.....
由于網關已經啟動, 埠是9195, 隨便在網址上訪問下 localhost:9195 , 回傳
{
code: -107,
message: "Can not find selector, please check your configuration!",
data: null
}
這時網關列印出日志
2021-01-13 23:06:49.346 ERROR 21212 --- [-work-threads-1] o.d.soul.plugin.base.utils.CheckUtils : can not match selector data: divide
關鍵類CheckUtils 作為提供selector的工具類, 追溯呼叫它的方法為 AbstractSoulPlugin 的 handleSelectorIsNull
private Mono<Void> handleSelectorIsNull(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) {
if (PluginEnum.WAF.getName().equals(pluginName)) {
return doExecute(exchange, chain, null, null);
}
return CheckUtils.checkSelector(pluginName, exchange, chain);
}
WAF? 看著像匹配并執行防火墻類的插件的實作方法 (doExecute()被繼承類實作, 模板方法 ), 然后獲得selector, 這里的selector是啥不明白, 暫放一邊, 繼續向上查看呼叫, 發現是該類的execute()方法呼叫的.
@Override
public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
String pluginName = named();
final PluginData pluginData = BaseDataCache.getInstance().obtainPluginData(pluginName);
if (pluginData != null && pluginData.getEnabled()) {
final Collection<SelectorData> selectors = BaseDataCache.getInstance().obtainSelectorData(pluginName);
if (CollectionUtils.isEmpty(selectors)) {
return handleSelectorIsNull(pluginName, exchange, chain);
}
final SelectorData selectorData = matchSelector(exchange, selectors);
if (Objects.isNull(selectorData)) {
return handleSelectorIsNull(pluginName, exchange, chain);
}
selectorLog(selectorData, pluginName);
final List<RuleData> rules = BaseDataCache.getInstance().obtainRuleData(selectorData.getId());
if (CollectionUtils.isEmpty(rules)) {
return handleRuleIsNull(pluginName, exchange, chain);
}
RuleData rule;
if (selectorData.getType() == SelectorTypeEnum.FULL_FLOW.getCode()) {
//get last
rule = rules.get(rules.size() - 1);
} else {
rule = matchRule(exchange, rules);
}
if (Objects.isNull(rule)) {
return handleRuleIsNull(pluginName, exchange, chain);
}
ruleLog(rule, pluginName);
return doExecute(exchange, chain, selectorData, rule);
}
return chain.execute(exchange);
}
execute方法在我看來, 就是所有插件的祖宗級入口, 方法由介面 SoulPlugin 定義, 這個介面應該是祖宗類, 這個方法應該是重點, 暫時也不研究, 在研究插件時, 看這里.
再看下AbstractSoulPlugin 被哪些插件類繼承了, 看到個熟悉的影子 DividePlugin , 和剛剛日志列印的 can not match selector data: divide有關系, 盲猜剛剛日志列印時, AbstractSoulPlugin的實作類是它, 開始debug, 先直接D在CheckUtils列印那行
public static Mono<Void> checkSelector(final String pluginName, final ServerWebExchange exchange, final SoulPluginChain chain) {
if (PluginEnum.DIVIDE.getName().equals(pluginName)
|| PluginEnum.DUBBO.getName().equals(pluginName)
|| PluginEnum.SPRING_CLOUD.getName().equals(pluginName)) {
log.error("can not match selector data: {}", pluginName);
Object error = SoulResultWrap.error(SoulResultEnum.CANNOT_FIND_SELECTOR.getCode(), SoulResultEnum.CANNOT_FIND_SELECTOR.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
return chain.execute(exchange);
}
對著執行緒堆疊向上追兩個呼叫, 到AbstractSoulPlugin這層, 發現實際的實作類確實是 DividePlugin , 那它的具體 doExecute() 的實作, 就是去處理得到的 Selector 了. 暫時不看, 該睡覺了…
明天將一個http服務跑起來, 看看有什么關鍵類在作用, 以及最重要的網關server和client如何作業
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/249031.html
標籤:其他
上一篇:攻防世界-wp-MISC-新手區-12-功夫再高也怕菜刀
下一篇:2021-01-14
