Distributed RPC Framework Apache Dubbo (Learning)

Table of contents

1. Evolution process of software architecture

1.1 Monolithic architecture

1.2 Vertical Architecture

1.3 SOA (Service-Oriented Architecture) architecture

1.4 Microservice Architecture

2. Overview of Apache Dubbo

2.1 Introduction

2.2 Dubbo architecture

3. Service registration center Zookeeper

3.1 Introduction to Zookeeper

3.2 Install Zookeeper

3.3 Start and stop Zookeeper

4. Dubbo quick start

4.1 Service Provider Development

4.2 Development of service consumers


1. Evolution process of software architecture

        The development of software architecture has experienced the evolution process from single architecture, vertical architecture, SOA architecture to microservice architecture.

1.1 Monolithic architecture

Architecture description: All functions are concentrated in one project (All in one).

Architecture advantages: simple architecture, low initial development cost, short development cycle, suitable for small projects.

Disadvantages of architecture: All functions are integrated in one project, which is not easy to develop, expand and maintain for large-scale projects; the technology stack is limited, and only one language can be used for development; system performance expansion can only be done by expanding cluster nodes, which is costly.

1.2 Vertical Architecture

Architecture description: Divide according to business to form small single projects.

Architectural advantages: the technology stack is scalable (different systems can be written in different editing languages).

Disadvantages of the architecture: functions are concentrated in one project, which is not conducive to development, expansion, and maintenance; system expansion can only be done through clusters; functional redundancy, data redundancy, and strong coupling between projects.

1.3 SOA (Service-Oriented Architecture) architecture

        SOA architecture, that is, service-oriented architecture. Loosely coupled coarse-grained application components (services) can be deployed, combined, and used in a distributed manner through the network according to requirements. A service usually exists in an operating system process in an independent form.

        From a functional point of view, business logic is abstracted into reusable services, and rapid business regeneration is realized through service orchestration. The purpose is to transform the original inherent business functions into general business services and realize rapid reuse of business logic.

Architecture description: Extract repeated functions or modules into components, provide external services, and use ESB (Enterprise Service Bus) as a communication bridge between projects and services.

Architecture advantages: Repeated functions or modules are extracted as services to improve development efficiency; high reusability; high maintainability.

Disadvantages of the architecture: The business of each system is different, and it is difficult to confirm that the functions or modules are duplicated; the granularity of extracted services is large; the coupling between systems and services is high.

1.4 Microservice Architecture

Divided into UI layer, service layer, data layer.

Architecture description: The system service layer is completely separated and extracted as microservices one by one. The granularity of the extraction is finer, following the single principle, and adopting a lightweight framework protocol for transmission.

Advantages of the architecture: the granularity of service splitting is finer, which is conducive to improving development efficiency; corresponding optimization schemes can be formulated for different services; it is suitable for the Internet era, and the product iteration cycle is shorter.

Disadvantages of the architecture: too fine granularity leads to too many services and high maintenance costs; the technical cost of distributed system development is high, which poses a great challenge to the team.

2. Overview of Apache Dubbo

2.1 Introduction

        Apache Dubbo is a high-performance Java RPC framework. Its predecessor is Alibaba's open source, lightweight Java RPC framework, which can be seamlessly integrated with Spring. In 2018, Alibaba donated this framework to the Apache Foundation.

What are RPCs?

        The full name of RPC is remote procedure call, that is, remote procedure call. For example, there are two servers A and B. An application is deployed on server A and an application is deployed on server B. The application on server A wants to call the method provided by the application on server B. Since the two applications are not in the same memory space, they cannot be called directly. , so it is necessary to express the semantics of the call and convey the data of the call through the network.

        It should be noted that RPC is not a specific technology, but refers to the entire network remote call process.

        RPC is a generalized concept. Strictly speaking, all remote procedure call methods belong to the category of RPC. Various development languages ​​have their own RPC framework. There are many RPC frameworks in Java, and RMI, Hessian, Dubbo, etc. are widely used.

Official website address: http://dubbo.apache.org

Dubbo provides three core capabilities: interface-oriented remote method invocation, intelligent fault tolerance and load balancing, and automatic service registration and discovery.

2.2 Dubbo architecture

Architecture diagram:

Node role description:

node

Role Name
Provider The service provider of the exposed service
Consumer The service consumer that invokes the remote service
Registry Registry for service registration and discovery
Monitor A monitoring center that counts service calls and call times
Container service running container

        The dotted lines are all asynchronous accesses, and the solid lines are all synchronous accesses. Blue dotted lines: functions completed at startup. Red dotted lines (solid lines) are all functions executed during program running.

