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 整合spring boot 的时候死锁 #2052

Closed
yunxiyi opened this issue Jul 9, 2018 · 3 comments
Closed

dubbo 整合spring boot 的时候死锁 #2052

yunxiyi opened this issue Jul 9, 2018 · 3 comments

Comments

@yunxiyi
Copy link
Contributor

yunxiyi commented Jul 9, 2018

dubbo 整合spring boot,在启动的时候发生死锁。在MulticastRegistry 在registered的时候。创建invoker过程中 ,会将MonitorFacotry注入MonitorFilter中。在取MonitorFacotry值时,首先会去SpiExtensionFactory 获取值,如果这里没有获取到;会到SpringExtensionFactory获取,SpringExtensionFactory 这个时候会触发ObjectFactory提前初始化。

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<T> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

这里会锁住所有对象,而被controller注解的,就是其中一员。

@Controller("/data")
public class DataController {

    @Reference(check = false)
    DemoService demoService;

    @PostConstruct
    public void init() {
        demoService.sayHello("hello world");
    }

    @RequestMapping("/info")
    @ResponseBody
    public Object info() {
        Map<String, Object> map = new HashMap<>();

        map.put("message", "134");
        return map;
    }

}

这个时候就可能产生死锁。因为main 线程可能正在执行创建bean
被 SPI 注解的接口不应该从SpringExtensionFactory 中获取代理对象。
所以这里修改了SpringExtensionFactory 的getExtension 的方法。

public <T> T getExtension(Class<T> type, String name) {

        //SPI never get from spring bean factory
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
            if (!loader.getSupportedExtensions().isEmpty()) {
                return loader.getAdaptiveExtension();
            }
            return null;
        }

        for (ApplicationContext context : contexts) {
            if (context.containsBean(name)) {
                Object bean = context.getBean(name);
                if (type.isInstance(bean)) {
                    return (T) bean;
                }
            }
        }

        logger.warn("No spring extension(bean) named:" + name + ", try to find an extension(bean) of type " + type.getName());

        for (ApplicationContext context : contexts) {
            try {
                return context.getBean(type);
            } catch (NoUniqueBeanDefinitionException multiBeanExe) {
                throw multiBeanExe;
            } catch (NoSuchBeanDefinitionException noBeanExe) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
                }
            }
        }

        logger.warn("No spring extension(bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");

        return null;
    }

这个是demo的地址,dubbo provider 使用的是dubbo 2.7.0-SNAPSHOT 中的dubbo-demo-provider。

@yunxiyi yunxiyi changed the title dubbo 整合spring boot 的时候报错 dubbo 整合spring boot 的时候死锁 Jul 9, 2018
@chenlei65368
Copy link

既然改成这样了为什么要打警告 WARN c.a.d.c.s.e.SpringExtensionFactory:63] [DUBBO] No spring extension(bean) named:defaultCompiler, try to find an extension(bean) of type java.lang.String

@chenlei65368
Copy link

SpringExtensionFactory:77] [DUBBO] No spring extension(bean) named:defaultCompiler, type:java.lang.String found, stop get bean. 如果避免这个警告?

@MingJunDuan
Copy link

dubbo版本2.6.4,如何避免这个警告呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants