Dubbo Configuration Rules Detailed

Source: Internet
Author: User
Tags return tag

Dubbo Configuration Rules Detailed

Welcome to Join Dubbo Group: 259566260

Research Dubbo also has been a half year, the majority of its source code analysis, as well as its internal mechanisms have a more in-depth understanding, as well as the implementation of the various modules. Dubbo contains a lot of content, if you want to understand Dubbo the first step is to start it, so that you can use it well, then how to better use it? You need to know the various configuration items of the Dubbo, and the ways in which they can be configured. Personal understanding of the configuration, like when the animal tamed, how good to tame a beast, it needs to know its various habits, thus adjusting, has reached its desired results. This article does not Dubbo which configuration items can be configured, but through this article, you should be able to know what configuration Dubbo can make. This article will analyze the Dubbo load configuration source code analysis, to make everyone on the configuration of Dubbo a more in-depth understanding. So as to "tame" the Dubbo so that it becomes your own Dubbo.

Dubbo in the configuration this piece is really perfect, offers a lot of parameters, and offers a variety of channels. Let's get to the bottom and see how Dubbo loads the configuration. Before you talk about this, let's introduce what classes are defined at the Dubbo source level to store the configuration items for each module, so that you know which modules Dubbo can configure.

Which things can be configured

Since most projects use spring, and Dubbo provides the configuration through spring, start here. Dubbo load Spring Integration is under Dubbo-config under the Dubbo-config-spring module, which has a class DubboNamespaceHandler that implements the interface provided by spring NamespaceHandlerSupport . So how does spring find the entire implementation class? There are two files in the Meta-inf folder of the module: Spring.handlers and Spring.schemas, the location of the Dubbo namespace XSD file in the two files and Dubbo namespace by DubboNamespaceHandlerto handle parsing. That's a lot of crap, just to show how spring is <dubbo:.../> configured.

Knowing how Dubbo and Spring are integrated when configuring a piece, then you should not be surprised how spring is so smart and able to parse Dubbo's namespace. Now let's see DubboNamespaceHandler what's in the class.

<!--Lang:java-->public class Dubbonamespacehandler extends Namespacehandlersupport {static {Version.chec    Kduplicate (Dubbonamespacehandler.class); } public void Init () {Registerbeandefinitionparser ("Application", New Dubbobeandefinitionparser (applicationconf        Ig.class, True));        Registerbeandefinitionparser ("module", New Dubbobeandefinitionparser (Moduleconfig.class, true));        Registerbeandefinitionparser ("Registry", New Dubbobeandefinitionparser (Registryconfig.class, true));        Registerbeandefinitionparser ("Monitor", New Dubbobeandefinitionparser (Monitorconfig.class, true));        Registerbeandefinitionparser ("Provider", New Dubbobeandefinitionparser (Providerconfig.class, true));        Registerbeandefinitionparser ("Consumer", New Dubbobeandefinitionparser (Consumerconfig.class, true));        Registerbeandefinitionparser ("Protocol", new Dubbobeandefinitionparser (Protocolconfig.class, true)); Registerbeandefinitionparser ("service", new DUbbobeandefinitionparser (Servicebean.class, true));        Registerbeandefinitionparser ("Reference", New Dubbobeandefinitionparser (Referencebean.class, false));    Registerbeandefinitionparser ("annotation", New Dubbobeandefinitionparser (Annotationbean.class, true)); }}

You can see init that a method is called inside a method registerBeanDefinitionParser , but the parameters are slightly different. The registerBeanDefinitionParser first parameter of the Dubbo method is the namespace of the following node name, and the second parameter is the node whose resolution is determined by whom. For example: registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true)); parsing <dubbo:application../> configuration information, and so on through spring can be configured <dubbo:module../> , and so on <dubbo:registry../> , not listed. As for the role of each label configuration, because it is not the content of this article, so here do not do too much introduction.

By the above should know clearly what Dubbo can be configured? This question should not bother you any more. Here's a look at how Dubbo loads these configuration items.

How to read our configuration read through spring's bean configuration

