“This is the ninth day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”

1. Distributed system theory

In the book “Distributed Systems and Principles”, there is the following definition: “a distributed system is a collection of independent computers, these computers to the user like a single related system”;

A distributed system is a system composed of a group of computer nodes that communicate through a network and work in coordination to complete a common task. Distributed systems are designed to use cheap, common machines to perform computing and storage tasks that a single computer cannot. The aim is to use more machines and process more data.

A distributed system is a software system built on a network.

First of all to be clear, only when the processing capacity of a single node cannot meet the increasing computation, storage, task, and the ascension of the hardware (add memory, disk, using better CPU) high to do more harm than good, the application cannot be further optimized, we only need to consider a distributed system. Because, the problem to be solved by the distributed system itself is the same as the single-machine system, and the multi-node topology of the distributed system through the network communication will introduce many problems that the single-machine system does not have. In order to solve these problems, more mechanisms and protocols will be introduced and more problems will be brought.

Distributed Service Architecture

RPC

Remote Procedure Call (RPC), a means of interprocess communication, is a technical idea rather than a specification. It allows a program to call a procedure or function in another address space (usually on another machine on a shared network) without the programmer explicitly coding the details of the remote call. That is, programmers write essentially the same calling code whether they call local or remote functions.

Using RPC to call a function procedure on the server:

  1. First, the client needs to tell the server that there is a mapping between the function and the process ID. When the client calls the function remotely, it needs to look up the function, find the corresponding ID, and then execute the code of the function.

  2. Client needs to pass the local parameters to a remote function, the process of local calls, direct pressure stack, but in the process of remote call is no longer the same memory, cannot directly transfer function parameters, so we need the client into a byte stream, the parameters to the server, and then the server will be the byte stream into itself can read format, Is a process of serialization and deserialization.

  3. When the data is ready, how do you transfer it? The network transport layer needs to call the ID and serialized parameters to the server, and then the calculated results serialized to the client, so the TCP layer can complete the above process, THE gRPC uses the HTTP2 protocol.

RPC has two core modules:

  • communication
  • Serialization: Ensure the correct transmission of data

2. Dubbo Overview

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.

  • Interface-oriented remote method calls: Remote methods are called just like local methods, with simple configuration and no API intrusion.
  • Intelligent fault tolerance and load balancing: It can replace hardware load balancers such as F5 on the Intranet, reducing costs and single points.
  • Automatic service registration and discovery: no longer need to write the service provider address, the registry queries the SERVICE provider IP address based on the interface name, and can smoothly add or remove service providers.

In short, Dubbo is a service framework. If there is no distributed requirement, it is not necessary to use it. Only if it is distributed, there is a need for a distributed service framework like Dubbo, which is essentially a service invocation

Dubbo website

Dubbo user documentation

Architecture diagram of Dubbo

A description of the node roles in the figure above

node The role that
Provider Expose the service provider of the service, which, at startup, registers its services with the registry. If the registration fails, 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 link.
Consumer Invokes the service consumer of the remote service, who, at startup, subscribes to the service they need in the registry. If the subscription fails, the service consumer, from the list of providers, selects one provider to call based on the soft load balancing algorithm, and if the call fails, selects another.
Registry A registry for service registration and discovery
Monitor A monitoring center that counts the number and time of service calls
Container Service run container

Call Relationship Description

  1. The service container is responsible for starting, loading, and running service providers.
  2. At startup, a service provider registers its services with the registry.
  3. Service consumers, at startup, 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 link.
  5. Service consumers, from the list of providers, based on the soft load balancing algorithm, select one provider to call, if the call fails, select another call.
  6. Service consumers and providers accumulate the number of calls and call time in memory, and regularly send statistics to the monitoring center every minute.

The Dubbo architecture is characterized by connectivity, robustness, scalability, and upgradability to future architectures.

3. Install the ZooKeeper registry

Zookeeper is a subproject of Apache Hadoop. It is a tree-based directory service that supports change push. It is suitable for use as a registry for Dubbo services.

1. Download and decompress Zookeeper

Download address

2. Open the bin directory after downloading

If you double-click the server to open it, a flash exit may occur.

The solution:

3. Start the CMD test

First open the server, and then open the client to test:

  1. Run the ls/command on the client to find a ZooKeeper directory in the root directory. A directory is a node.

    Zookeeper is a child node

  1. Add a node to the root directory:

  1. View information about the added node:

