
### Environment

* Dubbo version: 3.0.2.1
* Operating System version: Linux 4.14.152-127.182.amzn2.x86_64
* Java version: 1.8_310

### Steps to reproduce this issue

1. A provider annotated with @DubboService(tag = 'XXX')
2. A Consumer annotated with @DubboReference(tag = 'XXX')
3. Consumer will complain no provider found

Possible Cause:
1. TagDynamicStateRouter#line 112 will hardcode tag as 'noTag' even the service has a valid tag but without tagRouterRule set
```
invocation.setAttachment(TAG_KEY, NO_TAG);
```
2. TagStaticStateRouter#64 try to locate the tag with below code, however the tag attachment already set as noTag from previous router, hence the tag is always noTag even the url has a valid tag set.
```
 String tag = StringUtils.isEmpty(invocation.getAttachment(TAG_KEY)) ? url.getParameter(TAG_KEY) :
            invocation.getAttachment(TAG_KEY);
        if (StringUtils.isEmpty(tag)) {
            tag = NO_TAG;
        }
```

Possible Fix:
replace StringUtils.isEmpty as below function:
```
boolean isNoTag(String value) {
      return StringUtils.isEmpty(value) || NO_TAG.equals(value));
}
```
public boolean shouldRePool() {
        return false;
    }
    @Override
    public <T> RouterCache<T> pool(List<Invoker<T>> invokers) {
        RouterCache<T> routerCache = new RouterCache<>();
        ConcurrentHashMap<String, BitList<Invoker<T>>> addrPool = new ConcurrentHashMap<>();
        for (int index = 0; index < invokers.size(); index++) {
            Invoker<T> invoker = invokers.get(index);
            String tag = invoker.getUrl().getParameter(TAG_KEY);
            if (StringUtils.isEmpty(tag)) {
                BitList<Invoker<T>> noTagList = addrPool.computeIfAbsent(NO_TAG, k -> new BitList<>(invokers, true));
                noTagList.addIndex(index);
            } else {
                BitList<Invoker<T>> list = addrPool.computeIfAbsent(tag, k -> new BitList<>(invokers, true));
                list.addIndex(index);
            }
        }
        routerCache.setAddrPool(addrPool);
        return routerCache;
    }
    @Override
    public <T> void notify(List<Invoker<T>> invokers) {
        if (CollectionUtils.isEmpty(invokers)) {
            return;
        }
        pool(invokers);
    }
}