mysql 读写分离

origine : https://juejin.cn/post/6958673090318434340

前言

关于MySQL的知识点总结了一个图谱,分享给大家:

复制概述

Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。

请注意当你进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,你必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。

1.1 mysql支持的复制类型:

(1):基于语句的复制:在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选着基于行的复制。   

(2):基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍,从mysql5.0开始支持   

(3):混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。

1.2 复制解决的问题

MySQL复制技术有以下一些特点:

(1) 数据分布 (Data distribution )

(2) 负载平衡(load balancing)

(3) 备份(Backups)

(4) 高可用性和容错行 High availability and failover

1.3 复制如何工作

整体上来说,复制有3个步骤:

(1)master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);

(2)slave将master的binary log events拷贝到它的中继日志(relay log);

(3)slave重做中继日志中的事件,将改变反映它自己的数据。

下图描述了复制的过程:

该过程的第一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。下一步就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。

复制配置

有两台MySQL数据库服务器Master和slave,Master为主服务器,slave为从服务器,初始状态时,Master和slave中的数据信息相同,当Master中的数据发生变化时,slave也跟着发生相应的变化,使得master和slave的数据信息同步,达到备份的目的。

要点: 负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限。环境: Master和slave的MySQL数据库版本同为5.0.18 操作系统:unbuntu 11.10 IP地址:10.100.0.100

2.1、创建复制帐号

1、在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中

命令如下: mysql > GRANT REPLICATION SLAVE,RELOAD,SUPER ON . TO backup@’10.100.0.200’ IDENTIFIED BY ‘1234’;

建立一个帐户backup,并且只能允许从10.100.0.200这个地址上来登陆,密码是1234。

(如果因为mysql版本新旧密码算法不同,可以设置:set password for ‘backup’@’10.100.0.200’=old_password(‘1234’))

2.2、拷贝数据

(假如是你完全新安装mysql主从服务器,这个一步就不需要。因为新安装的master和slave有相同的数据)

关停Master服务器,将Master中的数据拷贝到B服务器中,使得Master和slave中的数据同步,并且确保在全部设置操作结束前,禁止在Master和slave服务器中进行写操作,使得两数据库中的数据一定要相同!

2.3、配置master

接下来对master进行配置,包括打开二进制日志,指定唯一的servr ID。例如,在配置文件加入如下值:

server-id=1 log-bin=mysql-bin

server-id:为主服务器A的ID值 log-bin:二进制变更日值

重启master,运行SHOW MASTER STATUS,输出如下:

image.png

2.4、配置slave

Slave的配置与master类似,你同样需要重启slave的MySQL。如下:

log_bin= mysql-bin server_id = 2 relay_log= mysql-relay-bin log_slave_updates = 1 read_only= 1

server_id是必须的,而且唯一。slave没有必要开启二进制日志,但是在一些情况下,必须设置,例如,如果slave为其它slave的master,必须设置bin_log。在这里,我们开启了二进制日志,而且显示的命名(默认名称为hostname,但是,如果hostname改变则会出现问题)。

relay_log配置中继日志,log_slave_updates表示slave将复制事件写进自己的二进制日志(后面会看到它的用处)。 有些人开启了slave的二进制日志,却没有设置log_slave_updates,然后查看slave的数据是否改变,这是一种错误的配置。所以,尽量使用read_only,它防止改变数据(除了特殊的线程)。但是,read_only并是很实用,特别是那些需要在slave上创建表的应用。

2.5、启动slave

接下来就是让slave连接master,并开始重做master二进制日志中的事件。你不应该用配置文件进行该操作,而应该使用CHANGE MASTER TO语句,该语句可以完全取代对配置文件的修改,而且它可以为slave指定不同的master,而不需要停止服务器。如下: ` mysql> CHANGE MASTER TO MASTER_HOST=’server1′,

-> MASTER_USER='repl',

-> MASTER_PASSWORD='p4ssword',

-> MASTER_LOG_FILE='mysql-bin.000001',

-> MASTER_LOG_POS=0;
复制代码

` MASTER_LOG_POS的值为0,因为它是日志的开始位置。

