Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dubbo support project loom #10768

Closed
1 task
AlbumenJ opened this issue Oct 20, 2022 · 3 comments
Closed
1 task

Dubbo support project loom #10768

AlbumenJ opened this issue Oct 20, 2022 · 3 comments
Labels
type/proposal Everything you want Dubbo have

Comments

@AlbumenJ
Copy link
Member

  • I have searched the issues of this repository and believe that this is not a duplicate.

Describe the proposal

@AlbumenJ AlbumenJ added the type/proposal Everything you want Dubbo have label Oct 20, 2022
@robberphex
Copy link
Contributor

robberphex commented Dec 11, 2022

随着JDK 19和 JEP 425的发布,是时候调研下dubbo如何支持project loom了。

loom对于上层的要求和建议,主要有几点(难度由低到高):

  1. 不应该缓存虚拟线程,即不应该像原来使用线程池那样池化。当然,这儿为了兼容性,可以使用ThreadPerTaskExecutor
  2. 目前synchronized和native method,会导致虚拟线程无法卸载(即完全占用了一个物理线程)。
    • 预计在将来的版本中,synchronized的限制可以取消,但是native method这一块,需要loom提供新的接口,然后现有的native代码做适配。
    • 我看了目前DubboServerHandler的调用栈,目前是没有上述两种情况的。
  3. loom最终的目标是"Code like sync, works like async",而dubbo内核依赖了netty这样的,基于回调的编程范式。不论是基于老版本dubbo兼容性考虑,还是基于老版本java兼容性考虑,都没法做大的修改。

所以,这一块,我们至少可以分2步走
第一步,在现有的基础上,逐步通过VirtualThread替换掉原有的Thread(DubboServerHandler、NettyServerWorker),并观察性能、异步编程难易度。在这一步,我们期望Dubbo的性能会有略微提升,用户的编程难度下降(尤其是流式、异步模式)。
第二步,根据第一步结果,如果大家都接受"Code like sync, works like async",那么我们可以逐步改造dubo内核,实现更加容易的异步、高性能编程。


目前进展
在本地跑了简单Demo,需要做出如下改造,即可体验VirtualThread:

  1. 添加VirtualThreadPool,
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.threadpool.ThreadPool;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREAD_NAME;
import static org.apache.dubbo.common.constants.CommonConstants.THREAD_NAME_KEY;

public class VirtualThreadPool implements ThreadPool {
  @Override
  public Executor getExecutor(URL url) {
    String name = url.getParameter(THREAD_NAME_KEY, 
      (String) url.getAttribute(THREAD_NAME_KEY, DEFAULT_THREAD_NAME)
    );
    ThreadFactory factory = Thread.ofVirtual().name(name).factory();
    return Executors.newThreadPerTaskExecutor(factory);
  }
}
  1. 添加SPI src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
virtual-thread=VirtualThreadPool
  1. 使用SPI,添加配置:dubbo.provider.parameters.threadpool=virtual-thread

最终的stack:

at com.alibaba.edas.boot.EchoServiceImpl.echo(EchoServiceImpl.java:16)
	at com.alibaba.edas.boot.EchoServiceImplDubboWrap0.invokeMethod(EchoServiceImplDubboWrap0.java)
	at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:73)
	at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:100)
	at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:55)
	at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56)
	at org.apache.dubbo.rpc.filter.ClassLoaderCallbackFilter.invoke(ClassLoaderCallbackFilter.java:38)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:79)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:45)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:100)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:54)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:192)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:54)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.ProfilerServerFilter.invoke(ProfilerServerFilter.java:57)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:133)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:327)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:194)
	at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:156)
	at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:102)
	at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:177)
	at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:53)
	at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:61)
	at java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:287)
	at java.base/java.lang.VirtualThread$VThreadContinuation.lambda$new$0(VirtualThread.java:174)
	at java.base/jdk.internal.vm.Continuation.enter0(Continuation.java:327)
	at java.base/jdk.internal.vm.Continuation.enter(Continuation.java:320)

@khatchad
Copy link

khatchad commented Feb 6, 2024

Is this issue closed by #13111?

@AlbumenJ
Copy link
Member Author

Is this issue closed by #13111?

Yep

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/proposal Everything you want Dubbo have
Projects
Status: Done
Development

No branches or pull requests

3 participants