Building PHP microservice cluster

Time:2020-7-24

In recent years, microservice architecture has become popular. Taking advantage of the recent time, it is very important to play tricks on micro service.

Microservice architecture

The concept of microservice was proposed by Martin Fowler in March 2014

Microservice architecture is an architecture model, which advocates dividing a single application into a group of small services. Services coordinate and cooperate with each other to provide final value for users. Each service runs in its own process, and lightweight communication mechanism is used to communicate between services. Each service is built around specific business, and can be independently deployed to production environment, class production environment, etc. In addition, a unified and centralized service management mechanism should be avoided as far as possible. For a specific service, the appropriate language and tools should be selected according to the business context.

The following figure shows the microservice architecture of an e-commerce system

Building PHP microservice cluster

Compared with single application, microservice architecture has the following advantages:

  1. Each service is relatively simple and only focuses on one business function;
  2. Microservice architecture is loosely coupled, and each service can be tested, deployed, upgraded and released independently;
  3. Each microservice can be independently developed by different teams, and the best and most appropriate programming languages and tools can be selected respectively;
  4. Each service can be expanded horizontally according to the needs to improve the concurrent ability of the system.

Without silver bullet, micro service architecture brings many advantages, but also has the following disadvantages:

  1. Microservice architecture improves the complexity of the system, increases the operation and maintenance costs and costs. For example, a single application may only need to be deployed to a small application service cluster, while the microservice architecture may need to build / test / deploy / run dozens of independent services, and may need to support multiple languages and environments;
  2. As a distributed system, microservice architecture introduces some other problems, such as message serialization, network delay, asynchronous mechanism, fault tolerant processing, service avalanche, etc;
  3. The complexity of service management, such as service registration, discovery, degradation, fusing, etc;
  4. Service and service call each other, which brings great challenge to system troubleshooting.

It can be said that it is the traditional application architecture system has become increasingly bloated, facing the problem of difficult maintenance and expansion. At the same time, the vigorous development of docker technology and the maturity of Devops idea have given birth to the emergence of a new architecture design style microservice architecture.

RPC framework

Each service in microservice architecture is usually not on the same machine or even in the same network environment. Therefore, how to call microservices is an urgent problem to be solved. We usually use RPC Protocol to solve this problem

RPC (remote procedure call) is a computer communication protocol. This protocol allows a program running on one computer to call subroutines of another computer without the need for programmers to program this interaction. ——Wikipedia

The framework of RPC Protocol is implemented, which enables the server and the caller to shield various underlying details, and enables the caller to call remote functions (services) just like calling local functions. RPC framework provides serialization, deserialization, connection pool management, load balancing, fault transfer, queue management, timeout management, asynchronous management and other functions for server and client. On the Internet, we found a schematic diagram of RPC framework

Building PHP microservice cluster

At present, according to the different technologies used to serialize data, it can be divided intoJSON-RPCandgRPCThere are two types:

  • Json-rpc is a lightweight RPC Protocol Standard Based on JSON format, which can be transmitted based on HTTP protocol or directly based on TCP protocol.JSON-RPCThe advantage is easy to use and read.
  • Grpc is a high-performance, general open source RPC framework. It is designed by Google mainly for mobile application development and based on HTTP / 2 protocol standard. It is developed based on protobuffer (protocol buffers) serialization protocol and supports many development languages.gRPCIt has the advantages of low latency, high efficiency, high scalability and support for distributed.

Consul

Now that we have the RPC framework, we can only consider business calls between services without considering the underlying transport details. At this point, if service a wants to call service B, we can configure the IP address and port of service B in service a, and then hand over the remaining transmission details to the RPC framework. This is not a problem when the microservice scale is very small, but it will face great challenges when the service scale is large and more than one instance is deployed for each service. For example, service B deploys three instances. At this time, service a wants to call service B, which instance’s IP should be requested? If two of the three instances deployed by service B are down, service a may still request the suspended instance, and the service will not be available. It is very inflexible to write IP address and port configuration files. Microservice architecture often needs to ensure high availability and dynamic scalability.

Therefore, we need a service registration and service discovery tool, which can dynamically change the service information and find the available IP address and port of the service. At present, there are many service discovery tools on the market, such as consult, zookeeper, etcd, doozerd and so on. This paper mainly takes consult software as an example.

Consult is a service software that supports multi data center, distributed and highly available service discovery and configuration sharing. It is developed by hashicorp company with go language and is open source based on Mozilla Public License 2.0 protocol. Consult supports health checks and allows HTTP, grpc, and DNS protocols to call APIs to store key value pairs.

The following is the architecture diagram after the introduction of service registration and service discovery tool:

Building PHP microservice cluster

