Home  >  Article  >  Backend Development  >  How to implement microservices using PHP?

How to implement microservices using PHP?

慕斯
慕斯forward
2021-06-18 11:12:475207browse

This article introduces how to use PHP to implement microservices? It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.

How to implement microservices using PHP?Why should we talk about service governance

As Internet browsing becomes larger and larger. The traditional MVC single architecture continues to expand as the application scale continues to expand. , application modules continue to increase, the entire application becomes more and more bloated, and maintenance becomes more difficult.

We must take measures to split by application, that is, split the original application into multiple applications according to business characteristics application. For example, a large e-commerce system may include a user system, product system, order system, evaluation system, etc. We can separate them into separate applications. The characteristic of multi-application architecture is that applications are independent and do not call each other.

Although multiple applications solve the problem of bloated applications, the applications are independent of each other, and some common businesses or codes cannot be reused.

Single application solution

For a large Internet system, it usually contains multiple applications, and there are often common services between the applications, and there are also calling relationships between the applications. . In addition, there are other challenges for large-scale Internet systems, such as how to deal with the rapid growth of users, how to manage the R&D team to quickly iterate product development, how to keep product upgrades more stable, etc.

Therefore, in order to make the business reusable and the module easier to expand and maintain, we hope that the business and the application can be separated. A certain business no longer belongs to an application, but is performed separately as an independent service. maintain. The application itself is no longer a bloated stack of modules, but is composed of modular service components.

Serviceization

Features

So what are the bright features of using Serviceization?

  • Applications are split into services based on business
  • Each service can be deployed independently
  • Services can be shared by multiple applications
  • Services can communicate with each other
  • The system is clearer in terms of architecture
  • The core module is stable and upgraded in units of service components, avoiding the risks caused by frequent releases
  • Convenient development and management
  • Separate Team maintenance, clear work, clear responsibilities
  • Business reuse, code reuse
  • Very easy to expand

Challenges faced by service-oriented

After the system is service-oriented, the dependencies will become more complex, and the number of interactions between services will also increase. In the development mode of fpm, because it cannot be resident in memory, every request It has to be loaded from scratch until the process exits, which adds a lot of useless overhead. The database connection cannot be reused and cannot be protected, because fpm is based on the process. The number of processes also determines the number of concurrencies, which is also a problem brought to us by the simplicity of fpm development. So why is the Internet platform Java more popular now, .NET# Neither ## nor PHP work in this regard. PHP is non-memory resident Needless to say. Beyond that, there are many other issues that need to be addressed. There are more and more services, and configuration management is complex

    Complex dependencies between services
  • Load balancing between services
  • Expansion of services
  • Service Monitoring
  • Service Downgrade
  • Service Authentication
  • Service Online and Offline
  • Service Document...
  • You can imagine the benefits that resident memory brings to us, such as

    Only start the framework initialization
  • If resident memory we It only handles the initialization of the framework in the memory at startup and concentrates on processing requests

  • Connection reuse
  • . Some engineers do not particularly understand that if a connection pool is not used, How about just sending a connection when a request comes in? This will lead to too many backend resource connections. For some basic services, such as Redis and database, connections are expensive.

    So is there any good solution? The answer is yes, and many people are using this framework, which is -
  • Swoft
.

Swoft is an RPC framework with Service Governance function. Swoft is the first PHP resident memory coroutine full-stack framework, based on the core concept of Spring Boot that convention is greater than configuration

Swoft provides a more elegant way to use RPC services similar to Dubbo, Swoft The performance is very good and similarGolangPerformance, the following is the stress test of Swoft performance on my PC.

