天天看點

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);      

那麼此時傳回的就隻包含查詢的和兩個字段。

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程序的數量和狀态

10、fpm啟動配置