In the project, spring XML is configured (although Dubbo also supports annotation forms, but the individual is not very respected, because this will integrate Dubbo into your project source code, and my advice is not to say Dubbo and your project tied too tightly, my proposal is Dubbo configuration and project isolation, To facilitate management, the project will not use Dubbo after joining, and the use of other distributed RPC framework, the adjustment of the project is relatively small), such as often through the following configuration items refer to a remote service:

<!--lang:xml--><dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" timeout="2000" check="false"/>

Through the above, you should know that it dubbo:reference will be new DubboBeanDefinitionParser(ReferenceBean.class, false) parsed (although it looks like all configurations are DubboBeanDefinitionParser parsed, but very different). Then look at DubboBeanDefinitionParser what's going on in the class.

<!--lang:java-->public class DubboBeanDefinitionParser implements BeanDefinitionParser {private static final Logger logger = LoggerFactory.getLogger(DubboBeanDefinitionParser.class);private final Class<?> beanClass;private final boolean required;public DubboBeanDefinitionParser(Class<?> beanClass, boolean required) {    this.beanClass = beanClass;    this.required = required;}public BeanDefinition parse(Element element, ParserContext parserContext) {    return parse(element, parserContext, beanClass, required);}@SuppressWarnings("unchecked")private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {....}}

Look at the definition of the class first, Dubbobeandefinitionparser implements the spring Beandefinitionparser interface, This interface is specifically used to parse the Bean's definition (which should be known by the class name) and implements the public beandefinition parse (element element, ParserContext ParserContext) method (although the entire method returns a beandefinition object, spring does not take advantage of the entire returned object, you can see the spring source, So to inject the bean definition into the spring container, we need to inject it manually into spring, because spring does not do this for us. ), and then call the static method private static Beandefinition parse (...) , then the class is mostly on a static method parse . Because the content of this method is too long, inconvenient to paste out all the content, I only analyze the main part. There is a class<?> beanclass parameter on the Dubbobeandefinitionparser constructor parameter, which specifies that the contents of the current label configuration are converted to the corresponding class. beandefinition and injected into the spring container.

