Architecture Design: Inter-system Communication (17)--Service governance and Dubbo Medium (analysis)

Source: Internet
Author: User

(next to the above)

2-5. Design mode: Proxy mode and Java support for proxy mode 2-5-1, typical proxy mode

The following class diagram illustrates the typical design design structure of the "proxy mode":

A typical proxy pattern can be summed up in one sentence: external systems/external modules to invoke the implementation of a specific business A, can not directly make real calls, but through a proxy object to make indirect calls. There are four characters in the typical dialing mode:

    • Subject: Business interface definition. This business interface defines the behavior, events, and other characteristics of the associated implementation class.

    • Realsubject: You can see the real implementation of the business definition. The principle of design is: Under no circumstances does it know that he is "acting".

    • Proxy: Agent identity, to help external systems/external modules to complete the specific business implementation of a call.

    • Client: External System/external module.

Next we use the Java language to implement this design:

    • Business Interface Definition (businessinterface):
/** * 这是一个业务接口:给第三方模块调用的处理过程。 * @author yinwenjie */publicinterface BusinessInterface {    /**     * @param username     */    publicvoiddosomething(String username);}
    • Real implementation class for the Business Interface (REALBUSINESSIMPL):
/** * This class is the real implementation of this business interface. * @author  Yinwenjie */ public  class  realbusinessimpl  Span class= "Hljs-keyword" >implements  businessinterface  { /* (non-javadoc) * @see testdesignpattern.proxy.businessinterface#dosomething (java.lang.String) */< /span>  @Override  public  void  dosomething  (String username) {//here lazy a bit, not in the project to import log4j dependency. Display with System.out  System.out.println ( "being User:"  + username + " for real business processing ... "); }}
    • Proxy implementation class for the Business Interface (PROXYBUSINESSIMPL)
 PackageTestDesignPattern.proxy.java;ImportTestDesignPattern.proxy.BusinessInterface;ImportTestDesignPattern.proxy.RealBusinessImpl;/** * The traditional "proxy mode" implemented in Java has many drawbacks. The biggest drawback is that:<br> * callers must be aware that they will invoke an object that needs to be proxied .... * @author Yinwenjie * * Public  class Proxybusinessimpl implements businessinterface {    /** * Real Call Object * /    PrivateRealbusinessimpl realbusiness; Public Proxybusinessimpl(Realbusinessimpl realbusiness) { This. realbusiness = realbusiness; }/* (non-javadoc) * @see testdesignpattern.proxy.businessinterface#dosomething (java.lang.String) * /    @Override     Public void dosomething(String username) {System.out.println ("---------before the official business is executed;"); This. realbusiness.dosomething (username); System.out.println ("---------after the execution of the official business;"); }}
    • Run up (Main):
 PackageTestDesignPattern.proxy.java;ImportTestDesignPattern.proxy.BusinessInterface;ImportTestDesignPattern.proxy.RealBusinessImpl; Public  class Main {     Public Static void Main(string[] args)throwsruntimeexception {/* * caller must know that I want to use realbusinessimpl specific implementation; * Must use Proxybusinessimpl for proxy. * * This approach to write the implementation of the design pattern is also possible, there is no practical significance * * /Realbusinessimpl realbusiness =NewRealbusinessimpl (); Businessinterface Proxybusinessinterface =NewProxybusinessimpl (realbusiness); Proxybusinessinterface.dosomething ("Yinwenjie"); }}

From the annotations in the above code, we can find the problem of the typical proxy pattern: The caller must know that I want to use REALBUSINESSIMPL the specific implementation is not proxied, and the agent needs to know who the specific agent is.

2-5-2, Java-supported dynamic agents

In order to solve this obvious problem, intelligent engineers invented the proxy mode of the deformation design-dynamic proxy mode: In the inheritance of the advantages of proxy mode, through the dynamic proxy mode of the third-party module/system does not need to know the "agent" implementation details, And proxies can be used to proxy any implementation class through a configuration file (or other directed file) (in fact, this is also the Spring Framework's core design pattern, the spring framework is not the return of this series of blog posts, interested readers can refer to their own source code). Let's look at the support for dynamic proxies in Java:

    • Call the Processor:
 PackageTestDesignPattern.proxy.dynamicjava;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportTestDesignPattern.proxy.BusinessInterface;/** * (proxy) calls the processor. <br> * What does that mean: When a "proxy" is called, the Invoke method in this implementation class is triggered. <br> * The proxy object, the method name that is called by the external module/External system, and the parameter information in the method are passed to the method as an invoke method argument. * * @author Yinwenjie * * Public  class Businessinvocationhandler implements Invocationhandler {    /** * Real Business processing objects * /    PrivateBusinessinterface realbusiness; Public Businessinvocationhandler(Businessinterface realbusiness) { This. realbusiness = realbusiness; }/* (Non-javadoc) * @see Java.lang.reflect.invocationhandler#invoke (java.lang.Object, Java.lang.reflect.Method, Java.lang.object[]) * /    @Override     PublicObjectInvoke(Object Proxy, Method method, object[] args)throwsThrowable {System.out.println ("(proxy) call processor is activated ====="); System.out.println (" Agent Object": "+ Proxy.getclass (). GetName ()); System.out.println (method name for "External module/External System" Call: "+ Method.getname ()); System.out.println ("---------before the official business is executed;"); Object Resultobject = Method.invoke ( This. realbusiness, args); System.out.println ("---------after the execution of the official business;");returnResultobject; }}
    • The following code shows how the external module/External system is called:
 PackageTestDesignPattern.proxy.dynamicjava;ImportJava.lang.reflect.Proxy;ImportTestDesignPattern.proxy.BusinessInterface;ImportTestDesignPattern.proxy.RealBusinessImpl; Public  class Main {     Public Static void Main(string[] args)throwsException {Businessinterface realbusiness =NewRealbusinessimpl (); Businessinvocationhandler Invocationhandler =NewBusinessinvocationhandler (realbusiness);/ * * Generate a dynamic proxy instance.         Inside the three parameters need to explain: * 1-loader: This newproxyinstance will have a return value, that is, the proxy object. * So the problem is that class instances must be created with ClassLoader support, and the first parameter is the ClassLoader * * 2-interfaces that the "proxy object" is created by: The second argument is an array.         In the design principle, one important principle is "dependency inversion", its practical experience is: "Rely on interfaces, not since the implementation." * Therefore, support for dynamic proxies in Java assumes that programmers follow this principle: interfaces defined by all business. This parameter specifies the "interface that the proxy object implements" for the dynamic proxy, * because a class in Java can implement multiple interfaces, so this parameter is an array (in my instance code, an interface businessinterface is defined for the real business implementation, * Only this interface is specified in the parameter. In addition, the type of this parameter is class, so if you do not define an interface, it is possible to specify a specific class.         But this does not conform to design principles. * * 3-invocationhandler: This is our "call processor", this parameter does not have much explanation * */Businessinterface proxybusiness = (businessinterface) proxy.newproxyinstance (Thread.CurrentThread (). GetCont Extclassloader (),NewClass[]{businessinterface.class}, Invocationhandler);//Formal callProxybusiness.dosomething ("Yinwenjie"); }}

As the comment in the code shows, the Proxy.newproxyinstance method has three parameters:

    • Loader: This newproxyinstance will have a return value, which is the proxy object. So the problem is that the creation of class instances must be supported by ClassLoader, and the first parameter is the ClassLoader that the proxy object is created on.

    • Interfaces: The second argument is an array. In the design principle, one important principle is "dependency inversion", its practical experience is: "Rely on interfaces, not since the implementation." Therefore, support for dynamic proxies in Java assumes that programmers follow this principle: interfaces defined by all business. This parameter specifies the interface that the proxy object implements for the dynamic proxy, because a class in Java can implement multiple interfaces, so this parameter is an array (in my instance code, an interface businessinterface is defined for the real business implementation only. So this is the only interface specified in the parameter. In addition, the type of this parameter is class, so if you do not define an interface, it is also possible to specify a specific class. But this does not conform to design principles.

    • Invocationhandler: This is our "call processor", and this parameter is not much explained.

Good design, one of the principles of compliance: a type of problem that must be addressed with a specific design, and there will never be two (or more) solutions.
-The beauty of architecture

3, Dubbo framework in-depth design analysis

From the Dubbo official website-The Technical Handbook (http://dubbo.io/Developer+Guide-zh.htm), it is certain that the technical details of the Dubbo official technical manual are much more informative than the technical details in my own article. But as I said earlier: the introduction of the Dubbo Framework is not just for the reader to introduce the Dubbo Service governance framework itself, more importantly, through this series of articles to the reader to introduce the entire system of communication technology knowledge level. as an important part of this knowledge system, the service governance framework, which is built on the RPC essentials, must be explained.

In this article, I will also have more references to the Dubbo website user manuals and technical manuals. Dubbo team to maintain the document is done in place, one thing I admire very much. Let's take a look at the Dubbo official documentation for the function descriptions in each of the layers:

    • Config: Configuration layer, external configuration interface, Serviceconfig,referenceconfig-centric, can be directly new configuration class, can also be generated through the spring parsing configuration class.

    • Proxy: Service agent layer, service interface transparent proxy, build client stub and server side skeleton of service, take Serviceproxy as center, extension interface is proxyfactory.

    • Registry: Registration Center layer, the Registration and discovery of the package service address, the service URL is the center, the extension interface is registryfactory,registry,registryservice.

    • Cluster: The routing layer, which encapsulates the routing and load balancing of multiple providers, and bridges the registry, with the Invoker as the center and the extension interface as cluster,directory,router,loadbalance.

    • Monitor: monitoring layer, RPC call times and call time monitoring, with statistics as the center, the expansion interface is Monitorfactory,monitor,monitorservice.

    • Protocol: The remote call layer, the envelope will call RPC, to Invocation,result as the center, the expansion interface for protocol, Invoker, exporter.

    • Exchange: Information exchange layer, encapsulating request response mode, synchronous to asynchronous, request, response-centric, extension interface exchanger,exchangechannel,exchangeclient, ExchangeServer.

    • Transport: Network transport layer, abstract Mina and Netty as the unified interface, with the message as the center, the expansion interface is CHANNEL,TRANSPORTER,CLIENT,SERVER,CODEC.

    • Serialize: Data serialization layer, reusable tools, extension interface for Serialization,objectinput,objectoutput,threadpool.

4, SPI and extension points:

Spi:service Provider Interface. As we have already mentioned in the previous article, if there is more than one implementation of an interface, then we must rely on the new keyword to tell the caller the specific implementation of this interface, and it is important to use the new key position and timing, because the delegate caller needs to know the ' concrete implementation ';

The article also mentions that the spring framework uses the ' bean ' configuration keyword to help us solve the problem with the new keyword, so that the caller itself does not need to focus on the specific implementation of the invoked interface. But how do you achieve this effect in a Dubbo framework that is relatively independent of the spring framework?

Here's a note: Many of the posts on the web mention that Dubbo and spring can be seamlessly combined, but there is no analysis of why the Dubbo framework can seamlessly integrate with the spring framework, which has made many readers think that the Buddo framework was developed based on spring.

But if you have studied the source code of Dubbo (or read Dubbo related technical documentation), you will find. Dubbo and Spring are completely two different technology components, so-called seamless integration refers only to the service layer of Dubbo, including the Config layer can be hosted by spring (in fact, this and the Dubbo framework of the core implementation is not a half-dime relationship);

but the two beautiful software, the use of design ideas are very consistent : textbook design pattern application.

The Dubbo framework extends (or otherwise implements) the "service Autodiscover" mechanism based on standard Java, and to clarify how Dubbo finds an implementation class for an internal interface, we first need to clarify the SPI mechanism of Java, And then what extensions do you have to make some necessary explanations for the Dubbo.

4-1. Java comes with SPI

For the interface and implementation in Java, we generally (or when you are learning Java) are defined and used in the following way (detailed comments have been made, and the code here has streamlined the annotations):

    • Business Interface Definition (businessinterface):
publicinterface BusinessInterface {    publicvoiddosomething(String username);}
    • Real implementation class for the Business Interface (REALBUSINESSIMPL):
public   Class  realbusinessimpl  implements  businessinterface  { public  void  dosomething  (String username) {System.out.println (" is for the User: " + username + " for real business processing ... "); } public  static   void  main  (string[] args) throws  runtimeexception {businessinterface realbusiness = new  Realbusinessimpl (); Realbusiness.dosomething ( "Yinwenjie" ); }}

In fact, starting with the JDK1.5 version, you do not need to specify a specific implementation class using the New keyword. You can create a name xxxx under the Meta-inf/searvices folder. Businessinterface file (Note that XXXX represents your package name, the entire file name is the same as the full class name of the Businessinterface interface), and then write "xxxxx" in the file contents. Realbusinessimpl "(note is the name of the full Businessinterface interface implementation Class). Once you have saved this file, you can instantiate the interface with the Java.util.ServiceLoader tool class provided by the JDK. The code snippet is as follows:

.....ServiceLoader<BusinessInterface> interface = ServiceLoader.load(BusinessInterface.class);  // 这样写的原因是,您可以一次指定这个接口的多个具体实现Iterator<BusinessInterface> iinterface= interface.iterator();  if (iinterface.hasNext()) {      BusinessInterface interfaceItem = iinterface.next();    interfaceItem.dosomething("yinwenjie");}...
4-2. Modifications made by the Dubbo framework

In the Dubbo framework, the main authors WILLIAM.LIANGF and ding.lid modified the SPI mechanism provided by the JDK (more accurately, "new"): Under the Meta-inf/dubbo folder, use K-v to describe the specific class to be created. This approach is called an "extension point" in the Dubbo framework.

The Dubbo framework supports the "Extension points" feature in the Com.alibaba.dubbo.common.extension package, where the primary class is Extensionloader. In this package, the author also explains why the SPI feature of the JDK is extended:

5, RPC module 5-1, Proxy: Agent layer

The proxy agent layer, in accordance with the Dubbo official documentation, is used to generate stubs and skeleton for RPC calls, so that the specific business implementation that you define on the Dubbo server does not need to be concerned with "how it will be called", but also the service interface you define is "decoupled from the RPC framework". is the main class diagram structure of the Dubbo frame proxy layer:

As shown (the figure is a bit small, please right-click to view), the proxy layer of the Abstractproxyfactory class and its two sub-class with the above described in the typical abstract factory model to design;

So how does the factory implementation under the Abstractproxyfactory work? Here we explain in the Javassistproxyfactory factory. Because the default extension (extension point) set on the Dubbo interface Proxyfactory, the Javassistproxyfactory factory is instantiated.

Extension Extension points:
Dubbo the configuration extension information inside the framework, the main role is to tell the abstract class through the Java annotations, which should be instantiated under which implementation. The Dubbo extension point configuration file is stored in the Mate-inf/dubbo/internal folder in the jar package. For the Proxyfactory interface, its extension point configuration file is the Com.alibaba.dubbo.rpc.ProxyFactory file in this directory;

Above, we mentioned the functionality of the Javassist component: dynamically loading the class at run time and instantiating it. So the invoker provided by Javassist-based javassistproxyfactory is to do the work, and here's the code snippet for Invoker in Javassistproxyfactory:

 Public<T>Invoker<T> Getinvoker (TProxyClass<T>type,URLUrl{    //TODO Wrapperclass does not correctly handle class names with $Final Wrapper wrapper=Wrapper.Getwrapper(Proxy.GetClass().GetName().indexOf(' $ ') < 0?Proxy.GetClass() :type);return New Abstractproxyinvoker<T> (Proxy,type,URL) {        @Override        protected Object Doinvoke(T Proxy,String MethodName,Class<?>[]parametertypes,Object[]arguments)throws Throwable{return wrapper.InvokeMethod(Proxy,MethodName,parametertypes,arguments); }};}

(the "TODO" in the source fragment above is not my addition, but William, one of the main authors of the Dubbo.) LIANGF) Here is a description of the Com.alibaba.dubbo.common.bytecode.Wrapper class of the common module inside the Dubbo framework, which exists as a tool class for generating "runtime class Code". The main logical processes are:

privatestaticmakeWrapper(Class<?> c) {    .......}

Another constant in Com.alibaba.dubbo.common.bytecode.Wrapper:

privatestaticfinal Map<Classnew ConcurrentHashMap<Class<?>, Wrapper>();

The relationship between wrapper and the surrogate class is clearly explained.

Architecture Design: Inter-system Communication (17)--Service governance and Dubbo Medium (analysis)

Contact Us

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

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

A Free Trial That Lets You Build Big!

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

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

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