Case detailed PHP-MSF source code

Source: Internet
Author: User
Tags reflector
This article mainly introduces the meaning of PHP-MSF source code and usage related problems, the need for friends follow the reference to learn it. Hope to help everyone.

Source interpretation also did a period of time, summed up his experience:

Grab the life cycle and let the code run in your head.

Analytic architecture, keyword layered boundary isolation

A good framework to understand the life cycle and architecture, the basic is already in the familiar state, followed by the fill details and coding proficiency

Here are a few more important tips:

Figure out what the tool is good at and what it's for. This information is also very easy to obtain, the documentation of the tool is usually marked out, you can use these features/features, try to point to meet

Looking at this project from an engineering point of view, primarily in line with the above architecture, in dealing with the core business, which is the function/feature above, engineering also involves security/testing/coding Specifications/language features, which are often less thought-out and less practiced when writing business code

The use of tools, recommended I now use the combination: Phpstorm + Baidu Brain Map + markdown notes + blog and the origin of PHP-MSF and other writing technology life-related blog to come and everyone eight, direct serving.

Life Cycle & Architecture

The official document produced a very good picture: Process the request flowchart. Recommend colleagues, have leisure time make similar diagram, to thinking very helpful.

Considering the life cycle & architecture based on this diagram, here's a look at some of the technical points in MSF:

Related knowledge of the association process

Extracts from technical points in MSF

Co-process

I will use my way to explain, if you need to know more, you can look at the resources I recommend later.

The class vs object is a very important set of concepts. class represents our abstraction of things, this abstract ability will be used in our future, I hope you consciously cultivate this aspect of consciousness, at least can play a role in comprehend by analogy. The object is the instantiated class, is really working, we want to discuss the process, is such a real working role.

Where does the co-process come from and where to go, and what does it do?

Think about these simple questions, perhaps your understanding of the process is even deeper, remember these keywords:

Produce. There needs to be a place to generate the co-process, you may not need to know the details, but need to know when it happened

Scheduling. There must be a lot of work together, so need to dispatch, how to dispatch it?

Destroyed. Will it be destroyed? When will it be destroyed?

Now, let's take a look at how the association is used, and notice here that I'm not comparing it with the implementation of the process, because in many cases the requirements are actually:

How to realize I don't care, I choose the best use.

MSF-Single-session Scheduling $response = yield $this->getredispool (' tw ')->get (' apicacheforabcoroutine ');//MSF-concurrent call $client1 = $this->getobject (client::class, [' http://www.baidu.com/']); yield $client 1->godnslookup (); $client 2 = $this- >getobject (Client::class, [' http://www.qq.com/']); yield $client 2->godnslookup (); $result [] = yield $client 1- >goget ('/'); $result [] = yield $client 2->goget ('/');

This is roughly the equation: using the covariance = plus yield, it's good to know where to add yield-where there is blocking IO, such as file io, network io (redis/mysql/http), and so on.

And, of course, there's a need for attention.

The scheduling sequence of the schedule, if not noticed, may degenerate into synchronous invocation.

Call chain: Yield is required on the call chain that uses yield. such as the following:

function A_test () {  return yield $this->getredispool (' tw ')->get (' Apicacheforabcoroutine ');} $res = yield a_test (); If yield is not added, it becomes synchronous execution.

Compare the swoole2.0 solution:

$server = new Swoole\http\server ("127.0.0.1", 9502, Swoole_base), $server->set ([' worker_num ' = 1,]);//need to be in the co-process serv In the async callback function of ER, $server->on (' Request ', function ($request, $response) {$tcpclient = new Swoole\coroutine\client (swoole_ SOCK_TCP);  You need to use the co-client $tcpclient->connect (' 127.0.0.1 ', 9501,0.5) $tcpclient->send ("Hello world\n");  $redis = new Swoole\coroutine\redis ();  $redis->connect (' 127.0.0.1 ', 6379); $redis->setdefer ();  Label delay Packet, implement concurrent call $redis->get (' key ');  $mysql = new Swoole\coroutine\mysql (); $mysql->connect ([' Host ' = ' 127.0.0.1 ', ' user ' = ' user ', ' password ' = ' pass ', ' database ' =  ' Test ',]);  $mysql->setdefer ();  $mysql->query (' Select Sleep (1) ');  $httpclient = new Swoole\coroutine\http\client (' 0.0.0.0 ', 9599);  $httpclient->setheaders ([' Host ' = ' api.mp.qq.com ']);  $httpclient->set ([' Timeout ' = 1]);  $httpclient->setdefer ();  $httpclient->get ('/');  $tcp _res = $tcpclient->recv (); $Redis_res = $redis->recv ();  $mysql _res = $mysql->recv ();  $http _res = $httpclient->recv (); $response->end (' Test end ');}); $server->start ();

The benefits of using the swoole2.0 solution are obvious:

You don't have to add yield.

Concurrent calls do not have to pay attention to the order of yield, use defer () delay to receive packets

However, there is no way to directly use the association = Plus yield such a simple equation, the above example needs to be used in conjunction with the Swoole server + Swoole co-client:

Server generates a co-process when an asynchronous callback is triggered

Client-triggered co-scheduling

Destroying the coprocessor at the end of an asynchronous callback execution

This leads to 2 questions:

What to do in asynchronous callbacks that are not in the Swoole coprocessor: Use Swoole\coroutine::create () to explicitly generate a co-process

What to do if you need to use a different co-Client: This is the goal of Swoole3, Swoole2.0 can consider using a co-task to disguise

So it looks like it's a little easier to use the co-process = plus yield? I do not think so, to add some points of view, everyone's own discretion:

Using yield, based on PHP generator + self Implementation of the PHP co-scheduler, want to use it without error, such as the above scheduling sequence, you still need to figure out the implementation of this piece

Swoole2.0 's native way, it's easier to understand, just know the timing of the process generation/dispatch/destruction can be used well

Swoole2.0 is it a very lossy performance to create and destroy the co-processes frequently in asynchronous callbacks? --No, it's actually some memory operation, much smaller than the process/object

Extracts from technical points in MSF

MSF has a lot to do with design, and a lot of code is worth drawing on.

Request context

This is a very important concept from FPM to swoole HTTP server. FPM is a multi-process pattern, although variables such as $_post are called hyper-global variables, but these variables are isolated between different fpm processes. But in Swoole HTTP server, a worker process processes multiple requests asynchronously, and a simple understanding is the following equation:

FPM worker:http request = 1:1swoole Worker:http request = 1:n

So, we need a new way to isolate the request.

In the programming language, there is a professional vocabulary scope (scope). The scope/life cycle is usually used, so the concept of life cycle that I have been emphasizing is really important.

The swoole itself is isolated:

$http = new Swoole_http_server ("127.0.0.1", 9501), $http->on (' request ', function ($request, $response) {  $ Response->end ("

MSF also has a layer of encapsulation on the context that allows the context to look as it pleases:

You can almost use this method to complete any required logic $this->getcontext ()->xxxmodule->xxxmodulefunction ();

Details to view the src/helpers/context.php file

Object Pool

The concept of object pooling may be unfamiliar, with the aim of reducing the frequent creation and destruction of objects in order to improve performance, MSF is well encapsulated and easy to use:

GetObject () can be/** @var demomodel $demoModel */$demoModel = $this->getobject (Demomodel::class, [1, 2]);

The specific code for the object pool is under src/base/pool.php:

The underlying uses reflection to implement the object's dynamic creation

Public function Get ($class, ... $args) {  $poolName = Trim ($class, ' \ \ ');  if (! $poolName) {    return null;  }  $pool   = $this->map[$poolName]?? null;  if ($pool = = null) {    $pool = $this->applynewpool ($poolName);  }  if ($pool->count ()) {    $obj = $pool->shift ();    $obj->__isconstruct = false;    return $obj;  } else {    //Use reflection    $reflector     = new \reflectionclass ($poolName);    $obj        = $reflector->newinstancewithoutconstructor ();    $obj->__usecount  = 0;    $obj->__gentime  = time ();    $obj->__isconstruct = false;    $obj->__dslevel  = Macro::D s_public;    Unset ($reflector);    return $obj;  }}

Using Splstack to manage objects

Private Function Applynewpool ($poolName) {  if (array_key_exists ($poolName, $this->map)) {    throw new Exception (' The name is exists in Pool map ');  }  $this->map[$poolName] = new \splstack ();  return $this->map[$poolName];} Management Object $pool->push ($classInstance); $obj = $pool->shift ();

Connection Pooling & Proxy

Connection Pool Pools

The concept of connection pooling is not to be discussed, so let's look directly at the implementation in MSF, where the code is src/pools/asynpool.php:

Public function __construct ($config) {  $this->callbacks = [];  $this->commands = new \splqueue ();  $this->pool   = new \splqueue ();  $this->config  = $config;}

Here you use the Splqueue to manage connections and commands that need to be executed. Can compare with above, think about why one uses Splstack, one uses Splqueue.

Agent Proxy

Proxies are further encapsulated on the basis of connection pooling, and MSF provides 2 packages:

Master slave

Cluster cluster

View the code in the example App\controllers\redis:

Class Redis extends controller{  //Redis connection pool Read and write sample public  function Actionpoolsetget ()  {    yield $this Getredispool (' P1 ')->set (' Key1 ', ' val1 ');    $val = yield $this->getredispool (' P1 ')->get (' Key1 ');    $this->outputjson ($val);  }  The Redis agent uses the sample (distributed) public  function Actionproxysetget ()  {for    ($i = 0; $i <=, $i + +) {      yield $this ->getredisproxy (' cluster ')->set (' Proxy '. $i, $i);    }    $val = yield $this->getredisproxy (' cluster ')->get (' Proxy22 ');    $this->outputjson ($val);  }  The Redis agent uses the example (master-slave) public  function Actionmaserslavesetget ()  {for    ($i = 0; $i <=; $i + +) {      Yiel D $this->getredisproxy (' Master_slave ')->set (' M '. $i, $i);    }    $val = yield $this->getredisproxy (' Master_slave ')->get (' M66 ');    $this->outputjson ($val);  }}

The agent is the connection pool on the basis of further things. Take master-slave mode as an example:

Master-Slave Policy: Read the main library, write from the library
Agent to do things:

To decide whether to read or write, select the appropriate library to perform the operation
Public Library

MSF's approach to public libraries, in the hope that different functional components can be pluggable, can be seen in both the Laravel framework and the Symfony framework, which are made up of the framework core plus a package. This kind of thought I was very recommended, but carefully look at Baidu brain Map-php-msf Source interpretation of this map, you will find the class and the dependency between the class, layered/boundary does not do well. If you have read my previous Blog-laravel source interpretation/blog-yii source Interpretation, contrast will feel very obvious.

However, this does not mean that the code is not good, at least the functional code, almost all good code. The superiority created from outside the function is more of a longing for a better life-and a little better.

Aop

PHP AOP Extension: HTTP://PECL.PHP.NET/PACKAGE/AOP

PHP-AOP Extension Introduction | Rango:http://rango.swoole.com/archives/83

AOP, aspect-oriented programming, Han boss's Blog-php-aop extension Introduction | Rango can see.

Need not understand a new thing, first see what this thing has the function:

AOP, separating business code from business-independent code, scenarios such as logging/performance statistics/security control/Transaction processing/exception handling/caching, etc.
Here is a quote from the code in the public number of the programmer, DD-Suphing, to let everyone feel the following:

Also CRUD, not using AOP

@postmapping ("/delete") public map<string, object> Delete (long id, String lang) {map<string, object> data = NE W hashmap<string, object> (); Boolean result = false; try {  //language (Chinese and English hints differ)  Locale local = "zh". Equalsignorecase (lang)? Locale.CHINESE:Locale.ENGLISH;  result = Configservice.delete (ID, local);  Data.put ("code", 0); } catch (Checkexception e) {  //parameter checksum error, such exceptions are known exceptions, do not need to print the stack, the return code is-1  data.put ("code", 1);  Data.put ("msg", E.getmessage ()); } catch (Exception e) {  ///Other unknown exception, need to print stack analysis, return code is  log.error (e);  Data.put ("code");  Data.put ("msg", e.tostring ()); } data.put ("result", result); return data;}

Using AOP

@postmapping ("/delete") public resultbean<boolean> Delete (long id) {return new resultbean<boolean> ( Configservice.delete (ID));}

The code only uses one line, the required characteristics of a few, do you want to write such CRUD code?

Configuration file Management

Define the pain points for configuration management first:

Whether to support thermal updates, resident memory needs to be considered

Consider different environments: Dev Test production

Easy to use

Hot more actually can be regarded as the overall needs of the resident memory server, the current PHP common solution is inotify, can refer to my previous Blog-swoft source interpretation.

MSF uses third-party libraries to parse the processing configuration file, which focuses on a array_merge () detail:

$a = [' a ' = = [  ' A1 ' + ' A1 ',]]; $b = [' a ' = = ['  B1 ' + ' B1 ',]]; $arr = Array_merge ($a, $b);//Note, array _merge () does not loop merge Var_dump ($arr);//result Array (1) {["A"]=> Array (1) {  ["B1"]=>  string (2) "B1"}}

Configuration used in MSF:

$ids = $this->getconfig ()->get (' Params.mock_ids ', []);//Compare Laravel$ids = Cofnig (' Params.mock_ids ', []);

It seems to be simpler in laravel, in fact, the function is loaded by composer AutoLoad, which wraps a layer on the actual operation. If you want to do this, look for your own needs.

Written in the last

The most complex part of MSF is in the service startup phase, and the inheritance is long:

AppServer, Msfserver, Httpserver, Server---

Another difficult point is the mongodbtask implementation principle.

MSF also encapsulates a number of useful features, RPC/Message Queuing/restful, which you can explore with your own documentation.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.