<!--lang:java-->private static beandefinition Parse (element element, ParserContext ParserContext, class<?    > Beanclass, Boolean required) {rootbeandefinition beandefinition = new Rootbeandefinition ();    Beandefinition.setbeanclass (Beanclass);    Beandefinition.setlazyinit (FALSE);    String id = element.getattribute ("id"); if ((id = = NULL | | id.length () = = 0) && required) {//construct a bean ID} .... parsercontext.getregistry    (). Registerbeandefinition (ID, beandefinition);        .... for (Method setter:beanClass.getMethods ()) {String name = Setter.getname (); if (Name.length () > 3 && name.startswith ("set") && Modifier.ispublic (setter.getmodifiers ()) && setter.getparametertypes (). length = = 1) {class<?> type = Setter.getparamet            Ertypes () [0];       String property = Stringutils.cameltosplitname (Name.substring (3, 4). toLowerCase () + name.substring (4), "-");     Props.add (property);            Method getter = null;            try {getter = Beanclass.getmethod ("Get" + name.substring (3), new class<?>[0]); } catch (Nosuchmethodexception e) {try {getter = Beanclass.getmethod ("is" + Name.subst                Ring (3), new class<?>[0]); } catch (Nosuchmethodexception e2) {}} if (getter = = NULL | |! Modifier.ispublic (Getter.getmodifiers ()) | | !            Type.equals (Getter.getreturntype ())) {continue; } if ("Parameters". Equals (property)) {parameters = Parseparameters (Element.getchildnodes (), Bea            Ndefinition); } else if ("methods". Equals property) {Parsemethods (ID, element.getchildnodes (), Beandefinition, Parserco            ntext); } else if ("arguments". Equals property) {parsearguments (ID, element.getchildnodes(), beandefinition, ParserContext);        } ..... beandefinition.getpropertyvalues (). Addpropertyvalue (property, reference); ......

It is clear from the above code that the method of getting the class is obtained through reflection, get/set so that the parameter can be injected into the spring, added to the beanDefinition spring container, and injected into it. The above is the mechanism for loading the configuration from spring.

Get the configuration from the Java Run command-D and properties

The above shows what modules Dubbo can configure, and which classes are used to store the configuration information, such as:,, ReferenceBean RegistryConfig etc., ServiceBean if you look inside the definition of these classes and see that they inherit the AbstractConfig abstract class, the method is defined in the abstract class. protected static void appendProperties(AbstractConfig config) Parameter when one implements its own subclass, next look at what it does:

<!--lang:java-->protected static void appendproperties (Abstractconfig config) {if (config = = null) {Retu    Rn    } String prefix = "Dubbo." + Gettagname (Config.getclass ()) + ".";    Method[] methods = Config.getclass (). GetMethods ();            for (Method method:methods) {try {String name = Method.getname ();                     if (Name.length () > 3 && name.startswith ("set") && Modifier.ispublic (Method.getmodifiers ())                && method.getparametertypes (). length = = 1 && isprimitive (method.getparametertypes () [0])) {                String property = Stringutils.cameltosplitname (Name.substring (3, 4). toLowerCase () + name.substring (4), "-");                String value = null; if (config.getid () = null && Config.getid (). Length () > 0) {String pn = prefix + config.get                    Id () + "." + property;                    Value = System.getproperty (PN); if (! Stringutils.iSblank (value) {logger.info ("Use System property" + pn + "to config Dubbo"); }} if (value = = NULL | | value.length () = = 0) {String pn = prefix + Pro                    Perty;                    Value = System.getproperty (PN); if (!                    Stringutils.isblank (value) {logger.info ("Use System property" + pn + "to config Dubbo"); }} if (value = = NULL | | value.length () = = 0) {Method Gett                    Er                    try {getter = Config.getclass (). GetMethod ("Get" + name.substring (3), new class<?>[0]); } catch (Nosuchmethodexception e) {try {getter = Config                        . GetClass (). GetMethod ("is" + name.substring (3), new class<?>[0]); } catch (Nosuchmethodexception E2) {getter= NULL; }} if (getter = null) {if (Getter.invoke (config, new objec                                T[0]) = = null) {if (Config.getid () = null && Config.getid (). Length () > 0) {                            Value = configutils.getproperty (prefix + config.getid () + "." + property); } if (value = = NULL | | value.length () = = 0) {value = Conf                            Igutils.getproperty (prefix + property);  } if (value = = NULL | | value.length () = = 0) {String Legacykey =                                Legacyproperties.get (prefix + property); if (Legacykey! = null && legacykey.length () > 0) {value = Convertlegacyvalu                                E (Legacykey, Configutils.getproperty (Legacykey));                }            }}}} if (value! = null && V Alue.length () > 0) {method.invoke (config, new object[] {convertprimitive (Method.getparametertypes ()                [0], value)});        }}} catch (Exception e) {logger.error (E.getmessage (), E); }    }}

The above method begins with the production of the current configuration prefix String prefix = "dubbo." + getTagName(config.getClass()) + "." , where you can see that all of the configuration items of Dubbo are dubbo. started, followed by getTagName methods to generate the configuration name of the current configuration class, in getTagName order to see how each configuration class generated the respective configuration name.

<!--lang:java-->private static final String[] SUFFIXS = new String[] {"Config", "Bean"};private static String getTagName(Class<?> cls) {    String tag = cls.getSimpleName();    for (String suffix : SUFFIXS) {        if (tag.endsWith(suffix)) {            tag = tag.substring(0, tag.length() - suffix.length());            break;        }    }    tag = tag.toLowerCase();    return tag;}

Parsing the above code clearly knows how to generate the configuration name of the respective configuration class, such as: Referencebean This method returns reference . So the configuration for referencing a remote bean is in dubbo.reference. Start with. After the prefix for the current configuration class is generated, all set methods of the current class are reflected by management, followed by System.getproperty , if none of them are removed from the Configutils.getproperty the . It is important to note that the value from system.getproperty does not determine whether the current property has a value (injected through spring), and the configutils.getproperty The fetch will determine if there is a value, if it is not, it can be explained that the priority of the Dubbo configuration item java-d takes precedence over the spring configuration, and the spring configuration takes precedence over the configuration of the properties file. This also conforms to the general project's rules . I don't know if you noticed. Either system.getproperty or configutils.getproperty takes two times, one time is String pn = Prefix + config.getid () + "." + Property , another time String pn = prefix + Property , the difference between the two is one more config.g Etid () , might be curious config.getid () What is it? When it comes to spring loading configuration, it should be known that the Config object is actually inside the spring container, and the getId here is actually the ID that we configured when we configured spring's bean. For example:

<!--lang:java--><dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" timeout="2000" check="false" />

This configuration produces an ReferenceBean object, so this is the config.getId() case demoService . So String pn = prefix + config.getId() + "." + property the purpose of the configuration is to have no configuration item for the current bean. For example: Configure the Dubbo consumption end time, generally through dubbo.reference.timeout , this is the specified consumer end of all beans time-out. Sometimes we need to specify that a bean time-out can be dubbo.reference.{beanId}.timeout specified by, for example, the time-out that can be configured on the dubbo.reference.demoService.timeout bean above.

To this Dubbo all the configuration of the way and its principles are analyzed and introduced, it seems to have not said how to find out what Dubbo configuration. Here we teach you how to find out what configuration Dubbo has. As described above, Dubbo sets the configuration item to the entity of each configuration class by judging whether there is a get/set method, and here everyone should know how to find out? is if you want to know the configuration of a Dubbo module, go directly to the corresponding configuration class to see what fields it has, know its field name, and determine the scope you want to configure, whether it is a global or a bean, and what path you want to configure, Follow the rules provided by Dubbo to determine how the corresponding fields are configured. Then you might say that the field when a word knows how to configure, then if the field when more than one word combination of it? Since Java's coding style is generally the same as the hump format: The first letter of the initial lowercase words, then the first letter capitalized, then this case corresponds to Dubbo how to get the configuration item? See below:

<!--lang:java-->  //name是get/set方法名 String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), "-");

It is not difficult to find the hump, Dubbo when the word - character to separate the words. In fact, here can basically be very good Configuration Dubbo, but there is a way above if you need to adjust the parameters need to restart the application, not to dynamic adjustment, so Dubbo to be able to meet the project does not restart the situation can be dynamically adjusted configuration parameters.

Add dynamic configurations with Dubbo management apps

The main principle of this approach is to publish the dynamic parameters to the registry (zookeeper) through the manager, then each node can obtain the latest configuration changes and then make dynamic adjustments. To know this piece of content, you need to take a look at the implementation of the class RegistryDirectory , which implements it NotifyListener . Then it can monitor any changes to the registry. RegistryDirectorybefore you get to know it, let's look at what information Dubbo stores in the registry for each service. If you use the zookeeper, then you will see a few directories under each service node directory, consumers , providers configurators routers . Where the dynamic configuration is placed in the configurators node directory. The service consumer listens configurators for directory changes, and the method is called if the change is made RegistryDirectory void notify(List<URL> urls) . When you listen to a configurators directory change-triggered void notify(List<URL> urls) method, urls It is similar override://... , indicating that some configuration that invokes the service is overwritten (all invocation configurations in Dubbo are shown in the form of URLs), The parameter information above the URL is replaced by the URL on the calling server, and the object of the service is reconstructed to Invoke update the parameters.

Parameters can be configured for the method of the interface

The whole scenario exists in the actual project, for example, there are multiple methods for an interface, sometimes it is not enough to say that the parameter configuration is now the interface level, and it needs to be accurate to the method level, such as the timeout setting for the interface call. Dubbo provides two ways to configure method-level configurations.

How Spring beans are configured
如下进行配置:<!--lang:xml--><dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" timeout="2000" check="false" >        <dubbo:method name="sayHello" timeout="1000"/></dubbo:reference>

Implemented by multiple nested dubbo:method tags.

Dynamic configuration

The Dubbo Manager provides dynamic configuration functionality by adding dynamic configuration and specifying the consumer of the notification to specify a method for a service to adjust parameters. It is there to configure the rule when the method name plus the name of the configuration item, for example: Key is configured as: sayHello.timeout , value= "10000". The manager then adds a node to the registry's corresponding service configurators override://...?sayHello.timeout=10000 , specifying that the consumer will listen to the change and execute the process of the above content.

There may be some areas where the Dubbo configuration has been introduced, and there are doubts as to what is not clearly stated. If you have questions, please ask questions or take a look at the relevant Dubbo source code, it will be more clearly understood.

Dubbo Configuration Rules Detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.