MasterofProject

Sogou Architecture design: communication system (17) - Service Management (analysis) and Dubbo's

label Dubboarchitecture designsystem communication
10673 people read comment(4) Collection report
Classification:

(above)

2-5, design patterns: agent model and JAVA support for proxy mode

2-5-1, typical agent model

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

Write the picture here.

Typical agent model can be summed up in one sentence: the external system / external module to call a specific business to achieve A, can not be called directly, but through a proxy object to conduct an indirect call. There are four roles in a typical dialing model:

  • Subject: service interface definition. This service interface defines the behavior, event, and other characteristics of the related implementation class.

  • RealSubject: you can see the real implementation of the business definition. The principle of design is: no matter what circumstances it does not know that they are "acting".

  • Proxy: agent identity, to help the external system / external modules to complete the specific business to achieve A call.

  • Client: external system / external module.

Next we use the JAVA language to achieve this design:

  • Service interface definition (BusinessInterface):
/ * *
* this is a business interface: the process of calling the third party modules.
*@authorYinwenjie
* /
Public Interface BusinessInterface{
    / * *
*@paramUsername
* /
    Public Void Dosomething(username String);
}
  • Real implementation class (RealBusinessImpl) of the service interface:
/ * *
* this class is the real implementation of the business interface.
*@authorYinwenjie
* /
Public Class RealBusinessImpl Implements BusinessInterface{

    * (non-Javadoc)
* testDesignPattern.proxy.BusinessInterface#dosomething @see (java.lang.String)
* /
    @Override
    Public Void Dosomething(username String) {
        Here a bit lazy /, no dependence in engineering log4j import. Display with System.out
System.out.println ("Being for the user:"+ username +"For real business processing... ");
}
}
  • Agent implementation class (ProxyBusinessImpl) for a service interface
PackageTestDesignPattern.proxy.java;

ImportTestDesignPattern.proxy.BusinessInterface;
ImportTestDesignPattern.proxy.RealBusinessImpl;

/ * *
* use java to achieve the traditional "agency model", there are many drawbacks. The biggest drawback is: <br>
* the caller must be clear, you will need to be an object called agent....
*@authorYinwenjie
* /
Public Class ProxyBusinessImpl Implements BusinessInterface{

    / * *
* real call object
* /
    PrivateRealBusiness RealBusinessImpl;

    Public ProxyBusinessImpl(realBusiness RealBusinessImpl) {
        This.realBusiness = realBusiness;
}

    * (non-Javadoc)
* testDesignPattern.proxy.BusinessInterface#dosomething @see (java.lang.String)
* /
    @Override
    Public Void Dosomething(username String) {
System.out.println ("Is the formal business before the execution;");
        This.realBusiness.dosomething (username);
System.out.println ("Our formal business execution;");
}
}
  • Run up (Main):
PackageTestDesignPattern.proxy.java;

ImportTestDesignPattern.proxy.BusinessInterface;
ImportTestDesignPattern.proxy.RealBusinessImpl;

Public Class Main{
    Public Static Void Main(args String[])ThrowsRuntimeException {
        *
* the caller must know that I want to achieve the specific use of RealBusinessImpl;
* must use ProxyBusinessImpl for proxy.
*
* this practice to write the implementation of the model can also be achieved, there is no practical significance
* * /
realbusinessimpl真实经济=新的realbusinessimpl();
businessinterface proxybusinessinterface =新的proxybusinessimpl(现实世界);

proxybusinessinterface doSomething(。“yinwenjie”);
}
}

从以上代码的注解中,我们就可以发现典型代理模式的问题:调用者必须知道,我要使用realbusinessimpl具体的实现是不被代理的,并且代理者还需要知道具体的代理者是谁。

2-5-2、Java支持的动态代理

为了解决这个明显的问题,聪明的程序员们发明出代理模式的变形设计--动态代理模式:在继承了代理模式优点的同时,通过动态代理模式第三方模块/系统并不需要知道”代理者”的实现细节了,并且代理者内部可以通过配置文件(或者其他导向性文件),对任何实现类进行代理(实际上这也是弹簧框架的核心设计模式,春天框架并不是这个系列博文的讲解返回,感兴趣的读者可以自行参考其源码)。下面我们来看看Java中对动态代理的支持:

  • 调用处理器:
testdesignpattern.proxy.dynamicjava;

进口java.lang.reflect.invocationhandler;
进口java.lang.reflect.method;

进口testdesignpattern.proxy.businessinterface;

* * * *
*(代理)调用处理器。<br>
*什么意思呢:当”代理者”被调用时,这个实现类中的调用方法将被触发。<br>
*“代理者”对象,外部模块/外部系统所调用的方法名、方法中的传参信息都将以调用方法实参的形式传递到方法中。
*
*作者yinwenjie
*
公共  businessinvocationhandler 实现了 InvocationHandler{

    * * * *
*真实的业务处理对象
*
    私人businessinterface现实世界;

    公共 businessinvocationhandler(businessinterface现实世界){
        现实世界,现实世界;
}

    / *(非Javadoc)
*“看Java。reflect。InvocationHandler #调用(java.lang.Object,java.lang.reflect.method,Java Object [ ])
*
    “重写”
    公共对象调用(代理对象、方法、对象[] args)抛出Throwable {
系统,println(。“(代理)调用处理器被激活=====”);
系统,println(。“代理者对象“:”+代理。getclass() getname());
系统,println(。“外部模块/外部系统”调用的方法名:”+ getname())的方法;

系统,println(。“---------正式业务执行前;”);
对象方法调用(resultobject =。现实世界中,args);
系统,println(。“---------正式业务执行后;”);

        返回resultobject;
}

}
  • 下面的代码说明了外部模块/外部系统如何进行调用:
testdesignpattern.proxy.dynamicjava;

进口java.lang.reflect.proxy;

进口testdesignpattern.proxy.businessinterface;
进口testdesignpattern.proxy.realbusinessimpl;

公共  主要{
    公共 静态 无效 主要(string [] args)抛出例外{
businessinterface真实经济=新的realbusinessimpl();
businessinvocationhandler InvocationHandler =新的businessinvocationhandler(现实世界);

        / *
*生成一个动态代理实例。里面的三个参数需要讲解一下:
* 1-loader:这个代理实例会有一个返回值,即代理对象。
*那么问题就是类实例的创建必须要有classloader的支持,第一个参数就是指等”代理对象”的创建所依据的类加载器
*
* 2-interfaces:第二个参数是一个数组。在设计原理中,有一个重要的原则是”依赖倒置”,它的实践经验是:“依赖接口,而不是以来实现”。
*所以,Java中动态代理的支持假定程序员是遵循这一原则的:所有业务都定义的接口这个参数就是为动态代理指定”代理对象所实现的接口”,
*由于Java中一个类可以实现多个接口,所以这个参数是一个数组(我的实例代码中,只为真实的业务实现定义了一个接口businessinterface,
* so the parameter is specified in this interface only. In addition, the type of this parameter is Class, so if you do not define the interface, it is possible to specify a specific class. But this does not conform to the design principles.
*
* 3-InvocationHandler: This is our "call handler", and this parameter does not have much to explain.
* * /
ProxyBusiness = (BusinessInterface) Proxy.newProxyInstance (= BusinessInterface)
Thread.currentThread ().GetContextClassLoader () (),
                NewClass[]{BusinessInterface.class},
InvocationHandler);

        / / official calls
ProxyBusiness.dosomething ("Yinwenjie");
}
}

