sofa
我们今天体验下 soul 的 sofa 插件。
1.启动 admin
2.在 bootstrap 的 pom.xml 文件中增加如下依赖:
sofa版本换成你的,注册中心的jar包换成你的,以下是参考。
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-rpc-all</artifactId>
<version>5.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-plugin-sofa</artifactId>
<version>${last.version}</version>
</dependency>
3.启动 bootstrap
4.在 admin 后台打开 sofa 插件。
5.找到 soul-examples 模块里的 soul-examples-sofa ,启动服务
sofa 服务也需要先启动 zookeeper 。
当我们看到 sofa client register success ,说明 sofa 接口已经注册成功了。
我们可以看 sofa examples 里配置是 contextPath 是 /sofa
soul:
sofa:
adminUrl: http://localhost:9095
contextPath: /sofa
appName: sofa
6.通过网关访问接口
http://localhost:9195/sofa/findAll
debug
其实我在测试 http://localhost:9195/sofa/findById 的时候一直报错,昨天搞到凌晨2点没找到问题,只是发现 findAll 没问题。今天起床后,就开始找这个问题,
在 SofaProxyService 的 genericInvoker() 里,我们看到 findAll 因为没有参数,走的上面 if 的逻辑, findById 需要传参数,走的下面的逻辑,然后 sofaParamResolveService 报空指针异常。
if (null == body || "".equals(body) || "{}".equals(body) || "null".equals(body)) {
pair = new ImmutablePair<>(new String[]{}, new Object[]{});
} else {
pair = sofaParamResolveService.buildParameter(body, metaData.getParameterTypes());
}
然后我就去找 sofaParamResolveService 赋值的地方
public SofaProxyService(final SofaParamResolveService sofaParamResolveService) {
this.sofaParamResolveService = sofaParamResolveService;
}
继续向上, SofaPluginConfiguration 里面,注册 sofaPlugin bean 的时候会把这个 service 加进去。
@Bean
public SoulPlugin sofaPlugin(final ObjectProvider<SofaParamResolveService> sofaParamResolveService) {
return new SofaPlugin(new SofaProxyService(sofaParamResolveService.getIfAvailable()));
}
然后我们发现是 ObjectProvider sofaParamResolveService 这里为空。
我找了下,发现类似的 AlibabaDubboPluginConfiguration 有实现类 DefaultDubboParamResolveServiceImpl,而 SofaParamResolveService 没有实现类,然后我自己在 DefaultDubboParamResolveServiceImpl(soul-web 模块) 那里加了个 DefaultSofaParamResolveServiceImpl ,重启 bootstrap 之后,发现 sofaParamResolveService 有值了,调 findById 也成返回了。
后面当我正准备给 soul 提 pr 的时候,发现官方已经把这个问题修复了,修复记录如下。
总结:
sofa 插件可以让我们通过 http 的方式来请求我们的sofa服务。
遇到 bug 不要慌,debug 总能找到问题的。