今日任务
- AlibabaDubboPlugin 研究
- ApacheDubboPlugin 研究
AlibabaDubboPlugin
将该启动的都开启, Mysql、Zookeeper、AlibabaDubbo服务、Soul-admin、Soul-bootstrap.
值得注意的是, 启动网关时打印了这几行日志:
2021-01-19 19:56:44.680 INFO 1623 --- [ctReadThread-37] o.d.s.p.a.d.c.ApplicationConfigCache : init aliaba dubbo reference success there meteData is :MetaData(id=1350474912353136640, appName=dubbo, contextPath=null, path=/dubbo/insert, rpcType=dubbo, serviceName=org.dromara.soul.test.dubbo.api.service.DubboTestService, methodName=insert, parameterTypes=org.dromara.soul.test.dubbo.api.entity.DubboTest, rpcExt={
"timeout":10000}, enabled=true)
2021-01-19 19:56:44.829 INFO 1623 --- [ctReadThread-37] o.d.s.p.a.d.c.ApplicationConfigCache : init aliaba dubbo reference success there meteData is :MetaData(id=1350474914580312064, appName=dubbo, contextPath=null, path=/dubbo/findByIdsAndName, rpcType=dubbo, serviceName=org.dromara.soul.test.dubbo.api.service.DubboMultiParamService, methodName=findByIdsAndName, parameterTypes=java.util.List,java.lang.String, rpcExt={
"timeout":10000}, enabled=true)
看着像服务信息缓存相关, 先记下 `ApplicationConfigCache` 这个类.
这次我们有了以前的经验, 直接找到 SoulWebHandler
的 execute()
方法, 看看调用的插件链长啥样:
plugins = {ArrayList@8953} size = 12
0 = {GlobalPlugin@8537}
1 = {WafPlugin@9085}
2 = {RateLimiterPlugin@9086}
3 = {HystrixPlugin@9087}
4 = {DividePlugin@9088}
5 = {WebClientPlugin@9089}
6 = {WebSocketPlugin@9090}
7 = {BodyParamPlugin@9091}
8 = {AlibabaDubboPlugin@9092}
9 = {MonitorPlugin@9093}
10 = {WebClientResponsePlugin@9094}
11 = {DubboResponsePlugin@9095}
比起简单的HTTP调用, 多了两个插件 BodyParamPlugin
、AlibabaDubboPlugin
、DubboResponsePlugin
, 这两个应该就是 Dubbo 服务相关的插件了.
继续跑跑链调用, 像之前的老熟人 DividePlugin
、WebClientPlugin
、WebClientResponsePlugin
和 WebSocketPlugin
都直接跳过了, 能理解, 毕竟走的 RpcType 类型为 dubbo.
最后再关注下线程变动信息, 因为有服务调用肯定应该是要异步的, 这里不是在调用服务就是准备调用, 总之它不老实就是了:
可以从以下截图看到, 插件调用在 BodyParamPlugin
到 AlibabaDubboPlugin
间线程发生变动, 看来 BodyParamPlugin
是关键的请求转发插件, 我们从它来开刀, 跟踪它的代码.
PS: 这里注意下, 此处 BodyParamPlugin
完整路径为: org.dromara.soul.plugin.alibaba.dubbo.param
public class BodyParamPlugin implements SoulPlugin {
@Override
public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
final ServerHttpRequest request = exchange.getRequest();
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
if (Objects.nonNull(soulContext) && RpcTypeEnum.DUBBO.getName().equals(soulContext.getRpcType())) {
// 获取请求头的 contentType
MediaType mediaType = request.getHeaders().getContentType();
ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
return serverRequest.bodyToMono(String.class)
.switchIfEmpty(Mono.defer(() ->
// 切换线程了
Mono.just(""))
)
.flatMap(body -> {
// 判断 contentType 是否 json, 是则将 body 信息注入上下文, 用 key 标识是 dubbo参数
if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) {
exchange.getAttributes().put(Constants.DUBBO_PARAMS, body)