### Environment

* Dubbo version: 3.2.0
* Operating System version: macos10.15.7
* Java version: 1.8

### Steps to reproduce this issue
服务提供者
```java
public class ApiProvider {
    public static void main(String[] args) {
        ServiceConfig<GreeterService> serviceConfig = new ServiceConfig<>();
        serviceConfig.setInterface(GreeterService.class);
        serviceConfig.setRef(new GreeterServiceImpl());

        ProtocolConfig protocol = new ProtocolConfig("tri", 20881);
        protocol.setExtProtocol("dubbo");

        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-triple-api-provider");
        applicationConfig.setRegisterMode("instance");
        applicationConfig.setMetadataType("remote");
        applicationConfig.setEnableFileCache(false);

        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        bootstrap.application(applicationConfig)
            .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
            .protocol(protocol)
            .service(serviceConfig)
            .start()
            .await();
    }
}
```
服务消费者
```java
public class ApiConsumer {
    public static void main(String[] args) throws InterruptedException {
        System.setProperty("dubbo.application.service-discovery.migration", "FORCE_APPLICATION");
        ReferenceConfig<GreeterService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setInterface(GreeterService.class);
        referenceConfig.setCheck(false);
        referenceConfig.setTimeout(3000);
        referenceConfig.setProtocol(CommonConstants.DUBBO);
        referenceConfig.setRetries(0);
        ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-triple-api-consumer");
        applicationConfig.setMetadataType("remote");
        applicationConfig.setEnableFileCache(false);
        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        bootstrap.application(applicationConfig)
            .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
            .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1))
            .reference(referenceConfig)
            .start();
        referenceConfig.get().sayHello(HelloRequest.newBuilder().setName("123").build());
    }
}
```


### Expected Behavior

服务端正常响应客户端

### Actual Behavior

服务消费者stacktrace
```
[19/05/23 03:10:58:058 CST] DubboShutdownHook  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.1] is stopping., dubbo version: 3.2.0, current host: 10.55.38.81
Exception in thread "main" org.apache.dubbo.rpc.RpcException: Failed to invoke the method sayHello in the service org.apache.dubbo.demo.GreeterService. Tried 1 times of the providers [10.55.38.81:20881] (1/1) from the registry 127.0.0.1:2181 on the consumer 10.55.38.81 using the dubbo version 3.2.0. Last error is: Invoke remote method timeout. method: sayHello, provider: DefaultServiceInstance{serviceName='dubbo-demo-triple-api-provider', host='10.55.38.81', port=20881, enabled=true, healthy=true, metadata={dubbo.endpoints=[{"port":20881,"protocol":"dubbo"},{"port":20881,"protocol":"tri"}], dubbo.metadata.revision=0261e84951c0c038110acb6ff1edbb32, dubbo.metadata.storage-type=remote, timestamp=1684480151231}}, service{name='org.apache.dubbo.demo.GreeterService',group='null',version='null',protocol='dubbo',port='20881',params={executor-management-mode=isolation, side=provider, file-cache=false, release=3.2.0, methods=sayHello,sayHelloAsync,sayMultiHello1,sayMultiHello2, deprecated=false, dubbo=2.0.2, interface=org.apache.dubbo.demo.GreeterService, service-name-mapping=true, register-mode=instance, generic=false, ispuserver=true, metadata-type=remote, application=dubbo-demo-triple-api-provider, prefer.serialization=fastjson2,hessian2, background=false, dynamic=true, anyhost=true},}, cause: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2023-05-19 15:10:55.126, end time: 2023-05-19 15:10:58.173, client elapsed: 124 ms, server elapsed: 2923 ms, timeout: 3000 ms, request: Request [id=0, version=2.0.2, twoWay=true, event=false, broken=false, mPayload=0, data=RpcInvocation [methodName=sayHello, parameterTypes=[class org.apache.dubbo.demo.hello.HelloRequest]]], channel: /10.55.38.81:56152 -> /10.55.38.81:20881
	at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:115)
	at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:341)
	at org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter.invoke(RouterSnapshotFilter.java:46)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:101)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter.invoke(MetricsClusterFilter.java:51)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:52)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter.invoke(ObservationSenderFilter.java:61)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.cluster.filter.support.ConsumerClassLoaderFilter.invoke(ConsumerClassLoaderFilter.java:40)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter.invoke(ConsumerContextFilter.java:118)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:194)
	at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$ClusterFilterInvoker.invoke(AbstractCluster.java:91)
	at org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:103)
	at org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterInvoker.invoke(ScopeClusterInvoker.java:131)
	at org.apache.dubbo.registry.client.migration.MigrationInvoker.invoke(MigrationInvoker.java:286)
	at org.apache.dubbo.rpc.proxy.InvocationUtil.invoke(InvocationUtil.java:57)
	at org.apache.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:75)
	at org.apache.dubbo.demo.GreeterServiceDubboProxy0.sayHello(GreeterServiceDubboProxy0.java)
	at org.apache.dubbo.demo.consumer.ApiConsumer.main(ApiConsumer.java:58)
Caused by: java.util.concurrent.ExecutionException: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2023-05-19 15:10:55.126, end time: 2023-05-19 15:10:58.173, client elapsed: 124 ms, server elapsed: 2923 ms, timeout: 3000 ms, request: Request [id=0, version=2.0.2, twoWay=true, event=false, broken=false, mPayload=0, data=RpcInvocation [methodName=sayHello, parameterTypes=[class org.apache.dubbo.demo.hello.HelloRequest]]], channel: /10.55.38.81:56152 -> /10.55.38.81:20881
	at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at org.apache.dubbo.rpc.AsyncRpcResult.get(AsyncRpcResult.java:208)
	at org.apache.dubbo.rpc.protocol.AbstractInvoker.waitForResultIfSync(AbstractInvoker.java:286)
	at org.apache.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:189)
	at org.apache.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:71)
	at org.apache.dubbo.metrics.filter.MetricsFilter.invoke(MetricsFilter.java:56)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:331)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:194)
	at org.apache.dubbo.rpc.protocol.ReferenceCountInvokerWrapper.invoke(ReferenceCountInvokerWrapper.java:78)
	at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invokeWithContext(AbstractClusterInvoker.java:380)
	at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:81)
	... 24 more
Caused by: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2023-05-19 15:10:55.126, end time: 2023-05-19 15:10:58.173, client elapsed: 124 ms, server elapsed: 2923 ms, timeout: 3000 ms, request: Request [id=0, version=2.0.2, twoWay=true, event=false, broken=false, mPayload=0, data=RpcInvocation [methodName=sayHello, parameterTypes=[class org.apache.dubbo.demo.hello.HelloRequest]]], channel: /10.55.38.81:56152 -> /10.55.38.81:20881
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture.doReceived(DefaultFuture.java:217)
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture.received(DefaultFuture.java:181)
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture$TimeoutCheckTask.notifyTimeout(DefaultFuture.java:291)
	at org.apache.dubbo.remoting.exchange.support.DefaultFuture$TimeoutCheckTask.lambda$run$0(DefaultFuture.java:278)
	at org.apache.dubbo.common.threadpool.ThreadlessExecutor$RunnableWrapper.run(ThreadlessExecutor.java:141)
	at org.apache.dubbo.common.threadpool.ThreadlessExecutor.waitAndDrain(ThreadlessExecutor.java:70)
	at org.apache.dubbo.rpc.AsyncRpcResult.get(AsyncRpcResult.java:202)
	... 33 more
```

客户端建立连接，服务端创建NettyChannel时，走主协议tri，创建内部Codec，即org.apache.dubbo.remoting.api.pu.DefaultCodec，是个空实现。
```java
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    super.channelActive(ctx);
    NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);// 创建nettychannel，内部codec为tri协议获取到DefaultCodec2
}
```

客户端协议确定以后，虽然org.apache.dubbo.remoting.transport.netty4.NettyConfigOperator#configChannelHandler将pipeline中的codec替换为DubboCountCodec了。
```java
if (!(codec2 instanceof DefaultCodec)){
    NettyCodecAdapter codec = new NettyCodecAdapter(codec2, channel.getUrl(), handler);
    ((NettyChannel) channel).getNioChannel().pipeline().addLast(
        codec.getDecoder()
    ).addLast(
        codec.getEncoder()
    );
}
```
但是org.apache.dubbo.remoting.transport.netty4.NettyChannel#send优化走业务线程encode，NettyChannel内部的codec是空实现，导致最后提交到netty的outputMessage是个空buffer，最终客户端收不到服务端的响应，超时结束。
```java
public void send(Object message, boolean sent) throws RemotingException {
	Object outputMessage = message;
	if (!encodeInIOThread) {
	    ByteBuf buf = channel.alloc().buffer();
	    ChannelBuffer buffer = new NettyBackedChannelBuffer(buf);
	    codec.encode(this, buffer, message); // 空实现
	    outputMessage = buf; // 空buffer
	}
```
} else {
                        Throwable t = future.cause();
                        if (t == null) {
                            return;
                        }
                        Response response = buildErrorResponse((Request) message, t);
                        handler.received(NettyChannel.this, response);
                    }
                }
            });
            if (sent) {
                
                timeout = getUrl().getPositiveParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT);
                success = future.await(timeout);
            }
            Throwable cause = future.cause();
            if (cause != null) {
                throw cause;
            }
        } catch (Throwable e) {
            removeChannelIfDisconnected(channel);
            throw new RemotingException(this, "Failed to send message " + PayloadDropper.getRequestWithoutData(message) + " to " + getRemoteAddress() + ", cause: " + e.getMessage(), e);
        }
        if (!success) {
            throw new RemotingException(this, "Failed to send message " + PayloadDropper.getRequestWithoutData(message) + " to " + getRemoteAddress()
                + "in timeout(" + timeout + "ms) limit");
        }
    }
    @Override
    public void close() {