abStress test processing speed It’s amazing. With i78 generationCPU, 16GB memory, 10000010,000 requests only took 5s in fpmIt is basically impossible to achieve in development mode. This is enough to prove Swoft`’s high performance and stability,

elegant service governance

Service Registration and Discovery

The microservice governance process often involves registering started services to third-party clusters, such as consul/etcd, etc. This chapter uses the swoft-consul component in the Swoft framework to implement service registration. Take Discovery for example.

Implementation logic

<?php declare(strict_types=1);namespace App\Common;use ReflectionException;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Bean\Annotation\Mapping\Inject;use Swoft\Bean\Exception\ContainerException;use Swoft\Consul\Agent;use Swoft\Consul\Exception\ClientException;use Swoft\Consul\Exception\ServerException;use Swoft\Rpc\Client\Client;use Swoft\Rpc\Client\Contract\ProviderInterface;/**
 * Class RpcProvider
 *
 * @since 2.0
 *        
 * @Bean()
 */class RpcProvider implements ProviderInterface{    /**
     * @Inject()
     *
     * @var Agent
     */
    private $agent;    /**
     * @param Client $client
     *
     * @return array
     * @throws ReflectionException
     * @throws ContainerException
     * @throws ClientException
     * @throws ServerException
     * @example
     * [
     *     &#39;host:port&#39;,
     *     &#39;host:port&#39;,
     *     &#39;host:port&#39;,
     * ]
     */
    public function getList(Client $client): array
    {        // Get health service from consul
        $services = $this->agent->services();

        $services = [
        
        ];        return $services;
    }
}

Service circuit breaker

In a distributed environment, especially in a distributed system with a microservice structure, it is very difficult for a software system to call another remote system. common. The callee of this remote call may be another process, or another host across the network. The biggest difference between this remote call and the internal call of the process is that the remote call may fail or hang. No response until timeout. What's worse is that if multiple callers call the same suspended service, then it is very likely that the timeout wait of a service will quickly spread to the entire distributed system, causing a chain reaction and consuming the entire Distributed systems have a lot of resources. It may eventually lead to system failure.

The circuit breaker (Circuit Breaker) mode is to prevent disasters caused by such waterfall-like chain reactions in distributed systems.

The basic circuit breaker mode ensures that the protection supplier will not be called when the circuit breaker is in the open state, but we also need additional measures to reset the circuit breaker after the supplier resumes service. A feasible approach is for the circuit breaker to periodically detect whether the supplier's service has been restored, and once restored, set the status to close. The circuit breaker is in the half-open state when retrying.

The use of fuses is simple and powerful. Just use a @Breaker annotation. Swoft fuses can be used in any scenario, such as service calls. When using it at any time, you can circuit break and downgrade it when requesting a third party

<?php declare(strict_types=1);namespace App\Model\Logic;use Exception;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Breaker\Annotation\Mapping\Breaker;/**
 * Class BreakerLogic
 *
 * @since 2.0
 *
 * @Bean()
 */class BreakerLogic{    /**
     * @Breaker(fallback="loopFallback")
     *
     * @return string
     * @throws Exception
     */
    public function loop(): string
    {        // Do something
        throw new Exception(&#39;Breaker exception&#39;);
    }    /**
     * @return string
     * @throws Exception
     */
    public function loopFallback(): string
    {        // Do something
    }
}

Service current limiting

Current limiting, circuit breaking, downgradingThis cannot be emphasized enough. , because it is indeed important. When service fails, the fuse must be disconnected. Current limiting is the biggest tool to protect yourself. If there is no self-protection mechanism, no matter how many connections there are, it will be received. If the backend cannot handle it, the frontend will definitely hang when the traffic is very large.

Current limiting is to limit the number of concurrency and requests when accessing scarce resources, such as flash sales and rush-sale products, thereby effectively cutting peaks and smoothing the traffic curve. The purpose of current limiting is to limit the rate of concurrent access and concurrent requests, or to limit the rate of requests within a time window to protect the system. Once the rate limit is reached or exceeded, the service can be denied, or queued and waited.

Swoft The bottom layer of the current limiter uses the token bucket algorithm, and the bottom layer relies on Redis to implement distributed current limiting.

Swoft speed limiter can not only limit the current controller, but also limit the methods in any bean, and can control the access rate of the method. Here is a detailed explanation with the following usage example

<?php declare(strict_types=1);namespace App\Model\Logic;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Limiter\Annotation\Mapping\RateLimiter;/**
 * Class LimiterLogic
 *
 * @since 2.0
 *
 * @Bean()
 */class LimiterLogic{    /**
     * @RequestMapping()
     * @RateLimiter(rate=20, fallback="limiterFallback")
     *
     * @param Request $request
     *
     * @return array
     */
    public function requestLimiter2(Request $request): array
    {
        $uri = $request->getUriPath();        return [&#39;requestLimiter2&#39;, $uri];
    }    
    /**
     * @param Request $request
     *
     * @return array
     */
    public function limiterFallback(Request $request): array
    {
        $uri = $request->getUriPath();        return [&#39;limiterFallback&#39;, $uri];
    }
}

key This supports symfony/expression-language expressions. If the speed is limited, the limiterFallback defined in fallback will be called. Method

Configuration Center

Before talking about the configuration center, let’s talk about the configuration file. We are not unfamiliar with it. It provides us with the ability to dynamically modify program running capabilities. To quote someone else's words:

Dynamic adjustment of flight attitude during system runtime!

I might call our job repairing parts on a fast-flying aircraft. We humans cannot always control and predict everything. For our system, we always need to reserve some control lines to make adjustments when we need to control the system direction (such as grayscale control, current limit adjustment). This is especially important for the Internet industry that embraces changes.

For the stand-alone version, we call it the configuration (file); for the distributed cluster system, we call it the configuration center (system);

What is the distributed configuration center

With the development of business and the upgrade of microservice architecture, the number of services and program configurations are increasing (various microservices, various server addresses, various parameters), and the traditional configuration file method and database method are Developers' requirements for configuration management can no longer be met:

  • 安全性:配置跟随源代码保存在代码库中,容易造成配置泄漏;
  • 时效性:修改配置,需要重启服务才能生效;
  • 局限性:无法支持动态调整:例如日志开关、功能开关;

因此,我们需要配置中心来统一管理配置!把业务开发者从复杂以及繁琐的配置中解脱出来,只需专注于业务代码本身,从而能够显著提升开发以及运维效率。同时将配置和发布包解藕也进一步提升发布的成功率,并为运维的细力度管控、应急处理等提供强有力的支持。

关于分布式配置中心,网上已经有很多开源的解决方案,例如:

Apollo是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

本章以Apollo 为例,从远端配置中心拉取配置以及安全重启服务。如果对 Apollo 不熟悉,可以先看Swoft 扩展 Apollo 组件以及阅读 Apollo 官方文档。

本章以 Swoft 中使用 Apollo 为例,当 Apollo 配置变更后,重启服务(http-server / rpc-server/ ws-server)。如下是一个 agent 例子:

<?php declare(strict_types=1);namespace App\Model\Logic;use Swoft\Apollo\Config;use Swoft\Apollo\Exception\ApolloException;use Swoft\Bean\Annotation\Mapping\Bean;use Swoft\Bean\Annotation\Mapping\Inject;/**
 * Class ApolloLogic
 *
 * @since 2.0
 *
 * @Bean()
 */class ApolloLogic{    /**
     * @Inject()
     *
     * @var Config
     */
    private $config;    /**
     * @throws ApolloException
     */
    public function pull(): void
    {
        $data = $this->config->pull(&#39;application&#39;);        
        // Print data
        var_dump($data);
    }
}

以上就是一个简单的 Apollo 配置拉取,Swoft-Apollo 除此方法外,还提供了更多的使用方法。

官方链接

  • Github
  • Doc
  • swoft-cloud/community

推荐学习:php视频教程

The above is the detailed content of How to implement microservices using PHP?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete