laravel开发总结(2)

1、避免使用select *

在laravel中,提供了Model::get()方法来获取实体对象,但是get()方法默认是使用的select *,我们知道,一条sql语句的时间一般由两部分组成,查询语句执行时间和结果传输时间。如果数据表的列比较多,且每一列的数据都不小,那么传输时间往往决定着整条sql语句的性能,减少不必要的字段传输,从而减少整个结果的传输量可以大大减少sql的总时间,进而提升性能。get()方法接受一个array来确定查询的字段。

$params = [
	'user_name',
	'email'
];
$users = User::where('delete_mark',false)->get(params);

那么此时返回的就只包含查询的user_nameuser\_nameemailemail两个字段。

2、修改了fpm的php.ini和fpm的配置文件后,最好使用fpm自带的语句启动一次

先使用php-fpm的方法运行,如果没有报错,转而使用service的方法
使用service的方法,如果php.ini配置出错,是不会有报错信息的,会让人误以为fpm启动成功了(本质上fpm确实启动成功了),
不过有很多必要的模块没有被加载进来。一般方法是直接找到Fpm的运行程序,例如:ubuntu在 /usr/sbin下面,然后执行

php-fpm7.3 -c /etc/php/7.3/fpm/php.ini
# -c 指定php配置文件位置(php.ini的位置) 
# -y 指定fpm配置文件位置
# 完整的例子如下
php-fpm7.3 -y /etc/php/7.3/fpm/php-fpm.conf -c /etc/php/7.3/fpm/php.ini

执行结果没有任何报错,那么可以确定php.ini是没有问题的。然后。执行

rm -f /run/php/php7.3-fpm.sock

中止fpm的运行,然后使用fpm服务打开

3、mysql设置自增id的起始值

这个方法在导数据的时候用得比较多,当甲方对数据不明确,导入的数据会被反复替换的时候,就可以使用此方法,重置自增的id。

alter table xxx_table AUTO_INCRMENT = 1;

4、缓存的生命周期

参考自 http缓存机制
主要在于cache-control这个header中起作用
在response的header中配置cache-control这个字段:可以告诉浏览器应该怎么去做

字段值 含义
no-cache 缓存必须重新校验
no-store 不存储缓存
no-transform 缓存内容时不能对改变任何数据
public 响应可被任何缓存区缓存
private 只在本地缓存,不允许任何中继缓存对其进行缓存(例如,浏览器可以缓存,但是CDN不能缓存)
must-revalidate 如果缓存的内容失效,请求必须发送到服务器以进行重新验证(请求失败返回504,而非中间缓存CDN)
proxy-revalidate 与must-revalidate类似,仅能用于共享缓存(如:CDN)
max-age 只接受 Age 值小于 max-age 值,并且没有过期的资源
s-maxage 仅能用于共享缓存,一般用在cache服务器上(如:CDN)

在request中header的配置cache-control字段,告诉服务器,我的缓存机制是如何的

字段值 含义
max-age 可以接收缓存最长时间
max-stale 可以接收过期的资源,但是过期时间必须小于 max-stale 值
min-fresh 可以接收一个更新过的资源,fresh生命期大于其当前 Age 跟 min-fresh 值之和
no-cache 在源服务器返回成功的验证之前不能使用缓存响应
no-store 直接禁止浏览器和所有中继缓存存储返回的任何版本的响应
no-transform 获取没有被转换过(比如压缩)的资源
only-if-cached 希望获取缓存内容而不发起请求
laravel中添加所有接口cache-control的方法

可以在中间件中加一个全局拦截添加cache-control的操作

nginx对缓存会做什么

利用请求的局部性原理,将请求过的内容在本地建立一个副本,下次访问时不再连接到后端服务器,直接响应本地内容
Nginx服务器启动后,会对本地磁盘上的缓存文件进行扫描,在内存中建立缓存索引,并有专门的进程对缓存文件进行过期判断、更新等进行管理
要使用缓存,首先要使用 proxy_cache_path 这个指令(必须放在 http 上下文的顶层位置),然后在目标上下文中使用 proxy_cache 指令
proxy_cache_path 有两个必填参数,第一个参数为 缓存目录,第二个参数keys_zone指定缓存名称和占用内存空间的大小

5、如何打印php到nginx的所有输出日志,方便定位错误(即监控php项目)

查看nginx中配置的access.log和error.log
php的错误可以在php.ini中查找路径,然后找到即可

从http请求的过程我们知道,一个http请求来到nginx之后,被nginx包装fastcgi协议传给php的sapi(例如php-fpm),fpm将fastcgi解析出来,发给php内核去执行,
然后php内核将执行后的结果直接返回给Nginx。从这一点可以得出,nginx的error日志产生于php执行内核,如果php执行内核出错,那么nginx就会出错。
也就是说,error.log出现的后端的问题,就是php内核执行抛出的。

那么,我该从哪里找到php收到了哪些请求呢?主要是不确定,nginx是否会把一些请求直接做缓存处理,从而不给php内核处理。

6、各种sapi里面的php.ini在启动的时候是如何相互运作的

理论上是使用的自己的php.ini。即自己目录下的,php的cgi扩展和fpm扩展是不同的存在

PHP-CGI

是 CGI 协议 php 的一个实现版。PHP-CGI 会为每个请求 fork 一个进程处理,处理完成后退出。
(这个模式叫做 fork-and-execute)。这样的模式不符合现在动不动大规模的流量,所以已退出历史舞台。

PHPFPM

当发现 PHP-CGI 性能不佳时,又恰好出现了 FastCGI 协议。所以 PHP 实现了一个 php 版本的 FastCGI,名字叫做 PHPFPM(FastCGI Process Manager)。
PHPFPM 启动时会开启 一个 master 进程和若干个 work 进程。master 进程监听请求,并转发给 work 进程处理,每一个 work 进程
都有一个 php 解释器,你的代码在每一个 work 进程中都有一份,work 进程是真正执行代码的地方。

有个情况是:cgi下面的php.ini什么扩展都没打开,fpm下面把该打开的扩展都打开了。当运行cgi的时候,却能正常使用这些扩展,原因何在?

7、文件句柄究竟如何工作

产生文件句柄的地方:
open系统调用打开文件(path_openat内核函数)
打开一个目录(dentry_open函数)
共享内存attach (do_shmat函数)
socket套接字(sock_alloc_file函数)
管道(create_pipe_files函数)
epoll/inotify/signalfd等功能用到的匿名inode文件系统(anon_inode_getfile函数)

查看线程占句柄数:ulimit -a
查看系统打开句柄最大数量:more /proc/sys/fs/file-max
查看打开句柄总数:lsof|awk ‘{print 2}’|wc -l 根据打开文件句柄的数量降序排列,其中第二列为进程ID:lsof|awk ‘{print2}’|sort|uniq -c|sort -nr|more
根据获取的进程ID查看进程的详情:ps -ef |grep pid
修改linux单进程最大文件连接数:

修改linux系统参数。vi /etc/security/limits.conf 添加
*  soft  nofile  65536
*  hard  nofile  65536
修改以后保存,注销当前用户,重新登录,执行ulimit -a ,ok ,参数生效了:

8、fastcgi协议内容

借鉴于FastCGI 协议规范中文版

fastcgi是web服务器(如nginx/apache)和处理程序之间的一种通信协议,它是与HTTP类似的一种应用层通信协议。

cgi是通用网关接口

FastCGI 和 CGI 应用实现上的最大的区别是,FastCGI 应用实现模块中会有一个常驻服务进程。一个 CGI 应用的典型实现是,每次响应一个 Web 服务器发送过来的请求时,都会创建和初始化一个新的处理进程,使用这个进程来产生此请求对应的响应数据,最后在处理结束之后,关闭此进程。FastCGI 应用的初始化要比 CGI/1.1 的简化很多,其进程是固定常驻的,不需要管理生命周期,不需要初始化标准输入输出流 stdin、stdout、stderr,也不需要读取大量的环境变量。此初始化的核心部分是监听一个 socket(套接字),通过这个 socket 来接收 Web 服务器发来的请求。可以让多个 HTTP 请求使用同一个连接进行数据交互,这样应用的实现就可以采用事件驱动编程模型或者多线程编程模型。
同一个请求的多个数据流的传输可以复用同一个连接。

fastcgi并不是属于php的,它是一种协议,php只是实现了能以这种协议交互(主要是sapi,例如php-fpm)。因为php并没有实现http网络模块

9、fpm如何查看worker进程的数量和状态

在终端通过ps aux | grep php查看到。
显示php-fpm: pool www的代表work子进程(实际处理请求)
显示php-fpm: process master的代表master主进程(负责管理work子进程)

10、fpm启动配置

worker进程数的设置
监听的端口
坚挺的socket
具体可以参考这一篇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章