Evolution of technology architecture

  

Before we study Dubbo, it is necessary to understand the evolution of the Internet’s technical architecture and communication methods, so that we can understand why we need to use a series of frameworks based on RPC ideas.

  

Single application Architecture

Colloquially speaking, “Monolith Application” is a monolith that packages all the functionality of an application into a single unit. When site traffic is low, only one application is needed to deploy all functions together to reduce deployment nodes and costs.

  

The characteristics of

  

  • All functions are integrated in one project;
  • All functions are deployed to the server in a WAR package;
  • Applications and databases are deployed separately.
  • You can deploy application clusters and database clusters to improve system performance.

  

Advantages:

  

  • Simple development: a single IDE can quickly build a single application;

  • Ease of sharing: A single archive contains all functionality and is easy to share between teams and different phases of deployment;

  • Easy to test: Once a single application is deployed, all services or features are available, simplifying the testing process because there are no additional dependencies and each test can be started as soon as the deployment is complete.

  • Easy to deploy: The entire project is a WAR package, and once Tomcat is installed, the application can be thrown onto it. Cluster deployment is also easy, with multiple Tomcat and one Nginx in a minute.

  

Disadvantages:

  

  • Impeding continuous delivery: Over time, individual applications can become larger and take longer to build and deploy, which discourages frequent deployments and continuous delivery. This problem is particularly acute in mobile application development;
  • Inflexible: as the project increases gradually, the whole development process will be a long time, even in the case of change by only one line of code, software developers need to spend a few minutes or more than one hour of time to compile all of the code, and then spend a lot of time just to redeploy generation product, to verify your changes are correct. If multiple developers work together on an application, then you have to wait for other developers to finish their work. This reduces team flexibility and frequency of functionality delivery;
  • Technology stack constraints: As projects get bigger, so do the technologies used by our applications. Some of these technologies are incompatible, such as the near-impossibility of mixing C++ and Java on a large scale in a single project. In this case, we need to abandon the use of incompatible technologies and choose a less suitable technology to implement a particular function.
  • Poor reliability: a link has an infinite loop, resulting in memory overflow, which will affect the whole project to hang.
  • Poor scalability: The system can only be expanded for applications, but cannot be expanded for certain functions. After the expansion, resources are wasted.
  • Technical debt: Suppose I have a messy module structure in my code base. At this point, I need to add a new feature. If the structure of this module is clear, maybe I only need 2 days to add this function, but now the structure of this module is chaotic, so I need 4 days. The extra two days are the interest on the debt. As time goes on and people change, technical debt is bound to increase.

  

Vertical application Architecture

  

When the volume of traffic gradually increases, the acceleration caused by the increase of a single application machine is getting smaller and smaller. The application is divided into several unrelated applications to improve efficiency.

  

The characteristics of

  

  • Vertical division of projects with single structure scale is to divide a large project into one single structure project.
  • There is data redundancy and high coupling between projects. For example, there is user information in the three projects in the figure above.
  • Interfaces between projects are used for data synchronization, for example, databases between databases are synchronized through network interfaces.

  

advantages

  

  • Low development cost and simple architecture;

  • Avoid unlimited expansion of single application;

  • System split realizes traffic sharing and solves the concurrency problem.

  • Capacity expansion and optimization for different systems;

  • Convenient horizontal expansion, load balancing, improved fault tolerance rate;

  • Different technologies can be used for different projects;

  • The systems are independent of each other.

  

disadvantages

  

  • Systems call each other. If the port or IP address of a system changes, the calling system needs to be manually changed.
  • The same logical code in a vertical architecture needs to be copied over time and cannot be reused.
  • System performance can only be expanded by expanding cluster nodes, which is costly and has bottlenecks.

  

SOA Service-oriented architecture

  

As more and more vertical applications become available, the interaction between applications becomes inevitable. Core businesses are extracted as independent services, gradually forming stable service centers. As the number of services increases, problems such as capacity evaluation and waste of small service resources gradually emerge. In this case, a scheduling center needs to be added to manage cluster capacity in real time based on access pressure to improve cluster utilization.

P.S. From a software design perspective, an ESB is an abstract layer of indirection that extracts something common in the dynamic interaction between the invocation and the invoked during service invocation, reducing the burden on the service caller. Java programming philosophy says, “All software design problems can be solved or simplified by adding an abstract layer of indirection!” Simply put, an ESB is a pipe that connects service nodes. To integrate services from different systems and protocols, the ESB translates and interprets messages and routes them so that different services can communicate with each other.

  

The characteristics of

  

  • SOA based architecture abstracts repetitive common functions into components and provides services to each system in the form of services.
  • Each project (system) communicates with the service through WebService, RPC, etc.
  • Use the ESB Enterprise Service Bus as a bridge for communication between projects and services.

  

advantages

  

  • The repetitive functions are extracted into services to improve the development efficiency and the reusability and maintainability of the system.
  • Cluster and optimization schemes can be developed according to the characteristics of different services;
  • Adopting an ESB reduces interface coupling in your system.

  

disadvantages

  

  • The blurred boundaries between systems and services are not conducive to development and maintenance.
  • Although the ESB is used, the interface protocol of the service is not fixed and various, which is not conducive to system maintenance.
  • The granularity of extracted services is too large and the coupling between system and services is high.
  • It involves a variety of middleware and has high requirements on the developer’s technology stack.
  • Complex service relationships make o&M, testing and deployment difficult

  

Microservices Architecture

  

  

The characteristics of

  

  • Completely separate the system service layer and extract the service layer into microservices one by one.
  • Each service in microservices corresponds to a unique business capability and follows a single principle.
  • Lightweight protocols such as RESTful are used for transmission between microservices.

  

advantages

  

  • Team independence: Each service is an independent development team, which can be a small team of two to five developers;
  • Technology independence: the decentralized idea is adopted, lightweight protocol communication such as RESTful is adopted between services, and the technology and language are used for development without interference from others;
  • Separation of the front and back ends: The front and back ends are developed separately to provide unified Rest interfaces, eliminating the need to develop different interfaces for PC and mobile terminals.
  • Database separation: Each microservice has its own storage capacity and can have its own database. You can have a unified database;
  • Finer granularity of service separation facilitates resource reuse and improves development efficiency.
  • New members of a team can go into production faster;
  • Microservices can be easily understood, modified, and maintained by a single developer so that small teams can focus on their own work. You don’t have to collaborate to be valuable;
  • The optimization scheme (such as expansion) of each service can be formulated more accurately to improve system maintainability;
  • Suitable for the Internet era, shorter product iteration cycle.

  

disadvantages

  

  • Too many micro services, high cost of service management, is not conducive to system maintenance;
  • The technical cost of distributed system development is high (network problems, fault tolerance problems, call relationships, distributed transactions, etc.), which poses great challenges to the team;
  • Microservices change from functional invocation to service invocation, either using RPC or HTTP REST, increasing overall system latency. This is inevitable, this requires us to change the original serial programming to concurrent programming or even asynchronous programming, increasing the technical threshold;
  • Multi-service operation and maintenance is difficult. With the increase of services, the pressure of operation and maintenance is also increasing.
  • The difficulty of the test increased. Services interact with each other through interfaces. When the interfaces change, it will affect all callers. At this time, automated testing becomes very important.

  

conclusion

  

Share two short stories to help you better understand the difference between SOA and microservices.

A story:

One day, long ago, Martin was talking to a friend and realized a great architectural design. He summed it up and told his friend, who said, this is nothing new, someone summed it up already, it’s called SOA.

Martin was delighted to start promoting SOA both inside and outside the company. As a result, he was constantly questioned and challenged.

You’re not SOA, are you? SOA here should be like this. Yes, here is my understanding of SOA. You see, this BOOK on SOA is not what you say. Particle size? SOA doesn’t talk about that. You’re not SOA. Layering has nothing to do with SOA, why would you say that? …

Martin couldn’t help it, so I called it Martin’s SOA. Lao Tzu invented the word, Lao Tzu is the highest authority, has the ultimate power of interpretation. Anyone else?

The idea itself is a good one, worthy of promotion, but Martin’s SOA is too tasteless, right? It’s better to have a good name that has some sort of legacy to SOA. Let’s just call it Microservices. It’s new and has services included in it.

Martin angrily accepted the suggestion, thinking, Damn it, IT’s SOA, and a bunch of bastards are forcing me to change my name.

Later, Martin found that every time he mentioned something, he would be challenged by the old evil and stupid forces to explain it. Therefore, every time he mentioned a concept, he had to invent a new word, so that a group of people would not question the challenge and talk about “my understanding” at the same time.

This is the story behind microservices, Agile, lean enterprise, continuous integration, continuous delivery.

Once a noun is created, the power of the namer to interpret it weakens over time (Cooper’s Persona, for example, was used by countless designers). Agile is already a bit lame, and when micro-services are lame, we’ll invent new words.

I can’t help it. I’m forced to do it.

  

Story 2:

In 1979, it was another spring. Wu Daniu, a barefoot doctor in putian rural area, was so enthusiastic about the reform that he did everything he said he would. Wu Daniu reported his ideas to the party secretary in the dim night and contracted the village health room the next day, starting his legendary career in the medical circle.

Rural clinics, as you know, it’s not a complicated thing, only a house, among a large counter space, half is a diagnosis and waiting area, half is the pharmacy, a doctor directly to find a doctor, if someone is in front of the find a seat, wait in line for a while, also in order to finish see sick doctor file directly, and then the next to continue, There’s no need for nurses or pharmacists. Wu does it all by himself.

After ten years of hard work, the time came to eighty-nine years, and it was spring. Wu Daniu, a bachelor in the past, had become a well-known figure in a country far away from home. His wife married and did not say, but a pair of twin sons were added to his family. However, there are also worries, although the rural clinic expanded to two, daughter-in-law can occasionally help, but the doctor is still only his own, every day from morning to night to earn money, want to earn more money how to do? Wu Daniu day and night, really give him to think of a move, how to do, expand the scale, recruit a few doctors together. Original Wu Daniu only heat and brain injuries for a headache, now new recruit a medical university graduate liu xiaoming specializes in the cold has a fever, again from the next village, the eldest brother man jen li specializes in gynecopathy, now becomes an ordinary small clinic has three independent department and a public (Wu Daniu daughter-in-law is responsible for) the small hospital pharmacy, Wu Daniu is surgical director of the dean, That’s three times what it was before. The director of Danu asked the famous calligrapher in the county to write a plaque for the new hospital — “Universal Love Hospital”, which was officially hung on an auspicious day.

Ten years later, another spring, Wu Daniu humanitarian hospital has developed into the medicine surgical gynecological surgery orthopaedics reproductive department six departments, each department 3 to 5 doctors, expensive purchases the blood tests also B chao deng advanced instruments, and dean is already out of the medical line, become a professional managers, But the big and small things of the hospital are all looking for him, and he is in a hot mess every day because of the more than 30 employees. He wants to expand the scale is really powerless. Say, or the level of college students have old men liu xiaoming to Daniel, dean of a meter, the independence departments, make each management department director himself, Daniel dean just between the department of coordination and the development of the hospital, to mobilize the enthusiasm of the grassroots, and liberating and dean to expand production catch big him great things, do not true? In this way, the new round of reform of fraternity hospital launched with vigour and vitality.

Again a decade, and a spring, and dean has become a local well-known entrepreneurs, humanitarian hospital also to 23 departments hundreds of employees, new problems have appeared in the development of, because each department independent registered, charge, laboratory, some departments all day busy efficiency good, some department is relatively mediocre, Even the various examination equipment assigned can not operate at full capacity, the whole hospital has many idle people. At this time, the dean of Daniu also broadened his vision, invited management experts to carry out the top-level design, and collected all the non-core services originally scattered to various departments into centralized management. The original 23 registration Windows were integrated into ten, and 23 charging Windows were integrated into eight, which were centrally arranged in the hall on the first floor to serve the whole hospital. Also scattered in various departments of inspection equipment set up the establishment of independent clinical laboratory, also serve for the floor, so that everyone have a job, the whole hospital service ability again on a new step, after this round of reform of humanitarian hospital through the departments at all levels of 3 armour hospital appraisal became famous far and near, Wu Daniu has also become the group CEO and chairman of love of others, The next step is to prepare for an IPO.

Here you may be a little confused, this has to do with micro services? The 1.0 stage of Daniel Clinic is equivalent to the single structure of software development. A programmer is in charge of the world, and it is difficult to grow bigger and stronger from beginning to end. The 2.0 stage of Daniu Clinic is equivalent to the vertical structure of software development, with each department divided according to business and easily extended horizontally. The 1.0 phase of Bo ‘ai Hospital is equivalent to the SOA structure of software development. Except for pharmacy (database), each service is provided independently (department director is responsible for it), but the director of Danu (ESB bus) is required to coordinate. The 2.0 stage of Bo ‘ai Hospital is equivalent to the micro-service structure of software development. Public services are shared within the hospital, and the management function of department directors is weakened (only doctors’ business). The advantage is that it is convenient to expand the capacity.

  

Microservice is to divide the application of a single architecture into independent running programs, namely services, which can communicate with each other through HTTP protocol (or message queue, such as RabbitMQ and Kafaka), using different programming languages and storage technologies. Automated deployment (e.g. Jenkins) reduces human control and error probability. The larger the number of services, the more complex it is to manage, so centralized management is adopted. For example, Eureka and Zookeeper are common service centralized management frameworks.

** Microservices is an architectural style where architecture is designed for decoupling and actually uses distributed system development. ** A large complex software application consisting of one or more microservices. Each microservice in the system can be deployed independently, and each microservice is loosely coupled. Each microservice focuses on only one task and does that task well.

In a word: Microservices are an outgrowth of SOA, which is a more modern and fine-grained way to implement SOA.

  

Communication mode

  

With the development of the Internet, application program from single to distributed, communication mode has also produced a lot of changes.

  

TCP/UDP

  

Both are transmission protocols. The main difference is that TCP requires three handshakes for connection, and four waves for disconnection. It is transmitted through streams. UDP encapsulates information into multiple packets and sends them directly without connection. So UDP is faster, but does not guarantee data integrity.

In a word: the oldest and most effective, timeless and expensive to learn. All communication boils down to TCP/UDP.

  

WebService

  

WebService (SOA, SOAP, WSDL, UDDI, XML) technology enables different applications running on different machines to exchange data or integrate with each other without additional, specialized third-party software or hardware. Applications implemented according to the WebService specification can exchange data with each other, regardless of the language, platform, or internal protocol they use.

WebService is a remote call technology across programming languages and operating system platforms. The process of WebService interaction is to follow SOAP protocol to encapsulate data through XML, and then transmit data through Http protocol.

In a word: Standardized Web API based on HTTP + XML.

  

RESTful

  

Representational State Transfer, which represents layer State Transfer. Internet Communication protocol HTTP is a stateless protocol. This means that all state is kept on the server side. Therefore, if the client wants to operate the server, it must somehow make a State Transfer happen on the server side. This transition is built on top of the presentation layer, so it is called “presentation layer state transition”.

The client can only use HTTP. Specifically, there are four verbs in the HTTP protocol that denote operations: GET, POST, PUT, and DELETE. They correspond to four basic operations: GET to obtain resources, POST to create resources (which can also be used to update resources), PUT to update resources, and DELETE to DELETE resources.

  • Stateless protocol HTTP has inherent advantages and strong expansion ability. For example, when secure encryption is required, a mature HTTPS solution is available.
  • JSON message serialization is lightweight and simple, readable by humans and machines, low learning cost, and friendly to search engines.
  • Regardless of the language, every popular language provides a mature Restful API framework.

In a word: Standardized Web API based on HTTP + JSON.

  

RMI

  

Remote Method Invocation Java in the implementation of distributed communication protocol, it greatly enhances the Java development of distributed applications. With RMI technology, one local JVM can call an object method that exists in another JVM as if it were just calling an object method in the local JVM.

Summary: Distributed communication protocol based on Java language.

  

JMS

  

Java Message Service (Java Message Service Application Interface) is an API for message-oriented middleware in the Java platform. It is used to send messages between two applications or in distributed systems for asynchronous communication. Most MQ supports JMS, such as RabbitMQ, ActiveMQ, Kafka, RocketMQ, and Redis.

In a word: JavaEE messaging framework standards.

  

RPC

  

Remont Proceduce Call, remote procedure Call It is the idea of requesting services from a remote computer program over a network without understanding the underlying network technology. RPC is just a concept, it is not a protocol or a framework.

The specific implementation of RPC can use RMI or RESTful, but generally not, because RMI cannot be cross-language, RESTful efficiency is low.

RPC is mostly used for communication within a server cluster, so a more efficient and shorter transmission mode is often used to improve efficiency. There are many RPC frameworks: Apache Thrift, Apache Dubbo, Google Grpc, etc.

Summary: To solve the problem of invocation between services in distributed systems. The remote call should be as convenient as the local call, so that the caller is not aware of the logic of the remote call.

  

Why is RPC needed?

  

This is mainly due to the inability to share memory space within several processes (applications are distributed on different machines), such as communication between different systems, or even communication between different organizations. In addition, due to the horizontal scaling of machines, applications need to be deployed on clusters of multiple machines, and so on.

For example, you now have two machines: machine A and machine B, with application A and application B deployed respectively. Suppose that application A on machine A wants to call the function or method provided by application B on machine B. Since application A and application B are not in the same memory space, they cannot be called directly. In this case, the method of calling and the data of calling need to be expressed through the network. Also known as remote invocation.

  

Implementation Principle of RPC

  

A complete RPC call process consists of four core parts, namely Client, Server, Client Stub and Server Stub, which can be understood as a Stub. Talk about these parts separately:

Client: The caller of a service.

Server: The provider of a service.

Client stubs: Store server address messages, package client request parameters into network messages, and send them to the server remotely over the network.

Server stub: Receives the message sent from the client, unpacks the message, and invokes local methods.

  

  

  1. A Client invokes a service in a local invocation (that is, as an interface);
  2. After receiving the call, the Client Stub is responsible for assembling methods, parameters, and so on into a message body that can be transmitted over the network (serializing the message body object into binary).
  3. The client sends the message to the server through Socket.
  4. The Server Stub receives the message and decodes it (deserializes the message object);
  5. The Server Stub invokes the local service based on the decoded result;
  6. Local services for business logic processing;
  7. The local service returns the result of business logic processing to the Server Stub.
  8. The Server Stub packages the return result into a message (serializes the result message object);
  9. The Server sends messages to the client through sockets.
  10. The Client Stub receives the result message and decodes it (deserializes the result message);
  11. The Client gets the final result.

The goal of RPC is to encapsulate steps 2, 3, 4, 5, 7, 8, 9, and 10.

  

Establish communication

  

The communication problem is solved by establishing a TCP connection between the client and the server, where all the data exchanged by the remote procedure call is transmitted. A connection can be an on-demand connection that breaks after the call, or a long connection that is shared by multiple remote procedure calls.

  

Service addressing

  

How the application on server A tells the underlying RPC framework how to connect to server B (such as the host or IP address) and the specific port, and what the name of the method is, so that the call can be made. For example, RPC, which is based on the Web services protocol stack, provides an endpoint URI or looks up from a UDDI (a directory service through which services are registered and searched) service. For RMI calls, an RMI Registry is also required to register the address of the service.

  

Network transmission

  

serialization

  

When an application on server A initiates A remote procedure call, the parameters of the method need to be transmitted to server B through an underlying network protocol such as TCP. Since the network protocol is binary, the values of the parameters in memory need to be serialized into binary form, namely Serialize or marshal. The serialized binary is sent to the B server through addressing and transport.

  

deserialization

  

After receiving the request, the server needs to deserialize the parameters (the reverse of serialization), restore them to the in-memory representation, and then find the corresponding method (part of the address) to make the local call (usually by generating Proxy to call, There are usually JDK dynamic proxies, CGLIB dynamic proxies, Javassist bytecode generation techniques, etc.), and then get the return value of the call.

  

The service call

  

B machine for local calls (Proxy) through agent after received the return value, at this time also need to be sent back to the return value is A machine, also need the serialized operation, and then through the network to send binary data back to A machine, and when A machine to receive these return values, then deserialize operation again, It is restored to an in-memory representation and finally handed over to the application on machine A for relevant processing (generally business logic processing operations).

  

A simple implementation of RPC based on RMI

  

Set up the Maven aggregation project

  

The parent project rmi – demo

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>rmi-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0 the SNAPSHOT</version>
    <modules>
        <module>rmi-api</module>
        <module>rmi-server</module>
        <module>rmi-client</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

</project>
Copy the code

  

Engineering rmi – API

  

This project is mainly to store the client and server will use the public interface.

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-api</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>

</project>
Copy the code

  

Entity class

  

Since network protocols are binary based and the values of parameters in memory are serialized to binary form, entity classes need to implement the Serializable interface.

package org.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 2159427410483687648L;
    private Integer id;
    private String username;

}
Copy the code

  

The service interface

  

Service interfaces exposed using JavaRMI must inherit the java.rmi.remote.Remote class, and methods must throw java.rmi.RemoteException.

package org.example.service;

import org.example.pojo.User;

import java.rmi.Remote;
import java.rmi.RemoteException;

/** * User management service */
public interface UserService extends Remote {

    User selectUserById(Integer userId) throws RemoteException;

}
Copy the code

  

The child engineering rmi server. –

  

It mainly provides the realization of service interface and RMI service configuration.

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-server</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0 the SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
Copy the code

  

The service implementation

  

Service interface implementation must inherit the Java. The rmi. Server UnicastRemoteObject class.

package org.example.service.impl;

import org.example.pojo.User;
import org.example.service.UserService;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/** * User management service */
public class UserServiceImpl extends UnicastRemoteObject implements UserService {

    public UserServiceImpl(a) throws RemoteException {}@Override
    public User selectUserById(Integer userId) throws RemoteException {
        System.out.println("User management service received a client request, request parameter userId =" + userId);
        // Simulate false data return
        return new User(userId, "Zhang"); }}Copy the code

  

Publishing service

  

Publish the service on the specified IP + port.

package org.example;

import org.example.service.UserService;
import org.example.service.impl.UserServiceImpl;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/** * Publish service */
public class Publish {

    public static void main(String[] args) throws RemoteException {
        UserService userService = new UserServiceImpl();
        try {
            // The exposed service port
            LocateRegistry.createRegistry(8888);
            // The exposed service address
            Naming.bind("rmi://localhost:8888/userService", userService);
            System.out.println("Service release successful!");
        } catch (AlreadyBoundException e) {
            e.printStackTrace();
        } catch(MalformedURLException e) { e.printStackTrace(); }}}Copy the code

  

Rmi sub project – the client

  

How the local client implements calling the remote interface.

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-client</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0 the SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
Copy the code

  

Remote service invocation

  

The remote service invocation is made through the specified IP + port.

package org.example.controller;

