Laravel crontab 配置问题

参考

Lnmp环境运行时一般会指定用户www运行。因此配置定时任务的时候,也需要使用www用户来运行定时任务,否则会造成laravel生成的日志是其它用户,导致laravel运行报错,没有日志的可写权限。

配置方法

1.获取当前系统PHP的环境变量

执行 env > /tmp/env.output 然后 cat /tmp/env.output

找到PATH

PATH=/usr/local/mysql/bin:/usr/local/php/bin:/usr/local/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

2.设置定时任务 -u 参数指定用户 命令参考 给www用户的crontab 添加环境变量PATH

crontab -u www -e

将PATH添加到crontab的第一行,

换行后将laravel的定时任务代码加上,截图中第二行, 制定了环境变量后,可以只写php 不用写php的完整路径 /usr/local/php/bin/php

3,不能遗漏的关键一步

在home目录下创建对应用户的文件目录,www 并修改用户权限为www 最后重启定时任务

cd home && mkdir www && chown -R www.www www
service crond restart

如果没有该用户的目录,crontab日志会有报错

(CRON) ERROR chdir failed (/home/www): No such file or directory

知识总结

Crontab详细介绍可以头部的参考链接,和《鸟哥linux私房菜-基础学习篇》第16章

任务调度分为两类: 系统任务调度 和 用户任务调度 

系统任务配置/etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

前四行是用来配置crond任务运行的环境变量,

  • 第一行SHELL变量指定了系统要使用哪个shell,这里是bash,
  • 第二行PATH变量指定了系统执行命令的路径,
  • 第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户,
  • 第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。
  • 第五行 前五个星号代表时间, user-name代表执行的用户,command代表执行的命令

crontab – u xxx -e 是用来设置用户系统任务调度的

所有用户定义的crontab文件都被保存在/var/spool/cron目录中。其文件名与用户名一致,使用者权限文件如下

/etc/cron.deny     该文件中所列用户不允许使用crontab命令
/etc/cron.allow    该文件中所列用户允许使用crontab命令
/var/spool/cron/   所有用户crontab文件存放的目录,以用户名命名

注意单独用户的crontab配置需要设置 PATH 并创建对应用户目录

service crond start    # 启动服务
service crond stop     # 关闭服务
service crond restart  # 重启服务
service crond reload   # 重新载入配置
service crond status   # 查看状态

PHP开源项目

参考

框架类

PHP框架

PECL扩展框架

类库工具

图像处理

文件处理

  • CSV – CSV数据操作
  • Flysystem  文件系统抽象层,readme中包含很多第三方云服务的扩展包

Office文档处理

爬虫

Mysql 性能调试或监控常用指令

show processlist

官方手册 https://dev.mysql.com/doc/refman/8.0/en/show-processlist.html

如果有 SUPER 权限,则可以看到全部的线程,否则,只能看到自己发起的线程(这是指,当前对应的 MySQL 帐户运行的线程)

说明各列的含义和用途,

id列:一个标识,你要kill 一个语句的时候很有用。

user列: 显示当前用户,如果不是root,这个命令就只显示你权限范围内的sql语句。

host列:显示这个语句是从哪个ip 的哪个端口上发出的。可用来追踪出问题语句的用户。

db列:显示这个进程目前连接的是哪个数据库。

command列:显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)

通常代表资源未释放,如果是通过连接池,sleep状态应该恒定在一定数量范围内

 实战范例:因前端数据输出时(特别是输出到用户终端)未及时关闭数据库连接,导致因网络连接速度产生大量sleep连接,在网速出现异常时,数据库too many connections挂死。

 简单解读,数据查询和执行通常只需要不到0.01秒,而网络输出通常需要1秒左右甚至更长,原本数据连接在0.01秒即可释放,但是因为前端程序未执行close操作,直接输出结果,那么在结果未展现在用户桌面前,该数据库连接一直维持在sleep状态

time列:此这个状态持续的时间,单位是秒。

state列:显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个sql语句,已查询为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成。

info列:显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。 

这个命令中最关键的就是state列,mysql列出的状态主要有以下几种:

Checking table

正在检查数据表(这是自动的)。

Closing tables

正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。

Connect Out

复制从服务器正在连接主服务器。

Copying to tmp table on disk

 由于临时结果集大于 tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。

索引及现有结构无法涵盖查询条件,才会建立一个临时表来满足查询要求,产生巨大的恐怖的i/o压力。

很可怕的搜索语句会导致这样的情况,如果是数据分析,或者半夜的周期数据清理任务,偶尔出现,可以允许。频繁出现务必优化之。

Copy to tmp table通常与连表查询有关,建议逐渐习惯不使用连表查询。

实战范例:

某社区数据库阻塞,求救,经查,其服务器存在多个数据库应用和网站,其中一个不常用的小网站数据库产生了一个恐怖的copy to tmp table操作,导致整个硬盘i/o和cpu压力超载。Kill掉该操作一切恢复。

Creating tmp table

正在创建临时表以存放部分查询结果。

deleting from main table

服务器正在执行多表删除中的第一部分,刚删除第一个表。

deleting from reference tables

服务器正在执行多表删除中的第二部分,正在删除其他表的记录。

Flushing tables

正在执行 FLUSH TABLES,等待其他线程关闭数据表。

Killed

发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。

Locked 被其他查询锁住了

有更新操作锁定

通常使用innodb(支持行锁定)可以很好的减少locked状态的产生,但是切记,更新操作要正确使用索引,即便是低频次更新操作也不能疏忽。如上影响结果集范例所示。

在myisam的时代,locked是很多高并发应用的噩梦。所以mysql官方也开始倾向于推荐innodb。

Sending data

 正在处理 SELECT 查询的记录,同时正在把结果发送给客户端。

Sending data并不是发送数据,别被这个名字所欺骗,这是从物理磁盘获取数据的进程,如果你的影响结果集较多,那么就需要从不同的磁盘碎片去抽取数据,偶尔出现该状态连接无碍。

回到上面影响结果集的问题,一般而言,如果sending data连接过多,通常是某查询的影响结果集过大,也就是查询的索引项不够优化。

如果出现大量相似的SQL语句出现在show proesslist列表中,并且都处于sending data状态,优化查询索引,记住用影响结果集的思路去思考。

Sorting for group

正在为 GROUP BY 做排序。

Sorting for order

正在为 ORDER BY 做排序。 

        和Sending data类似,结果集过大,排序条件没有索引化,需要在内存里排序,甚至需要创建临时结构排序  

Opening tables

这个过程应该会很快,除非受到其他因素的干扰。例如,在执 ALTER TABLE 或 LOCK TABLE 语句行完以前,数据表无法被其他线程打开。 正尝试打开一个表。

Removing duplicates

正在执行一个 SELECT DISTINCT 方式的查询,但是MySQL无法在前一个阶段优化掉那些重复的记录。因此,MySQL需要再次去掉重复的记录,然后再把结果发送给客户端。

Reopen table

获得了对一个表的锁,但是必须在表结构修改之后才能获得这个锁。已经释放锁,关闭数据表,正尝试重新打开数据表。

Repair by sorting

修复指令正在排序以创建索引。

Repair with keycache

修复指令正在利用索引缓存一个一个地创建新索引。它会比 Repair by sorting 慢些。

Searching rows for update

正在讲符合条件的记录找出来以备更新。它必须在 UPDATE 要修改相关的记录之前就完成了。

Sleeping

正在等待客户端发送新请求.

System lock

正在等待取得一个外部的系统锁。如果当前没有运行多个 mysqld 服务器同时请求同一个表,那么可以通过增加 –skip-external-locking参数来禁止外部系统锁。

Upgrading lock

INSERT DELAYED 正在尝试取得一个锁表以插入新记录。

Updating

正在搜索匹配的记录,并且修改它们。

User Lock

正在等待 GET_LOCK()。

Waiting for tables

该线程得到通知,数据表结构已经被修改了,需要重新打开数据表以取得新的结构。然后,为了能的重新打开数据表,必须等到所有其他线程关闭这个表。以下几种情况下会产生这个通知:FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, 或 OPTIMIZE TABLE。

waiting for handler insert

INSERT DELAYED 已经处理完了所有待处理的插入操作,正在等待新的请求。

Waiting for net, reading from net, writing to net

   偶尔出现无妨

   如大量出现,迅速检查数据库到前端的网络连接状态和流量

   案例:因外挂程序,内网数据库大量读取,内网使用的百兆交换迅速爆满,导致大量连接阻塞在waiting for net,数据库连接过多崩溃

大部分状态对应很快的操作,只要有一个线程保持同一个状态好几秒钟,那么可能是有问题发生了,需要检查一下。还有其它的状态没在上面中列出来,不过它们大部分只是在查看服务器是否有存在错误是才用得着。

show profiles
show profile for query 1

官方手册:https://dev.mysql.com/doc/refman/8.0/en/show-profile.html

show status
flush status
show global status
show engine innodb status(老版 show innodb status)

 show tables from information_schema

explain

官方手册 https://dev.mysql.com/doc/refman/8.0/en/using-explain.html

详细介绍:https://www.yangliuan.cn/?p=145

参考链接

物联网开发和网络编程需要掌握哪些知识?

MCU 参考

微控制单元,俗称单片机

micro python

在单片机上运行的精简python版本

socket 通信

粘包,少包,数据在内存中的存储字节序列解析及封装,包括 socket 优化及多进程时 socket 与惊群的效应问题解决办法

关于通信协议最基础的你必须知道 MQTT 协议及 MQTT-SN 协议的解释及封装和算法,我们的传感器设备大部分是 MQTT-SN 和字节流通信协议。

用到的时候后续补充

无限极分类的多种实现方式

递归

从数据库中查询出所有数据,然后递归处理

$category = [[
    'id' => 1,
    'pid' => 0,
    'name' => '1级分类',
], [
    'id' => 2,
    'pid' => 1,
    'name' => '2级分类',
], [
    'id' => 3,
    'pid' => 2,
    'name' => '3级分类',
], [
    'id' => 4,
    'pid' => 3,
    'name' => '4级分类',
], [
    'id' => 5,
    'pid' => 4,
    'name' => '5级分类'
], [
    'id' => 6,
    'pid' => 6,
    'name' => '6级分类'
]];

//递归成树形
function recurSionToTree(array $array = [], $pid = 0)
{
    $result = [];

    foreach ($array as $key => $value) {

        if ($value['pid'] == $pid) {
            $children = recurSionToTree($array, $value['id']);

            if ($children) {
                $value['children'] = $children;
            }

            $result[] = $value;
        }
    }

    return $result;
}

引用

从数据库查询出所有数据,然后遍历

function refToTree($data)
{
    $items = array();

    foreach ($data as $v) {
        $items[$v['id']] = $v;
    }

    $tree = array();

    foreach ($items as $k => $item) {
        if (isset($items[$item['pid']])) {
            $items[$item['pid']]['children'][] = &$items[$k];
        } else {
            $tree[] = &$items[$k];
        }
    }

    return $tree;
}

冗余字段,空间换时间

参考连接:https://learnku.com/courses/ecommerce-advance/7.x/database-structure/9086

在开始之前,我们需要先整理好 categories 表的字段名称和类型:

字段名称描述类型加索引缘由
id自增长 IDunsigned big int主键
name类目名称varchar
parent_id父类目 IDunsigned big int, null外键
is_directory是否拥有子类目tinyint
level当前类目层级unsigned int
path该类目所有父类目 idvarchar

这里我们需要解释一下 path 字段的意义,在无限级分类的实现中我们经常会遇到以下几个场景:

  • 场景一:查询一个类目的所有祖先类目,需要递归地去逐级查询父类目,会产生较多的 SQL 查询,从而影响性能。
  • 场景二:查询一个类目的所有后代类目,同样需要递归地逐级查询子类目,同样会产生很多 SQL 查询。
  • 场景三:判断两个类目是否有祖孙关系,需要从层级低的类目逐级往上查,性能低下。

而 path 字段就是用于解决这些问题而存在的,path 字段会保存该类目所有祖先类目的 ID,并用字符 - 将这些 ID 分隔开,根类目的 path 字段为 -。比如如下类目:

[
    [
        "id" => 1,
        "name" => "手机配件",
        "parent_id" => null,
        "level" => 0,
        "path" => "-"
    ],
    [
        "id" => 2,
        "name" => "耳机",
        "parent_id" => 1,
        "level" => 1,
        "path" => "-1-"
    ],
    [
        "id" => 3,
        "name" => "蓝牙耳机",
        "parent_id" => 2,
        "level" => 2,
        "path" => "-1-2-"
    ],
    [
        "id" => 4,
        "name" => "移动电源",
        "parent_id" => 1,
        "level" => 1,
        "path" => "-1-"
    ],
];

对应的类目树如下:

手机配件(1)
 ├─ 耳机(2)
 │   └─ 蓝牙耳机(3)
 └─ 移动电源(4)

现在我们再来逐一分析刚刚的几个场景:

场景一,查询『蓝牙耳机』的所有祖先类目:取出 path 字段的值 -1-2-,以 - 为分隔符分割字符串并过滤掉空值,得到数组 [1, 2] ,然后使用 Category::whereIn('id', [1, 2])->orderBy('level')->get() 即可获得排好序的所有父类目。

场景二,查询『手机配件』的所有后代类目:取出自己的 path 值 -,然后追加上自己的 ID 字段得到 -1-,然后使用 Category::where('path', 'like', '-1-%')->get() 即可获得所有后代类目。

场景三,判断『移动电源』与『蓝牙耳机』是否有祖孙关系:取出两者中 level 值较大的类目『蓝牙耳机』的 path 值 -1-2- 并赋值给变量 $highLevelPath,取另外一个类目的 path 值并追加该类目的 ID 得 -1-4- 并赋值给变量 $lowLevelPath,然后只需要判断变量 $highLevelPath 是否以 $lowLevelPath 开头,如果是则有祖孙关系。

可以看到我们通过新增一个冗余的 path 字段,就能很好地解决性能问题,这是一种很典型的(存储)空间换(执行)时间策略。

预排序树

参考连接

https://www.jianshu.com/p/48f6db8ea524

https://www.cnblogs.com/sonicit/archive/2013/05/21/3090518.html

记录Let’s encrypt 证书导致的两个严重问题

问题一

起因,公司的某项目APP客户反馈,ios打开数据响应很慢

2020年4月份出现,在ios系统上,证书解析非常慢,导致ios调取接口经常超时,而且时很多运营商都出现过这个问题,时快时慢.

起初以为时服务器网络问题,在PC上通过mtr检测后发现服务器和网络正常

使用ios网络诊断工具Best Net Tools 检测发现服务器和网络正常

最终通过人工对比测试发现,国内使用Let’s encrypt证书的网站,和其它证书赛克铁门,发现Let’s encrypt证书在ios系统上响应很慢

问题二

起因,公司某项目调取第三方同步数据接口的队列报错

GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

使用postman开启ssl验证接口没有响应,

参考https://stackoverflow.com/questions/46080133/laravel-curl-error-60-ssl-certificate-unable-to-get-local-issuer-certificate 修改php.ini curl.cainof 和openssl.cafile 配置新的证书后,还是报错,和原先配置的证书是一样的,所以并不是这个证书的原因.

最后解决方法,使用guzzle的配置项 verify 设置为false不验证ssl

文档 https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html#verify

总结

解决问题后,需要问为什么会出现这些问题,重新复习一下ssl相关知识和原理,后续慢慢完善

是什么?简介

干什么?用途

怎么干?应用

为什么?工作原理

NVM安装和使用

https://github.com/nvm-sh/nvm

参考github

要安装或更新nvm,应运行安装脚本。为此,您可以手动下载并运行脚本,也可以使用以下cURL或Wget命令:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

运行以上任一命令将下载一个脚本并运行它。该脚本会将nvm存储库克隆到〜/ .nvm,并尝试将以下代码段中的源代码行添加到正确的配置文件(〜/ .bash_profile,〜/ .zshrc,〜/ .profile或〜/ .bashrc)

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

更换镜像

export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node

安装node

nvm install node 安装默认版本
nvm install 12.16.2 安装指定版本

npm修改镜像地址 https://www.cnblogs.com/susu8/p/9208826.html

npm config set registry http://registry.npm.taobao.org

PHP实现守护进程的方式

nohup

nohup命令 可以将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端。

无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到$HOME/nohup.out文件中。如果没有文件能创建或打开以用于追加,那么 command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。

语法

nohup(选项)(参数)

选项

--help:在线帮助;
--version:显示版本信息。

参数

程序及选项:要运行的程序及选项。

实例

使用nohup命令提交作业,如果使用nohup命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:

nohup command > myout.file 2>&1 &

在上面的例子中,输出被重定向到myout.file文件中。

该指令表示不做挂断操作,后台下载

nohup wget site.com/file.zip

下面命令,会在同一个目录下生成一个名称为 nohup.out 的文件,其中包含了正在运行的程序的输出内容

nohup ping -c 10 baidu.com

PHP示例

nohup xxx.php &

使用pcntl和posix扩展实现

PHP 实现守护进程

  • fork 子进程
  • 父进程退出
  • 设置新的会话
  • 重置文件掩码
  • 关闭标准输入输出
<?php
// Fork the current process
$pid = pcntl_fork();

// If pid is negative, an error occurred
if ($pid == -1) {
    exit("Error forking...\n");
} 
// If pid is 0, this is the child process
elseif ($pid === 0) {
    // Make the child process a new session leader
    if (posix_setsid() === -1) {
        exit("Error creating new session...\n");
    }
    
    $dir = '../../../vendor/mydaemon.log';
    // Open a log file for writing
    $log = fopen($dir, 'w');

    // Loop indefinitely
    while (true) {
        // Write a message to the log file
        fwrite($log, "Daemon is running...\n");

        // Sleep for 5 seconds
        sleep(5);
    }
    
    //close the standard input, output, and error streams respectively.
    //REF:https://www.php.net/manual/zh/wrappers.php.php
    //REF:https://www.php.net/manual/zh/features.commandline.io-streams.php

    fclose(STDIN);
    fclose(STDOUT);
    fclose(STDERR);
} 
// If pid is positive, this is the parent process
else {
    // Exit the parent process
    exit('Exit the parent process');
}

Laravel 踩坑记录之路由与中间件,论规范的重要性

使用一种技术,就要遵循它的规范,尤其是在没有完全了解实现原理的时候,不能随意的DIY否则就会进入坑中

不明原因(可能的原因同事对框架做了修改)导致在控制器构造方方中使用$this->middleware()方法,terminate中间件没有生效,最后在路由中使用->middleware() 方法中间件生效

网络基础知识

网络协议 百科

是程序(人)与计算机,计算机与计算机交流(通讯)的基础,通俗的比喻,人与人之间交流需要同一种语言,计算机的网络通讯需要协议。

协议的三要素

语法:一断内容要符合一定的规则和格式,例如http协议的开头是http://xxx.com

语义:这一段内容规则代表的含义,例如http开头就表示http协议

顺序:先干啥后干啥

网络分层

7层是指OSI七层协议模型,主要是:应用层(Application)表示层(Presentation)会话层(Session)传输层(Transport)网络层(Network)数据链路层(Data Link)物理层(Physical)

5层只是OSI和TCP/IP的综合,是业界产生出来的非官方协议模型,但是很多具体的应用。实际应用还是TCP/IP的四层结构。为了方便可以把下两层称为网络接口层。五层体系结构包括:应用层运输层网络层数据链路层物理层。 

4层是指TCP/IP四层模型,主要包括:应用层运输层网际层网络接口层

网络为什么要分层

复杂的程序都要分层,这是程序设计的要求

个人理解,分层相当于人类社会的分工协作,目的是提升效率便于管理,很多网络程序都是采用这种模型,不同的进程做不同的事情。

复杂的事情简单化就要拆分。

域名

百度百科 维基百科

IP地址

IP(英语:Internet Protocol Address)是一种在Internet上的给主机编址的方式,也称为网际协议地址。常见的IP地址,分为IPv4IPv6两大类。

通俗的比喻,就相当于我们的通讯地址(你住哪),邮件快递都需要通讯地址。

MAC地址

MAC地址也叫物理地址、硬件地址,由网络设备制造商生产时烧录在网卡(Network lnterface Card)的EPROM(一种闪存芯片,通常可以通过程序擦写)

通俗的比喻,相当于我们的身份证,身份证号是唯一的不能不变。但是可以造假,操作系统识别出来的mac地址是可以更改的,它只不过是一个字符串。我们常说的修改mac指的是修改电脑中记录的既注册表中的记录

为什么需要两种地址

送快递的时候,既要验证地址对不对,又要验证人对不对,ip4地址不够用,很多网络对外是一个公网IP

公有地址 百科

公有地址(Public address)由Inter NIC(Internet Network Information Center因特网信息中心)负责。
这些IP地址分配给注册并向Inter NIC提出申请的组织机构。通过它直接访问因特网。即常说的公网IP查询

私有地址 百科

在现在的网络中,IP地址分为公网IP地址和私有IP地址。公网IP是在Internet使用的IP地址,而私有IP地址则是在局域网中使用的IP地址。私有IP地址是一段保留的IP地址。只使用在局域网中,无法在Internet上使用。即内网IP

地址范围

无类型域间选路(CIDR)百科

产生原因:地址划分不合理

C 类地址能包含的最大主机数量实在太少了,只有 254 个。当时设计的时候恐怕没想到,现在估计一个网吧都不够用吧。而 B 类地址能包含的最大主机数量又太多了。6 万多台机器放在一个网络下面,一般的企业基本达不到这个规模,闲着的地址就是浪费。

将 32 位(说的是二进制形式)的 IP 地址一分为二,前面是网络号,后面是主机号。从哪里分呢?你如果注意观察的话可以看到,10.100.122.2/24,这个 IP 地址中有一个斜杠,斜杠后面有个数字 24。这种地址表示形式,就是 CIDR。后面 24 的意思是,32 位中,前 24 位是网络号,后 8 位是主机号。

一般云主机的安全组白名单设置使用这种规则。 反爬虫笔记

特殊地址

广播地址 百科

广播地址(Broadcast Address)是专门用于同时向网络中(通常指同一子网)所有工作站进行发送的一个地址。

任何第一个字节大于223小于240的IP地址(范围224.0.0.1-239.255.255.254)是多点广播地址

网络通讯方式有单播,广播,组播。广播应用,有线电视,DHCP服务

通俗的比喻,老师需要对全班发送相同通知(信息),如果一个一个叫到办公室里说,非常好使,直接在教师里通知大家效率高。

子网掩码 百科

子网掩码(subnet mask)又叫网络掩码地址掩码、子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码只有一个作用,就是将某个IP地址划分成网络地址主机地址两部分。

作用

子网掩码是在IPv4地址资源紧缺的背景下为了解决lP地址分配而产生的虚拟lP技术,通过子网掩码将A、B、C三类地址划分为若干子网,从而显著提高了IP地址的分配效率,有效解决了IP地址资源紧张的局面。另一方面,在企业内网中为了更好地管理网络,网管人员也利用子网掩码的作用,人为地将一个较大的企业内部网络划分为更多个小规模的子网,再利用三层交换机的路由功能实现子网互联,从而有效解决了网络广播风暴和网络病毒等诸多网络管理方面的问题

0.0.0.0 百科

代表当前主机

127.0.0.1 百科

127.0.0.1是回送地址,指本地机,一般用来测试使用。回送地址(127.x.x.x)是本机回送地址(Loopback Address),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,协议软件立即返回,不进行任何网络传输。

网关 百科

网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同层–应用层

通俗比喻,大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网络发送信网关息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway [1] 就是一个网络连接到另一个网络的“关口”。也就是网络关卡

TIPS 由于历史的原因,许多有关TCP/IP的文献曾经把网络层使用的路由器称为网关,在今天很多局域网采用都是路由来接入网络,因此通常指的网关就是路由器的IP

网关实质上是一个网络通向其他网络的IP地址。

DNS 百科

域名系统(服务)协议(DNS)一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换

通俗的解释,即使访问网站如果让用户输入ip地址,太麻烦,不好记(缺少语义),于是发明了URL来定位站。

DNS是就是URL和IP的映射关系,通过URL查询到对应服务器的IP,然后访问。

查找IP地址的过程,这个过程就是域名解析

域名注册后,注册商为域名提供免费的静态解析服务。
一般的域名注册商不提供动态解析服务,如果需要用动态解析服务,需要向动态域名服务商支付域名动态解析服务费。

本机的DNS是hosts文件,操作系统网络程序会优先查询hosts

Hosts文件 百科

Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析

路由 百科

路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程 [1] 。路由工作在OSI参考模型第三层——网络层数据包转发设备。路由器通过转发数据包来实现网络互连。虽然路由器可以支持多种协议(如TCP/IP、IPX/SPX、AppleTalk等协议),但是在我国绝大多数路由器运行TCP/IP协议路由器通常连接两个或多个由IP子网或点到点协议标识的逻辑端口,至少拥有1个物理端口。路由器根据收到数据包中的网络层地址以及路由器内部维护的路由表决定输出端口以及下一跳地址,并且重写链路层数据包头实现转发数据包。路由器通过动态维护路由表来反映当前的网络拓扑,并通过网络上其他路由器交换路由和链路信息来维护路由表。

静态路由 百科

静态路由(英语:Static routing),一种路由的方式,路由项(routing entry)由手动配置,而非动态决定。与动态路由不同,静态路由是固定的,不会改变,即使网络状况已经改变或是重新被组态。一般来说,静态路由是由网络管理员逐项加入路由表

动态路由 百科

动态路由是指路由器能够自动地建立自己的路由表,并且能够根据实际情况的变化适时地进行调整

网络协议

UDP协议

UDP协议介绍,无状态,无响应,不保证可靠性会丢包

场景:

1.需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用

2.不需要一对一沟通,建立连接,而是可以广播的应用

3.需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也毫不退缩,一往无前的时候

TCP协议

TCP消息类型

信息描述
Syn用于启动和建立连接。它还可以帮助您在设备之间同步序列号。
ACK帮助对方确认它已收到SYN。
SYN-ACK来自本地设备的SYN消息和先前数据包的ACK。
FIN (鳍)用于终止连接。

三次握手

三次握手时序图

开始,客户端和服务端都处于 CLOSED 状态。

先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态 (第一次)

服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态(第二次)

客户端收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了(第三次)

服务端收到 ACK 的 ACK 之后,处于 ESTABLISHED 状态,因为它也一发一收了

四次挥手

四次挥手时序图

第一次挥手, A发送FIN,进入FIN_WAIT1状态,B收到FIN 进入CLOSED_WAIT状态,

第二次挥手,A收到ACK,进入FIN_WAIT_2状态(如果此时B断开,则A将永远留在这个状态,TCP协议没有对这个状态的处理,linux有,可以通过tcp_fin_timeout草书,设置超时

第三次挥手,B发送FIN,ACK到达A,

第四次挥手,A发送ACK给B,进入TIME_WAIT时间(这个时间足够长,足够B重新发送第三方次挥手,然后A重新进行第四次挥手,可以防止产生混乱,如端口被新应用占领,等到原先的包都失效,在空出新端口)

协议规定等待时间为 2MSL(2分钟),MSL 是 Maximum (最大) Segment (段) Lifetime (一生) ,报文最大生存时间。任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。实际应用中常用的是30秒,1分钟和2分钟。

TCP状态机

DNS 协议

这个协议就像是个地址簿,主要负责 “域名” => “IP 地址” 的查询。每次我们要邮寄信件之前都要拿出来查一查。

DHCP 协议

DHCP 全称叫动态主机配置协议(Dynamic Host (主机) Configuration Protocol (协议) ),主要负责计算机接入网络时的初始化。计算机刚开始就只有网卡的 MAC 地址,通过 DHCP 可以给它分配 IP 地址,并得到默认网关地址(这很重要,不知道网关就上不了网)和 DNS 服务器的地址。有了这些东西,这台计算机就可以和外界通讯了

ARP 协议

IP => Mac 根据ip地址获取mac地址

ARP 全称叫地址解析协议( Address (地址) Resolution Protocol),它服务于现在局域网中最流行的以太网协议。在以太网中,ARP 协议负责解析远程主机 IP 地址对应的 MAC 地址。之所以需要 ARP 协议,是因为我们平常应用程序连接目标计算机进行网络通讯时,都是提供了域名或 IP 地址。但对以太网来说,要想发信件出去,它要的是对方的 MAC 地址

RARP 协议

RARP 全称叫反向地址转换协议(Reverse Address (地址) Resolution Protocol (协议) )。顾名思义,它和 ARP 协议相反,负责的是 MAC 地址到 IP 地址的转换。RARP 协议已经被上面的 DHCP 协议所取代,平常用不太到了。

ICMP 协议

ICMP 全称叫互联网控制报文协议(Internet Control Message Protocol),它能够检测网路的连线状况,以保证连线的有效性。基于这个协议实现的常见程序有两个:ping 和 traceroute,它们可以用来判断和定位网络问题。

IGMP 协议

IGMP 全称叫互联网组管理协议(Internet Group Management Protocol (协议) ),它负责 IP 组播(Multicast)成员管理


数据传输过程

笔记参考

极客时间 趣谈网络协议

网络配置要素 https://www.cnblogs.com/guojun-junguo/p/9966412.html

网络分层 https://blog.csdn.net/cc1949/article/details/79063439

网络通讯模式 https://www.cnblogs.com/hnrainll/archive/2011/09/01/2161839.html

极客时间 许式伟架构课 IP网络:连接世界的桥梁

TCP协议(上):因性恶而复杂,先恶后善反轻松

TCP协议(下):西行必定多妖孽,恒心智慧消磨难

TCP 三次握手(SYN,SYN-ACK,ACK)