Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoguo0426 committed Jul 30, 2020
1 parent 1cc5b37 commit a8b258e
Show file tree
Hide file tree
Showing 25 changed files with 517 additions and 0 deletions.
28 changes: 28 additions & 0 deletions nginx/Php-fpm TcpSocket vs UnixSocket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@


Nginx连接fastcgi的方式有2种:
- unix domain socket
- TCP

Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。

与管道相比,Unix domain sockets 既可以使用字节流和数据队列,而管道通信则只能通过字节流。

Unix domain sockets的接口和Internet socket很像,但它不使用网络底层协议来通信。Unix domain socket 的功能是POSIX操作系统里的一种组件。

TCP和unix domain socket方式对比

TCP是使用TCP端口连接127.0.0.1:9000

Socket是使用unix domain socket连接套接字/dev/shm/php-cgi.sock(很多教程使用路径/tmp,而路径/dev/shm是个tmpfs,速度比磁盘快得多)

```code
fastcgi_pass unix:/tmp/php-cgi.sock
fastcgi_pass 127.0.0.1:9000
```

理论上,unix socket 不走网络,效率高一些,但稳定性不是很理想

https://blog.csdn.net/liv2005/article/details/7741732

https://www.cnxct.com/default-configuration-and-performance-of-nginx-phpfpm-and-tcp-socket-or-unix-domain-socket/
65 changes: 65 additions & 0 deletions nginx/php-fpm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@


#### 常见配置项

##### php-fpm进程分配

```code
pm = static | dynamic | ondemand
```
- pm = static 模式

表示创建固定数量的php-fpm子进程,由pm.max_children参数控制

- pm = dynamic 模式
表示启动进程是动态分配的,随着请求量动态变化的。它由pm.max_children,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers这几个参数共同决定。

- pm = ondemand 模式

进程在请求时按需创建,而不是动态的。可用于内存不足或内存过小的服务器

##### 进程池配置

- user = vagrant

拥有这个PHP-FPM进程池中子进程的系统用户。

- group = vagrant

拥有这个PHP-FPM进程池中子进程的系统用户组。

- listen = 127.0.0.1:9000

PHP-FPM进程池监听的IP地址和端口号,让PHP-FPM只接受nginx从这里传入的请求。

- listen.allowed_clients = 127.0.0.1

可以向这个PHP-FPM进程池发送请求的IP地址(一个或多个)。

- pm.max_children = 128

这个设置设定任何时间点PHP-FPM进程池中最多能有多少个进程。需要测试PHP应用,确定每个PHP进程需要使用多少内存,再把这个设置设为设备可用内存能容纳的PHP进程总数。

- pm.start_servers = 3

PHP-FPM 启动时PHP-FPM进程池中立即可用的进程数。

- pm.min_spare_servers = 2

PHP应用空闲时PHP-FPM进程池可以存在的进程数量最小值。这个设置的值一般与pm.start_servers设置的值一样,用于确保新进入的HTTP请求无需等待PHP-FPM在进程池中重新初始化进程。

- pm.max_spare_servers = 4

PHP应用空闲时PHP-FPM进程池中可以存在的进程数量最大值。这个设置的值一般比pm.start_servers设置的值大一点,用于确保新进入的HTTP请求无需等待PHP-FPM在进程池中重新初始化进程。

- pm.max_requests = 10000

回收进程之前,PHP-FPM进程池中各个进程最多能处理的HTTP请求数量。这个设置有助于避免PHP扩展或库因编写拙劣而导致不断泄露内存。

- slowlog = /path/to/slowlog.log

这个设置的值是一个日志文件在文件系统中的绝对路径。这个日志文件用于记录处理时间超过n秒的HTTP请求信息,以便找出PHP应用的瓶颈,进行调试。

- request_slowlog_timeout = 5s

