Home > Article > Backend Development > How to implement microservices using PHP?
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.
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.
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.
So what are the bright features of using Serviceization
?
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
So is there any good solution? The answer is yes, and many people are using this framework, which is -
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 similarGolang
Performance, the following is the stress test of Swoft
performance on my PC
.
ab
Stress test processing speed It’s amazing. With i78 generation
CPU, 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,
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 * [ * 'host:port', * 'host:port', * 'host:port', * ] */ public function getList(Client $client): array { // Get health service from consul $services = $this->agent->services(); $services = [ ]; return $services; } }
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('Breaker exception'); } /** * @return string * @throws Exception */ public function loopFallback(): string { // Do something } }
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 ['requestLimiter2', $uri]; } /** * @param Request $request * * @return array */ public function limiterFallback(Request $request): array { $uri = $request->getUriPath(); return ['limiterFallback', $uri]; } }
key This supports symfony/expression-language
expressions. If the speed is limited, the limiterFallback defined in
fallback will be called.
Method
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);
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('application'); // Print data var_dump($data); } }
以上就是一个简单的 Apollo 配置拉取,Swoft-Apollo
除此方法外,还提供了更多的使用方法。
推荐学习: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!