import org.example.pojo.User;
import org.example.service.UserService;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class UserController {

    public static void main(String[] args) {
        try {
            UserService userService = (UserService) Naming.lookup("rmi://localhost:8888/userService");
            User user = userService.selectUserById(1);
            System.out.println("Remote service call successful, return value message:" + user);
        } catch (NotBoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch(RemoteException e) { e.printStackTrace(); }}}Copy the code

  

test

  

As you can see from the tests that RPC’s RMI-based remote service invocation is complete, let’s learn how to use the RPC framework Dubbo to do the remote service invocation.

  

RPC framework

  

A typical RPC framework application scenario includes service registration and discovery (registry), load balancing, fault tolerance, network transmission, serialization and other components, among which “RPC-related protocol” indicates how the program carries out network transmission and serialization. There are many RPC frameworks: Apache Thrift, Apache Dubbo, Google Grpc, etc. The following figure shows the complete RPC framework architecture diagram:

  

Dubbo introduction

  

  

Liverpoolfc.tv: dubbo.apache.org/zh-cn/

Github:github.com/apache/dubb…

On February 15, 2018, Dubbo, Alibaba’s service governance framework, was voted as an Apache Foundation incubation project.

Apache Dubbo is a high-performance, lightweight, open source Java RPC framework that provides three core capabilities: interface-oriented remote method invocation, intelligent fault tolerance and load balancing, and automatic service registration and discovery.

  

Dubbo architecture

  

Dubbo provides three core functions: interface-oriented remote method invocation, intelligent fault tolerance and load balancing, and automatic service registration and discovery. The Dubbo framework is widely used within Alibaba, as well as by Dangdang, Qunar, netease Kaola, Didi and others.

Node Role description

  

node The role that
Provider The service provider that exposes the service
Consumer Service consumer that invokes the remote service
Registry A registry for service registration and discovery
Monitor A monitoring center that collects statistics on service invocation times and invocation time
Container Service run container

  

Call Relationship Description

  

  1. The service container is responsible for starting, loading, and running the service provider.
  2. At startup, service providers register their services with the registry.
  3. At startup, service consumers subscribe to the registry for the services they need.
  4. The registry returns a list of service provider addresses to the consumer, and if there are changes, the registry pushes the change data to the consumer based on the long connection.
  5. The service consumer, from the provider address list, selects one provider to call based on the soft load balancing algorithm. If the call fails, selects another one to call.
  6. Service consumers and providers accumulate calls and call times in memory and regularly send statistics to the monitoring center every minute.

  

Dubbo Quick Start

  

Let’s complete an introductory example of integrating Dubbo with a SpringBoot environment.

  

Set up the Maven aggregation project

  

The parent project dubbo – demo

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>dubbo-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0 the SNAPSHOT</version>
    <modules>
        <module>dubbo-api</module>
        <module>dubbo-provider</module>
        <module>dubbo-consumer</module>
    </modules>

    <! -- Inherits spring-boot-starter-parent dependency -->
    <! -- Use inheritance mode, implement reuse, conform to inheritance can be used -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0. RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.4.1</version>
        </dependency>
    </dependencies>

</project>
Copy the code

  

Engineering dubbo – API

  

This project is designed to house the common interfaces used by both providers and consumers.

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-api</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>
Copy the code

  

Entity class

  

Since network protocols are binary based and the values of parameters in memory are serialized to binary form, entity classes need to implement the Serializable interface.

package org.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 2159427410483687648L;
    private Integer id;
    private String username;

}
Copy the code

  

The service interface

  

package org.example.service;

import org.example.pojo.User;

/** * User management service */
public interface UserService {

    User selectUserById(Integer userId);

}
Copy the code

  

Engineering dubbo – the provider

  

It mainly provides the implementation of service interfaces and service configuration of service providers.

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-provider</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0 the SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
Copy the code

  

The configuration file

  

The configuration file needs to configure the service provider application information, the address of the registry and the exposed service, as well as the protocol and protocol port used and the packet address of the scanning service interface.

server:
  port: 7070 # port

# Dubbo configuration
dubbo:
  Provider application information used to calculate dependencies
  application:
    name: product-service
  Configure the registry
  registry:
    address: Multicast: / / 224.5.6.7:1234 Expose service addresses using Multicast registries
  Expose service on port 20880 with dubbo protocol
  protocol:
    name: dubbo Protocol name
    port: 20880 Protocol port
  # Scan for exposed services
  scan:
    base-packages: org.example.service
Copy the code

  

Service Realization (Service provider)

  