Call relationship description:

  1. The service container is responsible for starting, loading, and running the service provider;
  2. When the service provider starts, it registers the services it provides with the registration center;
  3. When the service consumer starts, it subscribes to the registration center for the services it needs;
  4. The registration center returns the service provider address list to the consumer. If there is a change, the registration center will push the change data to the consumer based on the long connection;
  5. The service consumer, from the list of provider addresses, selects a provider to call based on the soft load balancing algorithm, and if the call fails, select another provider to call;
  6. Service consumers and providers accumulate the number of calls and call time in memory, and regularly send statistical data to the monitoring center every minute.

3. Service registration center Zookeeper

        As can be seen from the previous Dubbo architecture diagram, the Registry (service registration center) plays a vital role in it. Dubbo officially recommends using Zookeeper as the service registry.

3.1 Introduction to Zookeeper

        Zookeeper is a sub-project of Apache Hadoop. It is a tree-type directory service that supports change push. It is suitable as a registration center for Dubbo services. It has high industrial strength and can be used in production environments and is recommended.
        In order to understand Zookeeper's tree directory service, let's first look at our computer's file system (also a tree directory structure):

        My computer can be divided into multiple drive letters (such as C, D, E, etc.), and multiple directories can be created under each drive letter. Files and subdirectories can be created under each directory, and finally a tree is formed. type structure. Through this tree-structured directory, we can store files in different categories, which is convenient for us to search later. And each file on the disk has a unique access path, for example: C:\Windows\kkb\hello.txt.

        Zookeeper tree directory service:

 Flow Description:


  • When the service provider (Provider) starts: write its own URL address to the /dubbo/com.foo.BarService/providers directory
  • When the service consumer (Consumer) starts: Subscribe to the provider URL address under the /dubbo/com.foo.BarService/providers directory
    . And write your own URL address to the /dubbo/com.foo.BarService/consumers directory
  • When the Monitoring Center (Monitor) starts: Subscribe to all provider and consumer
    URL addresses under the /dubbo/com.foo.BarService directory

3.2 Install Zookeeper

Download address: http://archive.apache.org/dist/zookeeper/

        The Zookeeper version used in this course is 3.4.6. After the download is complete, you can get a compressed file named zookeeper-3.4.6.tar.gz.

installation steps:

The first step: install jdk (omitted)

Step 2: Upload the zookeeper compressed package (zookeeper-3.4.6.tar.gz) to the linux system

Step 3: Unzip the compressed package tar -zxvf zookeeper-3.4.6.tar.gz -C /usr

Step 4: Enter the zookeeper-3.4.6 directory and create the data directory mkdir data

Step 5: Enter the conf directory and rename zoo_sample.cfg to zoo.cfg cd confmv zoo_sample.cfg zoo.cfg

Step 6: Open the zoo.cfg file and modify the data attribute: dataDir=/usr/zookeeper-3.4.6/data

3.3 Start and stop Zookeeper

Enter the bin directory of Zookeeper,

Start service command: ./zkServer.sh start
Stop service command: ./zkServer.sh stop
View service status: ./zkServer.sh status
Client connection: ./zkCli.sh

4. Dubbo quick start

        As an RPC framework, Dubbo's core function is to realize remote calls across networks. This section is to create two applications, one as a service provider and one as a service consumer. Through Dubbo, the method for the service consumer to remotely call the service provider is realized.

4.1 Service Provider Development

Development steps:

(1) Create a maven project (the packaging method is war) dubbodemo_provider, and import the following coordinates in the pom.xml file

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <maven.compiler.source>1.8</maven.compiler.source>
 <maven.compiler.target>1.8</maven.compiler.target>
 <spring.version>5.0.5.RELEASE</spring.version>
</properties>
<dependencies>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${spring.version}</version>
 </dependency>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>${spring.version}</version>
 </dependency>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>${spring.version}</version>
 </dependency>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>${spring.version}</version>
 </dependency>
  <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>${spring.version}</version>
 </dependency>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
  <version>${spring.version}</version>
 </dependency>
 <dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>${spring.version}</version>
 </dependency>
 <!-- dubbo相关 -->
 <dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.0</version>
 </dependency>
 <dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.4.7</version>
 </dependency>
 <dependency>
  <groupId>com.github.sgroschupf</groupId>
  <artifactId>zkclient</artifactId>
  <version>0.1</version>
 </dependency>
 <dependency>
  <groupId>javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.12.1.GA</version>
 </dependency>
 <dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.47</version>
 </dependency>
