# Internet **Repository Path**: interview_44/internet ## Basic Information - **Project Name**: Internet - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-04-19 - **Last Updated**: 2023-03-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # InternetCoding #### 介绍 专门针对开发面试,网络讲解,非常简单,只是一些简单概念! -[0、四层网络模型](#0四层网络模型) -[1、运算是否同一个局域网](#1运算是否同一个局域网) -[2、局域网广播](#2局域网广播) -[3、TCP-三次握手&四次揮手](#3TCP-三次握手四次揮手) -[4、什么事socket](#4什么事socket) -[5、一个网站访问请求](#5一个网站访问请求) -[6、https对传输的信息加密](#6https对传输的信息加密) -[7、XSS攻击](#7XSS攻击) -[8、sql注入](#8sql注入) -[9、SCRF攻击](#9SCRF攻击) -[10、DDOS是什么](#10DDOS是什么) -[11、网关如何防止网络攻击](#11网关如何防止网络攻击) -[12、网关,了解一下](#12网关了解一下) -[13、NIO,BIO,AIO](#13NIOBIOAIO) -[14、io操作](#14io操作) -[15、netty](#15netty) ### 0、四层网络模型 ![](./picture/0-4层网络协议.drawio.png) ### 1、运算是否同一个局域网 ![](./picture/1、判断是否同一局域网.png) 拿到子网地址与(子网掩码225.225.225.0)进行与运算,得出的结果高位进行对比,一致则在同一个局域网内,不一致则不在同一个局域网内。 ### 2、局域网广播 192.168.108.31的电脑,在局域网内发出广播,同一局域网内的所有电脑设备均会接收到该报文。 比较一下数据包接收方,mac地址是不是我的,如果接受地址不是我,则直接把包丢弃了,不做任何处理。 同时会经过交换机发到路由器,路由器内保存有地址表,根据数据包的目的地址,粗略知道了目的地址的发送方向,然后把报文发送给下一个路由器 (或者网络中转站),中转站会根据ip地址直接发送给目标地址,或者再发送给下一个路由器(或者网络中转站)。有算法,计算一共会发送多少次, 到不了就放弃。 ![](./picture/2、局域网网络广播.png) ### 3、TCP-三次握手&四次揮手 三次握手 3.1、TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状; 3.2、TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x , 此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。 3.3、TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个 序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。 3.4、TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入 ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。 3.5、当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。 ![](./picture/3、三次握手.png) 四次挥手 3.6、客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节 的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。 3.7、服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待) 状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送 数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。 3.8、客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务 器发送的最后的数据)。服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送 了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。 3.9、客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等 待)状态。注意此时TCP连接还没有释放,必须经过2 ∗ * ∗MSL、(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。 3.10、服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时 间要比客户端早一些。 ![](./picture/4、四次挥手.png) ### 4、什么事socket ![](./picture/5、简单了解一下socket通信.png) ### 5、一个网站访问请求 首先浏览器打开一个地址,例如baidu.com。 通过NDS服务器地址,找到DNS服务器,然后会通过域名查里面的对应ip。 拿到ip后,打包http请求,通过网关发送到路由器,路由器会根据ip地址,记录找,一直找到服务器为止。 ![](./picture/6、一个网站访问请求.png) ### 6、https对传输的信息加密 http协议 http1.0:短连接,频繁进行三次握手。 http1.1:改为使用长连接,连接收反复通信。 http2.0:多路复用,基于一个tcp连接并行发送多个请求以及接收响应,解决了http 1.1对同一时间同一个域名的请求有限制的问题。 对称加密,双方拥有相同的密钥,信息得到安全传输,但此种方式的缺点是: (1)不同的客户端、服务器数量庞大,所以双方都需要维护大量的密钥,维护成本很高。 (2)因每个客户端、服务器的安全级别不同,密钥极易泄露。 非对称加密,客户端用公钥对请求内容加密,服务器使用私钥对内容解密,反之亦然,但上述过程也存在缺点: (1)公钥是公开的(也就是黑客也会有公钥),所以第服务端私钥加密的信息,如果被黑客截获,其可以使用公钥进行解密,获取其中的内容 非对称加密既然也有缺陷,那我们就将对称加密,非对称加密两者结合起来,取其精华、去其糟粕,发挥两者的各自的优势 ![](./picture/7、https.png) 第一步,客户端发起一个连接请求,客户端支持的SSL的指定版本、加密组件(Cipher Suite)列表。 在第二步时服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有: (1)证书的发布机构CA (2)证书的有效期 (3)公钥 (4)证书所有者 (5)签名 第三步客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下: (1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验 (2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发 (3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。 (4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密 (5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比 (6)对比结果一致,则证明服务器发来的证书合法,没有被冒充 以下内容,我也看不懂~-_-~ 第四部,使用随机密码加密消息与hash值,发送给服务器。 第五步,服务器会用私钥解出随机密码。 第六步,用解出的随机密码解密消息。 第七步,用hash算法对消息进行hash值。 第八步,用发送过来的密码加密一段消息,同时发过来消息计算得hash值。 第九步,使用密码解密消息在用hash算法计算解密的消息值再与网站发过来的hash对比 第十步、之后进行通信,都是用随机密码进行加密 ### 7、XSS攻击 第一种:反射型XSS 通过广告去到了黑客的服务器,执行了恶意脚本会导致Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。 ![](./picture/8、反射型XSS.png) 第二种:持久性XSS 黑客发布了恶意脚本到正常网站中,一般可以留在评论区,用户执行之后会导致Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。 ![](./picture/9、持久型XSS.png) 防范: 一、消毒机制,脚本转义。 二、cookie打上httpOnly属性,浏览器中的js脚本被禁止访问这些httpOnly的,cookie的。 ### 8、sql注入 黑客使用;结束了前一段sql,后面再加一段执行sql。 ![](./picture/10、sql注入.png) 防范: mybatis、hibernate都是支持预编译的 放到底层的JDBC里,PreparedStatement,对SQL进行预编译,如果你给SQL的某个参数传入进去的是一个恶意SQL语句,人家预编译过后, 会让你的恶意SQL语句是无法执行的,所以千万不要直接自己用字符串去拼接SQL语句。 ### 9、SCRF攻击 用户访问不正常的网络,被黑客获取了cookie,然后黑客模拟用户登录,对数据造成破坏。 ![](./picture/11、SCFR攻击.png) 1、防止cookie被窃取:最最根本的,其实还是说防止cookie被窃取,可以给你的网站的cookie设置HttpOnly属性,禁止被别人的script脚本窃取, 那么别人就无法伪造用户登录请求了。 2、随机token:每次返回一个页面给你的时候,都生成一个随机token附加在页面的隐藏元素里,同时在你的redis里可以存以下,然后页面发送请求的 时候附加随机token,验证通过才能执行请求,你要是自己用postman构造请求就不知道随机token是什么了 3、验证码:页面提交必须搞一个验证码,那种图形的,现在比较流行的还有拖动一个拼图什么的,必须验证码通过了才能执行你的请求,避免黑客直接 伪造请求发送过来,这个其实是比较常见的,最好是在用户进行支付交易的时候,要求必须在页面上拖拽一个拼图验证码。 4、Referer请求头:这个是http请求里有一个referer请求头,带有这个请求的来源,你可以验证一下这个请求是不是从自己的页面里来的, 如果是的话才执行,否则就不要执行了。 ### 10、DDOS是什么 ![](./picture/12、DDOS简介.png) DDOS是利用网络传播规则,发起大量请求,打爆目标网络。 ![](./picture/13、DOS与网络机制.png) 肉机打开了目标服务器的三次握手,然后不理人,服务器等待关闭资源,一直打开新资源,就被撑爆了。 防范: 打110吧。 ### 11、网关如何防止网络攻击 以网关zuul为栗子: 增加我们的系统强壮性,要靠代码。 集成zullFilter拦截器,拿到请求上下文,就可以实现任意请求控制。 1、过滤XSS攻击脚本。 2、过滤sql注入脚本。 3、检查请求是否带随机token。 4、检查refer请求头。 5、根据ip地址限流。 ![](./picture/14、网关如何防止网络攻击.png) ### 12、网关,了解一下 1、网关请求,进行路由 2、动态路由,感知服务挂掉 3、恢复发布 4、授权认证 5、感知所有的接口请求 6、接口成功率 7、系统日志 8、数据缓存 9、限流熔断 种类:kong,getway,zuul,nginx+lua zuul: 8核16G,网关路由转发每秒抗1000+,100台机器抗10万QPS/s。 环境生产,微服务上线实践(利用网关) 1、开发一个新的服务,上线部署,在网关里面配置一下路径和新服务的映射关系,此时新过来请求就可以走到服务离去。 2、对已有服务进行更新迭代,走灰度发布,启用zuul filter启用,按照规则,把少量的流量导入新版本,如果新版本运行正常。 3、测试通过,版本改为current,全量机器部署,关闭灰度发布,服务调用负载均衡。 一般的互联网公司: 20多个服务, 服务注册中心3个足,把配置p调到极致,例如Eureka优化到1秒同步上线瞬间被感知。 每个服务部署2台机器,2核8G的配置,并发1000以内完全没问题。 网关3到4台,2核8G的配置每一台每秒抗几百个请求,3台可以接近2000qps。 数据库配置,8核32G,物理机高峰期每秒抗3000~4000请求,mysql负载非常高,资源非常紧张。 如何统计每个服务每秒多少请求量? metrics机制 统计机制,每个接口被调用的时候,记录,每分钟都做一个累加,每个接口没天做一个统计,访问次数就可以记录在数据库或者日志记录知道访问次数。 压测压什么? 每秒发送多少个请求,每分钟发起多少个请求,可以抗得住,工具可以知道没秒钟进入多少个请求后就进行阻塞, tp99:99%的请求耗费时间在1毫秒以内,1%的请求耗费在100毫秒以内 tp95,tp90 计算没个接口的访问耗时,历史总耗时,算出平均耗时,最新耗时。 如果你的系统访问量增大10倍? nginx会做负载均衡,网关加多10个,支持并发量提高10倍。 每个服务实例增加多10倍,Eureka机器每秒多几百个请求。Eureka机器首先进行资源提升,8核32G,几百个服务实例都可以抗得住。 数据库本来每秒几百个请求,提高数据库服务器的性能,数据库横向扩容。 ### 13、NIO,BIO,AIO 同步阻塞的BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信 ,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到 拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。 ![](./picture/15、bio.png) NIO BIO与NIO一个比较重要的不同,是我们使用BIO的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程, 每个连接共用一个线程。NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要 一个线程就可以搞定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。 ![](./picture/16、nio.png) AIO 与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会 将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。 基于nio,在读写数据的时候,是异步处理,不占用线程,线程可以干别的,知道操作系统干完之后,通知你,你就可以往下执行。 ### 14、io操作 ![](./picture/17、io操作.png) 1、DMA拷贝先把文件拷贝到OS的内核缓冲区 2、再通过cpu拷贝到JVM的用户缓冲区 3、cpu拷贝到socket缓冲区 4、DMA拷贝到网络引擎 5、发送数据出去 mmap内存映射技术 ![](./picture/18、mmap.png) mmap内存映射技术,提升读写效率。在第二步cpu拷贝到JVM用户缓冲区做了省略,只做映射工作。 mmap技术主要在RocketMq中使用,RocketMq主要基于mmap进行高效磁盘文件读写。 零拷贝 ![](./picture/19、零拷贝.png) tomcate与kafka都是使用零拷贝技术,只需要发生2次用户态与内核态切换,2次拷贝即可。 从2.1版内核开始,Linux引入了sendfile来简化操作: 系统调用sendfile()在代表输入文件的描述符in_fd和代表输出文件的描述符out_fd之间传送文件内容(字节)。 描述符out_fd必须指向一个套接字, 而in_fd指向的文件必须是可以mmap的。 这些局限限制了sendfile的使用,使sendfile只能将数据从文件传递到套接字上,反之则不行。 使用sendfile不仅减少了数据拷贝的次数,还减少了上下文切换,数据传送始终只发生在kernel space。 ### 15、netty netty是非常优秀的,高性能的,一套通信框架 底层是把NIO重度的封装 JDK提供了网络编程框架,NIO netty常用场景一般中间件系统,分布式消息系统:RocketMQ底层就是Netty ![](./picture/20、netty工作原理图.png) 先提供netty工作原理,有时间再深入研究。