进程
程序是一些保存在磁盘上的指令的有序集合,是静态的。进程是程序执行的过程,包括了动态创建、调度和消亡的整个过程,进程是程序资源管理的最小单位。
程序资源:内存资源、IO资源、信号处理等
线程
线程是操作操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程中的实际运作单位,一个进程内可以包含多个线程,线程是资源调度的最小单位。
同一进程中的多条线程共享该进程中的全部系统资源,如虚拟地址空间,文件描述符文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈、寄存器环境、线程本地存储等信息。
线程创建的开销主要是线程堆栈的建立,分配内存的开销。这些开销并不大,最大的开销发生在线程上下文切换的时候。
协程
协程,英文Coroutines,是一种比线程更加轻量级的存在。类比一个进程可以拥有多个线程,一个线程也可以拥有多个协程,因此协程又称微线程和纤程。
协程不是进程,也不是线程,它就是一个可以在某个地方挂起的特殊函数,并且可以重新在挂起处继续运行。所以说,协程与进程、线程相比,不是一个维度的概念。
参考: https://zhuanlan.zhihu.com/p/337978321
nginx
Nginx (“engine x”) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。
cgi,fast-cgi
也叫通用网关接口,是Web服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。
早期的webserver只能处理html等静态文件,无法处理动态语言(比如php程序),于是出现了cgi协议,只要按照cgi协议去编写程序,就能实现语言解释器与webwerver的通信。
但是该方法有个缺点,就是webserver每收到一个请求,都会去fork一个cgi进程,请求结束再kill掉这个进程。很明显这很浪费资源。
于是出现了fast-cgi。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。
php-fpm
全称:php-Fastcgi Process Manager.
php-fpm是 FastCGI 的实现,并提供了进程管理的功能。
进程包含 master 进程和 worker 进程两种进程。
master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。
Nginx + php-fpm
nginx 接收请求,然后通过反向代理功能将动态请求转向后端Php-fpm。具体流程如下:
请求
|
nginx
|
加载nginx fast-cgi模块
|
fast-cgi监听127.0.0.1:9000地址
|
请求到达127.0.0.1:9000
|
php-fpm 监听127.0.0.1:9000(master进程)
|
php-fpm 接收到请求,启用worker进程处理请求
|
php-fpm 处理完请求,返回给nginx
|
nginx将结果通过http返回给浏览器
nginx 相关命令
php-fpm 相关命令
文章参考:
php artisan 命令是Laravel框架自带的命令,方便用户快速创建、查看对应的模块参数等。
参考:
https://blog.csdn.net/jzhangc/article/details/116989108
四大部件
目录结构
app 应用核心目录
bootstrap 启动目录,用于载入配置文件,中间件等
config 配置文件目录。数据库,文件系统,cache等配置
database 数据库迁移文件以及填充文件
public 对外访问目录。index文件,静态资源等
resource 对应的视图文件以及为编译的前端资源,邮件模板,本地化语言文件
routes 路由目录。包括:web.php,api.php,console.php,changes.php。
storage 文件存储目录。缓存文件,日志,上传文件
tests 测试目录。自动化的测试脚本
Vendor 包含了应用通过composer 加载的依赖
这里只展示跟目录。具体参考:
https://laravelacademy.org/post/21960
请求原理
路由 => 中间件 => 控制器 => 模型 => 控制器 => 视图
通常控制器做处理数据,有点臃肿和庞大,中间可以件一些Sevice层,专门封装相关业务处理。控制器只负责和调用这些封装好的对象。这样做更符合设计原则。
原理
对称加密是指加密和解密使用相同的密钥的加密算法。它的加密原理是将明文 (输入的机密信息) 通过密钥进行加密,然后再将加密后的密文发送出去。接收方收到密文后,使用相同的密钥进行解密,从而获得明文。对称加密的优点在于速度快,加密强度高,且密钥管理简单。但是,它也存在缺点,例如密钥管理不当会导致密钥泄露,攻击者可以轻松地破解加密信息。
非对称加密是指加密和解密使用不同的密钥的加密算法。它的加密原理是将明文通过非对称密钥进行加密,然后再将加密后的密文发送出去。接收方收到密文后,使用对称密钥进行解密,从而获得明文。非对称加密的优点在于加密强度高,攻击者需要付出极大的代价才能破解加密信息,而且密钥管理简单。但是,它也存在缺点,例如由于非对称密钥较长,加密速度较慢,且密钥管理不当会导致密钥泄露。
区别
对称加密: 发送方和接收方密钥一样, 速度快,容易被破解, 安全性差。常见的算法有DES、IDEA、RC2等
非对称加密:发送方和接收方密钥不一样,速度慢,不容易被破解,安全性好。私钥加密的内容只有公钥才能解开,公钥加密的内容只有私钥才能解开。也就是说,用其中一个钥匙加密,那么必须用另一个钥匙解密。常见的算法有RSA、DAS、ECC等。
密钥管理
对称加密和非对称加密的安全性都非常高,因为它们使用高强度的密钥进行加密,使得攻击者需要付出极大的代价才能破解。密钥管理是加密很重要的环节,以下建议可以更安全的管理密钥:
应用
支付应用:非对称加密更安全
服务端-》客户端的交互:对称加密,比如mqtt 数据加密,一般用des加密
class test
{
private static $instance = null; //私有静态属性,存放该类的实例
private function __construct() //私有构造方法,防止在类的外部实例化
{
echo 'construct';
}
// private function __clone() //私有克隆方法,防止克隆
// {
// // Fatal error: Call to private TestSingleton::__clone() from context '' 外部clone时会报错
// }
public static function getInstance() //公共的静态方法,实例化该类本身,只实例化一次
{
// instanceof self 检测 变量是否为self的实例
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}
public function setSinVar ($sinVar) {
$this->sinVar = $sinVar;
}
public function getSinVar() {
return $this->sinVar;
}
}
$test_a = test::getInstance();
$test_b = test::getInstance();
$test_c = clone $test_b;
$test_a->setSinVar('aaa');
$test_b->setSinVar('bbb');
$test_c->setSinVar('ccc');
echo '</br>';
echo $test_a->getSinVar()."\r";
echo '</br>';
echo $test_b->getSinVar()."\r";
echo '</br>';
echo $test_c->getSinVar()."\r";
输出:
//construct
//bbb
//bbb
//ccc
合成复用原则(Composite/Aggregate Reuse Principle,CARP)是指尽量使用对象组 合(has-a)/聚合(contanis-a),而不是继承关系达到软件复用的目的。可以使系统更加灵 活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。
继承我们叫做白箱复用,相当于把所有的实现细节暴露给子类。组合/聚合也称之为黑箱 复用,对类以外的对象是无法获取到实现细节的。要根据具体的业务场景来做代码设计, 其实也都需要遵循 OOP 模型。
demo:
文章,数据库操作。两个各自的对象封装。
文章不应该继承数据库类来达到数据的增删改查,而是通过聚合,实例化数据库类来直接使用。当然不同的数据库应该中间有个抽象层,底层有选择来决定调用那个数据库。
定义:
开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则。
一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。
当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
意义:
降低代码耦合,减少风险,增强了系统的稳定性
Demo:
比如同一个接口,后面做了版本升级。为了保证原app等对该接口的调用,该接口不应该发生任何变动。为了新app支持新功能特性,应该支持新的版本接口,在新的接口里面实现这些功能并且提供给新的调用方。
任何基类可以出现的地方,子类一定可以出现。里氏替换原则是继承复用的基石,只有当衍生类可以替换基类,软件单位的功能不受到影响时,即基类随便怎么改动子类都不受此影响,那么基类才能真正被复用
这就要求必须以下的规则:
优点:
代码共享,即公共代码被抽到父类。
提高代码重用性。
子类在父类的基础上可以有自己的特性。
提高代码的扩展性。
缺点:
侵入性。一旦继承,父类全部属性和方法都被子类拥有
约束性。子类需要拥有父类的属性和方法,子类多了一些约束。
耦合性。父类出现修改情况时,需要考虑子类的修改。
现实中的demo:
比如你在数据库操作模型中写了一个基类的 查询。理论上这个查询只要继承了这个基类所有models都可以调用,所以子类调用的时候,如果子类重写了该方法并且更改了原来的功能。这个继承就变得不在有意义。
定义:
又叫最少知道原则,如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
作用:
其目的是降低类之间的耦合度,提高模块的相对独立性。
反作用:
增加了系统的复杂度