你可以用SHOW SLAVE STATUS语句查看slave的设置是否正确:

`mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************

         Slave_IO_State:

            Master_Host: server1

            Master_User: repl

            Master_Port: 3306

          Connect_Retry: 60

        Master_Log_File: mysql-bin.000001

    Read_Master_Log_Pos: 4

         Relay_Log_File: mysql-relay-bin.000001

          Relay_Log_Pos: 4

  Relay_Master_Log_File: mysql-bin.000001

       Slave_IO_Running: No

      Slave_SQL_Running: No

                         ...omitted...

  Seconds_Behind_Master: NULL`
复制代码

Slave_IO_State, Slave_IO_Running, 和Slave_SQL_Running是No

表明slave还没有开始复制过程。日志的位置为4而不是0,这是因为0只是日志文件的开始位置,并不是日志位置。实际上,MySQL知道的第一个事件的位置是4。

为了开始复制,你可以运行:

`mysql> START SLAVE;

运行SHOW SLAVE STATUS查看输出结果:

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************

         Slave_IO_State: Waiting for master to send event

            Master_Host: server1

            Master_User: repl

            Master_Port: 3306

          Connect_Retry: 60

        Master_Log_File: mysql-bin.000001

    Read_Master_Log_Pos: 164

         Relay_Log_File: mysql-relay-bin.000001

          Relay_Log_Pos: 164

  Relay_Master_Log_File: mysql-bin.000001

       Slave_IO_Running: Yes

      Slave_SQL_Running: Yes

                         ...omitted...

  Seconds_Behind_Master: 0`
复制代码

在这里主要是看:

Slave_IO_Running=Yes Slave_SQL_Running=Yes

slave的I/O和SQL线程都已经开始运行,而且Seconds_Behind_Master不再是NULL。日志的位置增加了,意味着一些事件被获取并执行了。如果你在master上进行修改,你可以在slave上看到各种日志文件的位置的变化,同样,你也可以看到数据库中数据的变化。

你可查看master和slave上线程的状态。在master上,你可以看到slave的I/O线程创建的连接:

在master上输入show processlist\G;

image.png

行2为处理slave的I/O线程的连接。

在slave服务器上运行该语句:

image.png

行1为I/O线程状态,行2为SQL线程状态。

2.5、添加新slave服务器

假如master已经运行很久了,想对新安装的slave进行数据同步,甚至它没有master的数据。

此时,有几种方法可以使slave从另一个服务开始,例如,从master拷贝数据,从另一个slave克隆,从最近的备份开始一个slave。Slave与master同步时,需要三样东西:

(1)master的某个时刻的数据快照;

(2)master当前的日志文件、以及生成快照时的字节偏移。这两个值可以叫做日志文件坐标(log file coordinate),因为它们确定了一个二进制日志的位置,你可以用SHOW MASTER STATUS命令找到日志文件的坐标;

(3)master的二进制日志文件。

可以通过以下几中方法来克隆一个slave:

(1)冷拷贝(cold copy)

停止master,将master的文件拷贝到slave;然后重启master。缺点很明显。

(2)热拷贝(warm copy)

如果你仅使用MyISAM表,你可以使用mysqlhotcopy拷贝,即使服务器正在运行。

(3)使用mysqldump

使用mysqldump来得到一个数据快照可分为以下几步:

<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。如下: mysql> FLUSH TABLES WITH READ LOCK; < 2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储: shell> mysqldump –all-databases –lock-all-tables >dbdump.db < 3>对表释放锁。 mysql> UNLOCK TABLES;

深入了解复制

已经讨论了关于复制的一些基本东西,下面深入讨论一下复制。

3.1、基于语句的复制(Statement-Based Replication)

MySQL 5.0及之前的版本仅支持基于语句的复制(也叫做逻辑复制,logical replication),这在数据库并不常见。master记录下改变数据的查询,然后,slave从中继日志中读取事件,并执行它,这些SQL语句与master执行的语句一样。

这种方式的优点就是实现简单。此外,基于语句的复制的二进制日志可以很好的进行压缩,而且日志的数据量也较小,占用带宽少——例如,一个更新GB的数据的查询仅需要几十个字节的二进制日志。而mysqlbinlog对于基于语句的日志处理十分方便。

