blob: 8011115ed8b8168ace2bd5053e05a664eb64c773 [file] [log] [blame]
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – Dubbo Design Principals</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/</link><description>Recent content in Dubbo Design Principals on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://dubbo.apache.org/en/docs/v2.7/dev/principals/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: The Devil Is In The Details</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/code-detail/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/code-detail/</guid><description>
&lt;p>Recently, I have been worried about the quality of the Dubbo distributed service framework. If there are more maintenance personnel or changes, there will be a decline in quality. I am thinking, is there any need for everyone to abide by it, according to a habit when writing code, I have summarized it. The code process, especially the framework code, should always keep in mind the details. Maybe the following will be said, everyone will feel very simple, very basic, but always keep in mind. Considering these factors in every line of code requires a lot of patience. It is often said that the devil is in the details.&lt;/p>
&lt;h2 id="prevent-null-pointer-dereference-and-index-out-of-bounds">Prevent null pointer dereference and index out of bounds&lt;/h2>
&lt;p>This is the exception I least like to see, especially in the core framework, in contrast I would like to see a parameter not legal exception with detail information. This is also a robust program developer who should be prevented in the subconscious by writing every line of code. Basically, you must be able to ensure that the code that is written once will not appear in the case of no test.&lt;/p>
&lt;h2 id="ensure-thread-safety-and-visibility">Ensure thread safety and visibility&lt;/h2>
&lt;p>For framework developers, a deep understanding of thread safety and visibility is the most basic requirement. Developers are required to ensure that they are correct in the subconscious when writing each line of code. Because of this kind of code, it will look normal when doing functional tests under small concurrency. However, under high concurrency, there will be inexplicable problems, and the scene is difficult to reproduce, and it is extremely difficult to check.&lt;/p>
&lt;h2 id="fail-fast-and-precondition">Fail fast and precondition&lt;/h2>
&lt;p>Fail fast should also become a subconscious mind, assert at the entrance when there are incoming parameters and state changes. An illegal value and state should be reported at the first time, rather than waiting until the time is needed. Because when it is time to use, other related states may have been modified before, and few people in the program handle the rollback logic. After this error, the internal state may be confusing, and it is easy to cause the program to be unrecoverable on a hidden branch.&lt;/p>
&lt;h2 id="separate-reliable-operation-and-unreliable-operation">Separate reliable operation and unreliable operation&lt;/h2>
&lt;p>The reliability here is narrowly defined whether it will throw an exception or cause a state inconsistency. For example, writing a thread-safe Map can be considered reliable, but writing to a database can be considered unreliable. Developers must pay attention to its reliability when writing each line of code, divide it as much as possible in the code, and handle exceptions for failures, and provide clear logic for fault-tolerant, self-protection, automatic recovery or switching. The entry point ensures that the code that is subsequently added is not misplaced, and the original fault-tolerant processing is confusing.&lt;/p>
&lt;h2 id="safeguard-against-exceptions-but-does-not-ignore-exceptions">Safeguard against exceptions, but does not ignore exceptions&lt;/h2>
&lt;p>The exception defense mentioned here refers to the maximum tolerance of the code on the non-crucial path, including the bug on the program. For example, the version number of program is retrieved by scanning the Manifest and jar package names. This logic is auxiliary, but the code is quite a bit. Although the initial test works well but you should add a try-catch block to cover the whole getVersion() function, if something goes wrong then print error message and return the basic version. Because getVersion() may encounter exception for specific unknown scene, or other developers mistakenly modify the logic (usually they won&amp;rsquo;t remove try-catch). Otherwise if it throws an exception, the main process will be interrupted which we don&amp;rsquo;t want to see. It should be controlled properly, do not abuse try-catch, and do not eat the exception silently.&lt;/p>
&lt;h2 id="reduce-scope-of-variable-and-use-final-liberally">Reduce scope of variable and use final liberally&lt;/h2>
&lt;p>If a class can be an Immutable Class, it is preferred to design it as an Immutable Class. The immutable class has natural concurrency advantages, reduce synchronization and replication, it can efficiently help analyze the scope of thread safety. Even if a mutable class, for references passed in from constructor then held internally, it is better to make this field final, so as not to be mistakenly modified. Don&amp;rsquo;t assume that the field won&amp;rsquo;t be reassigned if this field is private or this class is written by myself. One factor to consider is that this code may be modified by others. He may not aware your weak convention, and the Final is a invariant contract.&lt;/p>
&lt;h2 id="reduce-misunderstanding-when-modifying-do-not-bury-mine">Reduce misunderstanding when modifying, do not bury mine&lt;/h2>
&lt;p>It is repeatedly mentioned that the code being modified by the others, and this is something developers should keep in mind. This other person includes the future of yourself, you always have to think about this code, someone may change it. I should give the modified person a hint, let him know my current design intent, instead of adding hidden rules in the program, or bury some easily overlooked mines, such as: use null to indicate that it is not available, the size is equal to 0 means black list, this is a mine. The next modifier, including yourself, will not remember to have such an agreement, may later change some of the other bugs, accidentally changed to here, directly detonated the fault. For this example, one principle is to never distinguish between null references and null values.&lt;/p>
&lt;h2 id="improve-code-testability">Improve code testability&lt;/h2>
&lt;p>The testability here mainly refers to the ease of Mock and the isolation of the test cases. As for the automation, repeatability, stability, disorder, completeness (full coverage), lightweight (fast execution) of the test, the general developer, plus the assist of tools such as JUnit can do it. Can also understand its benefits, just the matter of workload. Primary emphasis on unicity(only test the target class itself) and isolation(do not propagate failure). Nowadays there is too much emphasis on completeness, a lot of crossed and repeated test cases. It seems fine, but the more test code, the higher maintenance cost. A common problem is that modifying a line of code or adding an assertion causes more than 100 test cases to fail. It will cost a lot of time to fix these variance test cases. Over time, this test cases can&amp;rsquo;t really reflect the current state of the code, and it will often be compromised to bypass. In the best case, modify a line of code, and only one line of test code does not pass. If the code is modified and the test case can still pass, that doesn&amp;rsquo;t work, indicating that the scenario is not covered. In addition, Mockability is the basis of isolation, it hide the logic of indirect dependencies. One of the biggest killers of Mockability is the static method, which should be avoid as possible.&lt;/p></description></item><item><title>Docs: The Configuration Design</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/configuration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/configuration/</guid><description>
&lt;blockquote>
&lt;p>&lt;a href="http://javatar.iteye.com/blog/949527">http://javatar.iteye.com/blog/949527&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>Dubbo design is now completely unobtrusive, namely the user only depends on the configuration of contract.After multiple versions of the development, in order to meet the demand of various scenarios, configuration is more and more.In order to maintain compatibility with only grow, lurking inside all sorts of styles, convention, rules.The new version will also be configured for a adjustment, remove the dubbo, properties, instead of all the spring configuration.Will think of some written in this memo.&lt;/p>
&lt;h2 id="classification-of-configuration">Classification of configuration&lt;/h2>
&lt;p>First of all, the purpose is to have a variety of configuration, which can be roughly divided into:&lt;/p>
&lt;ol start="0">
&lt;li>Environment configuration, such as: the number of connections, the timeout configuration, etc.&lt;/li>
&lt;li>Describe the configuration, such as: service interface description, service version, etc.&lt;/li>
&lt;li>Extension configuration, such as: protocol extension, strategy to expand, etc.&lt;/li>
&lt;/ol>
&lt;h2 id="configuration-format">Configuration format&lt;/h2>
&lt;p>Usually environment configuration, using the configuration properties will be more convenient, because is some simple discrete values, with the key - value configuration can reduce the learning cost configuration.&lt;/p>
&lt;p>Describe the configuration, information more often, and even have a hierarchy, using XML configuration would be more convenient, because the tree structure configuration expression was stronger.If very complex, and can also custom DSL as configuration.Sometimes such configuration can also use the Annotation instead of, because the configuration and related business logic, in the code is also reasonable.&lt;/p>
&lt;p>Another extension configuration, which may be different.If only policy interface implementation class to replace, can consider the properties of the structure.If there is a complex life cycle management, may need to configure such as XML.Sometimes extended by registering interface provided.&lt;/p>
&lt;h2 id="configuration-is-loaded">Configuration is loaded&lt;/h2>
&lt;p>For environment configuration, in the Java world, comparing to conventional approach, was agreed in a project under the classpath for the name of the configuration properties, such as: log4j. Properties, velocity. The properties and so on.Product during initialization, automatically from the classpath under loading the configuration.Our platform of many programs use a similar strategy, such as: dubbo. Properties, comsat. XML, etc.This has its advantages, is based on agreement, simplifies the user to configure the loading process of intervention.But also has its disadvantages, when the classpath is the same configuration, may be loaded by mistake, and when this isolation, may can&amp;rsquo;t find the configuration, and, when the user wants to configure into the unified directory, not very convenient.&lt;/p>
&lt;p>Dubbo new version removes &lt;code>dubbo.properties&lt;/code>, because the contract often conflicts configuration.&lt;/p>
&lt;p>And to describe the configuration, because want to participate in the business logic, usually embedded into the application of life cycle management.There are more and more using spring projects, directly using the spring configuration is common, and spring permits custom schema, configuration simplified is very convenient.Also has its disadvantages, of course, is strongly dependent on the spring, can ask programming interface to do the matching scheme&lt;/p>
&lt;p>In Dubbo configuration is described, but also environment configuration.Part with spring schame configuration is loaded, in part, from the classpath scanning properties configuration is loaded.Users feel very inconvenient, so in the new version of the merged, unified into spring schame configuration load, also increases the flexibility of configuration.&lt;/p>
&lt;p>Extension configuration, usually to the configuration of aggregate demand is higher.Because the product need to find the third party implementation, add it to the product inside.Agreed in the Java world, usually in a specified file each jar package down load, such as: the eclipse plugin. The XML, struts 2 struts - plugin. XML, and so on, this kind of configuration can consider Java standard service discovery mechanisms, namely in the jar meta-inf/services placed under the interface class name file, content is an implementation class name of the class in a row, like encryption algorithm in the JDK extension, the script engine extension, new JDBC driver, etc., are all in this way.see:&lt;a href="https://docs.oracle.com/en/cloud/saas/financials/22a/fafcf/service-provider-models.html">ServiceProvider Provider&lt;/a>。&lt;/p>
&lt;p>Dubbo old version under each jar package through agreement, place called Dubbo - context. The spring configuration XML extensions and integration, the new version to use the JDK&amp;rsquo;s own meta-inf/services, spring from too much dependence.&lt;/p>
&lt;h2 id="programmable-configuration">Programmable configuration&lt;/h2>
&lt;p>Configuration of programmability is very necessary, no matter in what way you load the configuration file, should provide a programming way of configuration, allows the user to not using a configuration file, complete the configuration process with code directly.As a product, especially the component products, usually require collaboration use and other products, when a user integration of your product, may need adapter configuration mode.&lt;/p>
&lt;p>Dubbo new version offers one-on-one configuration class with XML configuration, such as: ServiceConfig corresponding &lt;code>&amp;lt; Dubbo: service / &amp;gt;&lt;/code>, and one-to-one attributes, this configuration file configuration and programming the consistency of the understanding, reduce the learning cost.&lt;/p>
&lt;h2 id="configure-the-default">Configure the default&lt;/h2>
&lt;p>Configuration of the default, usually set the reasonable value of a regular environment, thus reducing the user&amp;rsquo;s configuration.Is generally recommended that in online environment for reference, the development environment can adapt by changing the configuration.The default Settings, had better be in the outermost configuration do processing load.The underlying program if found configuration is not correct, you should direct error, fault tolerance in the outermost layer.If, when the underlying program to use, found unreasonable configuration values, just fill a default value, it is easy to cover up the surface, and trigger a deeper problem.And configuration of the middle layer, probably don&amp;rsquo;t know the underlying USES a default value, some may be failure in the middle of the testing conditions.Dubbo first appeared in this problem, the middle layer with &amp;ldquo;address&amp;rdquo; as the cache Key, and the bottom, to &amp;ldquo;address&amp;rdquo; a default port number, lead to don&amp;rsquo;t add port number &amp;ldquo;address&amp;rdquo; and add the default port &amp;ldquo;address&amp;rdquo; did not use the same cache.&lt;/p>
&lt;h2 id="configuration-consistency">Configuration consistency&lt;/h2>
&lt;p>Configuration is always implied some style or hidden rules, should as far as possible to keep its consistency.For example: a lot of functions have switch, and then have a configuration value:&lt;/p>
&lt;ol start="0">
&lt;li>Whether to use the registry, the registry address.&lt;/li>
&lt;li>Whether to allow a retry, retries.&lt;/li>
&lt;/ol>
&lt;p>You may agree:&lt;/p>
&lt;ol start="0">
&lt;li>Each is to configure a Boolean type of switch, to configure a value.&lt;/li>
&lt;li>On behalf of the closed with an invalid values, N/A address 0 retries, etc.&lt;/li>
&lt;/ol>
&lt;p>No matter which way, all the configuration items, should keep the same style, Dubbo selected is the second.Also, similar to that of timeout, retry time, timer interval.If a unit is second, another unit is milliseconds (C3P0 configuration item is) so, staff will be crazy.&lt;/p>
&lt;h2 id="configuration-coverage">Configuration coverage&lt;/h2>
&lt;p>Provide configuration, want to consider developers, testers, piping, the system administrator.Testers can&amp;rsquo;t modify the code, and test environment is likely to be more complex, need to have some set aside for testers &amp;ldquo;back door&amp;rdquo;, can be modified in the peripheral configuration items.Like spring is accomplished configuration, support &lt;code>SYSTEM_PROPERTIES_MODE_OVERRIDE&lt;/code>, can through the JVM -d parameters, or like hosts agreed a cover configuration files, on the outside of the program, modify some configuration, easy to test.&lt;/p>
&lt;p>Dubbo support through the JVM parameter &lt;code> - Dcom. XXX. XxxService = Dubbo: / / 10.1.1.1:1234&lt;/code> directly make the remote service call bypass registry, point to point test.There is a kind of situation, developers to increase the configuration, can according to the deployment of online configuration, such as: &lt;code>&amp;lt; dubbo: registry address = &amp;quot;${dubbo. Registry. Address}&amp;quot; / &amp;gt;&lt;/code> because only one online registry, this configuration is no problem, and the testing environment may have two registry, testers can&amp;rsquo;t to modify configuration, changed to:
&lt;code>&amp;lt;dubbo:registry address=&amp;quot;${dubbo.registry.address1}&amp;quot; /&amp;gt;&lt;/code>,
&lt;code>&amp;lt;dubbo:registry address=&amp;quot;${dubbo.registry.address2}&amp;quot; /&amp;gt;&lt;/code>,So this place, Dubbo support in the ${Dubbo. Registry. Address} value, through vertical dividing multiple registry addresses, used to represent a registry address.&lt;/p>
&lt;h2 id="configuration-inheritance">Configuration inheritance&lt;/h2>
&lt;p>Configuration is also &amp;ldquo;duplicate code&amp;rdquo;, there is also a &amp;ldquo;generalization and elaboration&amp;rdquo; problem.Such as: Dubbo timeout Settings, each service, and each method, should be can set the timeout.But a lot of service don&amp;rsquo;t care about overtime, if required each method configuration, it is not realistic.So Dubbo adopted method inherit service timeout, overtime service timeout to inherit the default timeout, no configuration, opens up search.&lt;/p>
&lt;p>Dubbo, moreover, the old version all the timeout, retries, load balancing strategies are only in the service consumer configuration.But in the process of actual use, found that the service provider knows better than consumer, but the configuration items are used in consumer.The new version, joined in the provider can match these parameters, through the registry to the consumer,As a reference, if there is no configuration, consumer to provide configuration shall prevail, the equivalent of consumption ji-cheng fang the provider&amp;rsquo;s advice configuration values.And at the time of the relay configuration registry, can also be on the way to modify configuration, so that achieve the purpose of governance, the equivalent of inheritance relationship:Service consumers &amp;ndash;&amp;gt; Registry &amp;ndash;&amp;gt; Service provider
Dubbo, moreover, the old version all the timeout, retries, load balancing strategies are only in the service consumer configuration.But in the process of actual use, found that the service provider knows better than consumer, but the configuration items are used in consumer.The new version, joined in the provider can match these parameters, through the registry to the consumer.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/configuration-override.png" alt="configuration-override">&lt;/p>
&lt;h2 id="configuration-backward-compatibility">Configuration backward compatibility&lt;/h2>
&lt;p>Forwards compatibility is very good, as long as you guarantee configuration only grow, basically can guarantee forwards compatibility.But backward compatibility, but also should pay attention to, to prepare for subsequent to join the new configuration items.If a special configuration in configuration, you should make an appointment a compatibility for the &amp;ldquo;special&amp;rdquo; case rules, because the special case, probably will happen later.For example, have a configuration file is save &amp;ldquo;service = address mapping&amp;rdquo;, one of the special line, is saved &amp;ldquo;registry = address&amp;rdquo;.Now application load time to define &amp;ldquo;registry&amp;rdquo; the Key is special, do special processing, the other is &amp;ldquo;service&amp;rdquo;.New version found, however, to add a &amp;ldquo;monitoring center&amp;rdquo; = address, at this point, the old version of the program will handle &amp;ldquo;monitoring center&amp;rdquo; as a &amp;ldquo;service&amp;rdquo;, because the old code can&amp;rsquo;t be change, compatibility is will be very troublesome.If previously agreed upon in the &amp;ldquo;special&amp;rdquo; logo + XXX for special treatment, follow-up will be more convenient.&lt;/p>
&lt;p>Backward compatibility, can learn a lot from HTML5, refer to:&lt;a href="http://javatar.iteye.com/blog/949390">HTML5 design principle&lt;/a>&lt;/p></description></item><item><title>Docs: "Fool-proof" Design</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/dummy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/dummy/</guid><description>
&lt;blockquote>
&lt;p>&lt;a href="http://javatar.iteye.com/blog/804187">http://javatar.iteye.com/blog/804187&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>Recently I was feeling stupid because I solved too many stupid problems. The service framework is becoming more widely used. Every day, I have to help the endpoint user to resolve problems. Gradually, it is found that most of the problems are configuration errors, or duplicated files or classes, or network failure. So I prepare to add some &amp;ldquo;fool-proof&amp;rdquo; design to the further version. It may be very simple, but it is still a little help for troubleshooting speed. I hope that I can throw a brick to attract jade, and everyone can help to come up with more preventive measures to share.&lt;/p>
&lt;h2 id="check-for-duplicated-jars">Check for duplicated jars&lt;/h2>
&lt;p>The most annoying problem is that, if we have several jars with different version number at the same time, there will be a problem. Imagine that, a new version of the Class A may invoke a old version of the Class B, it&amp;rsquo;s related to the JVM loading order. The problem may encounter occasionally and hard to resolve. So the first, let&amp;rsquo;s try to avoid it. For each jar package, pick a class that will be loaded, check it for duplication for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Duplicate&lt;span style="color:#719e07">.&lt;/span>checkDuplicate&lt;span style="color:#719e07">(&lt;/span>Xxx&lt;span style="color:#719e07">.&lt;/span>class&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Utility class for check duplication:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">Duplicate&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">Duplicate&lt;/span>&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">checkDuplicate&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Class cls&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> checkDuplicate&lt;span style="color:#719e07">(&lt;/span>cls&lt;span style="color:#719e07">.&lt;/span>getName&lt;span style="color:#719e07">().&lt;/span>replace&lt;span style="color:#719e07">(&lt;/span>&lt;span style="color:#2aa198">&amp;#39;.&amp;#39;&lt;/span>&lt;span style="color:#719e07">,&lt;/span> &lt;span style="color:#2aa198">&amp;#39;/&amp;#39;&lt;/span>&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;.class&amp;#34;&lt;/span>&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">checkDuplicate&lt;/span>&lt;span style="color:#719e07">(&lt;/span>String path&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// search from ClassPath
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> Enumeration urls &lt;span style="color:#719e07">=&lt;/span> Thread&lt;span style="color:#719e07">.&lt;/span>currentThread&lt;span style="color:#719e07">().&lt;/span>getContextClassLoader&lt;span style="color:#719e07">().&lt;/span>getResources&lt;span style="color:#719e07">(&lt;/span>path&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Set files &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> HashSet&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> &lt;span style="color:#719e07">(&lt;/span>urls&lt;span style="color:#719e07">.&lt;/span>hasMoreElements&lt;span style="color:#719e07">())&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> URL url &lt;span style="color:#719e07">=&lt;/span> urls&lt;span style="color:#719e07">.&lt;/span>nextElement&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>url &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String file &lt;span style="color:#719e07">=&lt;/span> url&lt;span style="color:#719e07">.&lt;/span>getFile&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>file &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&lt;/span> file&lt;span style="color:#719e07">.&lt;/span>length&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>gt&lt;span style="color:#719e07">;&lt;/span> 0&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> files&lt;span style="color:#719e07">.&lt;/span>add&lt;span style="color:#719e07">(&lt;/span>file&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// if there are more than one indicates duplication
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>files&lt;span style="color:#719e07">.&lt;/span>size&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>gt&lt;span style="color:#719e07">;&lt;/span> 1&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger&lt;span style="color:#719e07">.&lt;/span>error&lt;span style="color:#719e07">(&lt;/span>&lt;span style="color:#2aa198">&amp;#34;Duplicate class &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> path &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; in &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> files&lt;span style="color:#719e07">.&lt;/span>size&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; jar &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> files&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span> &lt;span style="color:#719e07">catch&lt;/span> &lt;span style="color:#719e07">(&lt;/span>Throwable e&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span> &lt;span style="color:#586e75">// safe guard
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> logger&lt;span style="color:#719e07">.&lt;/span>error&lt;span style="color:#719e07">(&lt;/span>e&lt;span style="color:#719e07">.&lt;/span>getMessage&lt;span style="color:#719e07">(),&lt;/span> e&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="check-for-duplicate-configuration-files">Check for duplicate configuration files&lt;/h2>
&lt;p>It is also a frequently encountered problem that the configuration file is loaded incorrectly. Users often complain that they have the right configuration but program says something is wrong. After some troubleshooting, found that the configuration file is not even loaded. Many products put a default configuration file under classpath, if there are several, usually the first one loaded by JVM is effective. In order not to be bothered by such problem, just like checking duplicate jars, add this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>Duplicate&lt;span style="color:#719e07">.&lt;/span>checkDuplicate&lt;span style="color:#719e07">(&lt;/span>&lt;span style="color:#2aa198">&amp;#34;xxx.properties&amp;#34;&lt;/span>&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="check-for-optional-configuration">Check for optional configuration&lt;/h2>
&lt;p>The required configuration is estimated to be checked by everyone, because without it the program may not even start. However, for some optional parameters, some checks should also be made. For example, the service framework allows the service consumers and service providers to be associated with the registry, and allows direct configuring the service provider address to point-to-point direct connect. At this time, the registry address is optional, but if there is no point-to-point direct connect configured, the registry center address must be matched, and this time you have to check accordingly.&lt;/p>
&lt;h2 id="provide-error-message-with-a-solution-if-possible">Provide error message with a solution if possible&lt;/h2>
&lt;p>It&amp;rsquo;s hard to troubleshooting problem with a simple error message which has no detail information. For example, the last time I encountered a &amp;ldquo;Failed to get session&amp;rdquo; exception, just the few words. I&amp;rsquo;m wondering which session is wrong? What is the reason Failed? It makes me crazy, the problem happens in an production environment and it&amp;rsquo;s hard to reproduce. The exception should have some basic context information, such as author info, operation system, failed reason. The best exception information should be given a solution, such as the above: &amp;ldquo;From 10.20.16.3 to 10.20.130.20:20880 The network is unreachable. Please use telnet 10.20.130.20 20880 to test the network at 10.20.16.3. If it is called across data center, it may be blocked by the firewall. Please contact SA to grant access permission.&amp;rdquo; etc. The above can even judge whether it is cross data center based on IP address. Another example is the spring-web context loading, If spring is not started when getBean, spring will report an error. The error message says: &amp;ldquo;Please add: &lt;code>&amp;lt;listener&amp;gt;...&amp;lt;init-param&amp;gt;...&lt;/code>&amp;rdquo;, just copy and paste. We should learn from it. You can deliberately make a common mistake and see if you can solve the problem yourself by the error message. Or we can write some solution of common problems in error message.&lt;/p>
&lt;h2 id="and-also-the-environment-information">And also the environment information&lt;/h2>
&lt;p>Every time an application error occurs, the developer or QA will send the error message and ask the reason. At this time, I will ask some question again, which version is used? Is it a production environment or a development environment? Which registry center? Which project is it? Which machine? And which service? The problem is, some developers or QA can&amp;rsquo;t tell the difference, it waste me a lot of time. So, it is best to log some environment information, we can make a wrapper. Decorate the Logger interface such as:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">error&lt;/span>&lt;span style="color:#719e07">(&lt;/span>String msg&lt;span style="color:#719e07">,&lt;/span> Throwable e&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> delegate&lt;span style="color:#719e07">.&lt;/span>error&lt;span style="color:#719e07">(&lt;/span>msg &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; on server &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> InetAddress&lt;span style="color:#719e07">.&lt;/span>getLocalHost&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; using version &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> Version&lt;span style="color:#719e07">.&lt;/span>getVersion&lt;span style="color:#719e07">(),&lt;/span> e&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Utility class for retrieve version:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">Version&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">Version&lt;/span>&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> Logger logger &lt;span style="color:#719e07">=&lt;/span> LoggerFactory&lt;span style="color:#719e07">.&lt;/span>getLogger&lt;span style="color:#719e07">(&lt;/span>Version&lt;span style="color:#719e07">.&lt;/span>class&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> Pattern VERSION_PATTERN &lt;span style="color:#719e07">=&lt;/span> Pattern&lt;span style="color:#719e07">.&lt;/span>compile&lt;span style="color:#719e07">(&lt;/span>&lt;span style="color:#2aa198">&amp;#34;([0-9][0-9\\.\\-]*)\\.jar&amp;#34;&lt;/span>&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> String VERSION &lt;span style="color:#719e07">=&lt;/span> getVersion&lt;span style="color:#719e07">(&lt;/span>Version&lt;span style="color:#719e07">.&lt;/span>class&lt;span style="color:#719e07">,&lt;/span> &lt;span style="color:#2aa198">&amp;#34;2.0.0&amp;#34;&lt;/span>&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> String &lt;span style="color:#268bd2">getVersion&lt;/span>&lt;span style="color:#719e07">(){&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> VERSION&lt;span style="color:#719e07">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> String &lt;span style="color:#268bd2">getVersion&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Class cls&lt;span style="color:#719e07">,&lt;/span> String defaultVersion&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// search version number from MANIFEST.MF
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> String version &lt;span style="color:#719e07">=&lt;/span> cls&lt;span style="color:#719e07">.&lt;/span>getPackage&lt;span style="color:#719e07">().&lt;/span>getImplementationVersion&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>version &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">||&lt;/span> version&lt;span style="color:#719e07">.&lt;/span>length&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">==&lt;/span> 0&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> version &lt;span style="color:#719e07">=&lt;/span> cls&lt;span style="color:#719e07">.&lt;/span>getPackage&lt;span style="color:#719e07">().&lt;/span>getSpecificationVersion&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>version &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">||&lt;/span> version&lt;span style="color:#719e07">.&lt;/span>length&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">==&lt;/span> 0&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// if not found, extract from jar name
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> String file &lt;span style="color:#719e07">=&lt;/span> cls&lt;span style="color:#719e07">.&lt;/span>getProtectionDomain&lt;span style="color:#719e07">().&lt;/span>getCodeSource&lt;span style="color:#719e07">().&lt;/span>getLocation&lt;span style="color:#719e07">().&lt;/span>getFile&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>file &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&lt;/span> file&lt;span style="color:#719e07">.&lt;/span>length&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>gt&lt;span style="color:#719e07">;&lt;/span> 0 &lt;span style="color:#719e07">&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&lt;/span> file&lt;span style="color:#719e07">.&lt;/span>endsWith&lt;span style="color:#719e07">(&lt;/span>&lt;span style="color:#2aa198">&amp;#34;.jar&amp;#34;&lt;/span>&lt;span style="color:#719e07">))&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Matcher matcher &lt;span style="color:#719e07">=&lt;/span> VERSION_PATTERN&lt;span style="color:#719e07">.&lt;/span>matcher&lt;span style="color:#719e07">(&lt;/span>file&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> &lt;span style="color:#719e07">(&lt;/span>matcher&lt;span style="color:#719e07">.&lt;/span>find&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&amp;amp;&lt;/span>amp&lt;span style="color:#719e07">;&lt;/span> matcher&lt;span style="color:#719e07">.&lt;/span>groupCount&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>gt&lt;span style="color:#719e07">;&lt;/span> 0&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> version &lt;span style="color:#719e07">=&lt;/span> matcher&lt;span style="color:#719e07">.&lt;/span>group&lt;span style="color:#719e07">(&lt;/span>1&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// return version, return default if null
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> &lt;span style="color:#719e07">return&lt;/span> version &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">||&lt;/span> version&lt;span style="color:#719e07">.&lt;/span>length&lt;span style="color:#719e07">()&lt;/span> &lt;span style="color:#719e07">==&lt;/span> 0 &lt;span style="color:#719e07">?&lt;/span> defaultVersion &lt;span style="color:#719e07">:&lt;/span> version&lt;span style="color:#719e07">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span> &lt;span style="color:#719e07">catch&lt;/span> &lt;span style="color:#719e07">(&lt;/span>Throwable e&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// ignore exception, return default version
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> logger&lt;span style="color:#719e07">.&lt;/span>error&lt;span style="color:#719e07">(&lt;/span>e&lt;span style="color:#719e07">.&lt;/span>getMessage&lt;span style="color:#719e07">(),&lt;/span> e&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> defaultVersion&lt;span style="color:#719e07">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="dump-before-kill">Dump before kill&lt;/h2>
&lt;p>Every time there is a problem with the production environment, everyone panics. Usually the most direct way is to rollback and restart, to reduce the downtime. So that the scene is destroyed, and it&amp;rsquo;s hard to check the problem afterwards. Some problem is hard to reproduce in development environment and may happen under hard pressure. It is unlikely let the developer or Appops manually backup all the data before. Therefore, it is best to call dump before the kill script to backup automatically and avoid mistake. Dump script for example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">JAVA_HOME&lt;/span>&lt;span style="color:#719e07">=&lt;/span>/usr/java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">OUTPUT_HOME&lt;/span>&lt;span style="color:#719e07">=&lt;/span>~/output
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">DEPLOY_HOME&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#586e75">`&lt;/span>dirname &lt;span style="color:#268bd2">$0&lt;/span>&lt;span style="color:#586e75">`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">HOST_NAME&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#586e75">`&lt;/span>hostname&lt;span style="color:#586e75">`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">DUMP_PIDS&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#586e75">`&lt;/span>ps --no-heading -C java -f --width &lt;span style="color:#2aa198">1000&lt;/span> | grep &lt;span style="color:#2aa198">&amp;#34;&lt;/span>&lt;span style="color:#268bd2">$DEPLOY_HOME&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span> |awk &lt;span style="color:#2aa198">&amp;#39;{print $2}&amp;#39;&lt;/span>&lt;span style="color:#586e75">`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -z &lt;span style="color:#2aa198">&amp;#34;&lt;/span>&lt;span style="color:#268bd2">$DUMP_PIDS&lt;/span>&lt;span style="color:#2aa198">&amp;#34;&lt;/span> &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> &lt;span style="color:#2aa198">&amp;#34;The server &lt;/span>&lt;span style="color:#268bd2">$HOST_NAME&lt;/span>&lt;span style="color:#2aa198"> is not started!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">exit&lt;/span> 1;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">DUMP_ROOT&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">$OUTPUT_HOME&lt;/span>/dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> ! -d &lt;span style="color:#268bd2">$DUMP_ROOT&lt;/span> &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> mkdir &lt;span style="color:#268bd2">$DUMP_ROOT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">DUMP_DATE&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#586e75">`&lt;/span>date +%Y%m%d%H%M%S&lt;span style="color:#586e75">`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">DUMP_DIR&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">$DUMP_ROOT&lt;/span>/dump-&lt;span style="color:#268bd2">$DUMP_DATE&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> ! -d &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span> &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> mkdir &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;Dumping the server &lt;/span>&lt;span style="color:#268bd2">$HOST_NAME&lt;/span>&lt;span style="color:#2aa198"> ...\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">for&lt;/span> PID in &lt;span style="color:#268bd2">$DUMP_PIDS&lt;/span> ; &lt;span style="color:#719e07">do&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jstack &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jstack-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jinfo &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jinfo-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jstat -gcutil &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jstat-gcutil-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jstat -gccapacity &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jstat-gccapacity-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jmap &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jmap-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jmap -heap &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jmap-heap-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">$JAVA_HOME&lt;/span>/bin/jmap -histo &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/jmap-histo-&lt;span style="color:#268bd2">$PID&lt;/span>.dump 2&amp;gt;&amp;amp;&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/sbin/lsof &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> /usr/sbin/lsof -p &lt;span style="color:#268bd2">$PID&lt;/span> &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/lsof-&lt;span style="color:#268bd2">$PID&lt;/span>.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/bin/sar &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/sar &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/sar.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/bin/uptime &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/uptime &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/uptime.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/bin/free &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/free -t &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/free.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/bin/vmstat &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/vmstat &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/vmstat.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/bin/mpstat &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/mpstat &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/mpstat.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /usr/bin/iostat &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/usr/bin/iostat &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/iostat.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">[&lt;/span> -r /bin/netstat &lt;span style="color:#719e07">]&lt;/span>; &lt;span style="color:#719e07">then&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/bin/netstat &amp;gt; &lt;span style="color:#268bd2">$DUMP_DIR&lt;/span>/netstat.dump
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> -e &lt;span style="color:#2aa198">&amp;#34;.\c&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">echo&lt;/span> &lt;span style="color:#2aa198">&amp;#34;OK!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs: Talk About Expansion Of Extension And Incremental Extension</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/expansibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/expansibility/</guid><description>
&lt;blockquote>
&lt;p>&lt;a href="http://javatar.iteye.com/blog/690845">http://javatar.iteye.com/blog/690845&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>There are more and more products in our platform, the function of the product also more and more.Platform products in order to meet the requirement of each BU and department as well as product line, will surely will be a lot of irrelevant function together, the customer can use selective.In order to compatible with more demand for each product, each framework, are constantly expanding, and we often choose some extension of the extension, namely to old and new function expanded into a general implementation.I want to discuss is, in some cases also can consider to the expansion of the incremental way, also is to retain the original function of simplicity, new feature implementation independence.I have been doing the development of distributed service framework, and then take such problem in our project.&lt;/p>
&lt;p>Such as: remote invocation framework, definitely not serialize function, function is very simple, is to transfer as object, the object into a stream.But because of some places may be using osgi, such serialization, IO in this may be isolated and the business side of this.Need to stream into byte [] array, and then passed on to the business side of this serialization.In order to adapt itself to the requirements of the osgi, expanded the original non osgi with osgi scenes, so, no matter whether the osgi environment, all will move into a byte [] array, first copy again.However, most of the scenes with osgi, paid the price, but for the osgi.And if adopts incremental extension method, the osgi code intact, plus an osgi implementation, when wanting to use osgi, rely on osgi implementation can directly.&lt;/p>
&lt;p>Such as: remote invocation framework, definitely not serialize function, function is very simple, is to transfer as object, the object into a stream.But because of some places may be using osgi, such serialization, IO in this may be isolated and the business side of this.Need to stream into byte [] array, and then passed on to the business side of this serialization.In order to adapt itself to the requirements of the osgi, expanded the original non osgi with osgi scenes, so, no matter whether the osgi environment, all will move into a byte [] array, first copy again.However, most of the scenes with osgi, paid the price, but for the osgi.And if adopts incremental extension method, the osgi code intact, plus an osgi implementation, when wanting to use osgi, rely on osgi implementation can directly.&lt;/p>
&lt;p>Such as: no status messages before, is very simple, just pass a serialized object.Later a synchronous message send demand, need a Request/Response matching, using extended extension, naturally thought, stateless news is actually a Request without Response, add a Boolean state so in the Request, said do you want to return the Response.If the message is sent to a Session needs again, then add a Session interaction, and then found that the original synchronous message sent is a special case of Session message, all scenarios Session, don&amp;rsquo;t need the Session can be ignored.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/open-expand.jpg" alt="open-expand">&lt;/p>
&lt;p>If the incremental extension, stateless messages intact, synchronous message is sent, on the basis of stateless news add a Request/Response processing, message sending session, plus a SessionRequest/SessionResponse processing.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/close-expand.jpg" alt="close-expand">&lt;/p></description></item><item><title>Docs: Extension Points To Reconstruct</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/extension/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/extension/</guid><description>
&lt;blockquote>
&lt;p>&lt;a href="http://javatar.iteye.com/blog/1041832">http://javatar.iteye.com/blog/1041832&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>With the promotion of service, the website of Dubbo service framework requirements gradually increase, Dubbo existing developers can implement demand is limited, many requirements have been delay, and site classmates also want to participate, combined with field, so the platform will be open to internal part of the project, let everyone together to implement, Dubbo as one of the pilot project.&lt;/p>
&lt;p>Now that want to open it, about to take some extension point Dubbo, let participants black box extend as far as possible, rather than a white box to modify the code, or branch, quality, merger, the conflict will be hard to manage.&lt;/p>
&lt;p>First look at the Dubbo existing design:&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/design-step1.png" alt="design-step-1">&lt;/p>
&lt;p>There though some extension interface, but not very good collaboration, and loading and configuration of extension points are not unified handling, so face it under the refactoring.&lt;/p>
&lt;h2 id="step-1-the-core-plug-in-equal-treatment-to-the-third-party">Step 1, the core plug-in, equal treatment to the third party&lt;/h2>
&lt;p>Now that want to expand, extension point loading mode, the first thing to unification, micro core + plug-in, can achieve the principle of OCP is train of thought.&lt;/p>
&lt;p>Made up of a plugin lifecycle management container, core, core does not include any functions, this will ensure that all functions can be replaced, and framework, the authors can achieve the function of the extension must also can do it, so as to guarantee the equal treatment to a third party, so, the function of the framework itself also want to use the plug-in way, cannot have any hard coded.&lt;/p>
&lt;p>Micro core usually adopt the Factory, the IoC, the OSGi plugin lifecycle management.Consider the applicable Dubbo, strong don&amp;rsquo;t want to rely on the Spring IoC container.The IoC container that you made a small also feel a little too much design, so intend to use the most simple way of Factory management plug-in.&lt;/p>
&lt;p>Finally decided to adopt the JDK standard SPI extension mechanism, see: &lt;code>Java. Util. The ServiceLoader&lt;/code>, namely extension in the jar package &lt;code>meta-inf/services /&lt;/code> directory placed with interface of text files, with the same content for interface implementation class name, multiple separate implementation class name with a newline.Need to expand Dubbo agreement, for example, simply by XXX. Placed in a jar file: &lt;code>meta-inf/services/com. Alibaba. Dubbo. RPC. Protocol&lt;/code>, contents for &lt;code>com. Alibaba. XXX. XxxProtocol&lt;/code>.Dubbo by ServiceLoader scanning to all Protocol implementation.&lt;/p>
&lt;p>All plug-in and agreed, must be marked with: &lt;code>@ the Extension&lt;/code> (&amp;quot; name &amp;ldquo;), as the identity of the name, after loading is used to configure option.&lt;/p>
&lt;h2 id="step-2-each-extension-point-encapsulate-a-change-factor-only-to-maximize-reuse">Step 2 each extension point encapsulate a change factor, only to maximize reuse&lt;/h2>
&lt;p>Each extension point implementers, usually only care about one thing, now the extension points, is not entirely separate.Such as: Failover, the Route, LoadBalance, Directory not completely separate, all written by RoutingInvokerGroup died.&lt;/p>
&lt;p>Again, for example, protocol extension, the extension may just want to replace the serialization way, or just replace transmission mode, and Remoting and Http can also reuse serialization, etc.In this way, the need for transport, the client, the server implementation, protocol parsing, data serialization, allow different extension point.&lt;/p>
&lt;p>After break up, the design is as follows:&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/design-step2.png" alt="design-step-2">&lt;/p>
&lt;h2 id="step-3-the-entire-pipeline-design-logic-framework-itself-are-implemented-using-cross-section-intercept">Step 3, the entire pipeline design, logic framework itself, are implemented using cross section intercept&lt;/h2>
&lt;p>Now a lot of logic, are placed in the base class implementation, then by the method of template back to the realization of the tone categories, including: local, mock, generic, echo, token, accesslog, monitor, count, limit, etc., can use the Filter to realize all split, each function is called a ring on the chain.Such as: (the base class template method)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">abstract&lt;/span> AbstractInvoker &lt;span style="color:#268bd2">implements&lt;/span> Invoker &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Result &lt;span style="color:#268bd2">invoke&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Invocation inv&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#268bd2">throws&lt;/span> RpcException &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Pseudo code
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> active &lt;span style="color:#719e07">++;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>active &lt;span style="color:#719e07">&amp;gt;&lt;/span> max&lt;span style="color:#719e07">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wait&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> doInvoke&lt;span style="color:#719e07">(&lt;/span>inv&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> active &lt;span style="color:#719e07">--;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> notify&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#268bd2">abstract&lt;/span> Result &lt;span style="color:#268bd2">doInvoke&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Invocation inv&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#268bd2">throws&lt;/span> RpcException
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To: (chain filter)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">abstract&lt;/span> LimitFilter &lt;span style="color:#268bd2">implements&lt;/span> Filter &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Result &lt;span style="color:#268bd2">invoke&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Invoker chain&lt;span style="color:#719e07">,&lt;/span> Invocation inv&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#268bd2">throws&lt;/span> RpcException &lt;span style="color:#719e07">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Pseudo code
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&lt;/span> active &lt;span style="color:#719e07">++;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> &lt;span style="color:#719e07">(&lt;/span>active &lt;span style="color:#719e07">&amp;gt;&lt;/span> max&lt;span style="color:#719e07">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wait&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> chain&lt;span style="color:#719e07">.&lt;/span>invoke&lt;span style="color:#719e07">(&lt;/span>inv&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> active &lt;span style="color:#719e07">--;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> notify&lt;span style="color:#719e07">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="step-4-a-minimum-concept-consistent-conceptual-model">Step 4, a minimum concept, consistent conceptual model&lt;/h2>
&lt;p>Keep the concept of as little as possible, help to understand, for open systems is particularly important.In addition, the interface can use a consistent conceptual model, can guide each other, and reduce the model transformation,&lt;/p>
&lt;p>For example, Invoker method signature as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>Result &lt;span style="color:#268bd2">invoke&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Invocation invocation&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#268bd2">throws&lt;/span> RpcException&lt;span style="color:#719e07">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The Exporter method signature as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>Object &lt;span style="color:#268bd2">invoke&lt;/span>&lt;span style="color:#719e07">(&lt;/span>Method method&lt;span style="color:#719e07">,&lt;/span> Object&lt;span style="color:#719e07">[]&lt;/span> args&lt;span style="color:#719e07">)&lt;/span> &lt;span style="color:#268bd2">throws&lt;/span> Throwable&lt;span style="color:#719e07">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>But they are the same, only is a on the client side, one on the server side, different model classes are applied.&lt;/p>
&lt;p>For example, the URL string, parse and assembled, not a URL model classes, and the Parameters of the URL, but sometimes the Map, and sometimes the Parameters class wrapping,&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>export&lt;span style="color:#719e07">(&lt;/span>String url&lt;span style="color:#719e07">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>createExporter&lt;span style="color:#719e07">(&lt;/span>String host&lt;span style="color:#719e07">,&lt;/span> &lt;span style="color:#dc322f">int&lt;/span> port&lt;span style="color:#719e07">,&lt;/span> Parameters params&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Use consistent model:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>export&lt;span style="color:#719e07">(&lt;/span>URL url&lt;span style="color:#719e07">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>createExporter&lt;span style="color:#719e07">(&lt;/span>URL url&lt;span style="color:#719e07">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For example, the existing: Invoker, Exporter, InvocationHandler, FilterChainAre actually invoke behavior at different stages, can abstract away completely, unified for the Invoker, reduce the concept.&lt;/p>
&lt;h2 id="step-5-hierarchical-modular-extensions-rather-than-generic-type-extension">Step 5, hierarchical, modular extensions, rather than generic type extension&lt;/h2>
&lt;p>Why see:&lt;a href="../expansibility">expansibility&lt;/a>&lt;/p>
&lt;p>Generalization expansion refers to: the extension point gradually abstraction, take all functions, sets and new function is always set in and expand the function of the old concept.&lt;/p>
&lt;p>Combined extension refers to: the extension points orthogonal decomposition, all functions of overlap, new function is always based on the old function implementation.&lt;/p>
&lt;p>The above design, unconsciously will Dubbo existing function as the core functionality.Above contains the concept of Dubbo existing RPC all functions, including: the Proxy, the Router, Failover, LoadBalance, Subscriber, Publisher, Invoker, Exporter, Filter, etc.,
But these are the core?RPC can Run, kicked off what?And what is not kick off?Based on this consideration, the RPC can be broken down into two levels, Protocol and Invoker is the core of RPC.Other, including the Router, Failover, Loadbalance, Subscriber, the Publisher is the core, but the Routing.Therefore, the Routing as an extension of the Rpc core, design is as follows:&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/design-step3.png" alt="design-step-3">&lt;/p>
&lt;h2 id="step-6-and-networking">Step 6, and networking&lt;/h2>
&lt;p>After finishing, the design is as follows:&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/design-step4.png" alt="design-step-4">&lt;/p></description></item><item><title>Docs: Some In The Design Of The Basic Common Sense</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/general-knowledge/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/general-knowledge/</guid><description>
&lt;blockquote>
&lt;p>&lt;a href="http://javatar.iteye.com/blog/706098">http://javatar.iteye.com/blog/706098&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>Recently told the new team some design on the common sense, is likely to be new and some other help, the thought of a few temporarily, first write here.&lt;/p>
&lt;h2 id="the-api-and-spi-separation">The API and SPI separation&lt;/h2>
&lt;p>Framework or component there are generally two types of customers, one is a consumer, is an extension.API (Application Programming Interface) is used to users, and SPI (Service dojo.provide Interface) is used to expand.At design time, try to put them off, and don&amp;rsquo;t mix.In other words, the user is can&amp;rsquo;t see write the implementation of the extension.&lt;/p>
&lt;p>For example, a Web framework, it has an API interface to call the Action, there is a the execute () method, which is for the user to write business logic.Then, Web frameworks have a SPI interface to extend the control output, such as velocity templates output or a json output, etc.If this Web framework using an inheritance VelocityAction and a JsonAction as extension of the Action, with output velocity templates will inherit VelocityAction, want to use the json output will inherit JsonAction, this is the opposite of the API and SPI no separation example, SPI interface in the API interface.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/mix-api-spi.jpg" alt="mix-api-spi">&lt;/p>
&lt;p>Is a reasonable way, there is a separate Renderer interface, VelocityRenderer and JsonRenderer implementation, Web framework will transfer the output of the Action to the Renderer interface for rendering output.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/seperate-api-spi.jpg" alt="seperate-api-spi">&lt;/p>
&lt;h2 id="service-domainentitysession-domains-separation">Service domain/entity/session domains separation&lt;/h2>
&lt;p>Any framework or component, there will always be the core domain model, such as: Spring Bean, Struts Action, Service of Dubbo, Napoli Queue, and so on.The core areas of the model and its component is called physical domain, it represents our goal to operate on itself.Physical domain is thread-safe, usually either through the same class, sync, or copy the way.&lt;/p>
&lt;p>Service domain, that is, behavior domain, it is the function of the components, but also is responsible for the entity and session domains of life cycle management, such as Spring ApplicationContext, Dubbo ServiceManager, etc.Service domain objects often is heavy, and is thread-safe, and serve all calls to a single instance.&lt;/p>
&lt;p>What is a session?Is an interactive process.Session key is the concept of context, the context is what?For example, we said: &amp;ldquo;old place&amp;rdquo;, the &amp;ldquo;old place&amp;rdquo; is the context information.Why do you say &amp;ldquo;old place&amp;rdquo; other person will know, because we defined earlier the specific content of the &amp;ldquo;old place&amp;rdquo;.So, the context often hold state variables in the process of interaction, etc.The session object, were generally mild and every request to create an instance, destroyed after the request.In short: the meta information held by the entity domain, the temporary state of a request by the session domain, by the service domain throughout the entire process.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/ddd.jpg" alt="ddd">&lt;/p>
&lt;h2 id="on-the-important-process-to-interceptor-interface">On the important process to interceptor interface&lt;/h2>
&lt;p>If you want to write a remote invocation framework, the remote call block the process should have a unified interface.If you want to write an ORM framework, that at least the SQL execution, the Mapping process to intercept interface;If you want to write a Web framework, the request execution should be interception interfaces, and so on.No common framework can Cover all requirements, allowing external behavior, is the basic extension of the framework.Before a remote call, so that if someone wants to verify ordered CARDS, verification of black and white list, log statistics;If someone wants to add paging under packing before SQL execution, do data access control, statistics under the SQL execution time.If someone wants to check before the request execution, packaging, input and output flow request quantity statistics, and so on, can accomplish on their own, rather than into frame inside.Interception interfaces, usually to encapsulate process itself with an object, to the interceptor chain, such as: remote calls the main process for the invoke (), the interceptor interface to invoke usually (Invocation), Invocation object encapsulates the would have the execution context, and Invocation in an invoke () method, performed by the interceptor decide when, at the same time, also on behalf of the interceptor Invocation itself, such a interceptor Invocation is actually the process of packaging the next interceptor, until the last interceptor Invocation is packing the final invoke () process;Similarly, the main process for the execute SQL (), the interceptor interface is usually the execute (Execution), principle.Can implement ways, of course, the above is only for example.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/filter-chain.jpg" alt="filter-chain">&lt;/p>
&lt;h2 id="the-important-status-of-sending-events-and-set-aside-to-monitor-interface">The important status of sending events and set aside to monitor interface&lt;/h2>
&lt;p>Here to tell the difference between an event and the interceptor above, the interceptor is in the process of intervention, it is part of the process, is based on process behavior, and event is based on state data, any behavior changes of the same condition, the event should be consistent.Event is usually after the event notification is a Callback interface, the method name is usually past tense, such as onChanged ().Remote invocation framework, for example, when the network disconnect or even should send out an event, when there is an error can also be considered an event, such peripheral applications could be observed within the framework of change, make corresponding adjustment.&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/event-listener.jpg" alt="event-listener">&lt;/p>
&lt;h2 id="extension-interface-functions-as-a-single-composability">Extension interface functions as a single, composability&lt;/h2>
&lt;p>For example, the remote invocation framework agreement is to replace it.If only provide a general extension interface, switch can deal, of course, but the protocol support can be subdivided into the underlying communication, serialization, dynamic proxy mode and so on.If the interface split, orthogonal decomposition, will be easier to reuse existing logical extension, and just replace a part of the implementation strategy.Of course the decomposition the granularity of the need to grasp.&lt;/p>
&lt;h2 id="micronucleus-plug-in-equal-treatment-to-the-third-party">Micronucleus plug-in, equal treatment to the third party&lt;/h2>
&lt;p>&amp;ldquo;A good framework of development, abide by the concept of micronucleus.Eclipse is OSGi microkernel, Spring&amp;rsquo;s microkernel is the BeanFactory, Maven microkernel is breadth.With functional core is usually should not be, but a life cycle and integrated container, so that each function can interact through the same way and extension, and any function can be replaced.If they do not microkernel, must be at least equal treatment to a third party, namely, the author can realize the function of extension should can be done by extending all the way.The author want to regard themselves as extension, so as to ensure framework of sustainability and stability of the outside introversion.&lt;/p>
&lt;h2 id="dont-control-the-external-object-lifecycle">Don&amp;rsquo;t control the external object lifecycle&lt;/h2>
&lt;p>Such as the above said the Action using the interface and the Renderer extension interface.Framework if let users or extend the Action or the Renderer implementation class name of the class or kind of meta information submitted, then internally by reflecting newInstance () to create an instance of this framework is to control the Action or the Renderer implementation class life cycle, the Action or the Renderer physical, frameworks do it himself, external extension or integration are powerless.Good idea is to let the user or extend the Action or submitted to the realization of the Renderer class instance, framework just use these instances, is how to create these objects, how to destroy, had nothing to do with frame, frame up to provide assistant management tools, rather than absolute control.&lt;/p>
&lt;h2 id="configurable-must-be-programmable-and-maintain-friendly-coc-conventions">Configurable must be programmable, and maintain friendly CoC conventions&lt;/h2>
&lt;p>Framework using the environment uncertainty because of the many, there will always be some configuration, usually to a specified name classpath straight sweep configuration, or startup allows you to specify the configuration path.As a common framework, should do all can do configuration file must be able to programmatically, or when the user needs to be your frame with another frame integration will bring a lot of unnecessary trouble.&lt;/p>
&lt;p>In addition, as far as possible do a standard contract, if the user has to do things by some sort of agreement, there is no need for the configuration items.Such as: configuration templates location, you can agree, if in the templates directory doesn&amp;rsquo;t have to match, if you want to change the directory, and configuration.&lt;/p>
&lt;h2 id="distinguish-between-commands-and-queries-clear-pre-conditions-and-post-conditions">Distinguish between commands and queries, clear pre-conditions and post-conditions&lt;/h2>
&lt;p>This is part of the design by contract, try to keep to a return value method is to query methods, void return method is to command.Query methods are usually idempotence, without side effects, also is not change any state, the n results are the same, such as the get a property value, or query a database record.Command is to point to have side effects, namely will change state, such as set a value, or update a database record.If you have modified the status of the operation, do a query returns again, if possible, to split it into writing reading separation of the two methods, such as: User deleteUser (id), delete users and returns the deleted users, consider to the getUser () and void deleteUser ().In addition, each method is front-facing assert that the legitimacy of the incoming parameters, as far as possible the rear assertion returns the legitimacy, and documented.&lt;/p>
&lt;h2 id="incremental-extension-and-not-to-extend-the-original-core-concept">Incremental extension, and not to extend the original core concept&lt;/h2>
&lt;p>refer to:&lt;a href="../expansibility">expansibility&lt;/a>&lt;/p></description></item><item><title>Docs: The Robustness Of The Design Implementation</title><link>https://dubbo.apache.org/en/docs/v2.7/dev/principals/robustness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs/v2.7/dev/principals/robustness/</guid><description>
&lt;p>Dubbo as a remote service exposure, calls and management solutions, through the meridians of the application is running, its itself to achieve robustness of importance is self-evident.&lt;/p>
&lt;p>Here are some Dubbo principle and method of use.&lt;/p>
&lt;h2 id="the-log">The log&lt;/h2>
&lt;p>Logging is one of the most commonly used way to find, discover problems. Log quality is often neglected, there is no log on using expressly agreed upon. Attaches great importance to the use of the Log, and improve the concentration of the Log information. Log too much, too much chaos, could lead to useful information.&lt;/p>
&lt;p>To effectively use this tool to note:&lt;/p>
&lt;h3 id="record-the-contents-of-the-stipulated-strictly-warn-the-error-level">Record the contents of the stipulated strictly WARN, the ERROR level&lt;/h3>
&lt;ul>
&lt;li>WARN that can restore the problem without human intervention.&lt;/li>
&lt;li>The ERROR says requires human intervention.&lt;/li>
&lt;/ul>
&lt;p>With such agreement, the regulatory system found in the ERROR log file of the string will call the police, and to minimize the occurrence. Excessive alarm can let a person tired, make the person lose vigilance in alarm, make the ERROR log. Along with artificial, regularly check the WARN level information to assess the degree of &amp;ldquo;subhealth&amp;rdquo; system.&lt;/p>
&lt;h3 id="in-the-log-as-much-as-possible-to-collect-key-information">In the log, as much as possible to collect key information&lt;/h3>
&lt;p>What is the key information?&lt;/p>
&lt;ul>
&lt;li>Site information at the time of the problem, namely the screening questions to use information. Such as service invocation fails, to give the use of Dubbo version, the service provider&amp;rsquo;s IP, which is used in the registry; Which service invocation, which method and so on. This information if not given, then later artificial collection, problem after the site may have already can&amp;rsquo;t recover, increase the difficulty of the problem.&lt;/li>
&lt;li>If possible, the cause of the problem and the solution is given. This makes maintenance and problem solving becomes simple, rather than seeking savvy (often the implementer) for help.&lt;/li>
&lt;/ul>
&lt;h3 id="dont-duplicate-records-many-times-the-same-or-a-class-of-problems">Don&amp;rsquo;t duplicate records many times the same or a class of problems&lt;/h3>
&lt;p>The same or a kind of abnormal log continuous there dozens of times, still can often see.The human eye is easy to miss under the different important log information. Try to avoid this situation. Will appear in the foreseeable, it is necessary to add some logic to avoid.&lt;/p>
&lt;p>As a symbol for a question, a problem after log Settings after sign and avoid a repeat of the log. The problem clear sign after recovery.&lt;/p>
&lt;p>Although a bit troublesome, but do ensure log information concentration, the more effective for monitoring.&lt;/p>
&lt;h2 id="limit-set">Limit set&lt;/h2>
&lt;p>Resources are limited, CPU, memory, IO, etc. Don&amp;rsquo;t cry because it is outside of the request, the data is not limited.&lt;/p>
&lt;h3 id="the-size-of-the-thread-pool-exectorservice-and-saturated-strategy">The size of the thread pool (ExectorService) and saturated strategy&lt;/h3>
&lt;p>The Server end ExectorService set limit for processing requests. Use limited queue ExecutorService task waiting queue, avoid resource depletion. When the task waiting queue saturated, choose a suitable saturated strategy. This ensures smooth degradation.&lt;/p>
&lt;p>In Dubbo, saturated strategy is to discard data, waiting for the result is only a request timeout.&lt;/p>
&lt;p>Saturated, the specification has reached the maximum load, the service provider to logging in the operation of the saturated strategy of the problem, in order to monitor warnings. Remember to be careful not to repeat many times record well. (note that the default saturation strategy will not have these additional operation.) According to the frequency of the alarm, has decided to increase adjustment, etc., avoid system problems are ignored.&lt;/p>
&lt;h3 id="the-collection-capacity">The collection capacity&lt;/h3>
&lt;p>If to ensure element is controlled on the collection and is small enough, then you can rest assured use.This is most of the situation. If can&amp;rsquo;t guarantee anything, use a bounded set. When reach the boundary, choose a suitable strategy.&lt;/p>
&lt;h2 id="fault-tolerant---retry---recovery">Fault tolerant - retry - recovery&lt;/h2>
&lt;p>High availability components to tolerate its dependence on the failure of the component.&lt;/p>
&lt;h3 id="dubbo-service-registry">Dubbo service registry&lt;/h3>
&lt;p>The service registry using the database to store the information service providers and consumers. Different registry registry cluster through the database to synchronize data, to perceive other providers on the registry. Registry would ensure a provider and consumer data in memory, the database is unavailable, independent of the normal operation of foreign registry, just can&amp;rsquo;t get other registry data. When the database recovery, retry logic will modify memory write data back to the database, and get a new database data.&lt;/p>
&lt;h3 id="service-consumers">Service consumers&lt;/h3>
&lt;p>After the message service provider list from the registry, will save the provider list to memory and disk file. Consumers can function properly after this registry is down, even in the registry during outage restart consumers. Consumers started, find the registry is not available, will read the list stored in the disk file provider. Retry logic to ensure the registry after recovery, update the information.&lt;/p>
&lt;h2 id="retry-delay-strategy">Retry delay strategy&lt;/h2>
&lt;p>On a bit of the subproblem. Dubbo encountered two related scenario.&lt;/p>
&lt;h3 id="on-the-database-lock">On the database lock&lt;/h3>
&lt;p>Registration center will regularly update the database of a record timestamp, such cluster other registry perceive it is alive. Overdue registry and its associated data will be cleared. Database is normal, the mechanism as well. But the database load is high, its every action is slow. This occurs:&lt;/p>
&lt;p>A registry that B expired, delete B data. B find their data, to write their own data repeatedly. These repeated operation and increase load the database, deterioration.&lt;/p>
&lt;p>Use the following logic:&lt;/p>
&lt;p>When data is deleted B found themselves fail (write), choose to wait for this period of time and try again. Can choose to retry time exponentially, such as first class 1 minute, the second for 10 minutes, 100 minutes for the third time.
This decrease after operation, ensure database can cooling Down (Cool Down).&lt;/p>
&lt;h3 id="the-client-reconnection-registry">The Client reconnection registry&lt;/h3>
&lt;p>When a registry downtime, other Client will receive events at the same time, and to reconnect to another registry. The Client number is relatively more, will be the impact of the registry. Avoid method can be a Client reconnection random delay for 3 minutes, when the reconnection spread out.&lt;/p></description></item></channel></rss>