apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.4k stars 26.41k forks source link

No matter how I set it, the version is always 0.0.0 #5041

Closed yinjunonly closed 4 years ago

yinjunonly commented 5 years ago

Environment

Steps to reproduce this issue

1.Declare service:

<dubbo:service interface="com.xxx.RemoteDefaultService" version="0.0.1" timeout="5000" ref="remoteDefaultServiceImpl" group="commonComponent"/>

2.Generalizing calls using API

ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
reference.setApplication(this.applicationConfig);
reference.setRegistry(this.registryConfig);
reference.setInterface("com.xxx.RemoteDefaultService");
reference.setGeneric(true);
reference.setConsumer(consumerConfig);
reference.setGroup("commonComponent");
reference.setVersion("0.0.1");
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
GenericService genericService = cache.get(reference);
int len = params.size();
String[] invokeParamTyeps = new String[len];
Object[] invokeParams = new Object[len];
for (int i = 0; i < len; i++) {
    GenericParamsEntity current = params.get(i);
    invokeParamTyeps[i] = current.getTypeName();
    invokeParams[i] = current.getValue();
}
try {
    Object result = genericService.$invoke(method, invokeParamTyeps, invokeParams);
    return result;
} catch (GenericException e) {
    genericExceptionAnalytical(e);
    throw e;
}

3.Throw an exception

Not found exported service: 
········································································
·········································································
interface=com.xxx.RemoteDefaultService, version=0.0.0, generic=true}]

No matter how I set it, the version is always 0.0.0

bq-xiao commented 5 years ago

the same issue:

Env:

maven:
<dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.3</version>
</dependency>

OS: windows10
JDK:1.8

1.Provider source code:

@Service(version = "demo", interfaceClass = HelloWorldService.class)
public class HelloWorldServiceImpl implements HelloWorldService {

    @Value("${dubbo.application.name}")
    private String serviceName;

    @Override
    public String sayHello(String name) {
        return String.format("[%s] : Hello, %s", serviceName, name);
    }
}

2.Consumer source code:

@RestController
@RequestMapping("/sample")
public class HelloWorldController {
    @Reference(version = "demo", url = "dubbo://127.0.0.1:12345")
    private HelloWorldService helloWorldService;

    @GetMapping(value = "/hello/{name}")
    @ResponseBody
    public String say(@PathVariable("name") String name) {
        return helloWorldService.sayHello(name);
    }
}

3.But get below error log

org.apache.dubbo.remoting.RemotingException: org.apache.dubbo.remoting.RemotingException: Not found exported service: com.example.dubbo.springboot.api.service.HelloWorldService:12345 in [com.example.dubbo.springboot.api.service.HelloWorldService:demo:12345], may be version or group mismatch , channel: consumer: /192.168.0.190:9410 --> provider: /192.168.0.190:12345, message:RpcInvocation [methodName=sayHello, parameterTypes=[class java.lang.String], arguments=[aa], attachments={path=com.example.dubbo.springboot.api.service.HelloWorldService, input=270, dubbo=2.0.2, interface=com.example.dubbo.springboot.api.service.HelloWorldService, version=0.0.0}]
org.apache.dubbo.remoting.RemotingException: Not found exported service: com.example.dubbo.springboot.api.service.HelloWorldService:12345 in [com.example.dubbo.springboot.api.service.HelloWorldService:demo:12345], may be version or group mismatch , channel: consumer: /192.168.0.190:9410 --> provider: /192.168.0.190:12345, message:RpcInvocation [methodName=sayHello, parameterTypes=[class java.lang.String], arguments=[aa], attachments={path=com.example.dubbo.springboot.api.service.HelloWorldService, input=270, dubbo=2.0.2, interface=com.example.dubbo.springboot.api.service.HelloWorldService, version=0.0.0}]
bq-xiao commented 5 years ago

When remove the version property, it works fine.

yinjunonly commented 5 years ago

When remove the version property, it works fine.

I'm a previous project, I've managed it using version.

sonymoon commented 5 years ago

I have a demo locally. It works fine. Do you have a demo git repository link?

bq-xiao commented 5 years ago

I have a demo locally. It works fine. Do you have a demo git repository link?

@sonymoon Yes, i init a pubic repository, you can reference this link: dubbo-demo

And, i reference this guideline dubbo-spring-boot-project

superleo-cn commented 5 years ago

This is an interesting issue. At the first place, your demo didn't use any registry but just directly connected from Annotation. That's maybe the reason someone failed to reproduce your case:

   @Reference(url = "dubbo://127.0.0.1:12345", version = "1.0.0")
    private HelloWorldService helloWorldService;

I troubleshot the test cases and went through the source codes and figured out the dubbo didn't pick up the URL parameters as the 'RpcInvocation.Attachment'. That's no wonder you always get the default "0.0.0".

Here I have a go to show you my hotfix, which just passed the unit test of dubbo, about how to interim fix the issue.

org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.java


 @Override
    public Object decode(Channel channel, InputStream input) throws IOException {
        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)
                .deserialize(channel.getUrl(), input);

        String dubboVersion = in.readUTF();
        request.setVersion(dubboVersion);
        setAttachment(DUBBO_VERSION_KEY, dubboVersion);
        setAttachment(PATH_KEY, in.readUTF());

        // below is my current hotfix
        // get the service version from URL.
        String reqVersion = channel.getUrl().getParameter(VERSION_KEY);
        String defaultVersion = in.readUTF();
        // if empty, use the default version instead.
        setAttachment(VERSION_KEY, StringUtils.isEmpty(reqVersion) ? defaultVersion : reqVersion);

But I know that's not the ultimate solution, I am also still curious why the version inside the InputStream input is always 0.0.0. Looking forward any official maintainer to reply.

sonymoon commented 5 years ago
if (REGISTRY_PROTOCOL.equals(url.getProtocol())) {
     urls.add(url.addParameterAndEncoded(REFER_KEY, StringUtils.toQueryString(map)));
} else {
    urls.add(ClusterUtils.mergeUrl(url, map));
}

See org.apache.dubbo.rpc.cluster.support.ClusterUtils#mergeUrl. If no registry was set, some params will be removed including VERSION_KEY.

@bq-xiao For your case, temp solution: you can use http://dubbo.apache.org/zh-cn/docs/user/references/registry/simple.html if you don't have any registry center.

I was wondering why these params would be removed if there is no registry. @htynkn Any official answers?

chickenlj commented 4 years ago

用的是什么注册中心?请检查注册中心中 provider url 注册上去的 group version 值是什么?

另外贴一些日志,看看注册中心实际下发下来的 url 是什么,然后我们才能继续定位问题

chickenlj commented 4 years ago

Reopen if necessary.