- [ ] I have searched the [issues](https://github.com/apache/incubator-dubbo/issues) of this repository and believe that this is not a duplicate.
- [ ] I have checked the [FAQ](https://github.com/apache/incubator-dubbo/blob/master/FAQ.md) of this repository and believe that this is not a duplicate.

### Environment

* Dubbo version: xxx
* Operating System version: xxx
* Java version: xxx

### Steps to reproduce this issue

nacos registry serviceName may conflict when we have two provider with same service but one config version as A and left group empty and
one config group as A and left version empty

the two provider would get registered with same key    provdier:serviceName:A.

the cause of this issue is we ignore empty value when we construct the key,  relative code is 

```java
 private String getServiceName(URL url) {
        String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
        return getServiceName(url, category);
    }

    private String getServiceName(URL url, String category) {
        StringBuilder serviceNameBuilder = new StringBuilder(category);
        append(serviceNameBuilder, url, INTERFACE_KEY);
        append(serviceNameBuilder, url, VERSION_KEY);
        append(serviceNameBuilder, url, GROUP_KEY);
        return serviceNameBuilder.toString();
    }

private void append(StringBuilder target, URL url, String parameterName) {
        target.append(SERVICE_NAME_SEPARATOR);
        String parameterValue = url.getParameter(parameterName);
        if (!StringUtils.isBlank(parameterValue)) {
            target.append(parameterValue);
        }
    }
``` 

i think we should just keep a SEPARATOR as placeholder for empty value.


1. xxx
2. xxx
3. xxx

Pls. provide [GitHub address] to reproduce this issue.

### Expected Result

What do you expected from the above steps？

### Actual Result

What actually happens?

If there is an exception, please attach the exception trace:

```
Just put your stack trace here!
```

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
/**
 * Nacos {@link Registry}
 *
 * @see #SERVICE_NAME_SEPARATOR
 * @see #PAGINATION_SIZE
 * @see #LOOKUP_INTERVAL
 * @since 2.6.5
 */
public class NacosRegistry extends FailbackRegistry {