In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Php-msf source code introduction, I believe that many inexperienced people do not know what to do, so this article summarizes the causes of the problem and solutions, through this article I hope you can solve this problem.
From an engineering point of view, this project is mainly distinguished from the above architecture. in addition to dealing with the core business, that is, the above functions / features, engineering also involves security / testing / coding specifications / language features and so on. these are also the parts that usually think less and practice less when writing business code.
The use of tools, I recommend the combination I use now: phpstorm + Baidu brain map + Markdown notes + blog and php-msf Yuanyuan and other writing technology life-related blog again and everyone eight, directly served.
Life cycle & Architecture
The official document makes a very good picture: the flow chart of processing requests. Recommend colleagues to make similar pictures in their spare time, which is very helpful to thinking.
To think about lifecycle-architecture in terms of this diagram, without going into it here, let's take a look at some of the technical points in msf:
Knowledge related to cooperative process
Excerpt of technical points in msf
Cooperative process
I will explain it in my way, if you need to know more, you can see the resources I recommend later.
Vs-like objects are a set of very important concepts. Class represents our abstraction of things, and this abstract ability will be used all the time in the future. I hope everyone will consciously cultivate awareness in this area, at least play a role in analogy. The object is the instantiated class, is the real work, we are going to discuss the collaborative process, is such a real working role.
Where does Xiecheng come from, where to go, and what does it do?
If you think about these simple questions, maybe you will have a deeper understanding of the cooperative process. Remember these key words:
Produce. You need a place to generate collaboration. You may not need to know the details, but you need to know when it happened
Dispatch. There must be a lot of cooperative programs working together, so it needs to be dispatched, how to schedule it?
Destroy. Will it be destroyed? When will it be destroyed?
Now, let's take a look at the comparison of the way the program is used. Note here that I didn't compare it with the way the program is implemented, because most of the time, the requirements actually look like this:
I don't care how to achieve it, I choose the one that works best.
/ / msf-single cooperative scheduling $response = yield $this- > getRedisPool ('tw')-> get (' apiCacheForABCoroutine'); / / msf-concurrent cooperative call $client1 = $this- > getObject (Client::class, ['http://www.baidu.com/']);yield $client1- > goDnsLookup (); $client2 = $this- > getObject (Client::class, [' http://www.qq.com/']);yield $client2- > goDnsLookup (); $result [] = yield $client1- > goGet ('/') $result [] = yield $client2- > goGet ('/')
It's roughly an equation like this: use Synergy = plus yield, so just figure out where you need to add yield-there are places that block IO, such as file IO, network IO (redis/mysql/http), etc.
Of course, there are things that need to be paid attention to.
The scheduling order of co-programs, if not paid attention to, may degenerate into synchronous calls.
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 no yield is added, it becomes synchronous execution
Compare swoole2.0 's collaborative solution:
$server = new Swoole\ Http\ Server ("127.0.0.1", 9502, SWOOLE_BASE); $server- > set (['worker_num' = > 1,]); / / $server- > on (' Request', function ($request, $response) {$tcpclient = new Swoole\ Coroutine\ Client (SWOOLE_SOCK_TCP) in the asynchronous callback function of the co-program server) / / need to use the cooperative program client $tcpclient- > connect ('127.0.0.1 packets, 9501 precinct 0.5) $tcpclient- > send ("hello world\ n"); $redis = new Swoole\ Coroutine\ Redis (); $redis- > connect (' 127.0.0.1 records, 6379); $redis- > setDefer (); / / tagged delayed packet collection to achieve concurrent calls to $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 ()
Using swoole2.0 's collaborative program, the benefits are obvious:
No need to add yield.
There is no need to pay attention to the order of yield for concurrent call. Just use defer () to delay receiving packets.
However, there is no way to directly use a simple equation such as using co-program = plus yield. The above example requires the use of swoole server + swoole client:
Server generates a collaborator when an asynchronous callback is triggered
Client triggers cooperative scheduling
Destroy the protocol at the end of asynchronous callback execution
This leads to two problems:
What if it is not in the asynchronous callback of the swoole protocol server: use Swoole\ Coroutine::create () to explicitly generate the collaborator
What if you need to use other co-program Client: this is the goal of Swoole3, and Swoole2.0 can consider using co-program task as camouflage
In this way, it seems that it is easier to use Synergetic = plus yield? I don't think so. Add some points and consider for yourself:
Using yield, you still need to figure out the implementation of the PHP scheduler based on the php generator + yourself. If you want to use it without error, such as the scheduling sequence above, you still need to figure out how to implement it.
The native way of Swoole2.0 is actually easier to understand. You only need to know the timing of the generation / scheduling / destruction of the co-program.
Does frequent creation and destruction of protocols in asynchronous callbacks like Swoole2.0 consume performance?-- No, they are actually memory operations, which are much smaller than processes / objects.
Excerpt of technical points in msf
Msf has a lot of excellence in design, and a lot of code is worth using for reference.
Request context Context
This is a very important concept from fpm to swoole http server. Fpm is a multi-process mode. Although variables such as $_ POST are called hyperglobal variables, these variables are isolated among different fpm processes. But in swoole http server, a worker process processes multiple requests asynchronously, which is simply understood as the following equation:
Fpm worker: http request = 1: 1swoole worker: http request = 1: n
Therefore, we need a new way to isolate request.
In programming languages, there is a professional word scope (scope). Scope/ lifecycle is usually used, so the concept of lifecycle that I have been emphasizing is really important.
Swoole itself implements isolation:
$http = new swoole_http_server ("127.0.0.1", 9501); $http- > on ('request', function ($request, $response) {$response- > end ("Hello Swoole. #" .rand (1000, 9999). "); $http- > start ()
Msf also makes a layer of encapsulation on Context to make Context seem to do whatever it wants:
/ / you can almost complete any required logic $this- > getContext ()-> xxxModule- > xxxModuleFunction () in this way.
For details, please see the src/Helpers/Context.php file.
Object pool
The concept of object pool may be unfamiliar to you. The goal is to reduce the frequent creation and destruction of objects in order to improve performance. Msf is well encapsulated and easy to use:
/ / getObject () will be fine / * * @ var DemoModel $demoModel * / $demoModel = $this- > getObject (DemoModel::class, [1,2])
The specific code of object pool is under src/Base/Pool.php:
The bottom layer uses reflection to realize the dynamic creation of objects.
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::DS_PUBLIC; unset ($reflector); return $obj;}}
Use 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 Pool & Agent
Connection Pool Pools
The concept of connection pooling will not be discussed in detail. Let's look directly at the implementation in msf. The code is under src/Pools/AsynPool.php:
Public function _ _ construct ($config) {$this- > callBacks = []; $this- > commands = new\ SplQueue (); $this- > pool = new\ SplQueue (); $this- > config = $config;}
The SplQueue is used here to manage connections and commands that need to be executed. Compare it with the above and think about why one uses SplStack and the other uses SplQueue.
Agent Proxy
Proxy is a further encapsulation based on connection pooling. Msf provides two encapsulation methods:
Master-slave master slave
Cluster cluster
Look at the code in the sample App\ Controllers\ Redis:
Class Redis extends Controller {/ / Redis connection pool read and write example public function actionPoolSetGet () {yield $this- > getRedisPool ('p1')-> set (' key1', 'val1'); $val = yield $this- > getRedisPool (' p1')-> get ('key1'); $this- > outputJson ($val);} / / Redis proxy usage example (distributed) public function actionProxySetGet () {for ($I = 0; $I getRedisProxy (' cluster')-> set ('proxy'. $I, $I);} $val = yield $this- > getRedisProxy ('cluster')-> get (' proxy22'); $this- > outputJson ($val);} / / Redis agent usage example (master / slave) public function actionMaserSlaveSetGet () {for ($I = 0; $I getRedisProxy ('master_slave')-> set (' M'. $I, $I);} $val = yield $this- > getRedisProxy ('master_slave')-> get (' M66'); $this- > outputJson ($val);}
An agent is to make further trouble on the basis of connection pooling. Take the master-slave mode as an example:
Master-slave strategy: read master library, write slave library
What the agent does:
Judge whether it is a read operation or a write operation, select the appropriate library to execute
Public library
Msf pursues the practice of public library, hoping that different functional components can be plugged and plugged. This can be seen in the laravel framework and the symfony framework, both of which are composed of the core of the framework and each package. I highly recommend this idea, but if you take a closer look at the Baidu brain map-php-msf source code to interpret this map, you will find that the dependency between classes, layering / boundary is not good. If you read my previous blog-laravel source code interpretation / blog-yii source code interpretation, the comparison will be obvious.
However, this does not mean that the code is bad, at least functional code, almost all good code. The sense of superiority established outside the function is more of a yearning for a better life-it could be better.
AOP
Php AOP extension: http://pecl.php.net/package/aop
Introduction to PHP-AOP extension | rango: http://rango.swoole.com/archives/83
AOP, aspect-oriented programming, Han boss's blog-PHP-AOP extension introduction | rango can take a look.
If you need to know a new thing, first look at what it does:
AOP separates business codes from business-independent codes. Scenarios include logging / performance statistics / security control / transaction handling / exception handling / caching, etc.
Here is a quote from the official account article of programmer DD-Zhai Yongchao to let you feel:
Also CRUD, do not use AOP
@ PostMapping ("/ delete") public Map delete (long id, String lang) {Map data = new HashMap (); boolean result = false; try {/ / language (different in English and Chinese) Locale local = "zh" .equals IgnoreCase (lang)? Locale.CHINESE: Locale.ENGLISH; result = configService.delete (id, local); data.put ("code", 0);} catch (CheckException e) {/ / Parameter check error. This kind of exception belongs to known exception and does not need to print stack. The return code is-1 data.put ("code",-1); data.put ("msg", e.getMessage ()) } catch (Exception e) {/ / other unknown exceptions need to be printed for stack analysis. The return code is 99 log.error (e); data.put ("code", 99); data.put ("msg", e.toString ());} data.put ("result", result); return data;}
Use AOP
@ PostMapping ("/ delete") public ResultBean delete (long id) {return new ResultBean (configService.delete (id));}
The code uses only one line and requires a lot of features. do you want to write this kind of CRUD code?
Profile management
Let's first clarify the pain points of configuration management:
Whether to support hot updates, resident memory needs to be considered.
Consider different environments: dev test production
Easy to use
Hot can actually be regarded as the overall demand of resident memory servers. At present, the common solution of php is inotify, you can refer to my previous blog-swoft source code interpretation.
Msf uses third-party libraries to parse and process configuration files. Here we highlight a detail of array_merge ():
$a = ['a'= > ['a1'= >'a1',]]; $b = ['a'= > ['b1'= >'b1',]]; $arr = array_merge ($a, $b); / / Note that array_merge () does not circularly 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 looks simpler in laravel, but actually loads the function through composer autoload, which wraps the actual operation. As for whether or not to do so, it depends on your own needs.
Write at the end
The most complex part of msf is in the service startup phase, and the inheritance is also long:
Child-> Server-> HttpServer-> MSFServer-> AppServer, you can challenge if you are interested.
Another difficult point is the principle of MongoDbTask implementation.
Msf also encapsulates a lot of useful functions, RPC / message queue / restful, you can explore according to the documentation.
After reading the above, have you mastered the method of introducing the source code of php-msf? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.