进程的基础知识

基本概念

程序是存储在硬盘上的编译生成的二级制可执行文件.不占用系统资源,是具体的.

进程是一个二进制程序(在内存中)的执行过程(运行实例).占用系统资源,是抽象的.

启动程序时,程序的文件会被加载到内存中,产生进程,结合系统分配的资源完成运行,程序关闭或退出时,进程会结束.

POSIX标准(可移植操作系统接口 Portable Operating System Interface),为了统一 类UNIX操作系统编程接口,方便跨平台编程和程序的可移植。参考:posix是什么都不知道,就别说你懂Linux了!

进程处理机制

1个单核CPU(或CPU的一个核心)在一个时间点只能处理一个进程.

我们用电脑同时运行多个程序,是因为操作系统的”多道程序设计”技术,内核控制CPU在多道进程间切换,它将CPU的整个生命周期划分为多个长度相同的时间片,在每个时间片内只处理一个进程。因为时间片很小,我们会感觉这些软件同时都在运行。这种分时间片实现的多任务系统,我们把它叫分时系统

CPU划分的时间片是微小的(比如纳秒),以及CPU的运算速度非常快,所以使用时感觉是同时运行多个程序.多核CPU在同时,多进程运行方面比单核CPU有优势.

假如内存中只有3个进程A,B,C,CPU时间片分配情况

多进程切换时。把当前任务状态先保存起来,把另一个任务的状态恢复,并把执行权交给它即可。俗称上下文切换。任务的状态就是一堆寄存器的值。要切换进程,只需要保存和恢复一堆寄存器的值即可。

进程的属性

OS内核能够区分进程并可获取进程属性,进程属性保存在名为进程控制块(Process Control Block)的中结构体中,内核为每个进程维护一个进程控制块,用于管理进程属性.

标识符

(1)进程标识符(Process Identifier)PID,32位非负无符号整形数据,进程的唯一标识,用来标识不同进程.

(2)父进程标识符(Parent Process Identifier)PPID,创建子进程的父进程对应的PID,在linux系统中,除init进程(编号为1)外,其余进程都有父进程. 吗

(3)用户标识符(User Identifier) UID ,标识创建这个进程的用户。PCB结构体中有euid概念(Effective User Identifier) ,即有效用户标识符,标识以有效权限发起进程的用户。例:用户yangliuan 以root权限发起进程,那么进程的uid对应的用户为yangliuan,进程的euid对应用户为root

(4)组标识符(Group Identifier)GID,标识创建进程的用户所属组。euid对应的组标识符为egid(Effective Group Identifier)

<?php
echo '进程标识[PID]:', posix_getpid(), PHP_EOL;
echo '父进程标识符[PPID]:', posix_getppid(), PHP_EOL;
echo '用户标识符[UID]:', posix_getuid(), PHP_EOL;
echo '有效用户标识符[EUID]:', posix_geteuid(), PHP_EOL;
echo '组标识符[GID]:', posix_getgid(), PHP_EOL;
echo '有效组标识符[EGID]:', posix_getegid(), PHP_EOL;

进程的状态

(1)就绪态

进程所需资源已经分配到位,只等待CPU,当可以使用CPU时,进程会立即变为运行态,内核会维护一个运行对列,用来装载所有就绪态的进程,当CPU空闲时,内核会从队列中选择一个进程,为其分配CPU

(2)运行态

进程处于此状态时会占用CPU,处于此状态的进程数量必定小于等于处理器数量,因为每个CPU在一个时间点只能运行一个进程

(3)睡眠态

此状态的进程不能占用CPU

不可中断睡眠态,是由外部I/O调用造成,等待外部I/O硬件设备响应,此状态不可中断,即我们常说的阻塞。举例进程向硬盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态

可终端睡眠态,进程对应的当前用户请求已处理完毕,暂时退出退出CPU,当用户再次发出请求,会立即被唤醒,这种状态被称为挂起,程序中常用的方法是sleep() (php为例) ,类比可以理解为汽车已点火,但是没有往前开。

(4)终止态

进程已运行完毕,此时进程不会被调度,也不再占用CPU

进程状态转换示意图

寄存器信息

寄存器的数量是有限的,cpu在进行进程切换时,会保存当前进程的数据,以边下次切换回来的时候从中断处继续进行。该过程称为cpu的上下文切换。在服务端多进程编程模型中,进程数和cpu核数该如何匹配

页表指针

百度百科 页表机制

程序运行时,系统会为其开辟一段虚拟内存,虚拟内存和物理内存映射时,各个虚拟内存中的地址相同的数据会被MMU(Memory Managenment 内存管理单元) 映射的到内存中的不同物理地址,PCB会存储虚拟地址和内存地址的对应关系

linux采用分页存储方式管理内存,进程载入到内存之前,系统将用户进程的逻辑空间分成若干个大小相等的片(称 页面或页)并编号,为进程分配内存时,以块为单位将进程中的若干页装入多个可以不相邻的物理块中,linux使用页面表来存储逻辑地址和物理地址的对应关系,页表的实质是一个结构体,每个进程的PCB中都有一个进项页表的指针。

进程组与会话

同一个进程组(process group)的进程 ,进程组由用户启动的进程创建,用户启动进程是进程组的领导进程(process group leader) ,进程组中的领导进程pid是识别进程组id,即pgid

会话(session)是进程组的集合,会话中的每一个进程组称为一个工作job,

进程控制

linux启动时创建一个init进程,进程pid为1,是所有进程的父进程,负责启动getty进程,设置进程运行级别 回收孤儿进程。

linux系统对进程的控制主要包含:进程创建,进程任务转变,进程同步,退出进程

1.创建进程