package org.example.service.impl;

import org.example.pojo.User;
import org.example.service.UserService;
import org.apache.dubbo.config.annotation.Service;

/** * User management service * timeout Timeout period for invoking the service * version indicates the version number * group indicates the group * Interface, group, and version can specify one service * parameters = {"unicast", "false"} * It is recommended that service providers and service consumers run on different machines. * If they run on the same machine, set unicast = false to disable unicast subscriptions. Only multicast registries have this problem. * /
@service (timeout = 5000, version = "1.0", group = "user-provider", parameters = {"unicast", "false"})
public class UserServiceImpl implements UserService {

    @Override
    public User selectUserById(Integer userId) {
        System.out.println("User management service received a client request, request parameter userId =" + userId);
        // Simulate false data return
        return new User(userId, "Zhang"); }}Copy the code

Note: Parameters = {“unicast”, “false”} : It is recommended that service providers and service consumers run on different machines. If they run on the same machine, set unicast = false to disable unicast subscriptions. Only multicast registries have this problem.

  

Start the class

  

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Scan for services that need to be exposed. You do not need to add this annotation if it is declared in the configuration file
// @EnableDubbo(scanBasePackages = "org.example.service")
@SpringBootApplication
public class DubboProviderApplication {

	public static void main(String[] args) { SpringApplication.run(DubboProviderApplication.class, args); }}Copy the code

  

Engineering dubbo – consumer

  

pom.xml

  


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-consumer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0 the SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>
Copy the code

  

The configuration file

  

The configuration file needs to configure the service consumer application information and configure the registry to discover the services exposed by the registry.

server:
  port: 9090 # port

# Dubbo configuration
dubbo:
  # consumer application name, used to calculate dependencies, not matching conditions, not the same as provider
  application:
    name: dubbo-consumer
  Configure the registry
  registry:
    address: Multicast: / / 224.5.6.7:1234 Discover services exposed in the Multicast registry
Copy the code

  

Remote service invocation

  

package org.example.controller;

import org.apache.dubbo.config.annotation.Reference;
import org.example.pojo.User;
import org.example.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    // Dubbo provides the @Reference annotation to replace the @autowired annotation for introducing remote services
    If the version and group information are set when registering the service, the version and group information must be set when invoking the remote service
    @reference (timeout = 5000, version = "1.0", group = "user-provider", parameters = {"unicast", "false"})
    private UserService userService;

    @GetMapping("/{id}")
    public User selectUserById(@PathVariable("id") Integer id) {
        returnuserService.selectUserById(id); }}Copy the code

  

Start the class

  

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DubboConsumerApplication {

    public static void main(String[] args) { SpringApplication.run(DubboConsumerApplication.class, args); }}Copy the code

  

test

  

Start the service providers and service consumers, visit: http://localhost:9090/consumer/1 the results are as follows:

Dubbo Common label

  

  • dubbo:application: Application name
  • dubbo:registry: Connect to registry information (configure the registry)
  • dubbo:protocol: protocol by which the service provider registers the service
    • Dubbo protocol, default
    • The RMI protocol
    • Hessian protocol
    • The HTTP protocol
    • WebService agreement
    • Thrift agreement
    • The Memcached protocol
    • Redis protocol
    • Rest protocol (RESTful)
    • Grpc agreement
    • For more information about protocols, see: dubbo.apache.org/zh-cn/docs/…
  • dubbo:service: Declares the service interface to expose
  • dubbo:reference: Configure subscribed services (generate remote service proxies)

For more configuration information, see dubbo.apache.org/zh-cn/docs/…

Keep an eye out for the Dubbo registry, Dubbo load balancing policy and Dubbo console installation in our next post

This article is licensed under a Creative Commons attribution – Noncommercial – No Deductive 4.0 International license.

You can check out more articles about Dubbo in the category below.

  

🤗 your likes and retweets are the biggest support for me.

📢 Scan code pay attention to Mr. Hallward “document + video” each article is equipped with a special video explanation, learning more easily oh ~