但是,基于语句的复制并不是像它看起来那么简单,因为一些查询语句依赖于master的特定条件,例如,master与slave可能有不同的时间。所以,MySQL的二进制日志的格式不仅仅是查询语句,还包括一些元数据信息,例如,当前的时间戳。即使如此,还是有一些语句,比如,CURRENT USER函数,不能正确的进行复制。此外,存储过程和触发器也是一个问题。

另外一个问题就是基于语句的复制必须是串行化的。这要求大量特殊的代码,配置,例如InnoDB的next-key锁等。并不是所有的存储引擎都支持基于语句的复制。

3.2、基于记录的复制(Row-Based Replication)

MySQL增加基于记录的复制,在二进制日志中记录下实际数据的改变,这与其它一些DBMS的实现方式类似。这种方式有优点,也有缺点。优点就是可以对任何语句都能正确工作,一些语句的效率更高。主要的缺点就是二进制日志可能会很大,而且不直观,所以,你不能使用mysqlbinlog来查看二进制日志。 对于一些语句,基于记录的复制能够更有效的工作,如:

mysql> INSERT INTO summary_table(col1, col2, sum_col3) -> SELECT col1, col2, sum(col3) -> FROM enormous_table -> GROUP BY col1, col2;

假设,只有三种唯一的col1和col2的组合,但是,该查询会扫描原表的许多行,却仅返回三条记录。此时,基于记录的复制效率更高。

另一方面,下面的语句,基于语句的复制更有效:

mysql> UPDATE enormous_table SET col1 = 0; 此时使用基于记录的复制代价会非常高。由于两种方式不能对所有情况都能很好的处理,所以,MySQL 5.1支持在基于语句的复制和基于记录的复制之前动态交换。你可以通过设置session变量binlog_format来进行控制。

3.3、复制相关的文件

除了二进制日志和中继日志文件外,还有其它一些与复制相关的文件。

如下:

(1)mysql-bin.index

服务器一旦开启二进制日志,会产生一个与二日志文件同名,但是以.index结尾的文件。它用于跟踪磁盘上存在哪些二进制日志文件。MySQL用它来定位二进制日志文件。它的内容如下(我的机器上):

image.png

(2)mysql-relay-bin.index

该文件的功能与mysql-bin.index类似,但是它是针对中继日志,而不是二进制日志。内容如下: .\mysql-02-relay-bin.000017 .\mysql-02-relay-bin.000018

(3)master.info

保存master的相关信息。不要删除它,否则,slave重启后不能连接master。内容如下(我的机器上):

image.png

I/O线程更新master.info文件,内容如下(我的机器上):

image.png

(4)relay-log.info

包含slave中当前二进制日志和中继日志的信息。

3.4、发送复制事件到其它slave

当设置log_slave_updates时,你可以让slave扮演其它slave的master。此时,slave把SQL线程执行的事件写进行自己的二进制日志(binary log),然后,它的slave可以获取这些事件并执行它。如下:

image.png

3.5、复制过滤(Replication Filters)

复制过滤可以让你只复制服务器中的一部分数据,有两种复制过滤:在master上过滤二进制日志中的事件;在slave上过滤中继日志中的事件。如下:

image.png

复制的常用拓扑结构

复制的体系结构有以下一些基本原则:

(1)每个slave只能有一个master;

(2)每个slave只能有一个唯一的服务器ID;

(3)每个master可以有很多slave;

(4)如果你设置log_slave_updates,slave可以是其它slave的master,从而扩散master的更新。

MySQL不支持多主服务器复制(Multimaster Replication)——即一个slave可以有多个master。但是,通过一些简单的组合,我们却可以建立灵活而强大的复制体系结构。

4.1、单一master和多slave

由一个master和一个slave组成复制系统是最简单的情况。Slave之间并不相互通信,只能与master进行通信。如下:

image.png

如果写操作较少,而读操作很时,可以采取这种结构。你可以将读操作分布到其它的slave,从而减小master的压力。但是,当slave增加到一定数量时,slave对master的负载以及网络带宽都会成为一个严重的问题。 这种结构虽然简单,但是,它却非常灵活,足够满足大多数应用需求。一些建议:

(1)不同的slave扮演不同的作用(例如使用不同的索引,或者不同的存储引擎);

(2)用一个slave作为备用master,只进行复制;

(3)用一个远程的slave,用于灾难恢复;

4.2、主动模式的Master-Master(Master-Master in Active-Active Mode)

Master-Master复制的两台服务器,既是master,又是另一台服务器的slave。如图:

image.png

主动的Master-Master复制有一些特殊的用处。例如,地理上分布的两个部分都需要自己的可写的数据副本。这种结构最大的问题就是更新冲突。假设一个表只有一行(一列)的数据,其值为1,如果两个服务器分别同时执行如下语句: 在第一个服务器上执行:

mysql> UPDATE tbl SET col=col + 1; 在第二个服务器上执行: mysql> UPDATE tbl SET col=col * 2;

那么结果是多少呢?一台服务器是4,另一个服务器是3,但是,这并不会产生错误。 实际上,MySQL并不支持其它一些DBMS支持的多主服务器复制(Multimaster Replication),这是MySQL的复制功能很大的一个限制(多主服务器的难点在于解决更新冲突),但是,如果你实在有这种需求,你可以采用MySQL Cluster,以及将Cluster和Replication结合起来,可以建立强大的高性能的数据库平台。但是,可以通过其它一些方式来模拟这种多主服务器的复制。

4.3、主动-被动模式的Master-Master(Master-Master in Active-Passive Mode)

这是master-master结构变化而来的,它避免了M-M的缺点,实际上,这是一种具有容错和高可用性的系统。它的不同点在于其中一个服务只能进行只读操作。如图:

image.png

4.4、带从服务器的Master-Master结构(Master-Master with Slaves)

这种结构的优点就是提供了冗余。在地理上分布的复制结构,它不存在单一节点故障问题,而且还可以将读密集型的请求放到slave上。

 
 

遇到的错误:

1:Mysql error 1236 from master when reading data from binary log

解决办法:

  1. Slave: stop slave;
  2. Master: flush logs
  3. Master: show master status; — take note of the master log file and master log position
  4. Slave: CHANGE MASTER TO MASTER_LOG_FILE='log-bin.00000X', MASTER_LOG_POS=106;
  5. Slave: start slave;

iptables 概念、原理及相关操作介绍

iptables 概念、原理及相关操作介绍

origine : https://juejin.cn/post/6844904155153170440

基础概念

Linux 的包过滤功能,即 Linux 防火墙,它由 netfilter 和 iptables 两个组件组成。netfilter 位于内核空间,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。iptables 是一个命令行工具,位于用户空间,它使得插入、修改和删除信息包过滤表中的规则变得容易。

我们知道 iptables 是按照规则来办事的,规则其实就是网络管理员预定义的条件,规则一般的定义为”如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如:TCP、UDP、ICMP)和服务类型(如:HTTP、FTP和 SMTP)等。当数据包与规则匹配时,iptables 就根据规则所定义的方法来处理这些数据包,如放行(ACCEPT)、拒绝(REJECT)和丢弃(DROP)等。配置防火墙的主要工作就是添加、修改和删除这些规则。

当客户端访问服务器的服务时,客户端发送报文到服务器的网卡,而 TCP/IP 协议栈是属于内核的一部分,所以客户端的信息会通过内核的 TCP 协议传输到用户空间中的服务中,而此时客户端报文的目标终点(destination)为服务所监听的套接字(IP:PORT),当服务需要响应客户端请求时,服务发出的响应报文的目标终点则为客户端,这个时候服务所监听的IP与端口反而变成了原点(source)。netfilter 才是真正的防火墙,它是内核的一部分,如果我们想要防火墙能够达到”防火”的目的,则需要在内核中设置关卡,所有进出的报文都要通过这些关卡,经过检查后,符合放行条件的才能放行,符合阻拦条件的则需要被阻止,于是就出现了 INPUT 关卡和 OUTPUT 关卡。然而这些关卡在 iptables 中并不被称为”关卡”,而是被称为”链”。