如果当前HTTP请求的处理时间超过指定的值,就把请求的回溯信息写入slowlog设置指定的日志文件。
Empty file removed php/Http协议.md
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions php/composer.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,22 @@ $ composer config repo.packagist composer https://mirrors.aliyun.com/composer/
```

[文档](https://learnku.com/docs/composer/2018)


#### 自动加载机制
在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和require方法,去把定义这个class的文件包含进来。这个在小规模开发的时候,没有太大问题。但在大型的开发项目中,这样做会产生大量的require和include方法调用,这样不但降低效率,而且使得代码难以维护,况且require_once的代价很大。

在PHP5后,当加载PHP类时,如果类所在文件没有被包含进来,或者类名出错,Zend引擎会自动调用__autoload函数。此函数需要用户自己实现__autoload函数。

在PHP5.1.2版本后,可以使用spl_autoload_register函数自定义自动加载处理函数。但没有调用此函数,默认情况下会使用SPL自定的spl_autoload函数。

这就是类的自动装载(autoload)机制。autoload机制可以使得PHP程序有可能**在使用类时才自动包含类文件**,而不是一开始就将所有的类文件inlcude进来,这种机制也成为lazy loading.


https://learnku.com/articles/4681/analysis-of-the-principle-of-php-automatic-loading-function

https://blog.csdn.net/hguisu/article/details/7463333

https://www.jb51.net/article/31279.htm

https://learnku.com/php/t/1002/deep-composer-autoload
49 changes: 49 additions & 0 deletions php/opcode cache与JIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
### 机器码

> 学名机器语言指令,有时也被成为原生码(Native Code),是电脑的CPU可直接读取的数据。
机器码是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难写,一般从业人员接触不到。

而且机器码不支持跨平台,简单点说就是不同的CPU使用的机器码不一样。


### 字节码 bytecode
> 是一种包含执行程序,由一系列op代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。
字节码主要为了实现特定软件运行和软件环境,与硬件环境无关。字节码的实现方式是通过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟器将字节码转译为可以直接执行的指令。字节码的典型应用为Java bytecode,那PHP的就是opcode。

字节码在运行时通过虚拟机(PHP 的Zend虚拟机)做一次转换,生成机器指令,因此能够更好地跨平台运行。

字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。

通过介绍我们可以看到,CPU只能执行机器码,但为了实现应用跨硬件平台,我们就为了不同的编程语言实现了一个虚拟机,而这个虚拟机将我们写的代码编译成二进制代码,这个二进制代码就叫字节码,也叫中间码。Zend虚拟机编译好的字节码就叫opcode


### JIT

> JIT 是 just in time 的缩写,也就是即时编译编译器。使用即时编译器技术,能够加速PHP程序执行速度。
通常编译时与运行时两个阶段是独立分开的,脚本编译完成后,像 APC 与 OPCache 这样的字节码缓存组件会缓存这些操作码。而 JIT 去掉了编译时阶段,它将这编译时与运行时两个阶段合为一体,实现即时编译与执行。

JIT 是一种编译器策略,它将代码表述为一种中间状态,在运行时将其转换为依赖于体系结构的机器码,并即时执行。在 PHP 中,这意味着 JIT 将为 Zend VM 生成的指令视为中间表述,并以依赖于体系结构的机器码执行,也就是说托管代码的不再是 Zend VM,而是更为底层的 CPU。

另外值得一提的是,PHP JIT 对于使用 PHP 的网站来说提速可能并不明显,因为 JIT 在 CPU 密集型的代码上效果最好,而一般情况下,用 PHP 编写的程序都是 I/O 密集型的。

简单来说就是,PHP 程序往往受限于 I/O 而不是 CPU,使 PHP 代码运行速度变慢的因素往往是它们正在执行的 I/O 操作,包括连接、读取和写入数据库、高速缓存、文件与套接字等。

JIT 把翻译过的机器码保存起来,以备下次使用(这里面肯定有个类似与LRU的算法)。可见JIT要做的很简单,就是把中间码翻译成的机器码暂时(保存多久,怎么选择这里不做介绍)保存起来,这样再用到这个机器码的时候,就少了一次翻译。


### opcode cache

> 将中间码opcode缓存起来
![](assets/markdown-img-paste-20200716154916831.png)

**Zend引擎必须从文件系统读取文件、扫描其词典和表达式、解析文件、创建要执行的计算机代码(称为Opcode),最后执行Opcode。每一次请求PHP脚本都会执行一遍以上步骤,如果PHP源代码没有变化,那么Opcode也不会变化,显然没有必要每次都重行生成Opcode,结合在Web中无所不在的缓存机制,我们可以把Opcode缓存下来,以后直接访问缓存的Opcode岂不是更快,启用Opcode缓存之后的流程图如下所示:**

![](assets/markdown-img-paste-20200716155728428.png)

### 总结

**简单点描述JIT是用来缓存CPU执行的机器码的,opcode cache是用来缓存Zend虚拟机用的中间码的。**
16 changes: 16 additions & 0 deletions redis/常见问题.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,19 @@
这里可以结合使用`canal`(阿里开源的一款框架),通过框架可以对`MySQL``binlog`进行订阅,而`canal`正是模仿了`MySQL``slave`数据库备份请求,使得`Redis`的数据更新达到了相同的效果。

[参考文章](https://www.cnblogs.com/hunna/p/11942688.html)

#### RDB和AOF应用
https://segmentfault.com/a/1190000017193732?utm_source=coffeephp.com

#### Redis在高并发中使用

https://juejin.im/post/5d0f3c2be51d45595319e355

#### Redis中IO多路复用模型

https://draveness.me/redis-io-multiplexing/


#### Redis常见面试题

https://juejin.im/post/5b99d4bce51d450e7a24b66e#heading-0
89 changes: 89 additions & 0 deletions 系统/HTTP状态码.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

### 状态码

> 状态码是来告诉客户端,发生了什么事情。状态码为客户端提供了一种**理解事务处理结果**的便捷方式。状态码位于响应的起始行中。
> 比如,在行 HTTP/1.1 200 ok ,状态码就是200
状态码就是在每条响应报文的起始行中返回的。会返回一个数字状态和一个可读的状态。**数字码** 便于程序进行差错处理,而 **原因短语** 则便于人们理解

#### 原因短语

原因短语是响应起始行中的最后一个组件。它为状态码提供了 **文本形式** 的解释

> 比如,在行 HTTP/1.1 200 ok ,ok就是原因短语
### 状态码分类

可以通过三位数字代码对不同状态分类

- 200-299 表示成功
- 300-399 表示资源已经被转移走
- 400-499 表示客户端的请求出错
- 500-599 表示服务器端出错

#### 信息状态码
状态码 | 原因短语 | 含义
--|---|--
100 | Continue | 说明收到了请求的初始部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行相应
101 | Switching Protocols | 说明服务器正在根据客户端的指定,将协议切换成Update首部所列的协议

#### 成功状态码

状态码 | 原因短语 | 含义
--|---|--
200 | OK | 请求没问题,实体的主体部分包含了所请求的资源
201 | Created | 用于创建服务器对象的请求(比如:PUT)。响应的实体主体部分中应该包含了引用了已创建的资源的URL,Location首部包含的则是所具体的引擎。服务器必须在发送这个状态码之前创建好对象
202 | Accepted | 请求已被接受,服务器还未对其执行任何动作。不能保证服务器会完成这个请求;接受请求时,它看起来是有效的。服务器应在实体的主体部分包含对请求状态的描述,或附加请求预计处理时间,信息获取指针
203 | Non-Authoritative Information | 实体首部包含的信息不是来自于源端服务器,而是来自资源的副本。如果中间节点上有一份副本,但无法或没有对元数据进行验证,就会出现这种情况
204 | No Content | 响应报文中包含若干首部和一个状态行,但没有实体的主体部分。主要用于在浏览器不转为显示新文档的情况下,对其进行更新(比如刷新一个表单页面)
205 | Reset Content | 另一个主要用于浏览器的代码。负责告诉浏览器清除当前页面中的所有HTML表单元素
206 | Partial Content | 成功执行了一个部分或Range(范围)请求。客户端可以用过一些特殊的首部来获取部分或某个范围内的文档


#### 重定向状态码

状态码 | 原因短语 | 含义
--|---|--
300 | Multiple Choices | 客户端请求一个实际指向多个资源时会返回这个状态码,比如服务器上有某个HTML文档有多个语言版本。返回时会带有一个选项列表,用户可以选择期望使用的那项
301 | Moved Permanently | 在请求的URL已被移除时使用。响应的Location首部中应该包含资源现在所处的URL
302 | Found | 与301状态码类似;但是,客户端应该使用Location首部给出的URL来临时定位资源。将来的请求仍应使用老的URL
303 | See Other | 告知客户端应该用另一个URL来获取资源。新的URL位于响应报文的Location首部。其主要目的是允许POST请求的响应将客户端定向到某个资源上去
304 | Not Modified | 客户端可以通过所包含的请求首部,使其请求变成有条件的。若用户发起了一个条件GET请求,而资源近期未被修改,可以通过该状态码表明。带有这个状态码的响应不应该包含实体的主体部分
305 | Use Proxy | 用来说明必须通过一个代理来访问资源;代理的位置由Location首部给出。客户端是相对某个特定资源来解析这条响应的,不能假定所有请求,甚至所有对持有所请求资源服务器的请求都通过这个代理进行。如果客户端错误地让代理介入了某条请求,可能会引发破坏性的行为,而且会造成安全漏洞
306 | (未使用) | 当前未使用
307 | Temporary Redirect | 与301状态码类似;但客户端应该使用Location首部给出的URL来临时定位资源。将来的请求应该使用老的URL

#### 客户端错误状态码

状态码 | 原因短语 | 含义
--|---|--
400 | Bad Request | 用于告知客户端它发生了一个错误的请求
401 | Unauthorized | 与适当的首部一同返回,在这些首部中请求客户端在获取对资源的访问权之前,对自己进行认证
402 | Payment Required | (现在这个状态码还未使用,但已经被保留,以作未来之用)
403 | Forbidden | 用于说明请求被服务器拒绝了。如果服务器想说明为什么拒绝请求,可以包含实体的主体部分来对原因进行描述。但这个状态码通常是在服务器不想说明拒绝原因的时候使用的
404 | Not Found | 用于说明服务器无法找到所请求的 URL。通常会包含一个实体,以便客户端应用程序显示给用户看
405 | Method Not Allowed | 发起的请求中带有所请求的 URL 不支持的方法时,使用此状态码。应该在响应中包含 Allow 首部,以告知客户端对所请求的资源可以使用哪些方法
406 | Not Acceptable | 客户端可以指定参数来说明它们愿意接收什么类型的实体。服务器没有与客户端可接受的 URL 相匹配的资源时,使用此代码。通常,服务器会包含一些首部,以便客户端弄清楚为什么请求无法满足
407 | Proxy Authentication Required | 与 401 状态码类似,但用于要求对资源进行认证的代理服务器
408 | Request Timeout | 如果客户端完成请求所花的时间太长,服务器可以回送此状态码,并关闭连接。超时时长随服务器的不同有所不同,但通常对所有的合法请求来说,都是够长的
409 | Conflict | 用于说明请求可能在资源上引发的一些冲突。服务器担心请求会引发冲突时,可以发送此状态码。响应中应该包含描述冲突的主体
410 | Gone | 与 404 类似,只是服务器曾经拥有过此资源。主要用于 Web 站点的维护,这样服务器的管理者就可以在资源被移除的情况下通知客户端了
411 | Length Required | 服务器要求在请求报文中包含 Content-Length 首部时使用
412 | Precondition Failed | 客户端发起了条件请求,且其中一个条件失败了的时候使用。客户端包含了 Expect 首部时发起的就是条件请求
413 | Request Entity Too Large | 客户端发送的实体主体部分比服务器能够或者希望处理的要大时,使用此状态码
414 | Request URI Too Long | 客户端所发请求中的请求 URL 比服务器能够或者希望处理的要长时,使用此状态码
415 | Unsupported Media Type | 服务器无法理解或无法支持客户端所发实体的内容类型时,使用此状态码
416 | Requested Range Not Satisfiable | 请求报文所请求的是指定资源的某个范围,而此范围无效或无法满足时,使用此状态码
417 | Expectation Failed | 请求的 Expect 请求首部包含了一个期望,但服务器无法满足此期望时,使用此状态码。如果代理或其他中间应用程序有确切证据说明源端服务器会为某请求产生一个失败的期望,就可以发送这个响应状态码

#### 服务器错误状态码

状态码 | 原因短语 | 含义
--|---|--
500 | Internal Server Error | 服务器遇到一个妨碍它为请求提供服务的错误时,使用此状态码
501 | Not Implemented | 客户端发起的请求超出服务器的能力范围(比如,使用了服务器不支持的请求方法)时,使用此状态码
502 | Bad Gateway | 作为代理或网关使用的服务器从请求响应链的下一条链路上收到了一条伪响应(比如,它无法连接到其父网关)时,使用此状态码
503 | Service Unavailable | 用来说明服务器现在无法为请求提供服务,但将来可以。如果服务器知道什么时候资源会变为可用的,可以在响应中包含一个 RetryAfter 首部
504 | Gateway Timeout | 与状态码 408 类似,只是这里的响应来自一个网关或代理,它们在等待另一服务器对其请求进行响应时超时了
505 | HTTP Version Not Supported | 服务器收到的请求使用了它无法或不愿支持的协议版本时,使用此状态码。有些服务器应用程序会选择不支持协议的早期版本
Loading

0 comments on commit a8b258e

Please sign in to comment.