多道程序环境(多任务处理操作系统,可以同时运行多个程序)中需要创建进程的情况通常有4种:用户登录,作业调度,用户请求,应用请求。

当一个程序执行时,可能需要申请一些资源,如打开某个文件、请求某项服务 ,根据cpu运行的机制此时进程会进入睡眠态并放弃占用cpu,若要申请的资源与之后操作并不冲突,为了保障当前进程的持续进行(走完当前时间片),此时可以内存中在创建一个进程,让新的进程代替原进程执行资源申请的工作。

linux使用fork函数创建进程,系统会创建一个与原进程近乎相同的进程,之后父子进程都继续往下执行。如图

fork函数创建子进程

2.创建多个进程

fork函数创建进程时,系统会复制原程序,因此在通过父进程循环创建子进程时,要判断是不是父进程,只有父进程才能fork。

数据共享机制

子进程可以访问到与父进程完全相同的代码信息、数据信息和堆栈信息,在调用fork()函数时,遵循“读时共享写时复制”原则。

fork()函数创建子进程后,子进程获得父进程的数据空间,堆栈,页表,等副本,此时父子进程中变量的虚拟地址相同,虚拟地址对应的物理地址也相同,父子进程共享物理内存的页面信息,为了防止一方修改导致另一方出现访问异常,系统将页面信息标记为制度,fork()函数执行完毕。

之后父子进程都继续向下执行:此时子进程拥有与父进程相同的页表,若进程只需要进行数据访问,则到对应的物理地址中便能获取到数据,因为父子进程相同虚拟空间对应相同的物理地址,其访问机制如图。

读取时共享

若子进程要对数据段,堆栈中的数据进行修改, 系统会将待操作数据复制到内存中一块新的区域,修改副本数据为可写。之后子进程修改数据副本,因此父子进程可以保存各自的数据,父子进程中相同的虚拟地址对应内存中不同的物理地址。访问机制如图

写时复制

注意事项,同样的虚拟地址对应不通的物理地址,因为虚拟地址适合进程关联的,每个进程都有一段0~4G的虚拟内存,因此多个进程中会有数据处于相同虚拟地址 ,但虚拟内存只是系统的内存管理的一种技术,目的是使进程认为自己有一段连续的地址空间,方便分配与数据管理,他不是“实际”的,进程中的数据实际存在于内存对应的物理地址

<?php
//获取当期那进程id
$pid = posix_getpid();
echo "my pid: {$pid}", PHP_EOL;
$childNum = 5;
global $a;
$a = 1;
for ($i = 1; $i <= $childNum; ++$i) {
//fork一个进程
$pid = pcntl_fork();
//创建失败
if (-1 === $pid) {
echo "failt to fork!", PHP_EOL;
exit;
} elseif( $pid == 0 ) {
//当前进程pid
$mypid = posix_getpid();
//父进程pid
$parentpid = posix_getppid();
//子进程中操作父进程变量并显示结果
$a++;
echo "I'm the {$i}th child and my pid:{$mypid},parentpid:{$parentpid} a={$a}", PHP_EOL;
sleep($childNum);
exit;
} elseif ($pid > 0) {
//parent code
echo "fork the {$i}th child,pid:{$pid} a={$a}", PHP_EOL;
}
}

代码运行结果,全局变量a的值始终为2说明,无法修改父进程的值s

my pid: 37018
fork the 1th child,pid:37019 a=1
I'm the 1th child and my pid:37019,parentpid:37018  a=2
fork the 2th child,pid:37020 a=1
I'm the 2th child and my pid:37020,parentpid:37018  a=2
fork the 3th child,pid:37021 a=1
I'm the 3th child and my pid:37021,parentpid:37018  a=2
fork the 4th child,pid:37022 a=1
I'm the 4th child and my pid:37022,parentpid:37018  a=2
fork the 5th child,pid:37023 a=1
I'm the 5th child and my pid:37023,parentpid:37018  a=2

进程的执行顺序

