Dubbo Configuration Rules Detailed

Source: Internet
Author: User
Tags modifier return tag zookeeper
Detailed rules

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 under Dubbo-config below the Dubbo-config-spring module, where there is a class Dubbonamespacehandler, It implements the interface Namespacehandlersupport provided by spring. So how does spring find the entire implementation class? There are two files under the Meta-inf folder of the module: Spring.handlers and Spring.schemas, these two files have the location of the Dubbo namespace XSD file and Dubbo namespace from Dubbonamespacehandler to handle parsing. That's a lot of crap, just to show how spring is parsed <dubbo:.../> configured.

Knowing how Dubbo and Spring are integrated when configuring a piece, you should not be surprised how spring is so smart and able to parse Dubbo's namespace. Next look at what's in the Dubbonamespacehandler class.

<!--lang:java--> public class Dubbonamespacehandler extends Namespacehandlersupport {static {Version.
    Checkduplicate (Dubbonamespacehandler.class); } public void Init () {Registerbeandefinitionparser ("Application", New Dubbobeandefinitionparser (Applicationc
        Onfig.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 that the Init method calls a method Registerbeandefinitionparser, but the parameters are slightly different. The first parameter of the Registerbeandefinitionparser method is the Dubbo of the namespace under the node name, and the second parameter when the node is parsed by WHO. For example: Registerbeandefinitionparser ("Application", New Dubbobeandefinitionparser (Applicationconfig.class, true)); <dubbo:application. /> configuration information, and so on, <dubbo:module can be configured by spring. />,<dubbo:registry. /> And so on, not all 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.

The above should clearly know which 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= "" "check=" false "/>

Through the above, it should be known that dubbo:reference will be dubbobeandefinitionparser by new (Referencebean.class, false) To parse (although it looks like all configurations are parsed with Dubbobeandefinitionparser, it's a big difference). Then look at what's going on in the class Dubbobeandefinitionparser.

<!-- Lang:java--> public class Dubbobeandefinitionparser implements Beandefinitionparser {private static final Logger Logg

ER = 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, be
Anclass, required); } @SuppressWarnings ("Unchecked") private static Beandefinition parse (element element, ParserContext ParserContext,
Class<?> Beanclass, Boolean required) {...}} 

The

First looks at the definition of the class, Dubbobeandefinitionparser implements the spring Beandefinitionparser interface, which is specifically used to parse the Bean's definition (as the class name should know), and implements the public Beandefinition Parse (element element, ParserContext ParserContext) method (although the entire method returns a Beandefinition object, In fact, Spring does not take advantage of the entire returned object, you can look at the spring source, so to inject the bean definition into the spring container, you need to manually inject into the spring, because spring did not give us to do this thing please. ), and then call the static method private static Beandefinition parse (...), then the class is mainly in the static method of the 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 method parameter, It is the beandefinition that specifies that the current label configuration is converted to the corresponding class 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.getregi
    Stry (). Registerbeandefinition (ID, beandefinition);
        .... for (Method setter:beanClass.getMethods ()) {String name = Setter.getname (); if (Name.length () > 3 && name.startswith ("set") && Modifier.ispublic (setter.getmodifier S ()) && setter.getparametertypes (). length = = 1) {class<?> type = Setter.getpara
            Metertypes () [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.sub
                String (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 (), b
            Eandefinition); } else if ("methods". Equals property) {Parsemethods (ID, element.getchildnodes (), Beandefinition, Parserc
            Ontext); } 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 Get/set method of the class is obtained through reflection to determine if the parameter can be injected through spring, added to Beandefinition, and injected into the spring container. The above is the mechanism for loading the configuration from spring. get the configuration from the Java Run command-D and Properties

The above content sees which modules Dubbo can configure and which classes are used to store these configuration information, such as: Referencebean,registryconfig,servicebean, etc. If you look inside the definition of these classes, they all inherit the Abstractconfig abstract class, which defines the protected static void Appendproperties (Abstractconfig config) method. Parameter when one implements its own subclass, next look at what it does:

<!--lang:java--> protected static void Appendproperties (Abstractconfig config) {if (config = = null) {R
    Eturn;
    } 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.ge
                    TId () + "." + 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 + property;
                    Value = System.getproperty (PN); if (!
                    Stringutils.isblank (value) {logger.info ("Use System property" + pn + "to config Dubbo");  }} if (value = = NULL | | value.length () = = 0) {Method
                    Getter
                    try {getter = Config.getclass (). GetMethod ("Get" + name.substring (3), new class<?>[0]); } catch (Nosuchmethodexception e) {try {getter = Co
                        Nfig.getclass (). GetMethod ("is" + name.substring (3), new class<?>[0]); } catch (nosuchmethodexception E2){getter = null; }} if (getter = null) {if (Getter.invoke (config, new Ob
                                Ject[0]) = = null) {if (Config.getid () = null && Config.getid (). Length () > 0) {
                            Value = configutils.getproperty (prefix + config.getid () + "." + property); } if (value = = NULL | | value.length () = = 0) {Valu
                            E = configutils.getproperty (prefix + property);  } if (value = = NULL | | value.length () = = 0) {String legacykey
                                = Legacyproperties.get (prefix + property); if (Legacykey! = null && legacykey.length () > 0) {value = Convertlegacyval UE (Legacykey, Configutils.getproperty (Legacykey)); }}}} if (Val UE = NULL && value.length () > 0) {method.invoke (config, new object[] {convertprimitive (Me
                Thod.getparametertypes () [0], value)});
        }}} catch (Exception e) {logger.error (E.getmessage (), E);
 }
    }
}

The above method begins with the production of the currently configured prefix string prefix = "Dubbo." + Gettagname (Config.getclass ()) + ".", Here you can see that all the configuration items for Dubbo are starting with Dubbo. The next step is to generate the configuration name of the current configuration class by Gettagname method, and go inside to see how gettagname generates its own configuration name for each configuration class.

<!--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;
}

Analyzing the above code clearly knows how to generate the configuration name of the respective configuration class, for example: Referencebean will return reference by this method. So the configuration of referencing a remote bean is dubbo.reference. After the prefix of the current configuration class is generated, all the set methods of the current class are reflected by management, followed by System.getproperty from the Configutils.getproperty, if none are taken from the. It should be noted that the value from System.getproperty does not determine whether the current property has a value (injected by spring). And from the Configutils.getproperty will determine whether there is a value, if not to take from it, here can be explained that the priority of the Dubbo configuration item java-d precedence over the spring configuration, spring Configuration takes precedence over the configuration of the properties file, This also conforms to the general project rules. I don't know if you noticed, either System.getproperty or Configutils.getproperty will take two times, one string pn = prefix + config.getid () + "." + Property, Another is the string pn = Prefix + property, the difference between the two is that one more config.getid (), may be curious about config.getid () what is the content of it. When we introduce the spring load configuration, we should know that the Config object is actually inside the spring container, so the getid here is actually the ID that we configured when we configured the Spring bean. For example:

<!--lang:java-->
<dubbo:reference id= "Demoservice" interface= "Com.alibaba.dubbo.demo.DemoService" Timeout= "" "check=" false "/>

This configuration produces a Referencebean object, so Config.getid () is demoservice at this point. So string pn = prefix + config.getid () + "." + The purpose of the property configuration is to have no configuration item for the current bean. For example: Configure the Dubbo consumption end time, generally through the dubbo.reference.timeout, which is actually a specified consumer end of all beans time-out. Sometimes we need to specify that a bean time-out can pass through Dubbo.reference. {Beanid}.timeout is specified, for example, the above can be configured through Dubbo.reference.demoService.timeout to configure the bean's time-out.

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, 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 is Get/set method name
 String property = Stringutils.cameltosplitname (Name.substring (3, 4). toLowerCase () + name.substring (4), "-");

It is not difficult to find for the hump, Dubbo when the word character to separate the various 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, we need to take a look at the implementation of Class Registrydirectory, which implements the Notifylistener. Then it can monitor any changes to the registry. Before you get to know registrydirectory, let's look at what information Dubbo stores in the registry for each service. If you use zookeeper, you will see a few directory consumers,providers,configurators,routers under each service node directory. Where dynamic configuration is placed under the Configurators node directory. The service consumer listens for Configurators directory changes and calls Registrydirectory's void notify (List<url> URLs) method if the change occurs. When listening to the void notify (List<url> URLs) method triggered by the Configurators directory change, the URLs are similar to override://..., which means that certain configurations that invoke the service are overwritten ( All invocation configurations in Dubbo are presented in the form of URLs, where the parameter information above is replaced by the URL on the calling server, and the Invoke object of the service is reconstructed to achieve the purpose of updating 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

Configure as follows:

<!--lang:xml-->
<dubbo:reference id= "Demoservice" interface= " Com.alibaba.dubbo.demo.DemoService "timeout=" "check=" false ">
        <dubbo:method name=" SayHello "timeout= "/>"
</dubbo:reference>

By multiple nesting of a dubbo:method label

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.