In this architecture:

  • First, after the S-B instance is started, its service information (mainly the IP address and port number of the service) is registered in the consult.
  • Consult performs health checks on all registered services to determine which service instances are available and which are not.
  • After S-A is started, it can access the IP and ports of all healthy S-B instances by accessing consult, and put these information into its own memory. Then S-A can call S-B through these information.
  • S-A can update the service information of S-B stored in memory by listening to consult. For example, if s-b-1 is hung, the health check mechanism will mark it as unavailable. Such information changes will be monitored by S-A, and S-A will update the service information of s-b-1 in its memory.

It can be seen that in addition to the functions of service registration and service discovery, the consult software also provides the functions of health check and status change notification.

Hyperf

For Java developers, there are mature Dubbo and spring cloud microservice frameworks to choose from. As a PHPer, I checked “PHP + microservices” with Google, and found that there were few useful related contents, and there was no substantive reference value. I was extremely disappointed… Fortunately, Youda Shen implements a high-performance and flexible PHP collaboration framework hyperf based on the extension of swote, and provides relevant components of microservice architecture.

Hyperf is based onSwoole 4.3+The implementation of the high-performance, high flexibility PHP coprocessing framework, built-in coroutine server and a large number of commonly used components, performance than the traditional based onPHP-FPMThe standard components are implemented based on PSR standard and based on powerful dependency injection design, which ensures that most components or classes areReplaceableAndReusableYes.

Therefore, after learning the basic knowledge of microservice architecture, I built a PHP based microservice cluster using the hyperf framework. This is the source code address of the project: https://github.com/Jochen-z/p… 。 The project is built with dokcer,docker-compose.ymlThe code is as follows:

version: "3"

services:
  consul-server-leader:
    image: consul:latest
    container_name: consul-server-leader
    command: "agent -server -bootstrap -ui -node=consul-server-leader -client=0.0.0.0"
    environment:
      - CONSUL_BIND_INTERFACE=eth0
    ports:
      - "8500:8500"
    networks:
      - microservice

  microservice-1:
    build:
      context: .
    container_name: "microservice-1"
    command: "php bin/hyperf.php start"
    depends_on:
      - "consul-server-leader"
    volumes:
      - ./www/microservice-1:/var/www
    networks:
      - microservice
    tty: true

  microservice-2:
    build:
      context: .
    container_name: "microservice-2"
    command: "php bin/hyperf.php start"
    depends_on:
      - "consul-server-leader"
    volumes:
      - ./www/microservice-2:/var/www
    networks:
      - microservice
    tty: true

  app:
    build:
      context: .
    container_name: "app"
    command: "php bin/hyperf.php start"
    depends_on:
      - "microservice-1"
    volumes:
      - ./www/web:/var/www
    ports:
      - "9501:9501"
    networks:
      - microservice
    tty: true

networks:
  microservice:
    driver: bridge

volumes:
  microservice:
    driver: local

A consult container is started hereconsul-server-leaderAs a component of service registration and service discovery, containermicroservice-1andmicroservice-2The services of addition and division are provided respectively. containerappAs a service caller, theconsul-server-leaderThe URL of the container by accessingconsul-server-leaderobtainmicroservice-1andmicroservice-2The IP address and port of the service, and thenappThe RPC Protocol calls the service of addition and division to get the result and return it to the user.

appThe container deploys a hyperf project and provides HTTP services for web applications. For example, in theApp\Controller\IndexControllerIt’s in the controlleraddmethod:

public function add(AdditionService $addition)
{
  $a = (int) $this - > request - > input ('a ', 1);; accept front-end user parameters
  $b = (int)$this->request->input('b', 2);

  return [
    'a' => $a,
    'b' => $b,
    'Add' = > $addition - > Add ($a, $B) ා RPC call
  ];
}

stayApp\JsonRpc\AdditionServiceinaddImplementation of:

class AdditionService extends AbstractServiceClient
{
    /**
     *Define the service name of the corresponding service provider
     * @var string
     */
    protected $serviceName = 'AdditionService';

    /**
     *Define the service agreement of the corresponding service provider
     * @var string
     */
    protected $protocol = 'jsonrpc-http';

    public function add(int $a, int $b): int
    {
        return $this->__request(__FUNCTION__, compact('a', 'b'));
    }
}

InheritedAbstractServiceClientWe can create a microservice client request class. Hyperf helps us implement the details of interaction with consult and service providers at the bottom. We just need toAdditionServiceIn classaddMethod can be called remotelymicroservice-1andmicroservice-2Services provided.

At this point, the PHP microservice cluster is completed!

Reference articles:

  1. A detailed explanation of microservice architecture
  2. Microservice architecture and RPC details are indispensable
  3. Using consult to do service registration and service discovery
  4. Hyperf document – microservices

Recommended Today

As package jar and AAR

Jar packaging (only class files and manifest files are included, not resource files, such as pictures and all files in Res) 1. Create a new project in as and a new model module. Add the model dependency to build. Gradle in the project, and then compile the project. Then add the following configuration in build.gradle […]