在linux系统中,子进程应该由父进程回收,但是当在子进程被创建后,他与父进程及其他进程共同竞争系统资源,所以父子进程执行顺序是不确定 ,终止的先后顺序也是不确定。(在没有人为控制的情况下,比如在父进程使用wait sleep函数

fork函数在执行时,会复制父进程的代码,当分支较多时,代码比较庞大,每次fork时都要将所有代码复制一次,如此代码冗余造成的空间浪费不可忽视。可以将多于代码封装起来,在需要时使用exec函数族调用执行。

孤儿进程

父进程应该负责子进程的回收工作,但父子进程是异步运行的,若父进程在子进程退出之前退出,子进程就会变成孤儿进程,此时子进程会被init进程收养,之后init会替代原来的父进程完成状态收集工作。避免孤儿的方法:sleep()函数 wait()函数

僵尸进程

当进程调用了exit()函数之后,该进程并不是马上消失,而是留下一个称为僵尸进程的数据结构,僵尸进程是linux系统中另一种特殊进程,它几乎放弃了进程退出之前占用的所有内存,即没有可执行代码,也不能被调度,只能在进程列表中保留一个位置,记载进程的退出状态等信息供父进程收集。若父进程中没有回收子进程的代码,子进程将会一直处于僵尸态。

守护进程(daemon process) 后台进程、

在后台运行的一种特殊进程,通常在系统启动时启动,并在系统关闭时终止。它们通常不与用户交互,而是在后台执行某些任务,例如监视文件系统或网络连接,或者执行定期任务。它们通常以超级用户(root)权限运行,以便可以执行需要特权的任务。原理,fork一个子进程,父进程退出与前台终端的交互,设置子进程为会话领导者。可以通过信号来控制启动关闭。

daemon希腊神话半人半精灵守护神

进程同步

在多道程序环境中,进程是并行执行的,父进程与子进程可能没有交集,各自独立执行,子进程的执行结果是父进程的下一步操作的先决条件,此时父进程必须等待子进程执行。我们把异步环境下的一组并发进程因相互制约而互相发送消息、互相合作、互相等待、使各个进程按一定的速度和顺序执行称为进程间的同步。

sleep()函数来控制进程的执行顺序,但这种方法是一种权益之计,系统中进程的执行顺序是由内核决定的,这种方法很难做到对进程精确控制

linux系统中提供了wait()函数 waitpid()函数(php中PCNTL提供了这两个函数)来获取进程状态,实现进程同步。调用wait()函数的进程

参考

ubuntu 启动项管理工具

参考

启动软件图形化管理工具

单机show application 显示所有应用 搜索 startup application

可以通过 add remove edit 添加,删除,编辑来管理启动软件,该软件是ubuntu系统自带的

有些应用没有显示出来可以通过下列命令设置

sudo sed -i 's/NoDisplay=true/NoDisplay=false/g' /etc/xdg/autostart/*.desktop

执行之后多了好多软件

管理服务

Ubuntu或者Debian系统中update-rc.d命令,是用来更新系统启动项的脚本。这些脚本的链接位于/etc/rcN.d/目录,对应脚本位于/etc/init.d/目录。在了解update-rc.d命令之前,你需要知道的是有关Linux系统主要启动步骤,以及Ubuntu中运行级别的知识。

Linux系统主要启动步骤


读取 MBR 的信息,启动 Boot Manager。   
加载系统内核,启动 init 进程, init 进程是 Linux 的根进程,所有的系统进程都是它的子进程。   
init 进程读取 /etc/inittab 文件中的信息,并进入预设的运行级别。通常情况下/etc/rcS.d/ 目录下的启动脚本首先被执行,然后是/etc/rcN.d/ 目录。
根据 /etc/rcS.d/文件夹中对应的脚本启动 Xwindow 服务器 xorg,Xwindow 为 Linux 下的图形用户界面系统。
启动登录管理器,等待用户登录。

Ubuntu 中的运行级别

0 (关闭系统) 
1 (单用户模式,只允许root用户对系统进行维护。) 
2 到 5(多用户模式,其中3为字符界面,5为图形界面。) 
6 (重启系统)

切换运行级别

init [0123456Ss]
init 0 #命令关机; 
init 6 #命令重新启动

update-rc.d 的具体用法:

删除所有级别中的开机自启动 

update-rc.d -f <basename> remove 
-f: 强制删除所有符号链接 

basename就是要删除的程序的名称

删除boa的所有开机启动项:
sudo update-rc.d -f  boa remove

执行结果:

 Removing any system startup links for /etc/init.d/boa ...
   /etc/rc0.d/K20boa
   /etc/rc1.d/K20boa
   /etc/rc2.d/K20boa
   /etc/rc3.d/K20boa
   /etc/rc4.d/K20boa
   /etc/rc5.d/K20boa
   /etc/rc6.d/K20boa
添加boa开机启动项
sudo update-rc.d boa default

启动项终端图形管理界面

sudo apt-get install sysv-rc-conf

如果提示错误 Unable to locate package sysv-rc-conf,按如下方法处理

//1.编辑源文件
sudo gedit /etc/ap/sources.list
//2.将一下文本添加到文件中,如下图
deb http://archive.ubuntu.com/ubuntu/ trusty main universe restricted multiverse
//3.执行sudo apt update 更新后 重新安装

图形界面执行 sudo sysv-rc-conf

virtualbox 网络设置

参考

简介 virtual有四种网络模式

1.NAT Network Address Translation 网络地址转换

NAT模式是最简单的实现虚拟机上网的方式

Guest访问网络的所有数据都是由主机提供的,Guest并不真实存在于网络中,主机与网络中的任何机器都不能查看和访问到Guest的存在。

Guest可以访问主机能访问到的所有网络,但是对于主机以及主机网络上的其他机器,Guest又是不可见的,甚至主机也访问不到Guest。

  • 虚拟机与主机的关系:只能单向访问,虚拟机可以通过网络访问到主机,主机无法通过网络访问到虚拟机。
  • 虚拟机与网络中其他主机的关系:只能单向访问,虚拟机可以访问到网络中其他主机,其他主机不能通过网络访问到虚拟机。
  • 虚拟机与虚拟机的关系:相互不能访问,虚拟机与虚拟机各自完全独立,相互间无法通过网络访问彼此。

2.Bridged Adapter 网桥模式

使用桥接模式的虚拟机真实存在于网络中相当于一天独立的电脑

它是通过主机网卡,架设了一条桥,直接连入到网络中了。因此,它使得虚拟机能被分配到一个网络中独立的IP,所有网络功能完全和在网络中的真实机器一样。

网桥模式下的虚拟机,相当于真实存在于网络环境中的电脑.

  • 虚拟机与主机的关系:可以相互访问,因为虚拟机在真实网络段中有独立IP,主机与虚拟机处于同一网络段中,彼此可以通过各自IP相互访问。
  • 虚拟机于网络中其他主机的关系:可以相互访问,同样因为虚拟机在真实网络段中有独立IP,虚拟机与所有网络其他主机处于同一网络段中,彼此可以通过各自IP相互访问。
  • 虚拟机与虚拟机的关系:可以相互访问,原因同上。

3.Internal 内网模式

虚拟机与外网完全断开,只实现虚拟机于虚拟机之间的内部网络模式。

  • 虚拟机与主机的关系:不能相互访问,彼此不属于同一个网络,无法相互访问。
  • 虚拟机与网络中其他主机的关系:不能相互访问,理由同上。
  • 虚拟机与虚拟机的关系:可以相互访问,前提是在设置网络时,两台虚拟机设置同一网络名称.

4.Host-only Adapter 主机模式

主机模式,这是一种比较复杂的模式,需要有比较扎实的网络基础知识才能玩转。可以说前面几种模式所实现的功能,在这种模式下,通过虚拟机及网卡的设置都可以被实现。

我们可以理解为Guest在主机中模拟出一张专供虚拟机使用的网卡,所有虚拟机都是连接到该网卡上的,我们可以通过设置这张网卡来实现上网及其他很多功能,比如(网卡共享、网卡桥接等)。

  • 虚拟机与主机的关系:默认不能相互访问,双方不属于同一IP段,host-only网卡默认IP段为192.168.56.X 子网掩码为255.255.255.0,后面的虚拟机被分配到的也都是这个网段。通过网卡共享、网卡桥接等,可以实现虚拟机于主机相互访问。
  • 虚拟机与网络主机的关系:默认不能相互访问,原因同上,通过设置,可以实现相互访问。
  • 虚拟机与虚拟机的关系:默认可以相互访问,都是同处于一个网段

对比表格

NATBridged AdapterInternalHost-only Adapter
虚拟机-主机 O O X 默认不能需设置
主机-虚拟机 X O X 默认不能需设置
虚拟机-其它主机 O O X 默认不能需设置
其 它主机-虚拟机 X O X 默认不能需设置
虚拟机之间 X O 同网络O O

配置需求

需要模拟集群环境配置宿主机可以访问虚拟机,虚拟机之间可以相互访问

方案一

使用桥接模式,什么问题都能解决.缺点使用DHCP获取的动态ip,更换网络环境,需要修改应用配置,如mysql,redis连接.如果使用静态id,更换网络环境时可能造成ip冲突

方案二

Linux 软件管理常用命令

yum 和 rpm 软件管理

rpm命令 yum命令

yum下载软件包方法,应用场景,大型国企生产环境不允许开放外网

通过yum命令只下载rpm包不安装

yum 下载全量依赖 rpm 包及离线安装(终极解决方案

dnf软件管理

dnf命令

APT工具(新立得)

apt的全称是Advanced Packaging Tool是Linux系统下的一款安装包管理工具

保持依赖不更新

sudo apt-mark hold libqt5core5a libqt5dbus5 libqt5gui5 libqt5network5 libqt5qml5 libqt5qmlmodels5 libqt5quick5 libqt5widgets5

取消依赖不更新

sudo apt-mark unhold libqt5core5a libqt5dbus5 libqt5gui5 libqt5network5 libqt5qml5 libqt5qmlmodels5 libqt5quick5 libqt5widgets5

PPA管理

apt-key命令

sudo apt-key list
会出现这样:
pub   1024R/B455BEF0 2010-07-29
uid                  Launchpad clicompanion-nightlies
删除想删除的
sudo apt-key del B455BEF0

添加PPA源的命令为:
sudo add-apt-repository ppa:user/ppa-name
添加好更新一下: sudo apt-get update
删除命令格式则为:
sudo add-apt-repository -r ppa:user/ppa-name

或者
到源的目录:cd  /etc/apt/sources.list.d/ 可以看到关于源的文件,删除即可 

DPKG

dpkg 是Debian package的简写,为”Debian“ 操作系统 专门开发的套件管理系统,用于软件的安装,更新和移除。

所有源自”Debian”的Linux的发行版都使用 dpkg,   例如”Ubuntu”。

dpkg本身是一个底层的工具。上层的工具,如APT,被用于从远程获取软件包以及处理复杂的软件包关系。 

安装指定软件包

dpkg -i|--install <.deb file name> ... | -R|--recursive <directory> ...
ex:dpkg -i -R /dirname 安装目录下的所有deb包

解压软件包

dpkg --unpack <.deb file name> ... | -R|--recursive <directory> ...
ex:dpkg --unpack -R /dirname 解压目录下的deb包

重新配置和释放软件包

dpkg --configure <package> ... | -a|--pending
-a 将配置所有没有配置的软件包 

dpkg  --triggers-only <package> ... | -a|--pending

移除软件包

dpkg -r|--remove <package> ... | -a|--pending

移除软件包和配置

dpkg -P|--purge  <package> ... | -a|--pending

-V|–verify <软件包名> … 检查包的完整性

–get-selections [<表达式> …] 把已选中的软件包列表打印到标准输出

–set-selections 从标准输入里读出要选择的软件

–clear-selections 取消选中所有不必要的软件包

–update-avail <软件包文件> 替换现有可安装的软件包信息

–merge-avail <软件包文件> 把文件中的信息合并到系统中

–clear-avail 清除现有的软件包信息

–forget-old-unavail 忘却已被卸载的不可安装的软件包

-s|–status <软件包名> … 显示指定软件包的详细状态

-p|–print-avail <软件包名> … 显示可供安装的软件版本

-L|–listfiles <软件包名> … 列出属于指定软件包的文件 查看已安装文件的路径

dpkg -L libwebp-dev
/usr
/usr/include
/usr/include/webp
/usr/include/webp/decode.h
...

-l|–list [<表达式> …] 简明地列出软件包的状态

-S|–search <表达式> … 搜索含有指定文件的软件包

-C|–audit [<表达式> …] 检查是否有软件包残损

–yet-to-unpack 列出标记为待解压的软件包

–predep-package 列出待解压的预依赖

–add-architecture <体系结构> 添加 <体系结构> 到体系结构列表

–remove-architecture <体系结构> 从架构列表中移除 <体系结构>

–print-architecture 显示 dpkg 体系结构 指的是cpu的体系架构 例amd64

–print-foreign-architectures 显示已启用的异质体系结构

–assert-<特性> 对指定特性启用断言支持

–validate-<属性> <字符串> 验证一个 <属性>的 <字符串>

–compare-vesions <a> <关系> <b> 比较版本号 – 见下

–force-help 显示本强制选项的帮助信息

-Dh|–debug=help 显示有关出错调试的帮助信息
-?, –help 显示本帮助信息

–version 显示版本信息
Assert 特性: support-predepends, working-epoch, long-filenames, multi-conrep, multi-arch, versioned-provides.
可验证的属性:pkgname, archname, trigname, version.
调用 dpkg 并带参数 -b, –build, -c, –contents, -e, –control, -I, –info, -f, –field, -x, –extract, -X, –vextract, –ctrl-tarfile, –fsys-tarfile是针对归档文件的 (输入 dpkg-deb –help 获取帮助)
选项:

–admindir=<目录> 使用 <目录> 而非 /var/lib/dpkg

–root=<目录> 安装到另一个根目录下

–instdir=<目录> 改变安装目录的同时保持管理目录不变

–path-exclude=<表达式> 不要安装符合Shell表达式的路径

–path-include=<表达式> 在排除模式后再包含一个模式

-O|–selected-only 忽略没有被选中安装或升级的软件包

-E|–skip-same-version 忽略版本与已安装软件版本相同的软件包

-G|–refuse-downgrade 忽略版本早于已安装软件版本的的软件包

-B|–auto-deconfigure 就算会影响其他软件包,也要安装

–[no-]triggers 跳过或强制随之发生的触发器处理

–verify-format=<格式> 检查输出格式(‘rpm’被支持)

–no-debsig 不去尝试验证软件包的签名

–no-act|–dry-run|–simulate 仅报告要执行的操作 – 但是不执行

-D|–debug=<八进制数> 开启调试(参见 -Dhelp 或者 –debug=help)

–status-fd <n> 发送状态更新到文件描述符<n>

–status-logger=<命令> 发送状态更新到 <命令> 的标准输入

–log=<文件名> 将状态更新和操作信息到 <文件名>

–ignore-depends=<软件包>,… 忽略关于 <软件包> 的所有依赖关系

–force-… 忽视遇到的问题(参见 –force-help)

–no-force-…|–refuse-… 当遇到问题时中止运行

–abort-after <n> 累计遇到 <n> 个错误后中止


可供–compare-version 使用的比较运算符有:

lt le eq ne ge gt (如果版本号为空,那么就认为它先于任意版本号);

lt-nl le-nl ge-nl gt-nl (如果版本号为空,那么就认为它后于任意版本号);

< << <= = >= >> > (仅仅是为了与主控文件的语法兼容)

Snap 官方文档

Snap是Canonical推出的一种新的软件打包格式,彻底解决linux依赖性的问题,Snap 软件包拥有更加稳定和安全的特性。snap也就是安装snap软件包的命令。

安装snap

sudo apt install snap 

列出计算机上所有snap安装情况:

sudo snap list

在应用商店中查找snap:

sudo snap find <软件包名>

安装Snap软件:

sudo snap install <snap软件包名>


更新Snap软件:

sudo snap refresh <snap软件包名>

更新所有的snap软件包:

sudo snap refresh

要将Snap还原到以前安装的版本:

sudo snap revert <snap软件包名>

卸载snap软件:

sudo snap remove <snap软件包名>

参考

Linux网络调试 常用命令和分析工具 排查方法

查看/配置网络

ifconfig 查看IP地址

https://wangchujiang.com/linux-command/c/ifconfig.html

enx00e04cf0a10c: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.5  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 2408:8207:305c:1c30:b48f:56c7:81bb:bb9  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::2c1b:1b85:35cd:9642  prefixlen 64  scopeid 0x20<link>
        inet6 2408:8207:305c:1c30:e49b:195a:eeaa:1e44  prefixlen 64  scopeid 0x0<global>
        ether 00:e0:4c:f0:a1:0c  txqueuelen 1000  (Ethernet)
        RX packets 29715  bytes 31484642 (31.4 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22107  bytes 3794564 (3.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 4003  bytes 2920205 (2.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4003  bytes 2920205 (2.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
wlp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.111  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::6e92:514f:2d68:1da1  prefixlen 64  scopeid 0x20<link>
        ether 14:4f:8a:60:f2:2a  txqueuelen 1000  (Ethernet)
        RX packets 106  bytes 9074 (9.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 129  bytes 19965 (19.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

e开头的一般是有线网卡 例eth

lo 全称是 loopback,又称环回接口,往往会被分配到 127.0.0.1 这个地址。这个地址用于本机通信,经过内核处理后直接返回,不会在任何网络中出现

wlp开头表示无线网卡

flags = 4163 没有搜到什么意思

UP表示接口启用

BROADCAST 表示主机支持广播

RUNNING 表示接口正在工作

MULTICAST 主机支持多播

MTU:1500 最大传输单元 1500字节 百科

inet 网卡的IP地址

netmask 网络掩码

broadcast 广播地址

inet6 fe80::2aa:bbff:fecc:ddee prefixlen 64 scopeid 0x20<link> IPv6地址

ether 00:e0:4c:f0:a1:0c 连接类型:Ethernet (以太网) HWaddr (硬件mac地址)

txqueuelen (网卡设置的传送队列长度)

RX packets 接收时,正确的数据包数

RX bytes 接收的数据量

RX errors 接收时,产生错误的数据包数

RX overruns 接收时,由于速度过快而丢失的数据包数

RX dropped 接收时,丢弃的数据包数

RX frame 接收时,发生frame错误而丢失的数据包数

TX carrier 发送时,发生carrier错误而丢失的数据包数

TX collisions 冲突信息包的数目

mii-tool 配置网络设备协商方式的工具

https://wangchujiang.com/linux-command/c/mii-tool.html

是用于查看、管理介质的网络接口的状态,有时网卡需要配置协商方式,比如10/100/1000M的网卡半双工、全双工、自动协商的配置。但大多数的网络设备是不用我们来修改协商,因为大多数网络设置接入的时候,都采用自动协商来解决相互通信的问题。不过自动协商也不是万能的,有时也会出现错误,比如丢包率比较高,这时就要我们来指定网卡的协商方式。mii-tool就是能指定网卡的协商方式。下面我们说一说mii-tool的用法。

sudo mii-tool -v enx00e04cf0a10c
enx00e04cf0a10c: negotiated 100baseTx-FD, link ok
product info: vendor 00:07:32, model 0 rev 0
basic mode: autonegotiation enabled
basic status: autonegotiation complete, link ok
capabilities: 1000baseT-FD 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
advertising: 1000baseT-FD 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD

link ok 表示网线连接ok

basic mode: autonegotiation enabled 启用自动协商

route 查看网关

https://wangchujiang.com/linux-command/c/route.html

显示并设置Linux中静态路由表

常用方式 route -n 不执行DNS反向查找,直接显示数字形式的IP地址

route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 enx00e04cf0a10c
0.0.0.0         192.168.0.1     0.0.0.0         UG    600    0        0 wlp4s0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 wlp4s0
192.168.0.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp4s0
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 enx00e04cf0a10c

ip 网络配置工具

https://wangchujiang.com/linux-command/c/ip.html

用来显示或操纵Linux主机的路由、网络设备、策略路由和隧道

支持信息的object

OBJECT := { link | address | addrlabel | route | rule | neigh | ntable | tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm | netns | l2tp | macsec | tcp_metrics | token }

nc 全称netcat

用于设置路由器。它能通过 TCP 和 UDP 在网络中读写数据。通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它。

https://wangchujiang.com/linux-command/c/nc.html

查看端口实例

nc -vz xiaoyuapi.zcoming.com 443 -w2
Connection to xiaoyuapi.zcoming.com 443 port [tcp/https] succeeded!

故障排除

ping 测试主机之间网络的连通性

https://wangchujiang.com/linux-command/c/ping.html

执行ping指令会使用ICMP传输协议,发出要求回应的信息,若远端主机的网络功能没有问题,就会回应该信息,因而得知该主机运作正常

traceroute 显示数据包到主机间的路径

https://wangchujiang.com/linux-command/c/traceroute.html

用于追踪数据包在网络上的传输时的全部路径,它默认发送的数据包大小是40字节。

通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。

traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。一条路径上的每个设备traceroute要测3次。输出结果中包括每次测试的时间(ms)和设备的名称(如有的话)及其ip地址。

traceroute www.58.com
traceroute to www.58.com (211.151.111.30), 30 hops max, 40 byte packets
 1  unknown (192.168.2.1)  3.453 ms  3.801 ms  3.937 ms
 2  221.6.45.33 (221.6.45.33)  7.768 ms  7.816 ms  7.840 ms
 3  221.6.0.233 (221.6.0.233)  13.784 ms  13.827 ms 221.6.9.81 (221.6.9.81)  9.758 ms
 4  221.6.2.169 (221.6.2.169)  11.777 ms 122.96.66.13 (122.96.66.13)  34.952 ms 221.6.2.53 (221.6.2.53)  41.372 ms
 5  219.158.96.149 (219.158.96.149)  39.167 ms  39.210 ms  39.238 ms
 6  123.126.0.194 (123.126.0.194)  37.270 ms 123.126.0.66 (123.126.0.66)  37.163 ms  37.441 ms
 7  124.65.57.26 (124.65.57.26)  42.787 ms  42.799 ms  42.809 ms
 8  61.148.146.210 (61.148.146.210)  30.176 ms 61.148.154.98 (61.148.154.98)  32.613 ms  32.675 ms
 9  202.106.42.102 (202.106.42.102)  44.563 ms  44.600 ms  44.627 ms
10  210.77.139.150 (210.77.139.150)  53.302 ms  53.233 ms  53.032 ms
11  211.151.104.6 (211.151.104.6)  39.585 ms  39.502 ms  39.598 ms
12  211.151.111.30 (211.151.111.30)  35.161 ms  35.938 ms  36.005 ms

记录按序列号从1开始,每个纪录就是一跳 ,每跳表示一个网关,我们看到每行有三个时间,单位是ms,其实就是-q的默认参数。探测数据包向每个网关发送三个数据包后,网关响应后返回的时间;如果用traceroute -q 4 www.58.com,表示向每个网关发送4个数据包。

有时我们traceroute一台主机时,会看到有一些行是以星号表示的。出现这样的情况,可能是防火墙封掉了ICMP的返回信息,所以我们得不到什么相关的数据包返回数据。

有时我们在某一网关处延时比较长,有可能是某台网关比较阻塞,也可能是物理设备本身的原因。当然如果某台DNS出现问题时,不能解析主机名、域名时,也会 有延时长的现象;您可以加-n参数来避免DNS解析,以IP格式输出数据。

如果在局域网中的不同网段之间,我们可以通过traceroute 来排查问题所在,是主机的问题还是网关的问题。如果我们通过远程来访问某台服务器遇到问题时,我们用到traceroute 追踪数据包所经过的网关,提交IDC服务商,也有助于解决问题;但目前看来在国内解决这样的问题是比较困难的,就是我们发现问题所在,IDC服务商也不可能帮助我们解决。

mtr My traceroute

https://www.cnblogs.com/alexyuyu/articles/2811346.html

Linux 网络诊断工具MTR(My traceroute) 结合了ping跟tracert的一个工具

首先看最后一行,目标服务器有没有丢包,有的话再往前分析。

测试指定端口实例

sudo mtr -P 443 -i 0.5 -rwc 50 xiaoyuapi.zcoming.com

nslookup

是常用域名查询工具,就是查DNS信息用的命令。

https://wangchujiang.com/linux-command/c/nslookup.html

非交互模式直接加域名

nslookup xiaoyuapi.zcoming.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	xiaoyuapi.zcoming.com
Address: 47.92.203.163

telnet 登录远程主机和管理(测试ip端口是否连通)

https://wangchujiang.com/linux-command/c/telnet.html

telnet因为采用明文传送报文,安全性不好,很多Linux服务器都不开放telnet服务,而改用更安全的ssh方式了。但仍然有很多别的系统可能采用了telnet方式来提供远程登录,因此弄清楚telnet客户端的使用方式仍是很有必要的

检测端口,如下表示端口正常

telnet xiaoyuapi.zcoming.com 443
Trying 47.92.203.163...
Connected to xiaoyuapi.zcoming.com.
Escape character is '^]'.

tcpdump

https://wangchujiang.com/linux-command/c/tcpdump.html

 是一款抓包,嗅探器工具,它可以打印所有经过网络接口的数据包的头信息,也可以使用-w选项将数据包保存到文件中,方便以后分析

netstat 查看Linux中网络系统状态信息

https://wangchujiang.com/linux-command/c/netstat.html

可以查看网络协议tcp/udp ip地址监听状态 程序进程id等

netstat -ltnp //查看监听中的进程

ss socket统计信息

https://wangchujiang.com/linux-command/c/ss.html

比 netstat 好用的socket统计信息,iproute2 包附带的另一个工具,允许你查询 socket 的有关统计信息

命令安装

有些发行版可能没有这些命令需要自己安装

net-tools包含以下常用的命令:apt-get install net-tools

  • ifconfig:显示和配置网络接口的信息。
  • netstat:显示网络连接、路由表和网络统计信息。
  • arp:显示和操作ARP缓存。
  • route:显示和操作IP路由表。
  • hostname:显示或设置系统的主机名。

iproute2包含以下常用的命令: apt-get install iproute2

  • ip:用于配置和管理网络接口、路由表、策略路由、隧道、桥接等各种网络参数。
  • ss:显示套接字统计信息,包括网络连接、监听端口、进程关联的套接字等。
  • bridge:用于配置和管理网络桥接。
  • tc:配置和管理流量控制策略。
  • ipset:管理iptables使用的IP集合。
  • nstat:显示网络统计信息。
  • rtacct:显示路由表统计信息。

traceroute命令需要 apt-get install traceroute

网络监控工具

nethogs https://wangchujiang.com/linux-command/c/nethogs.html

//安装
sudo apt install nethogs
sudo yum install nethogs

//使用
sudo nethogs -d 1
sudo nethogs eth0 -d 1
GUI

网络问题排查思路

1.查看服务器服务是否正常,你的网络能否正常访问

当用户反馈APP或网站无法访问或卡顿的时候,首先用你的网络测试一下能否正常访问,

然后排查服务器是否有问题CPU,内存,网络,指标是否正常,进程数量,TCP连接数量 平均负载

各种日志,负载均衡日志,nginx日志,程序日志

2.客户端排查,收集详细的用户反馈

先让用户访问一些常用的网站和app,比如百度等,排除是否是用户的网络问题

收集问题用户数据,手机型号, 操作系统,网络类型(3G,4G,wifi) 运营商(移动,联通,电信),点击哪个模块哪个功能出现的网络故障提示,什么时间点,最好能录屏或者截个图。

或者在程序中增加功能,网络不好的时候弹窗提示用户反馈信息,用户点击反馈按钮收集客户端的ip操作系统型号,上报给服务器并记录下来,通过ip可以获取网络运营商的信息。

3.通过第三方测试平台,模拟用户的网络环境

站长之家测速工具

云服务提供商也用类似站点监控的工具 通过以上工具测试否为运营商问题

4.APP(移动测试)远程真机调试

参考

手机远程真机调试平台汇总
有哪些好用的App云测试平台

目前对移动App的测试主要指的是下面几部分:

兼容性测试——App对不同手机、操作系统版本的兼容性测试,包括安装、启动、卸载等。
功能测试——遍历应用的每一个角落,查看应用的功能、逻辑是否正常,完整。
性能测试——应用的性能怎样,如启动时间、反应时间、CPU占用率,内存占用率等。
稳定性测试——在一定时间内对App进行持续地测试,测试App运行的稳定性。
网络场景测试——测试不同网络环境中App的运行状况,如2G&3G,弱网络等。

Testin:Testin云测|全球领先的App及手游测试平台

腾讯优测:优测网-让测试更简单

贯众云测试:贯众云测试

百度MTC:百度移动云测试中心

阿里MQC:MQC 阿里移动质量中心

参考


UbuntuServer 18.04以上安装教程

1.请选择首选语言

2.请在下面选择您的键盘布局,或选择“识别键盘”以自动检测您的布局

3.欢迎使用Ubuntu ,世界上最受欢迎的 云,集群,和令人惊叹的物联网平台.这是ubuntu在服务器和网络设备上的安装

  • 1.安装ubuntu
  • 2.3 云平台安装 MAAS https://maas.io

4.配置网卡

5.配置代理

不需要代理直接 选择Done

选择镜像地址

推荐使用国内镜像,国外镜像由于墙的问题可能安装失败

https://mirrors.aliyun.com/ubuntu/

文件系统安装
  • 使用整个磁盘
  • 使用真个磁盘并且换装LVM(推荐)
  • 手动安装
选择磁盘安装
磁盘选项

采用默认配置

资料设置
选择安装openssh server

选择软件跳过,进入安装

重启进入登录界面,输入用户名密码

安装增强功能配置并共享文件夹

1.更新系统软件

sudo apt update && sudo apt upgrade

2.安装增强功能

设备>>安装增强功能

点击右下角光驱选择 /usr/share/virtualbox/VBoxGuestAdditions.iso

3.安装工具 dkms build-essential

sudo apt-get install dkms 
sudo apt-get install build-essential

4.挂在光驱

 sudo mount /dev/cdrom /mnt/
挂在成功

5.安装增加功能包

sudo /mnt/VBoxLinuxAdditions.run

6.配置共享文件夹(点击虚拟机设置或右下角文件夹图标)

挂载点名称

7.挂载磁盘 sudo mount -t vboxsf [挂在点名称] [挂载后的本地路径]

sudo mount -t vboxsf downloads /home/www/share

开启root登录

#设置root密码
sudo passwd root

vim /etc/ssh/sshd_config
添加#注释掉PermitRootLogin Prohibit-password
添加:PermitRootLogin yes

#重启sshd
serivce sshd restart

自建SSR服务器

作为一个码农如果不能翻墙上Google,工作起来很不方便.以前买过国产的梯子流量都没用完就挂了.lantern免费版有流量限制,收费版赶山一台vps的费用了.最后决定自己搭建一个.

购买一台VPS

参考链接https://tlanyan.me/vps-merchant-collection/

最后选择AWS Lightsail廉价版的AWS,月资费3.5刀起,需要信用卡

https://aws.amazon.com/cn/lightsail/

创建过程按照指引即可,云服务器创建大同小异,需要注意的是,AWS使用的免密登录,创建完成后记得下载秘钥文件

给代理端口添加白名单

搭建ssr服务端

参考https://cndaqiang.github.io/2017/09/28/ubuntu1604-ssr/#%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98

安装python

$ sudo apt-get update
$ sudo apt-get install python

下载安装包

$ mkdir shadowsocksr
$ cd shadowsocksr/
$ wget https://github.com/cndaqiang/shadowsocksr/archive/manyuser.zip
fork了一个仓库用于备份
https://github.com/yangliuan/shadowsocksr

安装配置

$ sudo apt-get install unzip
$ unzip manyuser.zip 
cd shadowsocksr-manyuser/

解压之后修改配置文件 config.json

  • server 服务器公网IP
  • server_ipv6 服务器ipv6
  • server_port 代理端口
  • pasword 密码
  • method 加密方式 这里使用aes-256-cfb
  • protocol 协议 origin
  • obfs 混淆方式 http_simple
  • additional 多租户配置

基本操作 启动 停止

sudo  python ./shadowsocks/server.py -c config.json -d start
sudo  python ./shadowsocks/server.py -c config.json -d stop

配置开机启动

方式很多略过

配置ssr客户端

参考链接https://alanlee.fun/2018/05/18/ubuntu-ssr/

github https://github.com/erguotou520/electron-ssr 作者已删除

备份地址 https://github.com/qingshuisiyuan/electron-ssr-backup

下载deb安装包,安装成功后/opt下会有electron-ssr 如果没有出现快捷方式,可能是安装有问题(权限),可以重启后再试试

其它操作系统参考文档

客户端配置项要与服务端一致

客户端配置项

WEB应用常见漏洞

Sql注入

原理:利用网页程序没有对传参进行过滤,执行不允许的sql语句获取重要数据 百度百科 维基百科

防御

后端程序对请求参数进行严格过滤,使用框架的查询构造器和ORM操作Sql,禁止直接用代码拼接sql语句

SQL注入详解

XSS(Cross site scripting 跨站脚本攻击)

原理 前端运行了用户输入的恶意js脚本

MDN说明

防御

php函数htmlspecialchars转义html标签

过滤敏感js标签 ezyang/htmlpurifier

现代前端框架会自动处理xss问题

PHP防御 XSS 安全漏洞 – HTMLPurifier

如何防止XSS攻击?美团点评

PHP如何防止XSS攻击

CSRF(Cross-site request forgery 跨站请求伪造)

原理 MDN文档说明

防御

如何防止CSRF攻击?-美团点评

SSRF(Server-Side Request Forgery 服务器端请求伪造)

原理

防御

XXE(XML外部实体注入)

原理

防御

参考

Linux 文件权限

linux基本权限

ll 查看文件详情
说明

基本权限

左侧第一栏 -drwxr-xr-x表示权限,共10位字符

1.第一位字符表示文件类型

d 目录

– 文件

l 软链接

b 块设备(存储设备接口)文件 如,磁盘

c 串行端口设备 如 键盘 鼠标 usb 等

s 套接字文件 (socket) ,用于进程间通信

p 管道文件 FIFO pipe 用于解决多个程序访问一个文件时造成的错误问题

2.后九位没三位一组表示 user(所有者) group(所属组) other(其它人)的权限

3.操作权限

linux 三种权限

r : 文件=>读取文件内容( 可用命令 cat more head tail) 目录=>列出目录(ls ll)

w: 文件=>编辑 、新增、修改文件内容(vi echo). 不包括删除文件,删除文件需要文件所在目录(上级)拥有w 和 x权限 . 目录=>新建 删除文件目录, 重命名 移动 (touch rm mv cp)

写文件内容(文件本身) 和 创建删除文件 是不同的权限啊(所在目录),

x:执行权限

权限的作用范围仅限子级