Test completed, OK!

Install and test Dubbo-admin

Dubbo-admin is a monitoring management background that can view which services are registered by service providers and which services are consumed by service consumers.

Dubbo-admin Download address

1. Download and unzip it

2. Package the project as a JAR

It’s packed here: link: pan.baidu.com/s/1HyWK7_R1… Extract code: N7S3

3. Start the Zookeeper server and run the jar package (CMD).Java jar dubbo - admin - 0.0.1 - the SNAPSHOT. The jar)

4, access request :localhost:7001, the login interface, the default user name and password are root.

Click Login to enter the Dubbo-admin interface successfully:

5. Simple case of SpringBoot integrating Dubbo and Zookeeper

Create an empty project

Create a subproject in the empty project: Provider-server, as the service provider;

Create another sub-project, consumer-server, as a consumer of services

5.1. Implement service registration

Import dependencies in the Provider-Server project:

<! -- import dependency dubbo-->
  <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
      <version>2.7.3</version>
  </dependency>

  <! -- Import the ZooKeeper client -->
  <! -- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
  <dependency>
      <groupId>com.github.sgroschupf</groupId>
      <artifactId>zkclient</artifactId>
      <version>0.1</version>
  </dependency>

  <! -- Exclude log conflicts -->
  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>2.12.0</version>
  </dependency>
  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>2.12.0</version>
  </dependency>
  <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.5.9</version>
      <! Slf4j-log4j12 -->
      <exclusions>
          <exclusion>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-log4j12</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
Copy the code

Ticket service:

The service layer

/ / ticket
public interface provideTicket {
    public String getTicket(a);
}
Copy the code

The Service layer implements classes

@Component
@Service// The service can be detected and scanned by the zooKeeper registry
public class TicketServiceImpl implements TicketService{
    @Override
    public String provideTicket(a) {
        return "Ticket bought successfully"; }}Copy the code

Write a configuration file:

server.port=8001
# Service application name
dubbo.application.name=provider-server
# Registry address
dubbo.registry.address=Zookeeper: / / 127.0.0.1:2181
# Services that require registration
dubbo.scan.base-packages=com.cheng.service
Copy the code

2. Start the program test

Start the ZooKeeper registry server first, then start the Provider -server service provider, then run the Dubbo-admin jar package, run the same as above, and finally access the request localhost://7001 to check whether our service is successfully registered:

Service registration succeeded! Click in to view the details of the service:

5.2. Realize service consumption

1. Import dependencies in the garden-server project:

<! -- import dependency dubbo-->
  <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
      <version>2.7.3</version>
  </dependency>

  <! -- Import the ZooKeeper client -->
  <! -- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
  <dependency>
      <groupId>com.github.sgroschupf</groupId>
      <artifactId>zkclient</artifactId>
      <version>0.1</version>
  </dependency>

  <! -- Exclude log conflicts -->
  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>2.12.0</version>
  </dependency>
  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>2.12.0</version>
  </dependency>
  <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.5.9</version>
      <! Slf4j-log4j12 -->
      <exclusions>
          <exclusion>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-log4j12</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
Copy the code

Writing a configuration file

server.port=8002
# Service consumers need to reveal their names to get services
dubbo.application.name=consumer-server
The address of the registry
dubbo.registry.address=Zookeeper: / / 127.0.0.1:2181
Copy the code

The service layer

@Service// Inject the Spring container
public class UserService {
    // The service consumer gets the service from the registry

    @Reference// Remote injection Service injection: copy the service provider interface (TicketService) to the service consumer directory, the same path as in the provider directory, (this method is more suitable for learning)
    TicketService ticketService;

    public void buyTicket(a) {
        String ticket = ticketService.getTicket();
        System.out.println("Get it at the registry."+ticket); }}Copy the code

Test Class test:

@Autowired
UserService userService;
@Test
void contextLoads(a) {
    userService.buyTicket();
}
Copy the code

Success:

Start the consume-server program, refresh the Dubbo-admin interface, and there will be service consumer records:

5.3,

Implement service registration:

  1. Import dependence
  2. Configure the registry address, service name, and service to scan
  3. Annotate @service on the Service to be registered (under dubbo, @dubboService for new dubbo)

Service consumption:

  1. Import dependence
  2. Configure the registry to expose the consumer’s service name
  3. Inject services from a distance, using @Reference