As the code notes Proxy.newProxyInstance method has three parameters:

  • Loader: this newProxyInstance will have a return value, that is, the proxy object. Then the problem is that the class instance creation must have the support of classloader, the first argument is to refer to the "proxy object" to create the basis of the classloader

  • Interfaces: the second parameter is an array. In the design principle, there is an important principle is "dependent on inversion", it's practical experience is: "rely on the interface, not to achieve". So, JAVA's support for dynamic agents assumes that the programmer is following this principle: all the operations are defined by the interface. This parameter is dynamic proxy specified proxy object implements the interface, because Java in a class can implement multiple interfaces, so this parameter is an array (my example code in that business only for the real implementation defines an interface BusinessInterface. So the parameters are specified in this interface. In addition, the type of this parameter is Class, so if you do not define the interface, but rather specify a specific class, but also feasible. But this does not conform to the design principles.

  • InvocationHandler: This is our "call handler", this parameter does not have much to explain.

A good design, one of the principles of compliance: a type of problem, must use a specific design to solve; absolutely does not appear in two (or a variety of) solutions.
- the beauty of Architecture

3, DUBBO framework in-depth design and analysis

(from the DUBBO official website - Technical Manual)

From the above DUBBO Technical Manual (official website:Http://dubbo.io/Developer+Guide-zh.htm), it is certain that the technical details of the DUBBO official technical manuals are much more detailed than the technical details of my article. But as I've said before:The reason why the introduction of DUBBO framework is not only for readers to introduce the DUBBO service management framework itself, but also more important is the introduction of this series of articles to readers to introduce the whole system of communication technology between the level of knowledge.As a service management framework which is built on the RPC elements, it is an important part of this knowledge system, so it must be explained.

In this article, I will also have more out of reference to the official website of the DUBBO user manual and technical manuals. DUBBO team on the maintenance of the document is to do more in place, one point is that I am very impressed. Let's take a look at the DUBBO official document, the function description of each layer in the image above:

  • Config: configuration layer, external configuration interface to ReferenceConfig, ServiceConfig as the center, you can directly new configuration class, you can also configure the configuration generated by spring parsing.

  • Proxy: Service agent layer, transparent agent service interface, the generation of the client server Stub and server Skeleton, with ServiceProxy as the center, the extension of the interface as ProxyFactory.

  • Registry: registration center layer, the registration of the address of the package and the discovery, in order to serve URL as the center, the extension of the interface for Registry, RegistryFactory, RegistryService.

  • Cluster: routing layer, the package of multiple providers of routing and load balancing, and bridging the registration center, to Invoker as the center, the extension interface for Cluster, Directory, Router, LoadBalance.

  • Monitor: monitor layer, RPC call times and call time monitoring, in order to Statistics as the center, the extension of the interface for Monitor, MonitorFactory, MonitorService.

  • Protocol: remote call layer, seal the RPC call to Invocation, Result as the center, the extension interface for the Protocol, Invoker, Exporter.

  • Exchange: information exchange layer, package request response mode, synchronous to asynchronous, to Request, Response as the center, the extension interface for Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer.

  • Transport: network transport layer, abstract netty and Mina for the unified interface, with Message as the center, the extension interface for Channel, Transporter, Client, Server, Codec.

  • Serialize: data serialization layer, a number of reusable tools, the extension of the interface for ObjectInput, Serialization, ObjectOutput, ThreadPool.

4, SPI and extension points:

Provider Interface SPI:Service. In the above we have already mentioned, an interface if there are multiple implementation, so we must rely on the new keyword to tell the caller interface implementation; with the location and timing of the new key is very important, because this represents the caller need to know 'implementation';

Above mentioned spring framework using 'bean' configuration keys to help us solve the problem of the new keyword, to let the caller itself does not need to concern the call interface implementation. But in the framework of DUBBO and Spring is relatively independent, how to achieve this effect?

Here to to explain: many online Posts referred to Dubbo and spring can be seamlessly combined. But it is not why Dubbo analysis framework can seamlessly combined and spring framework. It makes a lot of readers think BUDDO framework is based on the development of spring.

But if you have studied DUBBO source code (or read the DUBBO related technical documentation), you will find. Dubbo and spring is completely two different components of technology, the so-called seamless integration is refers to Dubbo service layer, including config layer can be spring managed only (in fact the core of this framework and Dubbo achieve no half dime);

But the two beautiful software, the design of the idea is very consistentApplication of textbook design pattern.

Dubbo frame expansion (or said in addition to achieve) based on the Java standard "automatic service discovery mechanism; to explain the Dubbo is how to find an internal interface implementation classes, we must first clarify the SPI mechanism of Java and the Dubbo were which extend some necessary explanation.

JAVA, 4-1 comes with the SPI

For java interface and implementation, we normally (or you in learning Java), were defined and used (above has done a detailed notes with the following way, the code here the annotation streamlined):

  • Service interface definition (BusinessInterface):
Public InterfaceBusinessInterface {
    Public Void Dosomething(username String);
}
  • Real implementation class (RealBusinessImpl) of the service interface:
Public Class RealBusinessImpl Implements BusinessInterface{
    Public Void Dosomething(username String) {
System.out.println ("Being for the user:"+ username +"For real business processing... ");
}

    Public Static Void Main(args String[])ThrowsRuntimeException {
RealBusiness BusinessInterface =NewRealBusinessImpl ();
RealBusiness.dosomething ("Yinwenjie");
}
}

In fact, from the beginning of the JDK1.5 version, you do not need to use the new keyword to specify the specific implementation class. You can in META-INF/searvices folder to establish a named xxxx.BusinessInterface files (note XXXX represents your package name, the file name and BusinessInterface interface full class name the same), then in the contents of the file in writing "xxxxx.RealBusinessImpl" interface complete BusinessInterface class name). After you save the file, you can use the java.util.ServiceLoader tool class provided by JDK to type the interface. Code fragments are as follows:

....
Interface ServiceLoader<BusinessInterface> = ServiceLoader.load (BusinessInterface.class);
The reason that / / is written, you can specify a plurality of specific implementations of this interface
Iinterface= interface.iterator Iterator<BusinessInterface> ();
If(iinterface.hasNext ()) {
InterfaceItem BusinessInterface = iinterface.next ();
InterfaceItem.dosomething ("Yinwenjie");
}
...

4-2, DUBBO framework to do the modification

In Dubbo framework, SPI mechanism of the JDK lead author william.liangf and ding.lid were modified (more accurate to say is "new"): META-INF/dubbo folder, using the K-V describe specific class to create. This way in Dubbo framework is said to "expansion".

In the DUBBO framework, the "extension point" function is supported in the com.alibaba.dubbo.common.extension package, the main class is ExtensionLoader. In this package, the author also explains why the SPI function to extend the JDK is described:

Write the picture here.

5, RPC module

5-1, proxy: agent layer

Proxy agent layer according to Dubbo official document is used to generate RPC stub and skeleton, do is let you in Dubbo server defined specific business implementation does not need to care about "will be how to call" and you define the service interface "and RPC framework decoupling". The following figure is the main class diagram structure of DUBBO framework proxy layer:

Write the picture here.

As shown above (figure a little small, please right click to zoom in), the AbstractProxyFactory layer of the proxy class and its two sub categories using the above we talked about the typical abstract factory pattern design;

So how does the factory under AbstractProxyFactory work? Here we explain the JavassistProxyFactory factory. Because the default ProxyFactory settings in the DUBBO interface extension (extension), is the JavassistProxyFactory factory to be.

Extension extension point:
DUBBO framework of the internal configuration of the expansion of information, the main role is to tell the abstract class through the JAVA note form, it should be an instance of the implementation of the. DUBBO expansion point configuration file storage location in the MATE-INF/dubbo/internal folder under the jar folder. For the ProxyFactory interface, the extension of the configuration file for the com.alibaba.dubbo.rpc.ProxyFactory file in this directory;

In the above, we have mentioned the function of this component of javassist: dynamic load class at runtime, and to make an instance of it. Then based on the JavassistProxyFactory Invoker is provided by the javassist is to complete the work, the following is provided in the JavassistProxyFactory code fragment Invoker:

Public<T>Invoker<T> getInvoker (TProxy,Class<T>Type,URLURL){
/ /TODO WrapperClass can not correctly handle with $classname
    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);
}
};
}

(source code fragment above 'todo' no, but one of the main authors of the Dubbo william.liangf) here to explain Dubbo framework in which common module com.alibaba.dubbo.common.bytecode.Wrapper class. This class as generation "run-time class generation code tools exist. The main logical process:

Private StaticWrapperMakeWrapper(Class<? > C) {
....
}

In addition com.alibaba.dubbo.common.bytecode.Wrapper constant:

Private Static FinalMap<Class<? >, WRAPPER_MAP Wrapper> =NewConcurrentHashMap<Class<? >, Wrapper> ();

It clearly illustrates the relationship between Wrapper and the class of agents.

top
Three
step on
Zero
Guess you're looking for
View comments
* the above user comments only represent their personal views, does not represent the views or position of the CSDN website
    personal data
    • visit65537 times
    • Integral:One thousand three hundred and forty
    • Grade
    • Rank:19071st name
    • original41
    • Reproduced:1
    • Translation:0
    • Comments:142
    Blog column
    Classification of articles