计算机网络基础知识
基本术语结点 (node) :网络中的结点可以是计算机,集线器,交换机或路由器等。链路(link ) : 从一个结点到另一个结点的一段物理线路。中间没有任何其他交点。主机(host) :连接在因特网上的计算机。ISP(Internet Service Provider) :因特网服务提供者(提供商)。IXP(Internet eXchange Point) : 互联网交换点 IXP 的主要作用就是允许两个网络直接相连并交换分组,而不需要再通过第三个网络来转发分组。RFC(Request For Comments) :意思是“请求评议”,包含了关于 Internet 几乎所有的重要的文字资料。广域网 WAN(Wide Area Network) :任务是通过长距离运送主机发送的数据。城域网 MAN(Metropolitan Area Network):用来将多个局域网进行互连。局域网 LAN(Local Area Network) : 学校或企业大多拥有多个互连的局域网。个人区域网 PAN(Personal Area Network) :在个人工作的地方把属于个人使用的电子设备用无线技术连接起来的网络 。分组/包(packet ) :因特网中传送的数据单元。由首部 header 和数据段组成。分组又称为包,首部可称为包头。存储转发(store and forward ) :路由器收到一个分组,先检查分组是否正确,并过滤掉冲突包错误。确定包正确后,取出目的地址,通过查找表找到想要发送的输出端口地址,然后将该包发送出去。带宽(bandwidth) :在计算机网络中,表示在单位时间内从网络中的某一点到另一点所能通过的“最高数据率”。常用来表示网络的通信线路所能传送数据的能力。单位是“比特每秒”,记为 b/s。吞吐量(throughput ) :表示在单位时间内通过某个网络(或信道、接口)的数据量。吞吐量更经常地用于对现实世界中的网络的一种测量,以便知道实际上到底有多少数据量能够通过网络。吞吐量受网络的带宽或网络的额定速率的限制。重要知识点计算机网络(简称网络)把许多计算机连接在一起,而互联网把许多网络连接在一起,是网络的网络。路由器是实现分组交换的关键构件,其任务是转发收到的分组,这是网络核心部分最重要的功能。分组交换采用存储转发技术,表示把一个报文(要发送的整块数据)分为几个分组后再进行传送。在发送报文之前,先把较长的报文划分成为一个个更小的等长数据段。在每个数据端的前面加上一些由必要的控制信息组成的首部后,就构成了一个分组。分组又称为包。分组是在互联网中传送的数据单元,正是由于分组的头部包含了诸如目的地址和源地址等重要控制信息,每一个分组才能在互联网中独立的选择传输路径,并正确地交付到分组传输的终点。互联网按工作方式可划分为边缘部分和核心部分。主机在网络的边缘部分,其作用是进行信息处理。由大量网络和连接这些网络的路由器组成核心部分,其作用是提供连通性和交换。计算机通信是计算机中进程(即运行着的程序)之间的通信。计算机网络采用的通信方式是客户-服务器方式(C/S 方式)和对等连接方式(P2P 方式)。客户和服务器都是指通信中所涉及的应用进程。客户是服务请求方,服务器是服务提供方。按照作用范围的不同,计算机网络分为广域网 WAN,城域网 MAN,局域网 LAN,个人区域网 PAN。计算机网络最常用的性能指标是:速率,带宽,吞吐量,时延(发送时延,处理时延,排队时延),时延带宽积,往返时间和信道利用率。网络协议即协议,是为进行网络中的数据交换而建立的规则。计算机网络的各层以及其协议集合,称为网络的体系结构。五层体系结构由应用层,运输层,网络层(网际层),数据链路层,物理层组成。运输层最主要的协议是 TCP 和 UDP 协议,网络层最重要的协议是 IP 协议。ping和ICMP是如何探测网络情况的?ping和traceroute都是基于ICMP协议进行的。ping查询报文的操作,通过直接ping ip或者ping 域名的方式,计算机会一直发送ICMP请求,目标收到了信息会回复ICMP信息,头部类型8和0分别表示了发送和接收信息。查询报文是属于按照正常思路使用ICMP协议的操作。于此相对的,就是差错报文,差错报文是利用tracerouter发送UDP包到目标计算机的不常用端口(30000以上)的方式来可以让目标计算机返回错误信息。如果成功访问到了目标的UDP层,也会因为端口问题返回ICMP请求,这反而说明了当前计算机和目标计算机是相通的!另外,也可以通过设置TTL(time to live)的方式来进行中间路由的校验。网关和路由的工作原理网关和路由器一般是黏在一起的,网关往往分为两种,转发网关和NAT(network address translate)网关。两者区别:转发网关在转发请求的时候只会改变mac头部,但是NAT网关在转发请求的时候会同时改变ip地址。转发网关仅仅是起到一个过路财神的作用,就是为了进行数据信息的传递工作。但是NAT网关的作用就相对有趣了,是为了进行内外网的衔接而存在的。外网ip地址很稀有,因此就相对很贵,基本不可能对于内网中的每台设备都专门配备一个外网的ip,所以通过路由器时都会被伪装为同一个外网的ip,不同的是端口,NAPT(network address-port protocol)就是为此而存在的,该协议维护了一张表,用以表达两个网络间ip-端口对的互相映射关系。比如192.168.0.1就映射为外网的10086端口,192.168.0.2就映射为外网的10087端口,这样从内网发送出去的数据就可以互相区分彼此了,发送出去的数据也可以找回返回的路了。路由协议:路由之间需要进行沟通从而知道你到底帮助我些什么?路由器会维护一张路由表来记录如下问题:(1)目的网络:你的目的地是哪里?(2)出口设备:将包从哪个口扔出去?(3)下一跳网关:下一个路由器的地址?路由之间通过两种算法来构建路由器之间的网状关系,以及相互的最短路径。第一种:距离矢量路由这种方式通过TCP协议来每隔几秒向邻近的路由器发送自己的路由信息,从而整个网络每个路由器都会通过这种方式逐渐丰富自己的路由信息,最后所有路由器都会知道自己与其他路由器的连接情况。这种方式的优先是新装入路由快,但是路由一旦不行了,刷新路由就很慢,必须要不断试探直到距离超过阈值,才会判定路由之间不通。另外一个缺点就是需要发送整个全部路由表。网络太大就吃不消了。基于该算法的协议为BGP(border gateway protocol),为了避免该算法的在网络过大下产生的问题,就分为iBGP和eBGP用以分别对付内网和外网。第二种:链路状态路由算法这种方式通过DUP协议来每隔一段时间来广播传递信息,常常用于数据中心。他发送的是路由状态的改变信息,因此发送的数据量会明显小于第一种。每当一台新的路由器启动时,会向邻居发送信息以确定自己和邻居之间的距离,然后将该信息广播出去,以让整个网络中的所有路由器都能知道他已经横空出世了!同理,当邻居发送他怎么停机了时也会发送改动信息,以告诉整个网络,他好像暂时不行了。基于该算法的协议为IGP(Interior Gateway Protocol),主要用于数据中心,因为他可能快速地对路由变化进行响应所以更加便于进行负载均衡的操作。路由器和交换机的区别工作层次不同:交换机比路由器更简单,路由器比交换机能获取更多信息,交换机工作在数据链路层,而路由器工作在网络层数据转发所依据的对象不同。交换机的数据转发依据是利用物理地址或者说MAC地址来确定转发数据的目的地址,而路由器是依据ip地址进行工作的传统的交换机只能分割冲突域,不能分割广播域;而路由器可以分割广播域拓展:域名、IP、MAC 与 ARP域名是我们取代记忆复杂的 IP 的一种解决方案IP 地址才是目标在网络中所被分配的节点。MAC 地址是对应目标网卡所在的固定地址(物理地址)。ARP 英文全名为:Address resolution protocol ,地址解析协议,ARP为IP与MAC提供动态映射,过程自动完成。当PC发出通信请求时,根据协议规定,它的目的地址必然是48bit的MAC地址的。MAC并不能和IP直接去通信。那么就需我们的ARP协议来做相应的转换工作。
Socket这样回答面试官还拿不到offer?
前言对TCP/IP、UDP、Socket,套接字这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。那么我想问:什么是TCP/IP、UDP?TCP、UDP的区别是?什么是三次握手?Socket在哪里呢?Socket是什么呢?你会使用它们吗?计算机网络分多少个层次?线程和进程的区别是?内存池,进程池,线程池是?TCP断开连接的具体过程,其中每一步是为什么那么做 ?传输控制层,网络层,数据链路层是什么?数据传输的一系列流程是什么?应用层中的App上位机软件是怎么跟服务器交互的?正文OSI 7层模式 如下 ↓↓↓↓↓↓↓↓↓↓↓↓首先要从计算机底层的分层开始讲起。俗称OSI 7层参考模型。计算机一共分为7层每一层管理相应的职能。计算机分层主要是达到解耦的目的。层与层之间是可以有接口调用的。应用层表示层会话层传输控制层网络层数据链路层物理层今天这一章节讲解的是Socket的底层原理,表示层与会话层被应用层都包含起来了,那么我们就从包含之后开始叙述。应用层我们都熟悉,就是基于应用层做的一系列开发调的一些API函数。应用层传输控制层网络层数据链路层物理层传输控制层 如下 ↓↓↓↓↓↓↓↓↓↓↓↓平时开发中数据库连接的时候就是一个Socket连接,Socket连接也就是计算机底层的IO输入输出,那么就出现了问题 如果两个Send发送给一个数据源应该建立几个连接呢?还是可以建立一个连接?通过Linux的nc指令 与百度的80端口建立连接,连接之后看下图。多了一个nc的连接。所以问题来了nc到底是一个什么东西?为什么可以与百度的80端口建立连接呢?Linux下nc连接的作用是实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口端口的扫描,nc可以作为client发起TCP或UDP连接机器之间传输文件机器之间网络测速通过如下图继续详细的介绍吧。应用层的app想与别人建立连接的流程是经过kemel内核的传输控制层(内核是什么东西向上翻阅一下)利用传输控制层的TCP进行操作,下图讲解了什么是TCP!很多文章都写发完三次握手包就已经完成创建了或者说是已经连接成功了,其实是不对的 ,双方建立连接之后必须是建立双方的资源之后才算是正常的建立连接 。如下图xshell效果图已经放在该图的下面。Recv-Q与Send-Q是两个建立连接的资源队列,应用层中的程序取数据时都是从这里取的。资源建立完成之后 也就是我们应用层的在new Socket的时候返回了一个socket。资源创建完成之后 完成了三次握手 下面就开始Send发送数据了,发送数据也是一样的,数据放入资源队列,如果服务端也想发送数据也是放入服务端的资源队列。这样就是两个资源队列的操作来回操作了。这样操作的好处与目的是解耦了与下面连接的虚无的这个过程。四次分手 -> 释放端口号-> 释放资源(四次分手这里简单看一下,后面会有专门讲解四次分手的流程)什么是Socket?我这里不讲具体的一大串的含义,想看的百度搜 什么是Socket 找百度百科就可以了!我这里只给出干货!Socket是一个套接字,它是一个四元组。什么是四元组呢?如下图↓↓↓↓比如举个例子:现在的浏览器都支持多个标签页,为什么每个标签页中的百度谷歌搜索不同的问题的时候,百度返回来的内容体为什么没有显示错呢? 这个就是和Socket有关!IP代表着某一个主机的地址,Port的作用是 寻找一个主机中无数个进程中的一个。 一个主机中有65535个端口号。那么问题来了 IPA连接IPB的同时可以连接IPC吗?IPA连接IPB的同时可以连接IPC吗? 如下图↓↓↓↓↓↓再向外界发送数据包时,只要返回的数据包能确认是张三还是李四就即可,所以四元组中也可以理解成 对象中嵌入一个List列表。好比我们做数据库主表外表一对多的时候 通过对象取里面的list列表,再从list列表中取对应的下标值一样。所以 IPA:1+IPB:80与IPA:1+IPC:80是可以区分出来的!目标地址不同 所以是12万一个电脑是否有两个一样的端口号?加网卡!答案是可以的我的电脑有两个IP地址 一个是物理地址一个是本地地址,做了以下的程序测试这块讲解的不太明细 请谅解! 这里是通过视频学的 做的一些程序测试都不存在了 这里了解就好四次分手流程(四次分手就是释放资源的一个过程) 如下↓↓↓↓↓↓FIN代表开始分手了,知会你一声Fin+Ack代表我知道了这件事Fin代表我同意了并且我也想跟你分手Ack代表确定完毕即将等待超时释放资源完成分手补充一下数据发送的细节并且稍微普及一下DDOS发送请求之后 服务端给我们返回一个syn,syn的大小是由当前的MTU绝对的。MTU是最大的传输单元,普遍大小是1500。如果一次传输的数据大于1500则分多次发送,大家可以利用抓包指令监控包的情况。先安装tcpdump。Linux的指令是 tcpdump -nn -i etho port 80 。 nn代表不把地址转换成名字 80代表抓哪个端口的包,具体的详细指令请 Linux抓包指令参考下图是数据发送的一个流程 ①.首先向百度发一个握手的请求包,②.百度向本地回了一个同意包,③.本地向百度回一个收到确认包开始交易。④.本地先向百度发送一个当前浏览器支持哪些算法的列表包,所以是168字节。⑤.1460和1321是两次内容包,一次发不完所以分两次。⑥.之后本地又向百度发一个ack的确认包,告诉百度当前内容已收到。并且开始四次分手 ⑦.本地向百度请求分手,⑧.百度告诉本地收到了并且我 也请求分手。⑨.最后本地向百度请求ack确认包 结束当前操作! 分手完毕!ddos是分布式拒绝服务。网络层 如下↓↓↓↓↓↓通过如下图我们讲述的知识是:IP:ip地址是由子网掩码生成的,通过二进制按位与运算的方式。它是4个字节,8个位,每一位的范围是0-255。换算流程以及广播地址的换算,网络地址的换算如下图↓↓↓↓Router:计算机底层的路由表,数据转发是通过路由表走的。Linux输入router -n 。 结合下图下表DNS子网掩码网关:网关是什么?举个例子,相当于古代一个当官家庭的大人,妻子或者下人所有官场上的反馈与传达什么意思都要依靠这个父亲。网关也是这样,一个局域网中的所有数据想要发送到外网中必须依靠这个网关。网络层的工作原理流程DestinationGatewayGenmaskFlagesMetricRefUseIFace0.0.0.0172.17.111.2530.0.0.0UG10000ehto172.17.96.00.0.0.0255.255.240.0U10000ehto为路由目标,可以是网络或者主机的IP地址包含默认的网关或通过其可访问主机或网络的网关包含网关后的网络或主机的子网掩码表示该条路由从哪个设备出去网络层的工作原理(发给谁拿谁的IP地址与路由表子网掩码的Genmask做二进制按位与):例子百度IP:220.181.38.149 子网掩码:255.255.255.0二进制百度:11011100.10110101.00100110.10010101二进制子网:11111111.11111111.11111111.00000000①百度的IP通过按位与子网的结果与destination作比较。如果正确就发出到GateWay到网关,如果错误下一条路由继续处理。②如果是局域网传输主机A按位与子网的结果与destination作比较如果符合直接校验网关,当网关是0.0.0.0时说明放行一切数据,说明局域网传输不需要网关。 所以直接转发到目标IP。③ 接①搭配下图继续聊。如果正确发出到GateWay网关后它的数据包中都包含着哪些数据呢?看图!如图得知 下面走到了数据链路层!网络层的作用:寻找网关地址或者不通过网关直接内外转发。网络层只关心谁到谁的位置。数据链路层 如下↓↓↓↓↓↓↓方便理解,给出一个不权威的解释。客户端制造Syn包发送到网关网关根据MAC地址收到后判断目标IP地址发现不是自己的,于是进行转发给上一级网关,也就是节点B,并且修改MAC地址为节点B的IP光纤运营商根据MAC地址收到后,判断目标IP地址,发现也不是自己的,于是再次进行转发给上一级网关也就是节点C,并且修改MAC地址为节点C的IP企业接入网光纤根据MAC的地址收到后判断目标IP地址,发现不是自己的,于是进行转发到公司服务器也就是端点B。并且修改MAC地址为端口B的IP百度服务器端(端点B)收到后,判断目标IP地址发现是自己的于是收下。最后总结一下总体流程先请求MAC地址,如果有就开始三次握手接下来按照上面就通了。没有的话要先通过ARP协议请求一个数据链路层的硬件地址,拿到之后就可以执行①的操作了用程序校验一下↓↓↓↓↓①对80端口的抓包,②抓包之前我把地址删掉了所以这里会先请求一遍ARP协议拿到硬件地址返回了00:50:56:f7:53:2b,这里是广播的发给了局域网的所有人,但是只有192.168.150.2才能给我返回③拿到之后开始三次握手,④发收内容体包,⑤最后四次分手断开面试技巧流程自我介绍什么的我就不说了,只说一下技术,拿Socket举例。常见的小白场景就是面试官:简单的介绍一下Socket 应聘人:你好面试官,不好意思我没用过,好像是通信用的。常见的初级场景就是。面试官:简单的介绍一下Socket 应聘人:你好面试官,Socket是一个安全套接字,用于通信。一个发送点一个接收点,有多种通信协议比如UDP/TCP,TCP是三次握手,UDP是不用握手的。UDP比TCP更高效。如果需要交互判断的选择TCP,如果不需要交互判断的选择UDP。以上没有加分项,或许你可以这样,中级场景面试官:简单的介绍一下Socket 应聘人:你好面试官,Socket我了解的是: A=>安全套接字,要想聊Socket就要深入计算机底层我们可以从OSI7层模型说起,描述每一层的作用。 B=>TCP是什么,告诉面试官为什么是面向连接的可靠的传输协议。TCP三次握手都做了哪些事情比如Syn包,Ack包,Syn+Ack包。 C=> 通过交互流程可以展开ddos简单介绍一下表明你懂的比较多。你是个有干货的人,你是个对技术敏感的人。乐于学习的人告诉面试官Socket在每一层都做了什么以及Socket通信的时候是如何和外界联系的【加分项】
Ceph Swift Api 配置与使用(三)(上)
Ceph Swift Api 配置与使用一、Ceph Swift Api 说明在 ceph 的使用上, 互联网大规模的文件场景下, fs 并不能满足生产的使用要求, rados 本地化操作也不便于服务的接入与使用, 这里我们就要采用 Ceph Swift Api 来实现文件的存储管理。二、Ceph Swift Api 特点Swift 是由 Rackspace 开发,用来为云计算提供可扩展存储的项目。专注于对象存储, 并提供一套 REST风格的Api 来访问, 与 Ceph 强一致性不同, 它是最终一致性。两者都是优秀的开源项目, 并无明显优劣之分,在使用场景上有所不同, 如果是专注于对象存储, 那么可以选择swift 即可满足需要, 如果还有块存储要求, 那么选择Ceph 更为合适。这里选择 Ceph , 因为通过网关可以适配兼容 swift api , 同时在数据访问上具有较强的扩展性:Ceph可通过Rados网关用兼容S3的RESTful API访问,对AWS云环境下的其他内容也能很好的兼容, 比如OpenStack Swift的对象存储访问接口。CephFS:是一个POSIX兼容的文件系统,可以在任何Linux发行版上运行,操作系统可直接访问Ceph存储。RBD:RBD是一个Linux内核级的块设备,允许用户像任何其他Linux块设备一样访问Ceph。ISCSI 网关: 这一增加的功能是SUSE加上去的,它允许管理员在Ceph之上运行iSCSI(互联网小型计算机系统接口)网关,从而将其转变为任何操作系统都可以访问的SAN(Storage Area Network,存储区域网络)文件管理器。三、Ceph RGW 介绍Ceph 可以提供块、文件和对象三种形态的存储。 RGW 就是提供对象存储的网关,也即对象存储网关。 所谓对象存储网关,也就是对象存储的入口,本质上是一个HTTP 服务器,与 Nginx 和 Apache 无特殊差别。通过这个网关入口,用户可以采用HTTP 协议,以 RESTful 的方式访问 Ceph 的对象存储。四、Ceph 存储结构在使用对象存储之前, 先要了解桶(container容器)概念及其存储结构:Ceph Swift Api 的调用, 需要先创建相应用户进行认证才能操作, 每个用户下面可以创建多个桶, 桶里面可以存储对象,对象就是各种数据文件, 包括文档, 图片等。传统上传文件的使用, 我们往往会指 定路径信息, 在这里, 桶和对象的关系好比文件夹与文件的概念, 不同之处是桶不能再嵌套桶, 也就是没有层级路径的概念。Ceph 存储结构 :五、Ceph Swift Api 服务端的配置1、确保集群正常安装并启动:如果rgw没有显示, 检查服务状态:systemctl list-unit-files|grep enabled|grep ceph重启RGW服务:ceph-deploy --overwrite-conf --ceph-conf ceph.conf rgw create CENTOS7-1
systemctl restart ceph-radosgw@*.service2、验证网关是否正常访问地址, http://192.168.88.161:7480出现以下提示代表正常3、创建Swift用户, 用于接口请求认证 sudo radosgw-admin user create --subuser="cephtester:subtester" --uid="cephtester" --display-name="cephtester" --key-type=swift --secret="654321" --access=fulluid 为主用户, subuser 为子用户信息, secret 指定密钥, 不指定则随机生成, access 拥有权限设定。返回结果:[root@CENTOS7-1 ceph-cluster]# sudo radosgw-admin user create --subuser="cephtester:subtester" --uid="cephtester" --display-name="cephtester" --key-type=swift --secret="654321" --access=full
{
"user_id": "cephtester",
"display_name": "cephtester",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [
{
"id": "cephtester:subtester",
"permissions": "full-control"
}
],
"keys": [],
"swift_keys": [
{
"user": "cephtester:subtester",
"secret_key": "654321"
}
],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}记住swift_keys下面的user和secret_key信息, 代码中需使用。4、激活管理后台的对象存储模块: 5、创建一个管理用户:radosgw-admin user create --uid=mgruser --display-name=mgruser --system返回结果:[root@CENTOS7-1 ceph-cluster]# radosgw-admin user create --uid=mgruser --display-name=mgruser --system
{
"user_id": "mgruser",
"display_name": "mgruser",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"auid": 0,
"subusers": [],
"keys": [
{
"user": "mgruser",
"access_key": "W462B8SE31NDCOQR4E6I",
"secret_key": "XPZcugMWRhYccFlEPIHKcyFVr73grVuiJgFD4rDR"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"system": "true",
"default_placement": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}根据生成的access_key与secret_key, 执行:ceph dashboard set-rgw-api-access-key W462B8SE31NDCOQR4E6I
ceph dashboard set-rgw-api-secret-key XPZcugMWRhYccFlEPIHKcyFVr73grVuiJgFD4rDR打开管理界面,https://192.168.88.161:18843 可以查看到我们刚才创建的两个用户:
面试题24解析-详谈DNS域名解析过程
前面的文章我们已经说过了,网站一般都是用B/S架构,统一使用应用层协议HTTP来进行数据交互,并且HTTP是无状态的短连接。每一个请求后台都有一个业务逻辑相对应。下面,咱们来看一下B/S网络架构的设计,如图所示:我们可以从图中发现,首先,DNS把域名解析成对应的ip地址,然后再根据ip地址找到对应的服务器并发送GET请求,最终,服务器将相应的资源返回到客服端。接下来,我们来分析一下DNS到底是怎么进行解析的(红框标注的) ?1域名解析的那几种方式?A记录:用来指定域名对应的IP地址,A纪录可以将多个域名解析到一个IP地址,但不能将一个域名解析到多个IP地址。MX记录:即Mail Exchange,它可以将域名下的邮箱服务器指向自己的Mail Server。CNAME记录:即Canonical Name(别名解析),可以为一个域名设置一个或者多个别名。NS记录:为某个域名指定DNS解析服务器,即该域名用指定的DNS服务器去解析IP地址。TXT记录:为域名设置说明。2怎么用工具查看域名解析过程?在windows和linux环境,都可以用nslookup工具来查看解析结果,如图所示:在linux系统,也可以使用dig命令来查询DNS的解析过程,如图所示:从上面我们可以清楚的看到整个域名是如何发起和解析的。从根域名(.)到gtld server (.com),再到Name Server(baidu.com.)的整个过程,我们可以发现baidu的dns备份服务器有好几个。3怎么清除缓存的域名?在windows环境,我们可以用ipconfig工具来处理,命令如下:ipconfig /flushdns结果如图所示:在linux环境,我们可以用nscd 工具来处理,命令 如下:sudo apt-get install nscd
sudo /etc/init.d/nscd restart结果如图所示:4JVM中DNS缓存设置一般像高级语言的虚拟机都会缓存DNS解析结果,因为这样可以节约DNS解析时间,同样JVM也不例外;JVM的DNS缓存一般是在InetAddress类中完成的,它有两种缓存结果,一种是正确解析结果的缓存,另一种是失败解析结果的缓存。由两个配置项来控制,配置项是在%JAVA_HOME%\lib\security\java.security文件中配置的。两个配置项分布是networkaddress.cache.ttl和networkaddress.cache.negtive.ttl,其默认值分别是-1(永不失效)和10(保留10秒钟)。怎么进行修改呢?直接修改java.secury文件的默认值。在JAVA启动时加启动参数 -Dsun.NET.inetaddress.ttl=XXX来修改默认值。5DNS域名解析详细过程主要请求过程实例图如下所示:下面,咱们结合图来详细聊聊它的请求流程:首先,浏览器会检查缓存中有没有这个域名所对应的ip地址;如果有,整个解析过程就结束了;如果没有,则会查找操作系统缓存中是否有这个域名对应的DNS解析结果。操作系统也可以通过改hosts文件来改变DNS解析过程。操作系统会把域名发送到你系统设置的LDNS(本地区域服务器)进行解析;如果没有命中,直接向Root Server域名服务器发送请求,根域名服务器直接返回本地域名服务器一个所查询域的主域名服务器(gTLD),如 ?.com/.cn/.org等;本地域名服务器再向上一步返回的gTLD服务器发送请求,gTLD服务器查找并返回该域名对应的Name Server域名服务器地址,该Name Server通常是你注册的域名服务器;Name Server会查找域名和IP的映射表,并返回对应的IP和TTL;Local DNS Server会缓存这个域名和IP的映射关系,缓存时间由TTL决定,并把解析结果返回给用户,用户的本地域名缓存时间也由TTL决定。6造成DNS域传输漏洞原因?DNS区域传送:指一台备用服务器使用来自主服务器的数据刷新自己的域数据库。一般只有在真的需要备用域名DNS服务器的安全网络环境中才有必要使用DNS区域传送,但是许多DNS服务器却被错误地配置成只要有client发出请求,就会向对方提供一个zone数据库的详细信息,造成这个漏洞的主要原因是:允许了不受信任的网络环境用户执行DNS区域传送(zone transfer)操作。
Java Socket与TCP/IP协议栈
本文阅读大概需要17分钟。一OSI 七层模型与TCP/IP四层模型很多同学知道在大学课程中,我们学习的《计算机网络》一书采用的是OSI七层网络模型(OSI Model),但是OSI?七层模型是一种抽象模型,在操作系统实际实现中,采用的是TCP/IP四层网络模型,四层模型将七层模型合并为了应用层(Application Layer)、传输层(Transport Layer)、网络层(Internet Layer)、链路层(Link Layer),使得网络系统在具体实现中更加简化,OSI七层网络模型与TCP/IP四层网络模型以及协议对应关系如下表所示。在计算机系统中,分层是一种很重要的编程思想,分层思想将系统的功能与责任进行了层次化划分,基本上所有系统的架构设计,都是按照层次架构作为基本架构来设计的。在计算机网络中,相同层次具有相同的协议处理方式,下层协议上层提供服务,上层协议的行为控制着下层的工作状态,层层之间责任单一,目的明确。二、Java对于TCP/IP协议的实现在网络程序开发中,操作系统都为我们提供了全面 方便的应用层网络操作类与接口,使得程序员在使用过程中无需考虑协议栈的细节,而专心于数据的传输处理过程中。当然,操作系统也为程序员提供了可以掌控协议细节的机会,例如使用原始套接字(Raw Socket)可以控制TCP的三次握手的细节实现TCP SYN扫描(注意部分 Windows 7系统不支持原始套接字的半开扫描)。但是在大多常规网络应用开发中,我们都直接使用系统提供的应用层接口来实现网络程序。这里我们罗列出在Java中常见的TCP/IP协议的实现类或方法,如下下表所示:三TCP协议为什么需要三次握手首先我们来看一下TCP协议三次握手的具体过程(本图选自网络):第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。那么,为什么TCP协议需要三次握手?在谢希仁的《计算机网络》中是这样说的:已失效的连接请求报文段会产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。换句话说,TCP之所以采用三次握手建立连接的机制,是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。在网络中不能确保数据包的一定可以发送成功,也不能确保数据包的发送顺序和到达顺序一致,三次握手机制避免了客户端与服务器之间在建立连接时可能因丢包而造成的一端 无法感知另一端状态的现象。关于TCP协议的四次挥手过程与原因与三次握手完全类同,这里就不说明了,关于TCP连接的关闭,后文将分析一个相关问题:TCP半关闭现象(Half-Close),这里我们先来看一下Java中如何使用Socket类建立一个TCP连接的过程。四Java中TCP通信的相关实现在上节我们分析了TCP协议建立连接,数据传输以及关闭连接的具体实现方式,而在实际的开发中,程序员只需了解TCP协议是一种可靠的传输协议即可实现数据在客户端与服务器之间稳定的传输。在Java中,提供了Socket与SocketServer类来实现TCP服务器与客户端的相关功能,一次正常的TCP通信其大致流程可以分为四步(BIO模式):这里有个问题,TCP的三次握手是在Socket的哪一步中实现?在ServerSocket.accept()与Socket.Connect()的过程中实现的,在客户端通过Connect()接口连接服务器时,操作系统底层的TCP/IP协议栈便开始了发送SYN包,回复SYN+1等TCP的三次握手过程,只有三次握手成功,ServerSocket.accept()才会返回一个合法的Scoket对象,客户端Socket.Connect()函数会正常返回,如果三次握手失败,客户端Socket.Connect()会抛出IOException异常。这里需要注意,具体的三次握手协议细节的实现,也不是在Java中实现的,Java只是运行在JVM虚拟机上的语言,具体的实现是由宿主主机的TCP/IP协议栈实现的,Java只是通过虚拟机调用了这些宿主主机提供的方法而已。五TCP半关闭现象(Half-Close)有TCP服务器与客户端应用程序开发经验的同学应该遇到过一个问题,那就是服务器端突然崩溃(kill 掉服务器进程),查看系统中的网络连接时,发现TCP客户端的状态还是处于连接状态(ESTABLISHED),而该TCP连接实际已经失效了,这就是TCP的Half-Close 现象。如果应用程序判断与服务器连接状态的方法依赖于TCP的连接状态,客户端将会一直认为与服务器的TCP连接是正常的,只有在客户端向服务器发送数据时,才能发现TCP连接对应的套接字失效了。之所以产生Half-Close现象就是由于客户端与服务器之间没有通过四次挥手的方式关闭TCP连接,在服务器的突然下线会造成客户端无法立即感知的问题。有同学会问,不是有超时时间吗,一旦超时,客户端不就可以感知到服务器已经下线了吗?不错,系统的协议栈实现具有超时时间的机制,但是在windows系统下,这个超时时间默认是2小时(作者未考证linux下的keepAlive时间)。那么如何避免Half-Close现象?1.首先进行再使用完tcp连接后,一定要将套接字close掉。2.添加心跳包机制,服务器与客户端之间的连接保持机制不应该依赖套接字的状态,而应该在TCP协议之上设计心跳包机制,例如每5分钟,客户端与服务器之间通过发送心跳包来感知对方的存在。3.TCP Server应该实现JVM的关闭钩子(Runtime.addShutdownHook()),主动关闭所有TCP连接,清理占用资源,JVM关闭钩子的使用方式如下所:服务器端(ServerSocket)绑定监听端口,等待客户端的TCP的连接(ServerSocket.accept())客户端(Socket)通过IP地址与端口连接服务器监听端口(Socket.Connect()),连接成功后服务器端返回表示该TCP连接的Socket对象。客户端与服务器通过打开Socket对象的InputStream和OutputStream数据流,实现数据的传输工作(Java将I/O相关的操作都提供了流操作接口,网络接口操作方式也一样)。客户端与服务器完成数据传输,关闭数据流,关闭TCP连接(Socket.close())。下图是Socket的通行模型图:总结TCP协议作为可靠传输协议,是所有协议中最常用的协议,什么?最常用的协议不是HTTP吗?HTTP协议只是TCP协议的应用协议而已。TCP协议相关的开发难点在于服务器端的开发,需要考虑并发性能,本文以讲解了TCP的协议为主,因此只采用了BIO模式进行分析,在之后的文章中将会分析高并发的TCP服务器的实现原理。
《微服务零基础入门教程》一步一步,带你走进微服务的世界(下)
四、微服务案例搭建使用微服务架构的分布式系统,微服务之间通过网络通信,我们通过服务提供者与服务消费者来描述微服务间的调用关系。服务提供者:服务的被调用方,提供调用接口的一方服务消费者:服务的调用方,依赖于其他服务的一方我们以电商系统中常见的用户下单为例,用户向订单微服务发起一个购买的请求。在进行保存订单之前需要调用商品微服务查询当前商品库存,单价等信息。在这种场景下,订单微服务就是一个服务消费者,商品微服务就是一个服务提供者。1、搭建环境创建父工程在IDEA中创建父工程并引入坐标<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>service-product</module>
<module>service-order</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.uncle</groupId>
<artifactId>micro-service-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>micro-service-demo</name>
<description>micro-service-demo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建微服务工程模块2、搭建商品微服务编写实体类@Data
@Entity
@Table(name="tb_product")
public class Product {
@Id
private Long id;
private String productName;
private Integer status;
private BigDecimal price;
private String productDesc;
private String caption; }这里使用了lombok简化实体类的开发Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率编写dao接口public interface ProductDao extends JpaRepository<Product,Long> ,
JpaSpecificationExecutor<Product> {}编写service层public interface ProductService {
//根据id查询
Product findById(Long id);
//查询全部
List findAll();
//保存
void save(Product product);
//更新
void update(Product product);
//删除
void delete(Long id);
}@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductDao productDao;
@Override
public Product findById(Long id) {
return productDao.findById(id).get();
}
@Override
public List findAll() {
return productDao.findAll();
}
@Override
public void save(Product product) {
productDao.save(product);
}
@Override
public void update(Product product) {
productDao.save(product);
}
@Override
public void delete(Long id) {
productDao.deleteById(id);
}
}编写web层@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public List findAll() {
return productService.findAll();
}
@GetMapping("/{id}")
public Product findById(@PathVariable Long id) {
return productService.findById(id);
}
@PostMapping
public String save(@RequestBody Product product) {
productService.save(product);
return "保存成功";
}
@PutMapping("/{id}")
public String update(@RequestBody Product product) {
productService.update(product);
return "修改成功";
}
@DeleteMapping("/{id}")
public String delete(Long id) {
productService.delete(id);
return "删除成功";
}
}controller中使用的@GetMapping是一个组合注解,相当与@RequestMapping(method=“get”)。类似的注解还有@PostMapping,@PutMapping,@DeleteMapping配置启动类package com.uncle.product;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*
* @author sjx
*/
@SpringBootApplication
@EntityScan("")
public class ProductApplication {
/**
* main 方法
* @param args:参数列表
*/
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
配置yml文件server:
port: 9002
spring:
application:
name: shop-service-product
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
username: root
password: 111111
jpa:
database: MySQL
show-sql: true
open-in-view: true3、搭建订单微服务编写实体类@Data
@Entity
@Table(name="tb_order")
public class Order {
@Id
private Long id;
private String productName;
private Integer status;
private BigDecimal price;
private String orderDesc;
private String caption; }这里使用了lombok简化实体类的开发Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率编写dao接口public interface OrdertDao extends JpaRepository<Order,Long> ,
JpaSpecificationExecutor<Order> {}编写service层public interface OrderService {
//根据id查询
Order findById(Long id);
//查询全部
List findAll();
//保存
void save(Order order);
//更新
void update(Order order);
//删除
void delete(Long id);
}@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDao productDao;
@Override
public Order findById(Long id) {
return productDao.findById(id).get();
}
@Override
public List findAll() {
return productDao.findAll();
}
@Override
public void save(Product product) {
productDao.save(product);
}
@Override
public void update(Product product) {
productDao.save(product);
}
@Override
public void delete(Long id) {
productDao.deleteById(id);
}
}编写web层@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public List findAll() {
return productService.findAll();
}
@GetMapping("/{id}")
public Product findById(@PathVariable Long id) {
return productService.findById(id);
}
@PostMapping
public String save(@RequestBody Product product) {
productService.save(product);
return "保存成功";
}
@PutMapping("/{id}")
public String update(@RequestBody Product product) {
productService.update(product);
return "修改成功";
}
@DeleteMapping("/{id}")
public String delete(Long id) {
productService.delete(id);
return "删除成功";
}
}controller中使用的@GetMapping是一个组合注解,相当与@RequestMapping(method=“get”)。类似的注解还有@PostMapping,@PutMapping,@DeleteMapping配置启动类package com.uncle.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*
* @author sjx
*/
@SpringBootApplication
@EntityScan("")
public class OrderApplication {
/**
* main 方法
* @param args:参数列表
*/
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
配置yml文件server:
port: 9001
spring:
application:
name: shop-service-order
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
username: root
password: 111111
jpa:
database: MySQL
show-sql: true
open-in-view: true4、服务调用RestTemplate介绍Spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring 模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。考虑到RestTemplate类是为调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连就不足为奇了,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate类具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法。RestTemplate方法介绍通过RestTemplate调用微服务配置RestTemplate//配置RestTemplate交给spring管理
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}编写下订单方法@PostMapping("/{id}")
public String order(Integer num) {
//通过restTemplate调用商品微服务
Product object =
restTemplate.getForObject("http://127.0.0.1:9002/product/1", Product.class);
System.out.println(object);
return "操作成功";
}硬编码存在的问题至此已经可以通过RestTemplate调用商品微服务的RESTFul API接口。但是我们把提供者的网络地址(ip,端口)等硬编码到了代码中,这种做法存在许多问题:应用场景有局限无法动态调整那么应该怎么解决呢,就需要通过注册中心动态的对服务注册和服务发现
《微服务零基础入门教程》一步一步,带你走进微服务的世界(上)
版本选择版本选择,本人:使用如下最新版本一定要注意版本适配一、系统架构的演变随着互联网的发展,网站应用的规模不断扩大,常规的应用架构已无法应对,分布式服务架构以及微服务架构势在必行,极需一个治理系统确保架构有条不紊的演进。1、单体应用架构Web应用程序发展的早期,大部分web工程(包含前端页面,web层代码,service层代码,dao层代码)是将所有的功能模块,打包到一起并放在一个web容器中运行。所有功能都部署在一个web容器中运行的系统就叫做单体架构。优点:所有的功能集成在一个项目工程中项目架构简单,前期开发成本低,周期短,小型项目的首选。缺点:全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。技术栈受限。2、垂直应用架构当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。优点:项目架构简单,前期开发成本低,周期短,小型项目的首选。通过垂直拆分,原来的单体项目不至于无限扩大不同的项目可采用不同的技术。缺点:全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。3、分布式SOA架构什么是SOASOA 全称为 Service-Oriented Architecture,即面向服务的架构。它可以根据需求通过网络对松散耦合的粗粒度应用组件(服务)进行分布式部署、组合和使用。一个服务通常以独立的形式存在于操作系统进程中。站在功能的角度,把业务逻辑抽象成可复用、可组装的服务,通过服务的编排实现业务的快速再生,目的:把原先固有的业务功能转变为通用的业务服务,实现业务逻辑的快速复用。通过上面的描述可以发现 SOA 有如下几个特点:分布式、可重用、扩展灵活、松耦合SOA架构当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。优点:抽取公共的功能为服务,提高开发效率对不同的服务进行集群化部署解决系统压力基于ESB/DUBBO减少系统耦合缺点:抽取服务的粒度较大服务提供方与调用方接口耦合度较高4、微服务架构优点:通过服务的原子化拆分,以及微服务的独立打包、部署和升级,小团队的交付周期将缩短,运维成本也将大幅度下降微服务遵循单一原则。微服务之间采用Restful等轻量协议传输。缺点:微服务过多,服务治理成本高,不利于系统维护。分布式系统开发的技术成本高(容错、分布式事务等)。5、SOA与微服务的关系SOA( Service Oriented Architecture )“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中。各个服务之间 通过网络调用。微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。二、分布式核心知识1、分布式中的远程调用在微服务架构中,通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分:序列化和通信协议。常见的序列化协议包括json、xml、hession、protobuf、thrift、text、bytes等,目前主流的远程调用技术有基于HTTP的RESTful接口以及基于TCP的RPC协议。RESTful接口REST,即Representational State Transfer的缩写,如果一个架构符合REST原则,就称它为RESTful架构。资源(Resources)??所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。REST的名称"表现层状态转化"中,省略了主语。“表现层"其实指的是"资 源”(Resources)的"表现层"。表现层(Representation)?“资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层”(Representation)。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。状态转化(State Transfer)?访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。综合上面的解释,我们总结一下什么是RESTful架构:?每一个URI代表一种资源;客户端和服务器之间,传递这种资源的某种表现层;客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。RPC协议RPC(Remote Procedure Call ) 一种进程间通信方式。允许像调用本地服务一样调用远程服务。RPC框架的主要目标就是让远程服务调用更简单、透明。RPC框架负责屏蔽底层的传输方式(TCP或者UDP)、序列化方式(XML/JSON/二进制)和通信细节。开发人员在使用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。RESTful和RPC之间的区别与联系1、HTTP相对更规范,更标准,更通用,无论哪种语言都支持http协议。如果你是对外开放API,例如开放平台,外部的编程语言多种多样,你无法拒绝对每种语言的支持,现在开源中间件,基本最先支持的几个协议都包含RESTful。2、 RPC 框架作为架构微服务化的基础组件,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节。让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务。2、分布式中的CAP原理现如今,对于多数大型互联网应用,分布式系统(distributed system)正变得越来越重要。分布式系统的最大难点,就是各个节点的状态如何同步。CAP 定理是这方面的基本定理,也是理解分布式系统的起点。CAP理论由 Eric Brewer 在ACM研讨会上提出,而后CAP被奉为分布式领域的重要理论。分布式系统的CAP理论,首先把分布式系统中的三个特性进行了如下归纳:Consistency(一致性):数据一致更新,所有数据的变化都是同步的Availability(可用性):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求 Partitiontolerance(分区容忍性):某个节点的故障,并不影响整个系统的运行通过学习CAP理论,我们得知任何分布式系统只可同时满足二点,没法三者兼顾,既然一个分布式系统无法同时满足一致性、可用性、分区容错性三个特点,所以我们就需要抛弃一样:需要明确一点的是,在一个分布式系统当中,分区容忍性和可用性是最基本的需求,所以在分布是系统中,我们的系统最当关注的就是A(可用性)P(容忍性),通过补偿的机制寻求数据的一致性。?三、常见微服务框架1、SpringCloudSpring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。2、SpringCloud AlibabaSpring Cloud alibaba为分布式应用开发提供一站式解决方案。它包含开发分布式应用程序所需的所有组件,使您可以轻松地使用Spring Cloud开发应用程序。有了Spring Cloud Alibaba,您只需要添加一些注释和少量配置,就可以将Spring Cloud的应用程序连接到阿里巴巴的分布式解决方案上,并利用阿里巴巴的中间件构建分布式应用系统。主要功能服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring CloudGateway, Zuul, Dubbo 和 RocketMQ限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。 服务注册与发现:适配Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。 消息驱动能力:基于 Spring Cloud Stream为微服务应用构建消息驱动能力。 分布式事务:使用 @GlobalTransactional 注解,高效并且对业务零侵入地解决分布式事务问题。阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有Worker(schedulerx-client)上执行。阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。3、ServiceCombApache ServiceComb 是业界第一个Apache微服务顶级项目, 是一个开源微服务解决方案,致力于帮助企业、用户和开发者将企业应用轻松微服务化上云,并实现对微服务应用的高效运维管理。其提供一站式开源微服务解决方案,融合SDK框架级、0侵入ServiceMesh场景并支持多语言。【感兴趣的同学可以进官网学习一下】4、ZeroC ICEZeroC IceGrid 是ZeroC公司的杰作,继承了CORBA的血统,是新一代的面向对象的分布式系统中间件。作为一种微服务架构,它基于RPC框架发展而来,具有良好的性能与分布式能力。5、拓展框架Java语言相关微服务框架DubboDubbo是由阿里巴巴开源的分布式服务化治理框架,通过RPC请求方式访问。Dubbo是在阿里巴巴的电商平台中逐渐探索演进所形成的,经历过复杂业务的高并发挑战,比Spring Cloud的开源时间还要早。目前阿里、京东、当当、携程、去哪等一些企业都在使用Dubbo。DropwizardDropwizard将Java生态系统中各个问题域里最好的组建集成于一身,能够快速打造一个Rest风格的后台,还可以整合Dropwizard核心以外的项目。国内现在使用Dropwizard还很少,资源也不多,但是与Spring Boot相比,Dropwizard在轻量化上更有优势,同时如果用过Spring,那么基本也会使用Spring Boot。AkkaAkka是一个用Scala编写的库,可以用在有简化编写容错、高可伸缩性的Java和Scala的Actor模型,使用Akka能够实现微服务集群。Vert.x/Lagom/ReactiveX/Spring 5这四种框架主要用于响应式微服务开发,响应式本身和微服务没有关系,更多用于提升性能上,但是可以和微服务相结合,也可以提升性能。.Net相关微服务框架.NET Core.NET Core是专门针对模块化微服务架构设计的,是跨平台应用程序开发框架,是微软开发的第一个官方版本。Service FabricService Fabric是微软开发的一个微服务框架,基于Service Fabric构建的很多云服务被用在了Azure上。SurgingSurging是基于RPC协议的分布式微服务技术框架,基于.NET Core而来。Microdot FrameworkMicrodot Framework用于编写定义服务逻辑代码,不需要解决开发分布式系统的挑战,能够很方便的进行MicrosoftOrleans集成。Node.js相关微服务框架SenecaSeneca是Node.js的微服务框架开发工具,可以用于编写可用于产品环境的代码。Hapi/Restify/LoopBack这三种框架的分工不同,前两种更适合开发简单的微服务后端系统,第三种更适合用在大型复杂应用开发,还可以用在现有微服务上的构建。Go相关微服务框架Go-Kit/Goa/DubbogoGo-Kit是分布式开发的工具合集,适合用于大型业务场景下构建微服务;Goa是用Go语言构建的微服务框架;Dubbogo是和阿里巴巴开源的Dubbo能够兼容的Golang微服务框架。Python相关微服务框架Python相关的微服务框架非常少,用的比较多的是Nameko。Nameko让实现微服务变得更简单,同时也提供了很丰富的功能,比如支持负载均衡、服务发现还支持依赖自动注入等,使用起来很方便,但是有限速、超时和权限机制不完善等缺点。
深度学习正则化(一)
学习目标目标了解偏差与方差的意义知道L2正则化与L1正则化的数学意义知道Droupout正则化的方法了解早停止法、数据增强法的其它正则化方式应用无2.3.1 偏差与方差2.3.1.1 数据集划分首先我们对机器学习当中涉及到的数据集划分进行一个简单的复习训练集(train set):用训练集对算法或模型进行训练过程;验证集(development set):利用验证集(又称为简单交叉验证集,hold-out cross validation set)进行交叉验证,选择出最好的模型;测试集(test set):最后利用测试集对模型进行测试,对学习方法进行评估。在小数据量的时代,如 100、1000、10000 的数据量大小,可以将数据集按照以下比例进行划分:无验证集的情况:70% / 30%有验证集的情况:60% / 20% / 20%而在如今的大数据时代,拥有的数据集的规模可能是百万级别的,所以验证集和测试集所占的比重会趋向于变得更小。100 万数据量:98% / 1% / 1%超百万数据量:99.5% / 0.25% / 0.25%以上这些比例可以根据数据集情况选择。2.3.1.2 偏差与方差的意义“偏差-方差分解”(bias-variance decomposition)是解释学习算法泛化性能的一种重要工具。泛化误差可分解为偏差、方差与噪声,泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。偏差:度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力方差:度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响噪声:表达了在当前任务上任何学习算法所能够达到的期望泛化误差的下界,即刻画了学习问题本身的难度。那么偏差、方差与我们的数据集划分到底有什么关系呢?1、训练集的错误率较小,而验证集/测试集的错误率较大,说明模型存在较大方差,可能出现了过拟合2、训练集和测试集的错误率都较大,且两者相近,说明模型存在较大偏差,可能出现了欠拟合3、训练集和测试集的错误率都较小,且两者相近,说明方差和偏差都较小,这个模型效果比较好。所以我们最终总结,方差一般指的是数据模型得出来了,能不能对未知数据的扰动预测准确。而偏差说明在训练集当中就已经误差较大了,基本上在测试集中没有好的效果。所以如果我们的模型出现了较大的方差或者同时也有较大的偏差,该怎么去解决?2.3.1.3 解决方法对于高方差,有以下几种方式:获取更多的数据,使得训练能够包含所有可能出现的情况正则化(Regularization)寻找更合适的网络结构对于高偏差,有以下几种方式:扩大网络规模,如添加隐藏层或者神经元数量寻找合适的网络架构,使用更大的网络结构,如AlexNet训练时间更长一些不断尝试,直到找到低偏差、低方差的框架。2.3.2 正则化(Regularization)正则化,即在成本函数中加入一个正则化项(惩罚项),惩罚模型的复杂度,防止网络过拟合2.3.2.1 逻辑回归的L1与L2正则化逻辑回归的参数W数量根据特征的数量而定,那么正则化如下逻辑回归的损失函数中增加L2正则化J(w,b) = \frac{1}{m}\sum_{i=1}^mL(\hat{y}^{(i)},y^{(i)})+\frac{\lambda}{2m}{||w||}^2_2J(w,b)=m1∑i=1mL(y^(i),y(i))+2mλ∣∣w∣∣22其中的L2范数可以理解:\frac{\lambda}{2m}{||w||}^2_2=\frac{\lambda}{2m}\sum_{j=1}^{n_x}w^2_j = \frac{\lambda}{2m}w^Tw2mλ∣∣w∣∣22=2mλ∑j=1nxwj2=2mλwTw解释:所有w参数的平方和的结果逻辑回归的损失函数中增加L1正则化J(w,b) = \frac{1}{m}\sum_{i=1}^mL(\hat{y}^{(i)},y^{(i)}) + \frac{\lambda}{2m}{||w||}_1J(w,b)=m1∑i=1mL(y^(i),y(i))+2mλ∣∣w∣∣1其中L2范数可以理解为:\frac{\lambda}{2m}{||w||}_1 = \frac{\lambda}{2m}\sum_{j=1}^{n_x}{|w_j|}2mλ∣∣w∣∣1=2mλ∑j=1nx∣wj∣注:其中,λ 为正则化因子,是超参数。由于 L1 正则化最后得到 w 向量中将存在大量的 0,使模型变得稀疏化,因此 L2 正则化更加常用。2.3.2.2 正则化项的理解在损失函数中增加一项,那么其实梯度下降是要减少损失函数的大小,对于L2或者L1来讲都是要去减少这个正则项的大小,那么也就是会减少W权重的大小。这是我们一个直观上的感受。接下来我们通过方向传播来理解这个其中的L2,对于损失函数我们要反向传播求参数梯度:(1) dW = \frac{\partial L}{\partial w}+ \frac{\lambda}{m} {W}dW=?w?L+mλW前面的默认损失函数的梯度计算结果默认为backprop,那么更新的参数就为(2) W := W - \alpha dWW:=W?αdW 那么我们将第一个公式带入第二个得到-->W := W - \alpha(\frac{\partial L}{\partial w} + \frac{\lambda}{m}W)??>W:=W?α(?w?L+mλW)
-->=W - \frac{\alpha \lambda}{m}W - \alpha*\frac{\partial L}{\partial w}??>=W?mαλW?α??w?L所以每次更新的时候都会让W(1 - \frac{\alpha \lambda}{m})W(1?mαλ),这个系数永远小于1,所以我们通常称L2范数为权重衰减。2.3.2.3 神经网络中的正则化神经网络中的正则化与逻辑回归相似,只不过参数W变多了,每一层都有若干个权重,可以理解成一个矩阵我们把w[l]w[l]理解某一层神经元的权重参数,其中这是加入了L2范数,可以是{}^2_F = \sum^{n^{[l-1]}}_{i=1}\sum^{n^{[l]}}_{j=1}(w^{[l]}_{ij})^2∥∥w[l]∥∥F2=∑i=1n[l?1]∑j=1n[l](wij[l])2对于矩阵的L2范数,有个专业名称叫弗罗贝尼乌斯范数(Frobenius Norm)2.3.2.4 正则化为什么能够防止过拟合正则化因子设置的足够大的情况下,为了使成本函数最小化,权重矩阵 W 就会被设置为接近于 0 的值,直观上相当于消除了很多神经元的影响,那么大的神经网络就会变成一个较小的网络。在加入正则化项后,当λ增大,导致W^[l]W[l]减小,Z^{[l]} = W^{[l]}a^{[l-1]} + b^{[l]}Z[l]=W[l]a[l?1]+b[l]便会减小。由上图可知,在 z 较小(接近于 0)的区域里,函数近似线性,所以每层的函数就近似线性函数,整个网络就成为一个简单的近似线性的网络,因此不会发生过拟合。2.3.3 Droupout正则化Droupout论文地址:http://jmlr.org/papers/volume15/srivastava14a.old/srivastava14a.pdfDroupout:随机的对神经网络每一层进行丢弃部分神经元操作。对于网络的每一层会进行设置保留概率,即keep_prob。假设keep_prob为0.8,那么也就是在每一层所有神经元有20% 的概率直接失效,可以理解为0.2.3.3.1 Inverted droupout这种方式会对每层进行如下代码操作# 假设设置神经元保留概率
keep_prob = 0.8
# 随机建立一个标记1 or 0的矩阵,表示随机失活的单元,占比20%
dl = np.random.rand(al.shape[0], al.shape[1]) < keep_prob
# 让a1对应d1的为0地方结果为0
al = np.multiply(al, dl)
# 为了测试的时候,每一个单元都参与进来
al /= keep_prob训练练的时候只有占比为pp的隐藏层单元参与训练。增加最后一行代码的原因,在预测的时候,所有的隐藏层单元都需要参与进来,就需要测试的时候将输出结果除以以pp使下一层的输入规模保持不变。假设keep_prob=p=0.8z^{l}=w^{l}a^{l-1}+b^{l}zl=wlal?1+bl ,当$l-1$层有比例为 $1-p=0.2$单元drop后,a^{l-1}al?1大约会变为原来的80%,为了保证ll层的zz值期望(可以理解为均值)不变,所以要在a^{l-1}al?1与dropout矩阵乘积后的权重进行扩大,要乘以\frac{1}{p}=10/8p1=10/8(增大)注:原始:(1+1+1+1+1+1+1+1+1+1)/10 = 1,现在其中20%失效,则平均值为0.8,所以0.8 * (10/8) = 1. 相当于其中8个神经元参数增大了(10/8)倍2.3.3.2 droupout为什么有效总结加入了 dropout 后,输入的特征都存在被随机清除的可能,所以该神经元不会再特别依赖于任何一个输入特征,也就是不会给任何一个输入特征设置太大的权重。通过传播过程,dropout 将产生和 L2 正则化相同的收缩权重的效果。对于不同的层,设置的keep_prob大小也不一致,神经元较少的层,会设keep_prob为 1.0,而神经元多的层则会设置比较小的keep_prob通常被使用在计算机视觉领域,图像拥有更多的特征,场景容易过拟合,效果被实验人员证明是很不错的。调试时候使用技巧:dropout 的缺点是成本函数无法被明确定义,因为每次会随机消除一部分神经元,所以参数也无法确定具体哪一些,在反向传播的时候带来计算上的麻烦,也就无法保证当前网络是否损失函数下降的。如果要使用droupout,会先关闭这个参数,保证损失函数是单调下降的,确定网络没有问题,再次打开droupout才会有效。2.3.4 其它正则化方法早停止法(Early Stopping)数据增强2.3.4.1 早停止法(Early Stopping)通常我们在训练验证的时候,发现过拟合。可以得到下面这张损失图通常不断训练之后,损失越来越小。但是到了一定之后,模型学到的过于复杂(过于拟合训练集上的数据的特征)造成测试集开始损失较小,后来又变大。模型的w参数会越来越大,那么可以在测试集损失减小一定程度之后停止训练。但是这种方法治标不治本,得从根本上解决数据或者网络的问题。
第5期 MongoDB配置启动方式
一、前言在安装好MongoDB后,我们常规会进入安装目录下的bin文件启动服务,但这种启动方式在测试的时候还可以用用,但在开发过程中或者生产环境中不太实用,我们要设置自动化启动才能满足我们的要求,希望通过本期的学习对大家有帮助。二、常规启动服务方式启动服务需要在管理员权限下打开PowerShell命令窗口2.1 mongod启动MongoDB服务# 进入MongoDB安装bin目录
$ cd 数据库路径
# 启动mongod服务
mongod
--dbpath = 数据库路径/data/
--logpath = 数据库路径/log/mongodb.log
--port = 27017
--auth 启用权限
Eg.mongod --dbpath=D:\MongoDB\Server\4.4\data --logpath=D:\MongoDB\Server\4.4\data\logs\mongodb.log --auth三、快速启动服务方式启动服务需要在管理员权限下打开PowerShell命令窗口3.1 设置为服务启动方式设置服务启动方式# 进入MongoDB安装bin目录
$ cd 数据库路径
# 设置MongoDB服务
mongod
--dbpath = 数据库路径/data/
--logpath = 数据库路径/log/mongodb.log
--port = 27017
--auth 启用权限
--install
--serviceName "服务名称"
Eg.
mongod --dbpath=D:\MongoDB\Server\4.4\data
--logpath=D:\MongoDB\Server\4.4\data\logs\mongodb.log
--auth
--install
--serviceName "MongoDB"启动服务$net start MongoDB暂停服务$net stop MongoDB删除服务$sc delete MongoDB3.2 mongo.cfg启动方式新增mongo.cfg并配置,配置如下:# mongod.cfg
##location for data
dbpath: D:\Program Files\MongoDB\Server\4.4\data
## location for log
logpath: D:\Program Files\MongoDB\Server\4.4\log\mongod.log启动配置$ mongod --config "D:/mongodb/server/mongo.cfg"设置为启动服务$ mongod --config "D:/mongodb/server/mongo.cfg" --install
--serviceName "MongoDB"启动服务$net start MongoDB暂停服务$net stop MongoDB删除服务$sc delete MongoDB四、Mongodb启动命令mongod参数说明基本参数参数名称说明--quiet# 安静输出--port arg# 指定服务端口号,默认端口27017--bind_ip arg# 绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP--logpath arg# 指定MongoDB日志文件,注意是指定文件不是目录--logappend# 使用追加的方式写日志--pidfilepath arg# PID File 的完整路径,如果没有设置,则没有PID文件--keyFile arg# 集群的私钥的完整路径,只对于Replica Set 架构有效--unixSocketPrefix arg# UNIX域套接字替代目录,(默认为 /tmp)--fork# 以守护进程的方式运行MongoDB,创建服务器进程--auth# 启用验证--cpu# 定期显示CPU的CPU利用率和iowait--dbpath arg# 指定数据库路径--diaglog arg# diaglog选项 0=off 1=W 2=R 3=both 7=W+some reads--directoryperdb# 设置每个数据库将被保存在一个单独的目录--journal# 启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里--journalOptions arg# 启用日志诊断选项--ipv6# 启用IPv6选项--jsonp# 允许JSONP形式通过HTTP访问(有安全影响)--maxConns arg# 最大同时连接数 默认2000--noauth# 不启用验证--nohttpinterface# 关闭http接口,默认关闭27018端口访问--noprealloc# 禁用数据文件预分配(往往影响性能)--noscripting# 禁用脚本引擎--notablescan# 不允许表扫描--nounixsocket# 禁用Unix套接字监听--nssize arg (=16)# 设置信数据库.ns文件大小(MB)--objcheck# 在收到客户数据,检查的有效性,--profile arg# 档案参数 0=off 1=slow, 2=all--quota# 限制每个数据库的文件数,设置默认为8--quotaFiles arg# number of files allower per db, requires --quota--rest# 开启简单的rest API--repair# 修复所有数据库run repair on all dbs--repairpath arg# 修复库生成的文件的目录,默认为目录名称dbpath--slowms arg (=100)# value of slow for profile and console log--smallfiles# 使用较小的默认文件--syncdelay arg (=60)# 数据写入磁盘的时间秒数(0=never,不推荐)--sysinfo# 打印一些诊断系统信息--upgrade# 如果需要升级数据库Replicaton 参数参数名称说明-fastsync# 从一个dbpath里启用从库复制服务,该dbpath的数据库是主库的快照,可用于快速启用同步--autoresync# 如果从库与主库同步数据差得多,自动重新同步,--oplogSize arg# 设置oplog的大小(MB)主/从参数参数名称说明--master# 主库模式--slave# 从库模式--source arg# 从库 端口号--only arg# 指定单一的数据库复制--slavedelay arg# 设置从库同步主库的延迟时间Replica set(副本集)选项参数名称说明--replSet arg# 设置副本集名称Sharding(分片)选项参数名称说明--configsvr# 声明这是一个集群的config服务,默认端口27019,默认目录/data/configdb--shardsvr# 声明这是一个集群的分片,默认端口27018--noMoveParanoia# 关闭偏执为moveChunk数据保存注:上述参数都可以写入 mongo.cfg 配置文档里例如:dbpath = /data/mongodb
logpath = /data/mongodb/mongodb.log
logappend = true
port = 27017
fork = true
auth = true
6 个火爆 GitHub 的后台管理模板,快来收藏!
1. vue-element-admin该项目是基于 Vue 和 Element-UI 实现的,使用了最新的前端技术栈,内置了许多强大的功能,比如国际化、动态路由等等,非常值得推荐!安装起来也十分的方便# clone the project
git clone https://github.com/PanJiaChen/vue-element-admin.git
# enter the project directory
cd vue-element-admin
# install dependency
npm install
# develop
npm run dev体验地址:https://panjiachen.gitee.io/vue-element-admin/GitHub Star 数量:62.5K项目地址:https://github.com/PanJiaChen/vue-element-admin2. AdminLTEAdminLTE 是一个基于 Bootstrap4.5 的响应式模板,其优点就是高度可定制化且易于使用。在不同的设备屏幕上都有非常好的适应表现,唯一的不足就是依赖的过多的 JQuery。体验地址:https://adminlte.io/themes/v3/GitHub Star 数量:36.9K项目地址:https://github.com/ColorlibHQ/AdminLTE3. iview-admin该项目同样是基于 Vue 的,同时搭配使用 iView UI 来实现一套完整的后台集成解决方案。虽然项目很久没有更新了,但是其统一的风格、优美的页面还是值得我们学习和使用的。体验地址:https://admin.iviewui.com/homeGitHub Star 数量:15.3K项目地址:https://github.com/iview/iview-admin4. ant-design-proAnt Design Pro 是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案,是开箱即用的典范。同时还配有完整的文档,供大家学习!体验地址:https://preview.pro.ant.design/dashboard/analysisGitHub Star 数量:27.3K项目地址:https://github.com/ant-design/ant-design-pro5. ngx-admin这是一个基于 Angular 的仪表模板,其强大多变的视觉主题,是一大特色和亮点!体验地址:http://www.akveo.com/ngx-admin/?utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20github%20readme&utm_source=ngx_admin&utm_medium=referral&utm_content=live_demo_linkGitHub Star 数量:21.8K项目地址:https://github.com/akveo/ngx-admin6. eladmin这是一个 Spring Boot 后台管理框架,非常的易用!它包含了前后端项目,想入门全栈的小伙伴一定不要错过体验地址:https://el-admin.xin/GitHub Star 数量:12.8K项目地址:https://github.com/elunez/eladmin好啦,今天就分享到这里,我们下次见!