Old topic: Re-look at the session that felt very difficult then.

  cookie, php, redis, session

Original address:https://t.ti-node.com/thread/ …

This is basically an old topic. Almost all phper will be asked about the session during the first interview. If there is no accident, it is usually as follows:

  1. What is php’s session
  2. Where does php’s session exist and when does it expire
  3. What is the difference between php’s session and cookie?

These three questions can be called the three basic questions about php session. If you don’t master them well, it will directly lead to the interview hanging up, which makes you sad.

A brief review of the above three issues:

  1. Session is translated into Chinese, which is probably a conversation. We know that the http protocol is a stateless protocol, which is expressed in extremely rude dialect, that is, “you don’t know which calf initiated this http request” or “you never know whether the end of this http request was the last Husky or the last fat man”, so in order to solve this problem, php introduces session to additionally mark “who initiated this http request”. In php, php generates a random session id for each different user, and everyone has a different session id. The user is identified by session id in every interaction with the server. It is very easy for php to generate a session. Just call the session_start () function directly. The following figure is the generated session file:


Where sess is the file prefix followed by “njjf8l3lh”**ff6 “is your session id. But now the content of the session file is empty, if we use the following code, we can generate the content of the session file:

<?php
// 开启session
session_start();
$_SESSION['hello'] = 'world';

Refresh the webpage, and then check the original session file again, which will have the following contents:

In other words, what you save to the global variable $_SESSION is essentially PHP text stored to you on the server. The server reads the corresponding session file according to your session id and then reads out the contents, and you will get your $_SESSION data.

  1. The session of php is stored in the system disk in the form of files by default. In php 7.0.28 running in ubuntu 16.04 system, the session is stored in the /var/lib/php/sessions folder, which can be checked and confirmed by session.save_path in php.ini configuration file. The expiration time of php is determined by the php configuration item session.gc_maxlifetime. the unit of value is seconds, and the default is 1440. that is to say, the session file is expired when the last modification time of the session file exceeds 1440 seconds.It is worth noting that expiration does not mean that this session file will be deleted by the garbage collection mechanism immediately, or it may remain for a period of time.So, when will it be deleted? This depends on the two configuration items session.gc_probability and session.gc_divisor. The ratio of these two options (session.gc _ probability/session.gc _ divider) is the probability of triggering the garbage collection mechanism. For example, (1/100) can be simply and roughly understood as “for every 100 requests generated, the php garbage collection mechanism will be triggered once to delete the expired session file”. Therefore, you remember: if you want an accurate expired session file in php, at least the default session configuration is absolutely impossible. On the other hand, it is not all because php has not started a single thread or process to scan for garbage, so it can only use this “probability” crude method to solve this problem, and it is not that it cannot be used..
  2. At the beginning, it was said that in order to understand the question of “whether it is husky or fat”, additional marking data had to be introduced, so in fact, the cookie before the session was created to solve the problem. The feud between the two lies in:

    • Cookie exist at the client, while the session exists at the server, so the session is relatively safer.
    • The server can read the session and cookie, but the client (that is, the browser) can only read the cookie.
    • By default, a cookie is indispensable to a session. In the final analysis, “safe session usage” must rely on cookies to mix meals. Because session id is saved by cookie, the client browser will carry the cookie every time it sends a request. the default name of the cookie is PHPSESSID, and the value is session id.
    • If the cookie is not available, then the session is not really unavailable. When cookie is disabled, session can be delivered by URL through configuration, i.e. query string is directly exposed to the URL, which is very unsafe and frightening. this method is not recommended and should even be directly disabled!
    • Cookie size is slightly limited (localstorage is said to be considered instead? ), session is relatively loose

This is about it. I don’t want to repeat it. I suggest you cooperate with php.ini file to study the above three problems.

If you really only look back at these three questions, isn’t it true that you should “look at the title like a tiger and open the content 1-5”? As I said, I am a serious blog website and a real php cultural website with some connotations. I can’t just talk about some elementary content, but a topic that must be filled with something that looks high-end anyway.

Just now, the default configuration is that the session is stored in a folder of the server in the form of a text file. Those who are interested should know that “too many files in a directory will reduce the reading efficiency”. Therefore, when using some PC software, you can see that these software will scatter the data needed by TA to different sub-directories. Php’s session file can do the same, which is generally relatively simple and crude. We need to focus on the following two php configuration items:

  • One is session.save_handler. The default value of this product is “files”, that is, files.
  • One is session.save_path. the default value of this product is a directory path, such as /var/lib/php/session. Now we change this value to something similar to session.save_path = “N; /path “is like this, where n is a positive integer, and the meaning of this value is to divide the directory into several levels, for example, we modify it to session. save _ path =” 2; /var/lib/php/sessions “,then restart apache or fpm process manager and execute the following code:
<?php
echo "let rock session";
session_start();

Refresh the webpage, as shown in the following figure:

The reason for the error is compared with what everyone has seen, which probably means that the folder “/var/lib/php/sessions/n/j/” does not exist, then switch to this directory and take a look, as shown in the following figure:

It was empty, which means that there is no sub-directory of /n/j, which seems to have to be created manually. However, you really can’t create it manually, because where do you know the name of the folder? Returning to a study of the configuration file, the following English words were found near the session.save_path configuration item:

; NOTE 1: PHP will not create this directory structure automatically.
;         You can use the script in the ext/session dir for that purpose.
; NOTE 2: See the section on garbage collection below if you choose to
;         use subdirectories for session storage

English is rather poor, probably translated, more inclusion:

; NOTE 1: PHP压根不会帮你创建这些文件夹,您自己个儿下载php源码包,到ext目录的session目中去找那个脚本去创建
; NOTE 2: 如果你要用子目录存储session的话,记得看下垃圾回收,不看就有坑。(坑在这里直接告诉大家吧,大概就是说你要自己搞子目录存session,那我那个靠信仰和概率才能触发的垃圾回收机制就压根就不触发了,你自己想办法搞定你的过期session,我不管了)

Therefore, we download a php source package, preferably the same php source package as the version of your running environment and decompress it. The command line is cut into ext/session directory, as shown in the following figure:

See that mod_files.sh? This is the script under Linux. Bat is for windows. Add execute permission to this script chmod +x mod_files.sh, and then check the following usage:

In order to help readers with myopia, friendship translation of usage:

./mod_files.sh 'session文件根目录' 目录深度 哈希函数比特量
对应我的php开发环境就是:
./mod_files.sh /var/lib/php/sessions/ 2 5
其中第一项就是你存储session的根目录,第二项就是那个N,第三项查看session.hash_bits_per_character配置项

Then execute, as shown in the following figure:

At this time, check in /var/lib/php/sessions, and there is indeed a directory. then, refresh the webpage again, and you may still encounter errors if you thought it was going well, as follows:

session_start(): open(/var/lib/php/sessions/n/j/sess_njjf8l3lhfrpq8nrlnl1d9qff6, O_RDWR) failed: Permission denied (13)

Vaguely recognize the letters Permission denied, which seems to be a problem of permission. Is it because the current apache process user or fpm process user does not have permission to write data to these directories? Change the owner of these directories to www-data (the user who runs fpm in my system) and try again. it is really good!

There are always unruly people who think that this can solve a lot of problems, but sadly, it is not. The current plan can solve the problem of too many session files to some extent, but there are still two problems that have not been solved:

  1. Is still a file storage, if the traffic is too large, sessIOn file read io from the hard disk may become the bottleneck of the program, of course SSD speed will be much better
  2. If the website is deployed to two servers respectively, the session cannot be shared and a failure occurs. What do you mean? In order to ensure high availability, the website program is installed on server A and server B respectively, and then the outermost nginx block is used at the front to balance the load. A certain http request from passerby A may be assigned to server A or server B. The session file generated by passer-by a on a will be saved to the hard disk of server a, but not on server b, if the user request is called to b, unfortunately, the session is lost, and some data will be lost, and passer-by a will probably scold customer service. In other words, server a and server b need to share the same session!

Therefore, a problem is introduced, that is, how to solve the problem of session sharing in distributed web deployment!

I won’t sell imprison son son, boring, the first thought is redis, for A and B to provide a C redis server, so that you can “how fast and save” to solve the problem at one stroke! According to the expectation, the introduction of redis can successfully solve three problems:

  • Memory level read and write speed, swish swish swish!
  • Session is easy shared, even if the service server continues to scale out to server d in the future
  • The expiration of the session can finally be accurate to seconds, saying no, no, no longer relying on faith and probability

The following two php configurations need to be corrected to store the session in redis. First, set session.save_handler = redis. Second, set session. Save _ Path = “TCP://127.0.0.1: 6379”. Then restart apache or fpm and refresh the webpage. If the webpage does not report any errors, theoretically the session data has already been sent to redis. Connect redis to check the key, as shown in the following figure:

From top to bottom, I executed a total of five redis commands, respectively:

  1. Look at all keys to get the session file name php assigned to me.
  2. Get the rest of the time for this key. redis the key is invalid after it expires.
  3. Looking at the data type of this key, you can see that it is string type.
  4. Use get to directly get the value of string
  5. After a period of time, I refreshed the webpage again, and then looked at the rest of the key with ttl again, which was extended to 1440 seconds again.

In addition to redis (memcache I won’t give an example, similar to redis), there is another scheme that is implemented through nfs sharing. The general principle is to get a server that is open to all php service servers for reading and writing through intranet sharing. As we all know, disks under linux can be mounted under a certain folder, so mount nfs under a certain directory of each php service server, and then modify the response configuration according to the above article. This, I have not tried it and I am too lazy to try it myself, so I’ll just give you a link if I’m lazy. It’s an article on Lao Ye’s blog.IMySQL | Lao ye teahouse, PHP implements NFS sharing of multi-server session sharing.

If you have any questions, please leave a message immediately.