The specific origin and functions of Dubbo are not introduced here. It is recommended to read the documents provided by apache http://dubbo.apache.org/zh-cn/index.html Here is a case of Dubbo realizing RPC function, which is convenient for everyone to understand.
Dubbo implements RPC
First, two projects are defined, one is Dubbo's client-side remote call, and the other is server-side service provision.
The structure is shown in the figure

api is only responsible for creating interfaces for both parties.
Here's the code and introduction
api module
The interface provided is responsible for customer use and provider module implementation
public interface ApiInterface { public String returnName(String name); }
The method that the client uses the provider module needs to be configured and registered
provider module
Implementation class
public class ProviderImpl implements ApiInterface { @Override public String returnName(String name) { return "Provider side echo:"+name; } }
The xml configuration of the provider module. See the internal notes for details.
<?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"> <!--Define provider information, such as name, version and definer ower etc.--> <dubbo:application name="dubbo-server"/> <!--Define the registry, N/A Do not register on behalf of--> <dubbo:registry address="N/A"/> <!--Configure protocol and port--> <dubbo:protocol name="dubbo" port="20880"/> <!--Specify the published interface and link to its implementation class--> <dubbo:service interface="com.zyh.dubbo.ApiInterface" ref="dubboImp"/> <!--Define an instance for external publishing and package it as bean--> <bean id="dubboImp" class="com.zyh.dubbo.ProviderImpl"/> </beans>
Load the configuration file and start to register it with Dubbo for external calls.
public class Bootstrap { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubbo-server.xml"); context.start(); System.in.read();//Block the current process so that the provider is always online to provide services } }
In addition, it should be noted that in the pom of the provider module, the api module needs to be introduced for the implementation and use of the provider module, and the dubbo module needs to be introduced.
<dependency><!--Introduce the called api Module, so that provider Modules can be implemented api Module interface--> <groupId>com.zyh.dubbo</groupId> <artifactId>dubbo-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> </dependency>
Once started, it will register with dubbo

After the server is started, there is a provider. After looking at it, it is found that it is actually a url (change the previous random code to dubbo: / / like this) + some protocols

Client configuration
public class App { public static void main( String[] args ) { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("dubbo-client.xml"); ApiInterface apiInterface = (ApiInterface) context.getBean("cliRes"); String res = apiInterface.returnName("zyh"); System.out.println(res); } }
Client xml configuration
<?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"> <!--Define provider information, such as name, version and definer ower etc.--> <dubbo:application name="dubbo-client"/> <!--Define the registry, N/A Do not register on behalf of--> <dubbo:registry address="N/A"/> <!--Provided after server startup url--> <dubbo:reference id="cliRes" interface="com.zyh.dubbo.ApiInterface" url="dubbo://192.168.106.1:20880/com.zyh.dubbo.ApiInterface"/> </beans
There is no doubt about the client-side pom configuration and dubbo. Another is our interface dependency library. After you install the server-side project through idea, there will be an api dependency, like the following dependency.
<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> </dependency> <dependency><!--Import installed locally dubbo-api Interface--> <groupId>com.zyh.dubbo</groupId> <artifactId>dubbo-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
After the client starts, the zk registry finds that there are many consumers in the node

If we run the program on the client and add system in. Read() stop and look at the consumer. It is found that the address port of the consumer will be maintained.

Generally speaking, it looks like RPC The client holds an api library. In the provider module, we link the relative url remote address to the interface methods of this api library. It is similar to calling our own JAVA library.
Configure ZK as registry
Of course, Dubbo can configure its own registry. Here we can configure the registry with ZK.
Server
First, change the configuration
<!--Define registry,to configure zk Address and port of-> <dubbo:registry address="zookeeper://ipaddr:2181"/>
The zk package and zkclient are introduced into pom, and the function of creating nodes through the zkclient is encapsulated in dubbo
<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.10</version> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
client
First, change the xml configuration and configure the zk registry. Since our service provider module has associated each interface method with its implementation class method, we don't need to formulate the url ourselves as before.
<!--Define registry--> <dubbo:registry address="zookeeper://ip:2181"/> <dubbo:reference id="cliRes" interface="com.zyh.dubbo.ApiInterface"/>
Operation results

After introducing zk, the URL in the / dubbo / interface / provider/url of the zk center is a temporary node, because the dubbo and zk of our server are based on session communication.
There is another problem. If you need some drag and drop processes to find the real url every time you make a call, the performance will be much lower than that. Therefore, we can configure the file attribute in the registry of the client to cache the address locally and save it in a file. As configured in zkclient
<dubbo:registry address="zookeeper://ip:2181" file="d:/dubbo-address"/>
You will find the configuration information of the provider on zk stored in the Dubbo address file of disk D. (I'll arrange the content slightly)

If our zookeeper goes down, he will also make a request to dubbo using the configuration in the cache
The dubbo caller also has an internal timer to periodically and actively refresh the cache. In addition, our client actually listens to relevant nodes. If the listening node changes, it will also notify our client.