The article will be short and messy - I am writing it with the purpose of passing a couple of hours before starting to roll back the site to the previous “normal” state.
This story began five hours ago. I was approached by the owner of one thematic news site. Subject - sporting events. The site has two problems. First, at the moments of large and highly anticipated contests, the number of visitors to the site increases by an order of magnitude. The second problem - it is made on WordPress, and rather casually. I think that initially it was a normal WP-site. But then he repeatedly “worked out”: wherever different ad units stuck, they entered new “solutions”, put all sorts of plugins for “optimization” and expansion of opportunities. In addition, every day, for several years, about a dozen posts appeared. The database size is several gigabytes, the 'upload' goes to tens of gigabytes. Over time, the site turned into something like this:
And here, somewhere in 0.00 in Moscow, the site begins to fall under the influx of sports enthusiasts. The main page then gives the code 500, then it loads for more than a minute. I suspect that the periods of such “raids” of visitors are the most bread time for such resources: clicks, bets and all that. The owner is nervous, which, in general, is understandable. And so it turns out that of those who are awake this Saturday night and understand something in web development, the owner has only me.
')
And then the next problem. I, to put it mildly, do not really like WordPress. And, worst of all, I don’t know much about it. Perhaps, therefore, I do not like, because I do not know how to cook it correctly. But the fact remains that up to this point I have never dealt with any major projects that are based on it. Of course, I met with personal blogs and websites of small offices on WP, where several hundred visitors a day are a blessing. There he coped well, no problem. But there were no special reasons to find out how it works with resources and how to ensure its normal performance was not there. Works and works.
But in this situation, you need to solve the problem of its performance. And very quickly. There is no time for reading manuals, there is no special knowledge and skills either. What to do? Then I start to get nervous - the mood of the site owner is transmitted.
Of course, the first thought is to follow the path of least resistance. Those. just switch to the older, more “powerful” fare. The site is hosted on VDS. And here it turns out that this method will not work: the transition to large resources -
only on request in those. hosting support. Deadline - from a few hours. Hoster explains this with KVM virtualization. Ok, this option is not suitable. Simultaneous calls in support and reading the site host takes about five minutes.
The next version that goes through my head: “WordPress is famous for its plugins. I even remember the names of two plugins for caching: WP Super Cache and WP Fastest Cache. ” As I learn later, both are included in all sorts of lists like "Top 10 caching plugins for WP", etc. I suspect that installing plugins on a constantly falling site is a very unpleasant task. Therefore, the site for about five minutes only works for me. I quickly put the first plugin, run over the settings - everything seems ok. I include the site for all visitors. The result is ... Zero. Perhaps something has improved, but it is like a dead poultice - improving imperceptibly with the naked eye. The site stubbornly continues to fall. Bad choice of plugin? Even faster, I press the buttons and put the second plugin. The result ... Yes, the same. Worn down and this plugin. All these manipulations take me almost fifteen minutes.
I suspect these plugins work fine. They have thousands and thousands of users and most of them are obviously happy. But my patient does not respond to them. Perhaps the reason is in its neglected internal state. In any case, this option is rejected - to understand what and why there does not work once.
The owner continues to send nerve letters. I am already going to answer that, despite all the efforts, it will not be possible to save the patient today and I will go on a date with a pillow. Unless, of course, it has not yet captured his wife. And here one more thought comes to mind.
Hands begin to search and download a clean distribution of WP, and the head to think. Before my eyes stands the image of an uncle, who often (and rather mischievously) loved to tell me during my youth: “Knowledge of a few principles often replaces knowledge of many facts.” And that's what I thought:
- All requests for the issuance of pages of the site, most likely, pass through some single "entry point", the router. There it is determined (or begins to be determined) what and in what order will be further connected / reckoned / withdrawn.
- Then, in fact, everything connects, counts and, unfortunately, is displayed. It is here, most likely, there is a devouring of resources. On endless queries to the database and other horrors.
- The horrors end, and the results at some "exit point" are given to the user.
And if this is at least something like this, then you can apply a caching system, which I call the "Ax". In addition, on this site, all visitors are given the same page in appearance. Those. A specific URL corresponds to a page that will look the same for any user. Well, except for those that are logged in to the admin. WP panels, but they do not count. Now it's just me.
Now you need to find the above-mentioned point "entry" and "exit". The “login” is found in the /index.php file. In which it is honestly written: "This file doesn’t do anything, but loads ...". Wonderful. The “exit point” is harder, but I remember that I heard something about the “shutdown” event in WP that runs after everything. A quick search for a clean distribution I find the “shutdown_action_hook” function in /wp-includes/load.php. Even faster, by writing an echo inside it, I check where in the page it will output “GoldenAxe!”. In the end. Fine! The sought points were found, it all took about 10 minutes. Now you need to somehow implement a very simple logic:
- When you first access the page, it is generated as usual. After all the output is generated, it will need to be written to a separate file. It should happen at the "exit point". The file will need to be written to the / _cache / folder. The file name will look like this: md5-hash URL of the page (without parameters), which is requested. Since this is the only parameter on which the appearance of the displayed page depends, this is quite enough.
- During the second access to the page at the “entry point”, we will check if the necessary folder in the folder with the cache files is available (with the corresponding requested URL md5-name). If there is - immediately read from it and display the result.
Everything. Whole system. It remains only to figure out how to collect the output. As many know, WP templates are a hell of a mixture of HTML and PHP. Those. they always contain constructions like:
<?php if($Some==1) echo '<div class="novost">'; else echo '<div class="statya">'; ?> <div class="item"></div> </div>
I think it's terrible. But so it is. Thus, we do not have some $ Content variable in which the entire content of the page would be collected before output and only then displayed once using the same “echo”. We have hundreds of these “echo” in the templates. And they need to somehow collect. Once upon a time, when I read the manual for PHP, I encountered the function “ob_get_contents ()” there. I never used it, but here it was useful. It returns the contents of the output buffer and goes to companies with the functions “ob_start ()” and “ob_end_clean ()”. The first turns on buffering, the second turns off and clears the buffer. All this I instantly google. Five more minutes passed. As a result, what code I put in the “entry point” and “exit point”:
<?php
Well, then it remained only to check the result. I deliberately left to myself the opportunity to request a page generated in a standard way (passing the “test” parameter for $ _REQUEST to the “entry point” in the URL). Having received the page output after caching with “Ax”, I compared it with the “standard” page output. I found a small difference - one js-script did not get into the cached version. The one that was responsible for loading additional posts to the list when clicking on the "show more posts" button. There was no time to figure out why it doesn’t fall into the output, so I just added the script call to the template. And it all worked.
Of course, the solution has a lot of flaws: if you add through the admin. panel new post, it will not be displayed in some lists. In those that are not loaded on this site using AJAX. For some reason, the count of post views has been incorrectly triggered. But all this stuff that you can survive a few hours.
And plus one, but big: the site has ceased to give the code 500 or wait for a response and the issuance of the page for a half minutes Now the output itself (page response) takes about 40 ms instead of 1.5 m and all users, without exception, can click on an advertisement. Of course, full page load takes more time: numerous non-optimized images, advertising scripts and other fonts do their job. But the eye is invisible. The site is fast.
On all the introduction of my "Ax" took no more than half an hour. Now I will go to shoot it and return the site to its original state. Sports competition is over, fans, and with them, and I, go to sleep.
Do not judge my decision too harshly. Remember that I took it under tight time constraints and without serious WordPress knowledge. Perhaps there was a more elegant and correct solution. If you know him - write in the comments. I can say that I felt like a veterinarian who had to operate on a person. Well, or vice versa. Good weather, friends!
Update . Reading the comments on the article, I realized that I could not clearly state the reason for its writing and draw the main idea. As a result, it seems to me, there was some misunderstanding between me and the readers. My fault. In my defense I will say that I wrote it already in a very salutary state.
This article is not about finding a truly correct solution under general conditions. It is about finding the optimal solution in the face of severe constraints: by time, by result and by knowledge. By knowledge, I mean not only my personal knowledge in the field of WP, which, I admit, is very superficial, but also information provided at my disposal. By “information” I mean, for example, various accesses. I had access to the files of the site itself and to the personal account on the site of the hoster. It mainly addresses the issues of payment and tariffs. At the same time I did not have access to the control panel by the server itself. With all that it implies. I didn’t come across this hoster before, so the order and features of its work were also a mystery to me.
Undoubtedly, the correct solution to the problem of this site in general looks like this: “we are looking for the causes of poor performance with the help of various tools and techniques. We prepare a local copy of the site. For a cup of tea we think about solutions, check them out. We update the working copy. We analyze its work and the effectiveness of updates. If necessary, make edits. Everything!".
In reality, I had an hour of time, a site losing visitors at the most unnecessary moment and a nervous owner. I did not have time to create a backup and a local copy (and, in fact, the very possibility of this). From here one more moment - I desperately did not want to hurt and break. This, as you know, would be a disaster. Therefore, another security requirement was his safety. Solutions such as removing already integrated plug-ins, in my opinion, do not meet this criterion. Even the installation of new ones, in general, did not arouse my delight.
Some of the commentators blame my curvature. Like, I could not put in the right places a tick in the settings of the WordPress plugin. With a 90% probability, this is not the reason. As I learned later, by comparing the net distribution of the same version of WP with the fact that there is on the site, even those WP files were corrected, which, as I understand it, are “system”. And they ruled very extensively. That, in theory, is completely unacceptable. Thus, the likelihood of full-time work of the system, which we call “WordPress”, is sharply reduced. Including the probability that it will regularly interact with caching plugins. In fact, in this case, we have a “black box”, some
custom project based on WP.
My decision is a
crutch . I am fully aware of this, as well as the fact that this decision is not something new or breakthrough and has certain disadvantages. At the same time, it was simple, safe and provided the necessary result: the availability of the site, its content and functionality for users at the time of peak loads. In addition, the crutch (due to simplicity) was easily and completely removed. I also acknowledge that having the opportunity and time to think and some additional information, I could have made another decision.
In general, the article is not so much about a specific technical solution, but about the situation itself. So I ask you to treat her. How to search for a fast, secure and satisfying solution in extreme conditions. And (I would like this) as an illustration on the theme “Knowledge of few principles often replaces knowledge of many facts.”