其实我们上面描述的场景并不完善,因为客户端发来的报文访问的目标地址可能并不是本机,而是其他服务器,当本机的内核支持 IP_FORWARD 时,我们可以将报文转发给其他服务器。这个时候,我们就会提到 iptables 中的其他”关卡”,也就是其他”链”,它们就是 PREROUTING(“路由前”)、FORWARD(“转发”)、POSTROUTING(“路由后”)。

也就是说,当我们启用了防火墙功能时,报文需要经过如下关卡,也就是说,根据实际情况的不同,报文经过”链”可能不同。如果报文需要转发,那么报文则不会经过 INPUT 链发往用户空间,而是直接在内核空间中经过 FORWARD 链和 POSTROUTING 链转发出去的。

iptables 结构

iptables 由表(table)、链(chain)和规则(rule)组成,其中表包含链,链包含规则。

我们把具有相同功能的规则集合叫做“表”,对于不同功能的规则,我们可以放置在不同的表中进行管理。iptables 中具有 filter、nat、mangle、raw 等几种内建表:

  • filter 表:iptables 的默认表。负责过滤功能、防火墙,也就是由 filter 表来决定一个数据包是否继续发往它的目的地址或者被丢弃。对应的内核模块为 iptables_filter。filter 表具有三种内建链:INPUT、OUTPUT、FORWARD。
  • nat 表:nat 是 network address translation 的简称,具备网络地址转换的功能。对应的内核模块为 iptables_nat。nat 表有三种内建链:PREROUTING、POSTROUTING、OUTPUT(CentOS 7 中还包含 INPUT,但是在 CentOS 6 中没有)。
  • mangle 表:用于指定如何处理数据包,具备拆解报文、修改报文以及重新封装的功能,可用于修改IP 头部信息,如:TTL。对应的内核模块为 iptables_mangle。mangle 表具有 5 种内建链:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。
  • raw 表:用于处理异常。对应的内核模块为 iptables_raw。raw 表包含2个内建链:PREROUTING 和 OUTPUT。

对于各个具体的链而言:

  • INPUT 链:处理来自外部的数据。
  • OUTPUT 链:处理向外发送的数据。
  • FORWARD 链:数据转发。通过路由表后发现目的地址非本机,则匹配该链中的规则。
  • PREROUTING 链:处理刚到达本机并在路由转发前的数据包。
  • POSTROUTING 链: 处理即将离开本机的数据包。

数据包的流转流程可以参考下图:

iptables 命令格式

iptables 命令格式为:

iptables [ -t 表名] 命令选项 [链名] [条件匹配] [-j 处理动作或跳转]
复制代码

如果没有显式设置表名,那么默认为 filter 表,即默认 -t filter。

命令选项

  • -L 列出一个或所有链的规则
  • -v 显示详细信息,包括每条规则的匹配句数量和匹配字节数
  • -x 在v的基础上,禁止自动换算单位(K,M)
  • -n 只显示ip地址和端口号,不显示域名和服务名称
  • -I 插入到防火墙第一条生效
  • -A 添加链是添加到最后一条
  • -D 删除指定链中的某一条规则,按规则序号或内容确定要删除的规则
  • -F 清空指定链中的所有规则,默认清空表中所有链的内容
  • -X 删除指定表中用户自定义的规则链

匹配条件

  • -i 入站请求interface(网卡)
  • -o 出站请求interface(网卡)
  • -s 入站源地址
  • -d 目标地址
  • -p 指定规则协议,如tcp, udp,icmp等,可以使用 all 来指定所有协议
  • –dport 目的端口,数据包的目的(dport)地址是80,就是要访问我本地的80端口
  • –sport 来源端口 数据包的来源端口是(sport)80,就是对方的数据包是80端口发送过来的。

动作

  • ACCEPT:允许数据包通过。
  • DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。
  • REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。(一般不使用REJECT(拒绝)行为,REJECT会带来安全隐患。)
  • SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
  • MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
  • DNAT:目标地址转换。
  • REDIRECT:在本机做端口映射。
  • LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。

iptables 规则

在上述描述中我们一直在提规则,可是没有细说。那么规则具体指什么呢?

规则:根据指定的匹配条件来尝试匹配每个流经此处的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理。

规则大致又两个逻辑单元组成:匹配条件和动作。最常用的匹配条件是“源地址”、“目标地址”、“源端口”、“目标端口”;最常用的动作有 ACCEPT(接受)、DROP(丢弃)、REJECT(拒绝)。

在实际操作 iptables 的过程中,是以“表”作为操作入口的,如果你经常操作关系型的数据库,那么当你听到“表”这个词的时候,你可能会联想到另一个词——“增删改查”,当我们定义 iptables 规则时,所做的操作其实类似于“增删改查”。我们不妨从最简单的“查”操作入手。

filter 表是我们最常用到的表,我们这里以 filter表为例来说明具体的操作。下面的命令展示如何查看 filter 表中的规则:

zhuzhonghua@host1:~$ iptables -t filter -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination   
复制代码

上面我们使用-t选项指定要操作的表,使用-L选项查看-t选项对应表的规则。-L 对应 List,意为列出规则。上面命令的含义为列出filter表的所有规则。

我们可以查看指定表中指定链的规则。比如,我们只查看 filter 表中 INPUT 链的规则:

zhuzhonghua@host1:~$ iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination 
复制代码

上面只显示了 filter 表中 INPUT 链的规则(省略 -t 选项默认为 filter 表),当然,你也可以指定只查看其它链。我们还可以使用-v选项查看出更多、更详细的信息,示例如下:

zhuzhonghua@host1:~$ iptables -vL INPUT
Chain INPUT (policy ACCEPT 1509K packets, 851M bytes)
 pkts bytes target     prot opt in     out     source               destination 
复制代码

这里我们看到多了一些字段,这些字段就是规则对应的属性,具体的含义归纳如下:

  • pkts: 匹配到的报文的个数。
  • bytes: 匹配到的报文包的大小总和。
  • target: 表示规则对应的“动作”,即规则匹配成功后需要采取的措施。
  • prot: 对应的协议,是否只针对某些协议应用此规则。
  • opt: 表示规则对应的选项。
  • in: 表示数据包由哪个interface(网卡)流入,我们可以设置通过哪块网卡流入的报文需要匹配当前规则。
  • out:表示数据包由哪个interface(网卡)流出,我们可以设置通过哪块网卡流出的报文需要匹配当前规则。
  • source: 表示规则对应的源头地址,可以是一个 IP,也可以是一个网段。
  • destination: 表示规则对应的目标地址。

上面链(Chain INPUT)的背后还有一个括号,括号里包含了policy ACCEPT1509K packets851M bytes三部分。

  • policy: 表示当前链的默认策略,policy ACCEPT 表示上面 INPUT 链中的默认动作为 ACCEPT, 换句话说就是,默认接受通过INPUT的所有请求。
  • packets: 表示当前链的默认策略匹配到的包的数量。
  • bytes:表示当前链的默认策略匹配到的所有包的大小总和。

如果需要,我们可以使用iptables -F INPUT 命令来清空 filter 表 INPUT 链中的规则。

假设我们有2台测试机,IP地址分别为 host1 和 host2, 我们可以在 host1 上使用 ping 命令来查看一下网络连通情况:

zhuzhonghua@host1:~$ ping host2
64 bytes from host2: icmp_seq=512 ttl=49 time=213 ms
64 bytes from host2: icmp_seq=513 ttl=49 time=213 ms
64 bytes from host2: icmp_seq=514 ttl=49 time=213 ms
复制代码

然后我们在 host1 上配置一条规则,拒绝 host2 上的所有报文访问 host1。对应的命令如下:

zhuzhonghua@host1:~$ iptables -t filter -I INPUT -s host2 -j DROP
复制代码

使用-I选项,指明将“规则”插入哪个链中,I 表示 Insert,即插入的意思,这里表示添加规则之意。使用-s选项,指明匹配条件中的“源地址”,即如果报文的源地址属于 -s 对应的地址,那么报文则满足匹配条件。s 表示 source,即源地址。使用-j选项,指明当匹配条件满足时,所对应的动作,上面指定了动作为 DROP,当报文的源地址为 host2 时,报文则被 DROP。

再来查看一下 filter 表中的 INPUT 链:

zhuzhonghua@host1:~$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 1421 packets, 344K bytes)
 pkts bytes target     prot opt in     out     source        destination        
  114  7992 DROP       all  --  *      *       host2          0.0.0.0/0 
复制代码

可以看到相应的规则已经添加了,在 iptables 中,动作被称之为 “target”, 所以上面的 target 字段对应的动作为 DROP。

现在 INPUT 链中已经存在了一条规则,它拒绝了所有来自 host2 的报文,如果此时我们在这条规则之后再配置一条规则—— 接受所有来自 host2 的报文,那么此时 iptables 的表现如何呢?

使用如下命令在 filter 表中追加一条规则:

zhuzhonghua@host1:~$ iptables -A INPUT -s host2 -j ACCEPT

zhuzhonghua@host1:~$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 355 packets, 133K bytes)
 pkts bytes target     prot opt in     out     source        destination        
 3960  274K DROP       all  --  *      *       host2          0.0.0.0/0         
    0     0 ACCEPT     all  --  *      *       host2          0.0.0.0/0 
复制代码

上面并没有继续使用-I选项,而是使用了-A选项,A代表 Append,也是表示在 INPUT 链中追加规则。-I-A之间的区别在于:-I表示在链的首部插入规则,而-A表示在链的头部插入规则。

上面的信息中也显示了新添加的 ACCEPT 规则在原先的 DROP 之后。

此时再在 host1 上尝试去 ping 通 host2 时会发现还是 ping 不通。看来新添加的规则没有生效。 我们这里再次添加一条相同的规则,不过此时使用-I选项来添加。

zhuzhonghua@host1:~$ iptables -I INPUT -s host2 -j ACCEPT

zhuzhonghua@host1:~$ iptables -nvL INPUT
Chain INPUT (policy ACCEPT 57 packets, 6438 bytes)
 pkts bytes target     prot opt in     out     source        destination        
   16  2274 ACCEPT     all  --  *      *       host2          0.0.0.0/0         
 7319  507K DROP       all  --  *      *       host2          0.0.0.0/0         
    0     0 ACCEPT     all  --  *      *       host2          0.0.0.0/0  
复制代码

如果我们此时再尝试 ping 通 host2 时,发现已经可以正常 ping 通了。如果观察仔细,我们可以发现,刚刚添加的 ACCEPT 规则在 DROP 规则之前了。可见,规则的顺序很重要。

如果报文已经被前面的规则匹配到,iptables 则会对报文执行对应的动作,即使后面的规则也能匹配到当前报文,很有可能也没有机会再对报文执行相应的动作了。就以上面的例子来说,报文先被第一条规则匹配到了,于是当前报文被“放行”了。也正因为报文已经被放行了,后面的第二条规则及时能够匹配到放行的报文,也没有机会在对刚才的报文进行丢弃操作了。这就是 iptables 的工作机制。

使用 iptables 是可以通过 --line-number 选项来列出规则的序号,如下所示:

zhuzhonghua@host1:~$ iptables --line-number -nvL INPUT
Chain INPUT (policy ACCEPT 13186 packets, 6606K bytes)
num   pkts bytes target     prot opt in     out     source        destination   
1     1568  278K ACCEPT     all  --  *      *       host2          0.0.0.0/0    
2     7319  507K DROP       all  --  *      *       host2          0.0.0.0/0    
3        0     0 ACCEPT     all  --  *      *       host2          0.0.0.0/0  
复制代码

我们在添加规则的时候,还可以指定新增规则的编号,这样我们就能在任意位置插入规则了,我们只要把刚才的命令稍作修改即可,如下:

zhuzhonghua@host1:~$ iptables t fileter -I INPUT 2 -s host2 -j DROP
复制代码

这里仍旧使用-I选项进行插入规则的操作,-I INPUT 2表示在 INPUT 链中新增规则,新增规则的编号为2。

在删除规则时,我们可以使用规则的编号去删除,也可以使用具体的匹配条件和动作去删除。

举例,我们删除第三条规则:

zhuzhonghua@host1:~$ iptables -t filter -D INPUT 3

zhuzhonghua@host1:~$ iptables --line-number -nvL INPUT
Chain INPUT (policy ACCEPT 87 packets, 9870 bytes)
num   pkts bytes target     prot opt in     out     source        destination  
1     5115  594K ACCEPT     all  --  *      *       host2          0.0.0.0/0  
2     7319  507K DROP       all  --  *      *       host2          0.0.0.0/0  
复制代码

我们再删除第一条规则:

zhuzhonghua@host1:~$ iptables -D INPUT -s host2 -j ACCEPT
zhuzhonghua@host1:~$ iptables --line-number -nvL INPUT
Chain INPUT (policy ACCEPT 228 packets, 26328 bytes)
num   pkts bytes target     prot opt in     out     source        destination  
1     7325  507K DROP       all  --  *      *       host2          0.0.0.0/0 
复制代码

如果要一下子全部清空怎么操作?这个在前面已经提及过了,使用iptables -t 表名 -F 链名-F选项为 flush 之意,即冲刷指定的链,即删除指定链中的所有规则。此操作相当于删除操作,在没有保存 iptables 规则的情况下慎用。如果不指定链名,那么会删除表中的所有规则,即iptables -t 表名 -F

此处省略修改规则、保存规则的具体操作。


作者:飞书技术
链接:https://juejin.cn/post/7135389670196084743

changer version de php dans Ubuntu

How to Install PHP 5.6, PHP 7.3 on Ubuntu 18.04 & 16.04 using PPA

Thanks to Ondřej Surý for maintaining PPA of latest PHP5 versions on launchpad. If you want to install the specific version of PHP, then this article can be helpful for you. This article will help you for installing PHP 5.6 or PHP 7.3 using PPA on Ubuntu 18.04 LTS, 16.04 LTS, 14.04 LTS or 12.04 LTS systems. If you have already had a higher version installed on your system and you need to install lower version, then you have to remove higher version first and remove the apt repository from the system.

Install PHP 5.6 on Ubuntu

Use the following set of commands to enable PPA for PHP 5.6 in your Ubuntu system and install PHP 5.6.

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install -y php5.6

Check Installed PHP Version:

php -v 

PHP 5.6.40-10+ubuntu16.04.1+deb.sury.org+1 (cli)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

Install PHP 7.3 on Ubuntu

Use the following set of command to add PPA for PHP 7.3 in your Ubuntu system and install PHP 7.3.

sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install -y php7.3

Check Installed PHP Version:

php -v 

PHP 7.3.9-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Sep  2 2019 12:54:04) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.9, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.9-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

Switch Between PHP Version’s

If you have installed multiple PHP versions and want to use differently than the default. Use the following steps to switch between php5.6 and php7.3 version. You can use the same command for other PHP versions.

From PHP 5.6 => PHP 7.3

Apache:-

sudo a2dismod php5.6
sudo a2enmod php7.3
sudo service apache2 restart

CLI:-

sudo update-alternatives --set php /usr/bin/php7.3
sudo update-alternatives --set phpize /usr/bin/phpize7.3
sudo update-alternatives --set php-config /usr/bin/php-config7.3

From PHP 7.3 => PHP 5.6

Apache:-

sudo a2dismod php7.3
sudo a2enmod php5.6
sudo service apache2 restart

CLI:-

sudo update-alternatives --set php /usr/bin/php5.6
sudo update-alternatives --set phpize /usr/bin/phpize5.6
sudo update-alternatives --set php-config /usr/bin/php-config5.6

React

1 : la cycle de vie :

https://blog.hhking.cn/2018/09/18/react-lifecycle-change/

note sur mongo DB

Installation dans ubuntu :

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

installer studio 3T:

https://studio3t.com/knowledge-base/articles/installation/#install-studio-3t

d’autres outils:

https://www.guru99.com/top-20-mongodb-tools.html

*********************************************************************************

les commands utils

show dbs, show databases

use db-lyu

db : afficher la base actuelle

show collections

mongoose :

connection :fsdfs

mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
const db = mongoose.connection;
db.once('open', function() {
  // we're connected!
});