Generalized call of basic features of Dubbo

  Dubbo supports generalization calls. What are generalization calls? What is the benefit of generalized invocation? To put it bluntly, generalized invocation means that the service consumer does not have a service interface.

  In the article " Introduction to Dubbo - Building a Simplest Demo Framework ", we have completed the most basic construction and invocation of Dubbo. Our dubbo-provider, dubbo-consumer, and dubbo-consumer2 all depend on dubbo-api. In fact, dubbo-api does nothing, but defines an interface. That is to say, when we develop and write Demo, one thing we must do is to have service consumers and service providers under the same path. The same interface, but there will be a specific implementation of the interface on the service provider side. The reason why there is an interface without any specific implementation on the service consumer is because at the beginning of the design of RPC, the designer's highest concept is that you go Interface-oriented programming, when you make a remote call, you do not realize that you are making a remote call, but you can also get the interface. I believe you also feel that when a service consumer calls a service, it is different from calling an ordinary The interface is the same.

  Generalized call means that the service consumer does not have the service interface for some reason. There are many reasons for this. For example, it is cross-language. A PHP engineer wants to call a certain java interface, but he cannot write one by one according to your agreement. The interface of Dubbo is not a cross-language RPC framework, but it is not impossible to solve this problem. This PHP programmer built a simple java web project, introduced the jar package of dubbo, used the generalization of dubbo to call, and then used the web Return json, which can also complete cross-language calls. One of the benefits of generalized calls is this.

  Well, in short, the most direct manifestation of generalized invocation is that the service consumer does not need to implement any interface to complete the invocation of the service.

1. Introduction to generalized calls

  The old rule, we now define a simple interface on the service provider side, (the difference from usual is that the interface does not need to be copied to the same path of the service provider, because the service consumer does not need to use this interface to call ), here we continue to use the case code in the article " Introduction to Dubbo - Building a Simplest Demo Framework ".

  Define a simple interface DemoService.java

package com.alibaba.dubbo.demo;

import java.util.List;

public  interface DemoService {
    List<String> getPermissions(Long id);
}

  The concrete implementation of this interface DemoServiceImpl.java

package com.alibaba.dubbo.demo.impl;

import com.alibaba.dubbo.demo.DemoService;

import java.util.ArrayList;
import java.util.List;

public class DemoServiceImpl implements DemoService {
    public List<String> getPermissions(Long id) {
        List<String> demo = new ArrayList<String>();
        demo.add(String.format("Permission_%d", id - 1));
        demo.add(String.format("Permission_%d", id));
        demo.add(String.format("Permission_%d", id + 1));
        return demo;
    }
}

  Spring's configuration file provider.xml on the service provider side

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd" > 
    <!-- Defines provider application information for calculating dependencies; this name will be displayed in dubbo-admin or dubbo-monitor for convenience Identification --> 
    < dubbo:application name ="demotest-provider" owner ="programmer" organization ="dubbox" /> 
    <!-- Use zookeeper registry to expose services, pay attention to enable zookeeper first --> 
    < dubbo:registry address ="zookeeper://localhost:2181" /> 
    <!-- Use dubbo protocol to expose services on port 20880 --> 
    < dubbo:protocol name ="dubbo" port ="20880"  />
    <!--Use the dubbo protocol to implement the defined api.PermissionService interface --> 
    < dubbo:service interface ="com.alibaba.dubbo.demo.DemoService" ref ="demoService" protocol ="dubbo" /> 
    <!-- Concrete implementation of this Interface bean -->   
    < bean id ="demoService" class ="com.alibaba.dubbo.demo.impl.DemoServiceImpl" /> 
</ beans >

  On the service provider side, write a startup class Provider.java:

package com.alibaba.dubbo.demo.impl;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

public class Provider {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "provider.xml");
        System.out.println(context.getDisplayName() + ": here");
        context.start();
        System.out.println( "The service has started..." );
        System.in.read();
    }
}

  Well, so far, the configuration files of generalized invocation service providers are all over. You can see that neither the code nor the spring configuration files have any special processing, which is no different from general service providers. Generalized call, from these four words, we know that the way of calling is different. Let's look at the code writing on the service consumer side.

  Because the service consumer has no interface, we directly write the consumer spring configuration file consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
      
    < dubbo:application name ="demotest-consumer" owner ="programmer" organization ="dubbox" /> 
    <!-- Subscribe the provider's address to zookeeper, which will be pushed regularly by zookeeper --> 
    < dubbo:registry address ="zookeeper: //localhost:2181" /> 
    <!-- Use the dubbo protocol to call the defined api.PermissionService interface --> 
    < dubbo:reference id = "permissionService" interface = "com.alibaba.dubbo.demo.DemoService" generic = "true" /> 
</ beans >

  You can see that there are two places to pay attention to in the configuration file above. The first is the interface. In fact, the interface does not exist on the consumer side. This is different from what is usually written. The second place needs to be The place to pay attention is the label generic=”true”, which means that the interface supports generic calls.

  Well, let's write a service test class and see how to make a generic call to Consumer.java

package com.alibaba.dubbo.consumer;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.alibaba.dubbo.rpc.service.GenericService;

public class Consumer {
    public static void main(String[] args) {
        /////////////////Spring泛化调用/////////  
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
        context.start();
        System.out.println("consumer start");
        GenericService demoService = (GenericService) context.getBean("permissionService");
        System.out.println("consumer");
        Object result = demoService.$invoke("getPermissions", new String[] { "java.lang.Long" }, new Object[]{ 1L });
        System.out.println(result);
    }
}

  In the Main function, after reading "permissionService" from the context of spring, it is forced to be converted to the class of GenericService, and then the $invoke method of GenericService is called. This method has three parameters. The first parameter is that you call the remote The specific method name of the interface, the second parameter is the type of the input parameter of the permissionService method, and the last parameter is the value. 

  Let's test it, start the main function of dubbo-provider, and then start the test class Consumer.java of the service consumer, you will find that the console prints:

[22/04/18 05:06:36:036 CST] main  INFO config.AbstractConfig:  [DUBBO] Refer dubbo service com.alibaba.dubbo.rpc.service.GenericService from url zookeeper://localhost:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=demotest-consumer&check=false&dubbo=2.5.3&generic=true&interface=com.alibaba.dubbo.demo.DemoService&methods=getPermissions&organization=dubbox&owner=programmer&pid=6604&side=consumer×tamp=1524387995725, dubbo version: 2.5.3, current host: 10.39.56.134
consumer
[Permission_0, Permission_1, Permission_2]

  It can be seen that it can be adjusted without problems.

  We just said that a PHP programmer wants to build a simple web project, but you tell him to depend on the spring configuration file, which is not easy for him. Dubbo also helped you think of it, generic invocation, service consumption The terminal can not rely on the spring configuration file, we rewrite the test class Consumer:

package com.alibaba.dubbo.consumer;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.utils.ReferenceConfigCache;
import com.alibaba.dubbo.rpc.service.GenericService;

public class Consumer {
    public static void main(String[] args) {

        // Ordinary coding configuration   
        ApplicationConfig application = new ApplicationConfig();  
        application.setName("dubbo-consumer");  
  
        // Connection registry configuration   
        RegistryConfig registry = new RegistryConfig();  
        registry.setAddress("zookeeper://127.0.0.1:2181");  
  
        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();  
        reference.setApplication(application);  
        reference.setRegistry(registry);  
        reference.setInterface("com.alibaba.dubbo.demo.DemoService");  
        reference.setGeneric( true ); // declared as a generalized interface   
  
        ReferenceConfigCache cache = ReferenceConfigCache.getCache();  
        GenericService genericService = cache.get(reference);  
  
        // Basic types and Date, List, Map do not need to be converted, directly call   
        Object result = genericService.$invoke("getPermissions", new String[] { "java.lang.Long" },  
                 new Object[] { 1L } );  
        System.out.println(result);
    }
}

  Restart the class. The console prints normally:

[22/04/18 05:09:09:009 CST] main  INFO config.AbstractConfig:  [DUBBO] Refer dubbo service com.alibaba.dubbo.rpc.service.GenericService from url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=dubbo-consumer&check=false&dubbo=2.5.3&generic=true&interface=com.alibaba.dubbo.demo.DemoService&methods=getPermissions&organization=dubbox&owner=programmer&pid=21144&side=consumer×tamp=1524388149244, dubbo version: 2.5.3, current host: 10.39.56.134
[Permission_0, Permission_1, Permission_2]

  It can also be called normally.

 

2. Summary of generalization calls

  The generalized call can facilitate the user's expansion of the dubbo service consumer side, which can facilitate and enrich the calling method of the service consumer, and even make a disguised Rest call. These are all possible, but its shortcomings are also obvious. The parameter passing is complicated and inconvenient to use. But this approach cannot be missed.

 

Reference article: https://blog.csdn.net/linuu/article/details/54313560

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324717036&siteId=291194637
Recommended