</dependencies>
<build>
 <plugins>
  <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
   <version>2.3.2</version>
   <configuration>
    <source>1.8</source>
    <target>1.8</target>
   </configuration>
  </plugin>
  <plugin>
   <groupId>org.apache.tomcat.maven</groupId>
   <artifactId>tomcat7-maven-plugin</artifactId>
   <configuration>
    <!-- 指定端口 -->
    <port>8081</port>
    <!-- 请求路径 -->
    <path>/</path>
   </configuration>
  </plugin>
 </plugins>
</build>

(2) Configure the web.xml file

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
 <display-name>Archetype Created Web Application</display-name>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:applicationContext*.xml</param-value>
 </context-param>
 <listener>
  <listener-
class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
</web-app>

(3) Create a service interface

package com.lxs.service;
public interface HelloService {
  public String sayHello(String name);
}

(4) Create a service implementation class

package com.lxs.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.lxs.service.HelloService;
@Service
public class HelloServiceImpl implements HelloService {
  public String sayHello(String name) {
    return "hello " + name;
 }
}

Note: The Service annotation used on the service implementation class is provided by Dubbo and is used to publish the service externally
(5) Create applicationContext-service.xml under src/main/resources

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
    <dubbo:application name="dubbodemo_provider" />
    <!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
    <dubbo:registry address="zookeeper://192.168.134.129:2181"/>
    <!-- 注册 协议和port -->
    <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
    <!-- 扫描指定包,加入@Service注解的类会被发布为服务 -->
    <dubbo:annotation package="com.lxs.service.impl" />
</beans>

(6) Start the service

tomcat7:run

4.2 Development of service consumers

Development steps:

(1) Create a maven project (the packaging method is war) dubbodemo_consumer, the pom.xml configuration is the same as the above service provider, only need to change the port number of the Tomcat plug-in to 8082;

(2) Configure the web.xml file

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
 <display-name>Archetype Created Web Application</display-name>
 <servlet>
  <servlet-name>springmvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
  <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:applicationContext-web.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>springmvc</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
</web-app>

(3) Copy the HelloService interface in the service provider project to the current project

(4) Write Controller

package com.lxs.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.lxs.service.HelloService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/demo")
public class HelloController {
  @Reference
  private HelloService helloService;
  @RequestMapping("/hello")
  @ResponseBody
  public String getName(String name){
    //远程调用
    String result = helloService.sayHello(name);
    System.out.println(result);
    return result;
 }
}

Note: The HelloService injected into the Controller uses the @Reference annotation provided by Dubbo

(5) Create applicationContext-web.xml under src/main/resources

<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
<dubbo:application name="dubbodemo-consumer" />
<!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
<dubbo:registry address="zookeeper://192.168.134.129:2181"/>
<!-- 扫描的方式暴露接口 -->
<dubbo:annotation package="com.lxs.controller" />
</beans>

(6) Run the test tomcat7:run start

Enter http://localhost:8082/demo/hello.do?name=Jack in the browser to view the browser output.

Thinking 1: In the Dubbo entry case above, we copied the HelloService interface from the service provider project (dubbodemo_provider) to the service consumer project (dubbodemo_consumer). Is this approach appropriate? Is there a better way?
Answer: This approach is obviously bad. The same interface is copied twice, which is not conducive to later maintenance. A better way is to create a maven project separately, and create this interface in this maven project. Projects that need to rely on this interface only need to
introduce maven coordinates in the pom.xml file of their own project.
Thinking 2: In the service consumer project (dubbodemo_consumer), only the HelloService interface is referenced, and no implementation class is provided. How does Dubbo make remote calls?
Answer: The bottom layer of Dubbo is based on the proxy technology to create a proxy object for the HelloService interface, and the remote call is completed through this proxy object. You can view the internal structure of this proxy object through the debug function of the development tool. In addition, Dubbo implements the bottom layer of network transmission based on the Netty framework.
Thinking 3: In the Dubbo entry case above, we use Zookeeper as the service registration center. Service providers need to register their service information with Zookeeper, and service consumers need to subscribe to the services they need from Zookeeper. At this time, Zookeeper services become Very important, how to prevent Zookeeper single point of failure?
Answer: Zookeeper actually supports cluster mode. Zookeeper clusters can be configured to achieve high availability of Zookeeper services and prevent single points of failure.

Distributed RPC Framework Apache Dubbo (Learning)

The road is long and long, I will search up and down!

Guess you like

Origin blog.csdn.net/weixin_38817361/article/details/124262877