在springboot中使用dubbo,本来是件挺简单的事情,但现实的世界就是如此的复杂,今天我用一个亲身经历的跳坑和填坑的事来讲在spring boot中使用高版本dubbo(当当的魔改版)的三重境界。
1、看山是山,使用官方starter简单的使用dubbo starter集成进spring boot还是非常简单的。
在springboot2的pom.xml中引入dubbo的starter
<dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>在启动类里面加上注解@EnableDubboConfiguration
@EnableDubboConfiguration @SpringBootApplication public class DubbodemoApplication { public static void main(String[] args) { SpringApplication.run(DubbodemoApplication.class, args); } }在application.properties里面写dubbo的相关配置
spring.dubbo.application.name=mydubbostarterdemo spring.dubbo.server=true spring.dubbo.protocol.name=dubbo spring.dubbo.registry.address=zookeeper://127.0.0.1:2181作为服务的提供者,我们发布一个服务
public interface IHelloService { public String hello(String str); } import com.alibaba.dubbo.config.annotation.Service; //这个service的注解是dubbo的service,不是spring的service注解 @Service(interfaceClass = IHelloService.class) @Component public class HelloServiceImpl implements IHelloService { @Override public String hello(String str) { String returnStr = "Hello "+str; return returnStr; } }然后运行DubbodemoApplication就能发布这个服务了。
同样的,在消费者那边,我们直接用@Reference注解来引用这个服务即可
@Reference private IHelloService helloService; @GetMapping("/hello/{name}") public String hello(@PathVariable("name") String name) { String str = helloService.hello(name); System.out.println(str); return str; }记得在消费者的工程里面要加上IHelloService的接口类。
这样就能愉快的调用了
是不是很简单,是不是很容易。但是这个世界是复杂的,我们看下pom文件可以看到,里面引用的dubbo版本是2.6.0
但现在很多地方用的并不是dubbo,而是当当改过的dubbo,最新的版本已经到了2.8.4,如果服务提供者用这个版本,那么消费者还用这种方法调用,就会报错
2019-12-05 11:51:28.094 ERROR 17808 --- [nio-8088-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method hello in the service com.skyblue.dubbodemo.service.IHelloService. Tried 3 times of the providers [192.168.1.103:20880] (1/1) from the registry 115.29.199.6:2181 on the consumer 192.168.1.103 using the dubbo version 2.6.0. Last error is: Failed to invoke remote method: hello, provider: dubbo://192.168.1.103:20880/com.skyblue.dubbodemo.service.IHelloService?anyhost=true&application=mydubbostarterdemo&check=false&dubbo=2.8.4a&generic=false&interface=com.skyblue.dubbodemo.service.IHelloService&methods=hello&pid=17808®ister.ip=192.168.1.103&remote.timestamp=1575517827193&side=consumer×tamp=1575517879746, cause: Fail to decode request due to: RpcInvocation [methodName=hello, parameterTypes=null, arguments=null, attachments={path=com.skyblue.dubbodemo.service.IHelloService, input=223, dubbo=2.6.0, version=0.0.0}]] with root cause com.alibaba.dubbo.remoting.RemotingException: Fail to decode request due to: RpcInvocation [methodName=hello, parameterTypes=null, arguments=null, attachments={path=com.skyblue.dubbodemo.service.IHelloService, input=223, dubbo=2.6.0, version=0.0.0}] at com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.returnFromResponse(DefaultFuture.java:218) ~[dubbo-2.6.0.jar:2.6.0] at com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:137) ~[dubbo-2.6.0.jar:2.6.0] at com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:111) ~[dubbo-2.6.0.jar:2.6.0] at com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker.doInvoke(DubboInvoker.java:95) ~[dubbo-2.6.0.jar:2.6.0] at com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:142) ~[dubbo-2.6.0.jar:2.6.0] ......