SoftwareBasic
2021-02-20 14:55:30 5 举报
AI智能生成
开发
作者其他创作
大纲/内容
计算机网络:自顶向下
图解http
阅读书籍
深入理解HTTP协议、HTTP协议原理分析
解读HTTP/2与HTTP/3 的新特
HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。
HTTP 1.1支持持久连接,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。
1) HTTP1.0 和 HTTP1.1 的区别
HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议.
浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接
短连接
当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接
长连接:
client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作.短连接一般只会在 client/server间传递一次读写操作
TCP短连接
client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
TCP长连接
2) HTTP的长连接和短连接
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密
3) HTTP 和 HTTPS 的区别
递归查询:如果DNS 服务器本地没有存储查询DNS 信息,那么该服务器会询问其他服务器,并将返回的查询结果提交给客户机。(也就是说客户机发送请求后自己只用等待结果即可,中间具体过程交给服务器实现)
客户机A向DNS服务器B发送查询请求,B查询本地服务器发现没有记录,无法解析,则它继续递归查询DNS服务器C,C查询本地服务器发现也没有记录,无法解析,则C继续递归查询DNS服务器D,D查询本地服务器发现有记录,可以解析,则D将解析后的结果传送给C,C将解析后的结果传送给B,B将解析后的结果传送给A,自此,解析结束
例子
图解
迭代查询
DNS 服务器会向客户机提供其他能够解析查询请求的DNS 服务器地址,当客户机发送查询请求时,DNS 服务器并不直接回复查询结果,而是告诉客户机另一台DNS 服务器地址,客户机再向这台DNS 服务器提交请求,依次循环直到返回查询的结果。(也就是说客户机的请求需要自己挨个去查询才能得到结果,服务器没有结果时候只会给你提供其它服务器的地址,而不会帮你去请求查询,这与递归截然相反)
客户机A向DNS服务器B发送查询请求,B查询本地服务器发现没有记录,无法解析,则它会告诉客户机A,“我无法查询”,但是会把其他可能有的服务器比如B的地址告诉客户机A,让客户机A去请求服务器C,如果A接着查询C发现C也没有,但是C会把其他可能有的服务器比如D的地址告诉客户机A,假设最终由D查询并解析出来,则直接将结果递交给客户机A
递归查询
4) DNS 的两种解析过程(迭代查询和递归查询)
动态主机配置协议,使用UDP协议工作, 给内部网络自动分配IP地址
5) DHCP介绍
https每次get、push都需要输入用户名和密码
ssh只需要在本地维护一个sshkey的文件,不需要每次都输入信息。
6) HTTPS和SSH方式的区别和使用
GET方法使用的时候,浏览器中会产生目标URL,而POST不会。
GET一般用于获取/查询资源信息,而POST一般用于更新资源信息
7) POST和GET的区别
http3.0
HTTP、DNS、DHCP
2) 从输入网址到获得页面的过程
3) Session、Cookie 与 Application
4) SQL 注入
网络常见面试题
应用层/dns、http
一个 TCP 连接可以发多少个 HTTP 请求
1) TCP的流量控制、差错控制、拥塞控制
2) TCP协议是如何确保传输可靠性的
3) TCP的三次握手和四次挥手
4) TCP和UDP有什么区别
TCP相关概念
传输层/tcp、udp
1) IP、ARP 和 RARP、ICMP 和 IGMP、IP地址和MAC地址、计算机网络中各层协议之间关系
2) 路由器、网桥器材等基本概念
3) IP地址划分、子网划分、构造超网、VPN和NAT、路由协议、IPV6
IP地址划分
广播路由算法?
生成树
如何解决广播风暴
广播路由算法?如何解决广播风暴
网络层/ip
CRC(循环荣誉码)
海明码
网络校验方式
数据链路层
物理层
相关知识点
将http的request的keepAlive设置为false
1
8*60*1000【修改为8分钟】
修改request的timeout:
修改request的ReadWriteTimeOut
2
if (resp != null){ resp.Close();}if (req != null){ req.Abort();}
关闭request和response
3
System.Net.ServicePointManager.DefaultConnectionLimit = 500;
修改DefaultConnectionLimit的设置
4
在req = (HttpWebRequest)WebRequest.Create(constSkydriveUrl);setCommonHttpReqPara(ref req);resp = (HttpWebResponse)req.GetResponse();语句之前,添加System.GC.Collect();
垃圾回收
5
HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
网络性能问题
网络问题集锦
计算机网络
继承、实现
依赖、关联
聚合、组合
关系
表示符号上的区别
UML各种图以及继承、实现、依赖、关联、聚合、组合的联系与区别
用例图
用例视角
类图
对象图
设计视角
序列图
协助图
状态图
活动图
进程视角
构建图
实现视角
部署图
拓扑视角
九种图
UML
操作系统-精髓与设计原理(第八版)
深入理解计算机操作系统(原书第三版)
程序是如何跑起来的
作业调度和空闲分区分配算法
PV操作
只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)
无名管道
FIFO可以在无关的进程之间交换数据,与无名管道不同
FIFO,也称为命名管道
1、管道
2、消息队列
信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据,若要在进程间传递数据需要结合共享内存
3、信号量
4、共享内存
借助于网络的进程间通信
Socket
绑定
监听
5、套接字通信
输入输出通信
6、stream
进程间通信方式
系统为每个进程在内存中分配一定的区域,用来存放各个句柄,即一个个32位无符号整型值(32位操作系统中)。每个32位无符号整型值相当于一个指针,指向内存中的另一个区域(我们不妨称之为区域A)。而区域A中存放的正是对象在内存中的地址。当对象在内存中的位置发生变化时,区域A的值被更新,变为当前时刻对象在内存中的地址,而在这个过程中,区域A的位置以及对应句柄的值是不发生变化的。这种机制,用一种形象的说法可以表述为:有一个固定的地址(句柄),指向一个固定的位置(区域A),而区域A中的值可以动态地变化,它时刻记录着当前时刻对象在内存中的地址。这样,无论对象的位置在内存中如何变化,只要我们掌握了句柄的值,就可以找到区域A,进而找到该对象。而句柄的值在程序本次运行期间是绝对不变的,我们(即系统)当然可以掌握它。这就是以不变应万变,按图索骥,顺藤摸瓜
如何查看windows句柄
什么是句柄
操作系统
float类型与double类型数谁更大
1、无条件传送方式,最简单的传送方式,所配置的硬件和软件最少。2、查询传送方式,CPU的利用受到影响,陷于等待和反复查询、不能再作他用;而且,这种方法不能处理掉电、设备故障等突发事件。3、中断传送方式,是计算机最常用的数据传送方式,可随时向CPU发中断请求信号,以便及时响应,及时处理,实现实时控制。4、直接数据通道传送方式,不经过CPU中转,也不通过中断服务程序,既不需要保存、恢复断点和现场,所以传送数据的速度比中断方式更快。
DMA之理解
程序传送方式
微机原理/组成原理
加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方。
对称密钥加密
站点/个人拥有属于自己的一套密码(公钥和私钥),公钥公开,私钥隐秘。任何其他站点发送给该站点的信息,需要使用该站点的公钥加密,只要私钥可以解密。
因为加密和认证的不同,所以公私钥的作用的使用方式也不同
加密是将数据资料加密,使得非法用户即使取得加密过的资料,也无法获取正确的资料内容,所以数据加密可以保护数据,防止监听攻击。其重点在于数据的安全 性
Bob将他的公开密钥传送给Alice。Alice用Bob的公开密钥加密她的消息,然后传送给Bob。Bob用他的私人密钥解密Alice的消息
加密解密的过程如下
加密
身份认证是用来判断某个身份的真实性,确认身份后,系统才可以依不同的身份给予不同的权限。其重点在于用户的真实性。两者的侧重点是不同的
Alice用她的私人密钥对文件加密,从而对文件签名。Alice将签名的文件传送给Bob。Bob用Alice的公钥解密文件,从而验证签名
身 份认证的过程如下
认证
加密、认证、公钥、私钥
非对称加密
对称加密与非对称加密
把 username和 password 做成 username:password 的样子(用冒号分隔)进行 Base64 编码。Base64(\"username:password\") 得到一个字符串(如:把 haoel:coolshell 进行 base64 后可以得到 aGFvZW86Y29vbHNoZWxsCg )把 aGFvZW86Y29vbHNoZWxsCg 放到 HTTP 头中 Authorization 字段中,形成 Authorization: Basic aGFvZW86Y29vbHNoZWxsCg,然后发送到服务端。服务端如果没有在头里看到认证字段,则返回 401 错,以及一个个 WWW-Authenticate: Basic Realm='HelloWorld' 之类的头要求客户端进行认证。之后如果没有认证通过,则返回一个 401 错。如果服务端认证通过,那么会返回 200。
技术原理
把用户名和口令放在网络上传
最大的问题
一般要配合 TLS/SSL 的安全加密方式来使用
改进
HTTP Basic
请求方把用户名口令和域做一个 MD5 – MD5(username:realm:password) 然后传给服务器,这样就不会在网上传用户名和口令了,但是,因为用户名和口令基本不会变,所以,这个 MD5 的字符串也是比较固定的,因此,这个认证过程在其中加入了两个事,一个是 nonce 另一个是 qop
基本思路
其中的 nonce 为服务器端生成的随机数,然后,客户端做 HASH1=MD5(MD5(username:realm:password):nonce:cnonce) ,其中的 cnonce 为客户端生成的随机数,这样就可以使得整个 MD5 的结果是不一样的
如果 qop 中包含了 auth ,那么还得做 HASH2=MD5(method:digestURI) 其中的 method 就是HTTP的请求方法(GET/POST…),digestURI 是请求的URL
如果 qop 中包含了 auth-init ,那么,得做 HASH2=MD5(method:digestURI:MD5(entityBody)) 其中的 entityBody 就是HTTP请求的整个数据体
然后,得到 response = MD5(HASH1:nonce:nonceCount:cnonce:qop:HASH2) 如果没有 qop 则 response = MD5(HA1:nonce:HA2)
GET /dir/index.html HTTP/1.0Host: localhostAuthorization: Digest username=\"Mufasa\
最后,我们的客户端对服务端发起如下请求—— 注意HTTP头的 Authorization: Digest
WWW-Authenticate: Digest realm=\"testrealm@host.com\
首先,调用方发起一个普通的 HTTP 请求。比如:GET /coolshell/admin/ HTTP/1.1 服务端自然不能认证能过,服务端返回 401 错误,并且在 HTTP 头里的 WWW-Authenticate 包含如下信息
过程
没有在网上传递用户的密码,而只是把密码的 MD5 传送过去,相对会比较安全,而且,其并不需要是否 TLS/SSL 的安全链接
优点
整个过程其实关键是用户的 password,这个 password 如果不够得杂,其实是可以被暴力破解的
整个过程是非常容易受到中间人攻击——比如一个中间人告诉客户端需要的 Basic 的认证方式 或是 老旧签名认证方式(RFC2069)
缺陷
优点和缺陷
Digest Access
这个东西来自于 MAC – Message Authentication Code,是一种用于给消息签名的技术,也就是说,我们怕消息在传递的过程中被人修改,所以,我们需要用对消息进行一个 MAC 算法,得到一个摘要字串,然后,接收方得到消息后,进行同样的计算,然后比较这个 MAC 字符串,如果一致,则表明没有被修改过(整个过程参看下图)。而 HMAC – Hash-based Authenticsation Code,指的是利用 Hash 技术完成这一工作,比如:SHA-256算法
图示
HMAC
App ID
目前来说,玩得最好最专业的应该是 AWS 了,我们可以通过 S3 的 API 请求签名文档看到 AWS 是怎么玩的。整个过程还是非常复杂的,可以通过下面的图片流程看个大概。基本上来说,分成如下几个步骤
过程图示
AKIDEXAMPLE 是 AWS Access Key ID, 也就是所谓的 AppID,服务器端会根据这个 AppID 来查相关的 Secret Access Key,然后再验证签名。如果,你对这个过程有点没看懂的话,你可以读一读这篇文章——《Amazon S3 Rest API with curl》这篇文章里有好些代码,代码应该是最有细节也是最准确的了
最后,发出 HTTP Request 时,在 HTTP 头的 Authorization 字段中放入如下的信息
这个东西没有标准 ,所以,各家的实现很不一致。比如:Acquia 的 HMAC,微信的签名算法 (这里,我们需要说明一下,微信的 API 没有遵循HTTP 协议的标准,把认证信息放在 HTTP 头的 Authorization 里,而是放在 body 里
不好的地方
把 AppID 和 HMAC 用于 API 认证
App Secret Key + HMAC
JWT 是一个比较标准的认证解决方案,这个技术在 Java 圈里应该用的是非常普遍的。JWT 签名也是一种 MAC(Message Authentication Code)的方法
简介
服务器端
1、应用服务会检查 JWT Token,确认签名是正确的。2、然而,因为只有认证服务器有这个用户的 Secret Key(密钥),所以,应用服务器得把 JWT Token 传给认证服务器。3、认证服务器通过 JWT Payload 解出用户的抽象 ID,然后通过抽象 ID 查到登录时生成的 Secret Key,然后再来检查一下签名。4、认证服务器检查通过后,应用服务就可以认为这是合法请求了。
客户端
JWT 的签名流程
使用 RSA 非对称算法,在认证服务器这边放一个私钥,在应用服务器那边放一个公钥,认证服务器使用私钥加密,应用服务器使用公钥解密,这样一来,就不需要应用服务器向认证服务器请求了,
但是,RSA 是一个很慢的算法,所以,虽然你省了网络调用,但是却费了 CPU,尤其是Header 和 Payload 比较长的时候。
所以,一种比较好的玩法是,如果我们把 header 和 payload 简单地做 SHA256,这会很快,然后,我们用 RSA 加密这个 SHA256 出来的字符串,这样一来,RSA 算法就比较快了,而我们也做到了使用 RSA 签名的目的。
最后,我们只需要使用一个机制在认证服务器和应用服务器之间定期地换一下公钥私钥对就好了
上面的这个过程,是在认证服务器上为用户动态生成 Secret Key 的,应用服务在验签的时候,需要到认证服务器上去签,这个过程增加了一些网络调用,所以,JWT 除了支持 HMAC-SHA256 的算法外,还支持 RSA 的非对称加密的算法
说明
JWT – JSON Web Tokens
用户为了想使用一个第三方的网络打印服务来打印他在某网站上的照片,但是,用户不想把自己的用户名和口令交给那个第三方的网络打印服务,但又想让那个第三方的网络打印服务来访问自己的照片,为了解决这个授权的问题, OAuth 这个协议就出来了
起源
User(照片所有者-用户)Consumer(第三方照片打印服务)Service Provider(照片存储服务)
这个协议有三个角色
Consumer 获取 Request TokenService Provider 认证用户并授权 ConsumerConsumer 获取 Access Token 调用 API 访问用户的照片
这个协义有三个阶段
Consumer(第三方照片打印服务)需要先上 Service Provider 获得开发的 Consumer Key 和 Consumer Secret当 User 访问 Consumer 时,Consumer 向 Service Provide 发起请求请求Request Token (需要对HTTP请求签名)Service Provide 验明 Consumer 是注册过的第三方服务商后,返回 Request Token(oauth_token)和 Request Token Secret (oauth_token_secret)Consumer 收到 Request Token 后,使用 HTTP GET 请求把 User 切到 Service Provide 的认证页上(其中带上Request Token),让用户输入他的用户和口令。Service Provider 认证 User 成功后,跳回 Consumer,并返回 Request Token (oauth_token)和 Verification Code(oauth_verifier)接下来就是签名请求,用 Request Token 和 Verification Code 换取 Access Token (oauth_token)和 Access Token Secret (oauth_token_secret)最后使用 Access Token 访问用户授权访问的资源。
授权过程
授权过程流程图
因为上面这个流程有三方:User,Consumer 和 Service Provide,所以,又叫 3-legged flow,三脚流程
OAuth 1.0 也有不需要用户参与的,只有 Consumer 和 Service Provider 的, 也就是 2-legged flow 两脚流程,其中省掉了用户认证的事
Consumer(第三方照片打印服务)需要先上 Service Provider 获得开发的 Consumer Key 和 Consumer SecretConsumer 向 Service Provide 发起请求请求 Request Token (需要对 HTTP 请求签名)Service Provide 验明 Consumer 是注册过的第三方服务商后,返回 Request Token(oauth_token)和 Request Token Secret (oauth_token_secret)Consumer 收到 Request Token 后,直接换取 Access Token (oauth_token)和 Access Token Secret (oauth_token_secret)最后使用 Access Token 访问用户授权访问的资源。
衍生
我们可以看到,有两个密钥,一个是 Consumer 注册 Service Provider 时由 Provider 颁发的 Consumer Secret,另一个是 Token Secret。签名密钥就是由这两具密钥拼接而成的,其中用 & 作连接符。假设 Consumer Secret 为 j49sk3j29djd 而 Token Secret 为 dh893hdasih9 那个,签名密钥为:j49sk3j29djd&dh893hdasih9在请求 Request/Access Token 的时候需要对整个 HTTP 请求进行签名(使用 HMAC-SHA1 和 HMAC-RSA1 签名算法),请求头中需要包括一些 OAuth 需要的字段,如:Consumer Key :也就是所谓的 AppIDToken:Request Token 或 Access TokenSignature Method :签名算法比如:HMAC-SHA1Timestamp:过期时间Nonce:随机字符串Call Back:回调 URL
签名的示意图
OAuth 中的签名
OAuth 1.0 – 3 legged & 2 legged
在前面,我们可以看到,从 Digest Access, 到 AppID+HMAC,再到 JWT,再到 OAuth 1.0,这些个 API 认证都是要向 Client发一个密钥(或是用密码)然后用 HASH 或是 RSA 来签 HTTP 的请求,这其中有个主要的原因是,以前的 HTTP 是明文传输,所以,在传输过程中很容易被篡改,于是才搞出来一套的安全签名机制,所以,这些个认证的玩法是可以在 HTTP 明文协议下玩的。这种使用签名方式大家可以看到是比较复杂的,所以,对于开发者来说,也是很不友好的,在组织签名的那些 HTTP 报文的时候,各种,URLEncode 和 Base64,还要对 Query 的参数进行排序,然后有的方法还要层层签名,非常容易出错,另外,这种认证的安全粒度比较粗,授权也比较单一,对于有终端用户参与的移动端来说也有点不够。所以,在 2012 年的时候,OAuth 2.0 的 RFC 6749 正式放出。
目前,Facebook 的 Graph API 只支持 OAuth 2.0协议,Google 和 Microsoft Azure 也支持Auth 2.0,国内的微信和支付宝也支持使用 OAuth 2.0
OAuth 2.0 依赖于 TLS/SSL 的链路加密技术(HTTPS),完全放弃了签名的方式,认证服务器再也不返回什么 token secret 的密钥了,所以,OAuth 2.0 是完全不同于 1.0 的,也是不兼容的。
特性
一个是 Authorization Code Flow, 这个是 3 legged 的一个是 Client Credential Flow,这个是 2 legged 的
Authorization Code 是最常使用的 OAuth 2.0 的授权许可类型,它适用于用户给第三方应用授权访问自己信息的场景。这个 Flow 也是 OAuth 2.0 四个 Flow 中我个人觉得最完整的一个 Flow,其流程图如下所示。
示意图
client_id 为第三方应用的 App IDresponse_type=code 为告诉认证服务器,我要走 Authorization Code Flow。redirect_uri 意思是我跳转回第三方应用的 URLscope 意是相关的权限state 是一个随机的字符串,主要用于防 CSRF 攻击。
https://login.authorization-server.com/authorize? client_id=6731de76-14a6-49ae-97bc-6eba6914391e &response_type=code &redirect_uri=http%3A%2F%2Fexample-client.com%2Fcallback%2F &scope=read &state=xcoiv98CoolShell3kch
当用户(Resource Owner)访问第三方应用(Client)的时候,第三方应用会把用户带到认证服务器(Authorization Server)上去,主要请求的是 /authorize API,其中的请求方式如下所示。
当 Authorization Server 收到这个 URL 请求后,其会通过 client_id 来检查 redirect_uri 和 scope 是否合法,如果合法,则弹出一个页面,让用户授权(如果用户没有登录,则先让用户登录,登录完成后,出现授权访问页面)。
请流动的链接是第 1)步中的 redirect_uri其中的 state 的值也和第 1)步的 state一样。
https://example-client.com/callback? code=Yzk5ZDczMzRlNDEwYlrEqdFSBzjqfTG &state=xcoiv98CoolShell3kch
当用户授权同意访问以后,Authorization Server 会跳转回 Client ,并以其中加入一个 Authorization Code。如下所示:
POST /oauth/token HTTP/1.1Host: authorization-server.comcode=Yzk5ZDczMzRlNDEwYlrEqdFSBzjqfTG&grant_type=code&redirect_uri=https%3A%2F%2Fexample-client.com%2Fcallback%2F&client_id=6731de76-14a6-49ae-97bc-6eba6914391e&client_secret=JqQX2PNo9bpM0uEihUPzyrh
接下来,Client 就可以使用 Authorization Code 获得 Access Token。其需要向 Authorization Server 发出如下请求。
access_token 就是访问请求令牌了refresh_token 用于刷新 access_tokenid_token 是 JWT 的 token,其中一般会包含用户的 OpenID
{ \"access_token\": \"iJKV1QiLCJhbGciOiJSUzI1NiI\
如果没什么问题,Authorization 会返回如下信息
GET /v1/user/picturesHost: https://example.resource.comAuthorization: Bearer iJKV1QiLCJhbGciOiJSUzI1NiI
接下来就是用 Access Token 请求用户的资源了
流程的一个细节上的解释
Authorization Code Flow
Client Credential 是一个简化版的 API 认证,主要是用于认证服务器到服务器的调用,也就是没有用户参与的的认证流程。下面是相关的流程图
流程图
本质上就是 Client 用自己的 client_id 和 client_secret 向Authorization Server 要一个 Access Token,然后使用 Access Token 访问相关的资源
POST /token HTTP/1.1Host: server.example.comContent-Type: application/x-www-form-urlencodedgrant_type=client_credentials&client_id=czZCaGRSa3F0Mzpn&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw
请求示例
{ \"access_token\":\"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3\
返回示例
微信公从平台的开发文档中,使用了 OAuth 2.0 的 Client Credentials 的方式(参看文档“微信公众号获取 access token”),我截了个图如下所谓。我们可以看到,微信公众号使用的是 GET 方式的请求,把 AppID 和 AppSecret 放在了 URL中,虽然这也符合 OAuth 2.0,但是并不好,因为大多数网关代理会把整个 URI 请求记到日志中。我们只要脑补一下腾讯的网关的 Access Log,里面的日志一定会有很多的各个用户的AppID 和 AppSecret……
微信示例
Client Credential Flow
OAuth 2.0 的两个主要的 Flow
OAuth 2.0 – Authentication Code & Client Credential
区分两个概念:Authentication(认证) 和 Authorization (授权),前者是证明请求者是身份,就像身份证一样,后者是为了获得权限。身份是区别于别人的证明,而权限是证明自己的特权。Authentication 为了证明操作的这个人就是他本人,需要提供密码、短信验证码,甚至人脸识别。Authorization 则是不需要在所有的请求都需要验人,是在经过 Authorization 后得到一个 Token,这就是 Authorization。就像护照和签证一样
区分三个概念:编码 Base64Encode、签名 HMAC、加密 RSA。编码是为了更的传输,等同于明文,签名是为了信息不能被篡改,加密是为了不让别人看到是什么信息。
两个概念和三个术语
使用复杂地 HMAC 哈希签名方式主要是应对当年没有 TLS/SSL 加密链路的情况。JWT 把 uid 放在 Token 中目的是为了去掉状态,但不能让用户修改,所以需要签名。OAuth 1.0 区分了两个事,一个是第三方的 Client,一个是真正的用户,其先拿 Request Token,再换 Access Token 的方法主要是为了把第三方应用和用户区分开来。用户的 Password 是用户自己设置的,复杂度不可控,服务端颁发的 Serect 会很复杂,但主要目的是为了容易管理,可以随时注销掉。OAuth 协议有比所有认证协议有更为灵活完善的配置,如果使用 AppID/AppSecret 签名的方式,又需要做到可以有不同的权限和可以随时注销,那么你得开发一个像 AWS 的 IAM 这样的账号和密钥对管理的系统。
初衷
无论是哪种方式,我们都应该遵循 HTTP 的规范,把认证信息放在 Authorization HTTP 头中。不要使用 GET 的方式在 URL 中放入 secret 之类的东西,因为很多 proxy 或 gateway 的软件会把整个 URL 记在 Access Log 文件中。密钥 Secret 相当于 Password,但他是用来加密的,最好不要在网络上传输,如果要传输,最好使用 TLS/SSL 的安全链路。HMAC 中无论是 MD5 还是 SHA1/SHA2,其计算都是非常快的,RSA 的非对称加密是比较耗 CPU 的,尤其是要加密的字符串很长的时候。最好不要在程序中 hard code 你的 Secret,因为在 github 上有很多黑客的软件在监视各种 Secret,千万小心!这类的东西应该放在你的配置系统或是部署系统中,在程序启动时设置在配置文件或是环境变量中。使用 AppID/AppSecret,还是使用 OAuth1.0a,还是 OAuth2.0,还是使用 JWT,我个人建议使用 TLS/SSL 下的 OAuth 2.0。密钥是需要被管理的,管理就是可以新增可以撤销,可以设置账户和相关的权限。最好密钥是可以被自动更换的。认证授权服务器(Authorization Server)和应用服务器(App Server)最好分开。
注意事项
小结
HTTP API 认证授权术
BSD licenseX11 license 即MIT licenseFreeBSDMIT licenseApache licenseOpenssl licenseZope Public licenseboost software license V1Python licenseZlib licenseOpenBSD licenseCode Project Open License (CPOL)
允许商业集成且没有开源风险的许可证
NOSL V1.0IBM public license V 1.0Sun Public LicenseNokia Open Source LicenseNPLCDDLEPL V1Common Public License V1Mozilla Public LicenseCreative Commons Public Domain License
修改后源代码需要公开的许可证
GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。GPL 带有很强的传染性,那么如果一个库使用GPL发布,那么使用这个库的所有软件也必须使用GPL发布
GPL
传染性/商业不友好软件
开源软件License汇总
六种License直观图
软件license/开源风险
监控网站上的HTTP/HTTPS访问请求,并通过自定义过滤规则和启用Web攻击防护等功能,帮助您部署网站访问控制
waf证书(Web应用防火墙(WAF))
信息安全
计算机理论
Java学习笔记Java_Practice
Go学习笔记GO_Practice
高效开发工具EfficientDevTools
软件基础知识SoftwareBasic
机器学习
数据结构和算法AlgorithmPractice
数据库(原理和指令)
中间件(指令和原理)
踩坑记录(复盘和总结)
工作项目UML图汇总
高可用/高并发/高性能解决方案(3H)
路径跳转
VMware虚拟机下载与安装
VMware10.0.0版本下载地址+安装教程+许可证密钥
VMware虚拟机
VMware虚拟机安装Ubuntu16-18系统超详细过程(含下载地址)
不建议
win10上Hyper-V安装ubuntu18.04
镜像安装
update是更新软件列表,upgrade是更新软件
ubuntu基础知识
以管理员身份运行命令提示符,运行以下命令:bcdedit /set hypervisorlaunchtype off重启系统后再次运行VMware Player,就不会再出现与Device/Credential Guard不兼容的错误提示了。
VMware Player 与 Device/Credential Guard 不兼容。在禁用 Device/Credential Guard 后,可以运行 VMware Player。
此条仅供参考,实际情况不一定
VMware Workstation pro无法在Windows上运行,检查可在Windows上运行的此应用的更新版本
sudo apt-get install -f
ubuntu提示Software database is broken解决办法
注意
第六条 sudo vmware-install.pl
Ubuntu提示:正在进行简易安装时 无法手动启动 vmware tools 安装
vmware tools 安装
Ubuntu如何安装搜狗输入法
Ubuntu输入法框架(Keyboard input method system)设置后无法保存
运行命令:im-config后,点击OK
ubuntu怎么显示右上角没有小键盘?
fcitx-config-gtk3
找出输入法设置
VMware上Ubuntu安装搜狗输入法
输入法
第一步: 安装好 vmware tools
System Settings
Displays
1360x768
apply
第二步: VMware搭建的Ubuntu无法全屏
vmware虚拟机屏幕如何适应窗口全屏
窗口全屏
comment:配置描述past:共享的文件路径browseable:是否可以浏览read only:是否只读create mask:创建文件掩码,与的关系,因为Windows下创建文件默认带有可执行权限, 你不想一个文本文件也有可执行权限吧?所以这里配置为0664也就是-rw-rw-r--。directory mask:创建文件夹掩码,文件夹需要有x权限,否则其他用户无法进入,这里配置为0775,也就是drwxrwxr-x。valid users:有效用户是其所有者(valid users = %S)
Samba服务的配置总结
原理
sudo apt-get install samba
samba
配置访问的用户名和显示的路径名
准备smb.conf
sudo smbpasswd -a 用户名
sudo service smbd restart
安装步骤
是配置参数中有问题。逐行删除确认即可
debian samba出错:set_variable_helper(yes ): value is not boolean!
Samba配置,启动失败报错:Job for smb.service failed because the control process exited with error code.
在smb.conf里加上writable = yes把共享目录加上写权限 chmod 777 xxx
报错
service smb status
需要找到init.d 这个文件,这下面有很多server
不同系统叫的samba名称不一样
/etc/init.d/samba start
service smbd start
启动samba服务
Redhat 或者 Centos 配置开机自启动samba的图形配置界面工具为 ntsysvUbuntu 没有这个命令,但是有替代的命令,功能类似,命令为 sysv-rc-conf$ apt-get install -y sysv-rc-conf$ sysv-rc-conf (必要时可以加sudo)配置 smbd samba nmbd 服务 等级 1到5 在显示的页面上,用鼠标点或者空格键,将1-5的小方格设置为X,就开机自启动了
开机启动samba
samba命令
Ubuntu 搭建Samba服务器
Ubuntu搭建httpd
ubuntu安装问题集锦
ps afx|grep apt
kill -9 xx
杀死所有的apt进程
sudo rm /var/lib/dpkg/locksudo dpkg --configure -asudo apt update
删除锁定文件
sudo apt-get install openssh-server
LINUX开启ssh服务,报错:ssh: connect to host 192.168.6.129 port 22: Connection refused
网络重新连接
/etc/network/interfaces
/etc/resolvconf/resolv.conf.d/base
/etc/NetworkManager/NetworkManager.conf
service network-manager restart
方式一
/etc/init.d/networking restart
方式二
最后重启网络
Ubuntu16.04设置静态IP后无法联网
先设置主机网络
sudo vi /etc/network/interfaces
设置dns
sudo vim /etc/resolvconf/resolv.conf.d/base
sudo /etc/init.d/networking restart
设置ubuntu网卡,重启网卡
1. 打开主机的(WIN10)防火墙2. 选择高级设置3.入站规则4. 找到配置文件类型为“公用”的“文件和打印共享(回显请求 – ICMPv4-In)”规则,启用规
主机可以ping通虚拟机时,但虚拟机ping不通主机 的问题
联网问题
ufw status verbose #非管理员需加sudo即可
防火墙状态查看
ufw enable #非管理员需加sudo即可
激活防火墙:
ufw disable #非管理员需加sudo即可
关闭防火墙
Ubuntu18.04.2LTS 如何查看、打开及关闭防火墙
防火墙
网络
sudo apt-get install vim-gtk
输入vi 按tab键,显示有vim
验证
sudo vim /etc/vim/vimrc
syntax on意思是语法高亮,如果您的被注释掉了,请“让它出来”。就像下图所示
请在您的VIM的最后一行,输入他们,可以让您的VIM变得更漂亮、舒服。set nu // 在左侧行号set tabstop //tab 长度设置为 4set nobackup //覆盖文件时不备份set cursorline //突出显示当前行set ruler //在右下角显示光标位置的状态行set autoindent //自动缩进
VIM的配置
安装vim
:set mouse-=a
方法一:
if has('mouse') \tset mouse-=a endif
方法二:
vim鼠标不能右键粘贴、跨系统复制粘贴
vim --version
查看vim 版本
shift+6
shift+4
vim快速移动光标至行首和行尾
vim
sudo rm /var/crash/*
sudo gedit /etc/default/apport 将其中的enable=1改为enable=0即可
system program problem detected
Ctrl+Alt+T打开终端
ubuntu打开终端(方法5种)
Ubuntu16.04修改主机名和查看主机名的方法
如何在ubuntu的桌面上双击执行py脚本
关闭pop up功能sudo gedit /etc/default/apport 将其中的enable=1改为enable=0即可
cd /var/lib/dpkgsudo mv info info.bak sudo mkdir info然后重新安装,就ok了
Errors were encountered while processing
系统
su命令不能切换root,提示su: Authentication failure,只要你sudo passwd root过一次之后,下次再su的时候只要输入密码就可以成功登录了
su: Authentication failure问题
权限
重启命令 : 1、reboot 2、shutdown -r now 立刻重启 3、shutdown -r 10 过10分钟自动重启 4、shutdown -r 20:35 在时间为20:35时候重启 如果是通过shutdown命令设置重启的话,可以用shutdown -c命令取消重启
关机命令 : 1、halt 立刻关机(一般加-p 关闭电源) 2、poweroff 立刻关机 3、shutdown -h now 立刻关机 4、shutdown -h 10 10分钟后自动关机
ubuntu重启、关机命令
python --version
Ubuntu16.04系统查看已安装的python版本,及Python2与Python3之间切换
查看python版本
使用
service --status-all
ubuntu 查看系统服务的列表
ubuntu使用问题集锦
ubuntu的使用
Centos 7.2基础安装和配置(含分区方案建议)
更详细版
修改yum源
systemctl status firewalld.service
systemctl stop firewalld.service
systemctl disable firewalld.service
Centos7的使用
Mac的使用
Linux环境
把当前用户加入root权限组,能解决很多莫名奇妙的问题
bin为binary的简写,主要放置系统的必备执行文件,例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar等
bin
主要放置应用程序工具的必备执行文件,例如:c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome*、 gzip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb*、wget等。
/usr/bin:
主要放置系统管理的必备程序,例如:cfdisk、dhcpcd、dump、e2fsck、fdisk、halt、ifconfig、ifup、 ifdown、init、insmod、lilo、lsmod、mke2fs、modprobe、quotacheck、reboot、rmmod、 runlevel、shutdown等。
/sbin:
主要放置网路管理的必备程序,例如:dhcpd、httpd、imap、in.*d、inetd、lpd、named、netconfig、nmbd、samba、sendmail、squid、swap、tcpd、tcpdump等
/usr/sbin
linux中bin与sbin目录的作用及区别介绍
reponame=$(ls ./)for line in $reponamedocd $lineecho \"======\"$line\"===status\"git statuscd ../done
for((i=1;i<=10;i++)); do echo $(expr $i \\* 3 + 1); done
for循环
read
等待输入
read ansif [\"$ans\" -eq \"liuj\"]; thenecho ok1fiif [[ $ans = *[[:digit]:] ]];thenecho okfi
if判断
list=$(cat repo.txt)i=0for line in $listdolet i++echo $linedoneecho $i
变量自增定义及for循环内自增,计算 let 的用法
let a+=b (不需要$)
let
i=0echo $i((i++))echo $i
双括号 ((i++))
echo $(expr $a + $b)
expr
echo $[$a+$b]
$[]
Linux小数数值计算之bc命令
linux无法直接进行小数运算,需要使用bc命令
数学运算
ctrl+r
history
快速查询历史输入指令
${parameter//pattern/string}
echo liujun | tr \"liu\" \"pan\"
字符串切割的几种方法
变量名=变量值 , 注意=左右不能有空格,使用$变量名调用变量
查看变量:使用set命令可以查看所有变量,包括普通变量和环境变量
删除变量:使用unset变量名即可
变量名由数字,字母和下划线组成,不能以数字开头,变量之中有空格用引号括起来
拼接变量时注意$变量名要放在\"\"内才有效
或者用 / 分隔开,比如$path/bin
变量的拼接
方法一:使用``(tab键上的符号)包住执行的命令
方法二:将命令放入$()内执行
将命令的执行结果赋值给变量
命令替换与变量替换差bai不多,都是用来重组命令du行的,先完成引号里的命令行,然后将其结果替换出来,再重组成新的命令行
$( )与` `(反引号)都是用来作命令替换的。
${ }变量替换,$var与${var}
linux中$()和${}的区别
linux中如何声明和使用变量
alias 自定义命令='命令或脚本语句'
临时设置,重启失效。
修改配置文件:~/.bashrc
alias sqlmap='python /root/tools/sqlmap-master/sqlmap.py'
永久设置(非全局配置别名)
Linux添加别名
Linux语法
touch jj.kk
touch aa/bb/cc
创建文件
mkdir abc
递归创建目录,即使上级目录不存在,会按目录层级自动创建目录
mkdir -p
创建文件夹
-d:直接把欲删除的目录的硬连接数据删除成0,删除该目录; -f:强制删除文件或目录; -i:删除已有文件或目录之前先询问用户; -r或-R:递归处理,将指定目录下的所有文件与子目录一并处理; --preserve-root:不对根目录进行递归操作; -v:显示指令的详细执行过程。
rm -rf abc
mkdir tmptar xvf *.tar -C tmprm -rf $(ls tmp)
不小心将压缩包解压在当前文件夹,导致目录很乱,需要删除解压出来的文件
第一句创建文件夹; 第二句将tar包压缩到指定目录tmp; 第三句删除tmp中ls列出来的所有文件。(加上-r-f可以不用每次询问)
每个语句后是否有 ^M, ‘$’\ 等奇怪的后缀,导致语句无法执行
文件遍历及删除
删除文件夹/文件:
for i in $(find ../ -name \"*.123456\")doecho $iread #防止误删rm -rf $i done
或者 find . -name \"*.123456\" -exec rm -rf {} \\;
删除所有以123456结尾的文件
创建、删除文件
tar –xvf file.tar //解压 tar包 tar -xzvf file.tar.gz //解压tar.gz tar -xjvf file.tar.bz2 //解压 tar.bz2 tar –xZvf file.tar.Z //解压tar.Z unrar e file.rar //解压rar unzip file.zip //解压zip
tar 指令 、zip指令 和 rar 指令
解压文件
tar -zcvf a.tar.gz a/
压缩文件
解压/压缩文件
相当于cat -n a.txt
nl 显示的时候,顺道输出行号
cat 由第一行开始显示文件内容
tac 从最后一行开始显示,可以看出 tac 是 cat 的倒着写
more 一页一页的显示文件内容
less 与 more 类似,但是比 more 更好的是,他可以往前翻页!
-n 5: 显示头5行的文件
head 只看头几行
tail 只看尾巴几行
显示文本行数
:set nu
查看文件内容
按下 i 进入修改模式
:q! 强制退出不保存
:wq 保存并退出
按下esc退出当前模式
yy + p 或者 Y +P —— yy复制光标所在行,p在其下一行粘贴GG 或者shift g —— 表示跳至文本结尾;
:e 重新加载文件:e! 强制丢掉本地修改,从磁盘加载文件
vim 文件刷新
/license —— 在文本中查找license;
在命令模式下敲斜杆( / ),这时在状态栏(也就是屏幕左下脚)就出现了 “/” 然后输入你要查找的关键字敲回车
继续查找此关键字,敲字符 n
敲字符N(大写N)就会向前查询
vim查找关键字
直接跳到14行看
vim /tools/1.txt +14
修改文件: vi 或 vim
gedit
stat a.txt
展示最大深度为4的文件及大小,--max-depth=4最大深度为4
du -h --max-depth=4 文件名/
查看文件的详细属性
\"\\\" +ENTER 就可以实现换行
linux命令行如何换行
echo -e \"ab\cd\"
当与-e选项一起使用时,echo命令将解释反斜杠转义的字符,例如换行符\
shell脚本中,换行符号
换行
符号 \">\" 代表重写要输出的文件\">>\"代表要追加要输出的文件,不改变原文件的内容
用命令tee,除了写入文本文件,终端仍然会有输出结果git status | tee -a ./1.txt
Linux中将终端的打印结果输出 追加 到文本文件中
文本追加
$ : > filename$ > filename$ echo \"\" > filename$ echo > filename$ cat /dev/null > filename上面3种方式,能将文件清空,而且文件大小为0而下面两种方式,导致文本都有一个\"\\0\",而使得文件大小为1
linux中快速清空文件内容的几种方法
清空
在Linux下查看二进制文件的软件:xxd (2进制)hexdump (16进制)
用vim编辑二进制文件
查看、修改文件vim/cat
find ./ -iname \"*.java\"
find ./ -iname *.java | grep abc
find /path/to/search -type d -name \"name-of-dir\"
查找目录
精确查找 —w
查找路径下所有含有kk的文件和文件夹,并且把他们转移至 .hhh路径下 find . -name \"*kk*\" -exec mv {} ./hhh/ \\;
-o 是 -or 的意思
find / -name \"*pp\" -o -name \"*po\"
上面这条命令会查找当前文件夹下面的所有java文件和xml文件,find默认采用emacs正,则,会比较罗嗦
find ./ -regex \".*\\.java\\|.*\\.xml\"
采用posix-extended正,则会比较简单
find ./ -regextype posix-extended -regex \".*\\.(java|xml)\"
find . -name \"*.[h|c|sh]\"只能把 .c 和 .h 的文件查找出来,没有把 .sh 的文件找出来,这是为什么呢?
问题
特别注意
find查询符合两个匹配名字的写法
find 路径 -name 文件名 2>/dev/null
find时,不显示Permission denied
find指令
搜索大于10MB的文件:$ find /path/to/search -size +10M
搜索小于10MB的文件:$ find /path/to/search -size -10M
搜索大小恰好为10MB的文件:$ find /path/to/search -size 10M
搜索大小在100MB到1GB之间的文件:$ find /path/to/search -size +100M -size -1G
查找特定大小或大于X的文件
如何显示目录中最大的文件:$ find /path/to/search -type f -printf \"%s\\t%p\\" | sort -n | tail -1请注意,find命令已被排序到另外两个方便的Linux实用程序:sort和tail。 Sort将按文件的大小顺序排列文件列表,而tail将仅输出列表中的最后一个文件,该文件也是最大的
如果您要输出例如最大的前5个文件,则可以调整tail命令。$ find /path/to/search -type f -printf \"%s\\t%p\\" | sort -n | tail -5
使用head命令来确定最小的文件:$ find /path/to/search -type f -printf \"%s\\t%p\\" | sort -n | head -5
如果要搜索目录而不是文件,只需在类型选项中指定“ d”即可。如何显示最大目录:$ find /path/to/search -type d -printf \"%s\\t%p\\" | sort -n | tail -1
查找最大的目录或文件
find . -maxdepth 0 -name \"myfile.txt\"仅搜索当前目录中的文件,而不递归搜索
$ find . -maxdepth 1 -name \"myfile.txt\"仅在当前目录和更深的一个子目录中搜索文件:
设置maxdepth,查找深度
搜索所有空文件:$ find /path/to/search -type f -empty
搜索所有空目录:$ find /path/to/search -type d -empty
如果希望自动删除find返回的空文件或目录,那么将此命令与-delete选项结合使用也非常方便。删除目录(和子目录)中的所有空文件:$ find /path/to/search -type f -empty -delete
查找并处理空文件(零长度)
搜索超过30天之前已修改的所有文件:$ find /path/to/search -type f -mtime +30
搜索30天前刚修改过的所有文件:$ find /path/to/search -type f -mtime 30
搜索最近30天内修改过的所有文件:$ find /path/to/search -type f -mtime -30
注意最后有个 \\;
特别强调,对于不同的系统,直接使用分号可能会有不同的意义, 使用转义符 '\\'在分号前明确说明
-l 只统计行数-w 只统计单词数-m 只统计字符数
如果希望find命令输出有关找到的文件的更多信息,例如修改日期,则可以使用-exec选项并包含ls命令:$ find /path/to/search -type f -mtime -30 -exec ls -l {} \\;
atime:访问时间(access time),指的是文件最后被读取的时间,可以使用touch命令更改为当前时间;ctime:变更时间(change time),指的是文件本身最后被变更的时间,变更动作可以使chmod、chgrp、mv等等;mtime:修改时间(modify time),指的是文件内容最后被修改的时间,修改动作可以使echo重定向、vi等等;
查找最近30分钟修改的当前目录下的.php文件find . -name '*.php' -mmin -30
查找最近 X天/xmin 内的修改文件
没有权限尽管这可能发生在许多不同的目录中,但在搜索根目录时肯定会发生。这意味着,当您尝试在整个硬盘上搜索文件时,find命令将产生大量错误消息。为避免看到这些错误,您可以将find的stderr输出重定向到stdout,并将其通过管道传递到grep。$ find / -name \"myfile.txt\" 2>%1 | grep -v \"Permission denied\"此命令使用grep的-v(反向)选项来显示所有输出,除了显示“拒绝权限”之外的所有输出
列出文件未经允许被拒绝
find -name \".*\" -perm 755
查找符合特定权限的文件
find高级用法
grep 'pattern1\\|pattern2' filename
grep -E 'pattern1|pattern2' filename
egrep 'pattern1|pattern2' filename
grep -e pattern1 -e pattern2 filename
匹配多个单词-or操作
grep -E 'pattern1.*pattern2' filename
grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename
匹配多个单词-and操作
grep -v
去掉空格和#注释,生成新的文件
egrep -v \"#|^$\" 1.txt >2.txt
匹配多个单词-not操作
匹配
-i 或 --ignore-case : 忽略字符大小写的差别
-n 或 --line-number : 在显示符合样式的那一行之前,标示出该行的列数编号
-d <动作> 或 --directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作
-r 或 --recursive : 此参数的效果和指定\"-d recurse\"参数相同递归查找
-o 或 --only-matching : 只显示匹配PATTERN 部分
内容显示较多时,只想明显查看是否含有某个字符串,使用-o
--exclude
grep -nr -o --color Main --exclude=\"*.java\" --exclude=\"*.cs\" --exclude=\"*.xml\"
demo
不查找某类文件
grep -inr license --include=\"*.txt\"
grep -inro --color readme --exclude=\"*.log\"
查找
查找并列出 在aaa目录下 含有xxxxxx内容的文件
grep -rl xxxxxx /aaa
grep -rl xxxxxx /aaa | xargs sed -i 's/xxxxxx/9876543210/g'
grep -An 关键字 文件 显示匹配的一行,并显示该行前的n行grep -Bn 关键字 文件 显示匹配的一行,并显示该行后的n行grep -Cn 关键字 文件 显示匹配的一行,并显示该行前后的n行grep -n 关键字 文件同grep -Cn 关键字 文件grep -v grep 搜索出来的内容排除grep 后显示grep 30 -A 10 显示30行及之前的10行grep 完全匹配:字符前后增加\\bgrep -w \"lll\" a.log 完全匹配,等同上面grep -i 忽略大小写grep -o只显示匹配关键字
* 重复0个或多个前面的字符? 代表重复0个或一个前面的字符.*匹配所有字符+ 代表重复一个或多个字符. 点号代表一个字符
grep显示行内容
grep指令
第一句表示由bin路径下的bash解释器来解释该脚本,第二句定义count变量,第三句for循环,括号内是查找搜索语句,$()表示执行括号内的语句,并把返回值保存,以供查找。第三四do,第五句打印line的值,第六句 %05d 表示至少输出5位数字,取count的值赋给name0,第七句name=${name0:0:5},将name0从左到右的0~5位数据赋值给name(列如name0数据为123456,那么name被赋值为12345,没有6),第八句打印name;第九句重命名;第十句自增,等同于Count=$(( Count+1)) 或者 let Count++(Count和++之间不能有空格);第十一句打印;十二句结束。
脚本释义
#!bin/bashCount=1for line in $( find -name readme.txt )doecho \"find ${line}\"name0=$(printf \"%05d\" $Count)name=${name0:0:5}echo $namecp ${line} \"readme\"$name\".txtnew\"(( Count=Count+1))echo $Count \"Rename OK\"done
查找并对比文件
find/grep
mv aflie bfile 将afile重命名为bfile
mv afile /tmp 把当前目录下的afile移动到/tmp/目录下
把 b 文件夹移动到 c 文件夹下面
mv. a/b c/
mv(移动和重命名文件)
注意:号
scp ./a.txt liujun@10.10.10.10:/home/liujun/a/
scp到多台服务器。需要配置免密登录,写脚本同步
scp(远程移动文件)
cp -r c/d a/b(将c目录下的d目录下的所有文件及其子目录文件全部拷贝到a目录下的b目录下)
cp test a/b/test1(将test文件拷贝到a目录下的b目录下,并且重新命名为test1)
ls *.jpg | xargs -n1 -I {} cp {} /data/images
复制所有图片文件到 /data/images 目录下
cp(拷贝和覆盖)
for i in $(find ../ -name \"*liujun*\")do nn=$(echo $i |sed 's/liujun/love/') mv $i $nndone
将某路径下 含有liujun的文件和文件夹名,改为love
文件复制、远程复制、移动
pwd :显示当前路径
返回上一层: ../
ll
ls -l
ls
ls -a
ls:查看当前目录下内容
跳转到某个路径:cd abc
文件目录操作
i:表示inserts:表示searchg:表示global
将当前sed目录下1.txt文件里的ccc替换成xxx# sed -i 's/ccc/xxx/g' ./sed/1.txt
文本替换
查看当前目录下1.txt的文件第三行sed -n 3p ./1.txt
, 这里没有空格
显示包含\"hhh\"的行到包含\"omc\
查找区间
文本查看
类似 grep -n 5555 kk.ll
sed -n /查找内容/p kk.ll
文本过滤/查看
注意 1i 不是 li
sed -i -e '1i happy' -e '$a new year' yum.log
插入行首行尾
按目录全文搜索关键词keywordsgrep -lri 'keywords' /home/work
注意符合: `
按目录批量替换关键词keywordssed -i \"s/oldWords/newWords/g\" `grep keywords -rl /home/work`
全文搜索及批量替换
sed \"s/bbb/aaa/g\" test.txt > test2.txtmv test2.txt test.txt
sed -i '' 's/old/new/g' file_name
mac下如何使用Sed批量替换文件夹下的字符串
文本编辑 sed
AWK程序设计语言
awk 赋值给 shell 变量的方法
文本处理 awk
输出1~10
seq -w 1 10
文本输出 seq
将文件夹下面的所有文件从dos转化为Unix
find ./ -iname \"*\" -exec dos2unix {} \\;
dos2unix
1. 在windows下的文本文件的每一行结尾,都有一个回车('\')和换行('\') 2. 在linux下的文本文件的每一行结尾,只有一个回车('\'); 3. 在Mac下的文本文件的每一行结尾,只有一个换行('\');
todos
解决办法
文件内容后面有^M
文件格式转换
-h 安装的进度条就有了
-v, --verbose 提供更多的详细信息输出
rpm -ivh foo-1.0-l.i386.rpm
安装
rpm –e 软件名
卸载
-U:即升级的意思
-Uvh
rpm -Uvh foo-2.0-l.i386.rpm
升级软件包
rpm -qa |grep vagrant
不要加入后缀之类的
rpm –q vagrant
rpm –qa
rpmRed Hat
dpkgubuntu
wget
列出所有软件安装包
带@是已经安装的base是linux自带的软件包Centos7.4-BM 是安装BM时,BM提供的软件包
yum list | grep *** // 显示已安装,未安装的包
yum list
把/var/cache/yum/ 下面的文件删除了
yum repolist all
yum makecache
yum update
在Centos7系统中执行yum clean all 之后,发现yum的其他执行都报错了
yum clean all
yum
文件安装
首先对文本进行排序 sort 1.txt. >./2.txt注意到:sort后的文件不能写回原文件,会丢失数据
对比文件 diff 1.txt 2.txt注意要先排序再对比
文本对比diff和排序sort
文件/文本
chmod u+x *.sh (给所有的sh文件加权限)
chmod -R u+x /root (给root及其子文件加权限)
更改目录权限
chgrp
改变文件所有者及用户组
chown
-R : 递归改变
修改文件权限
ls -al test.txt
查看test.txt具有的权限
注:该命令通常用命令“.”来替代。
如:source /etc/profile 与 . /etc/profile是等效的,比如 ./test.sh 可以直接执行
source FileName 作用:在当前bash环境下读取并执行FileName中的命令。
生效文件
然后输入密码和确认密码,一路回车,记得最后选一个y(表示yes),搞定,大部分创建配置都在 /etc/adduser.conf 里面写好了,系统会自动在/home路径下创建用户,如果需要加sudo权限,则使用 vim /etc/sudoers指令,在# User privilege specification下方加入指令: liujun ALL=(ALL:ALL) ALL 即可。
推荐使用
adduser liujun
在使用useradd命令创建新用户时,不会为用户创建主目录,不会为用户指定shell版本,不会为用户创建密码。 -d \"/home/liujun\" 表示指定用户登录目录,-m 表示没有这个目录则创建一个,-s 表示用户登录后使用的shell,不写的话,会导致丢失 .Xauthority 文件,会给后续使用造成很大麻烦;然后使用passwd liujun 指令给用户创建密码,否则无法登录和使用。
useradd -d \"/home/liujun\" -m -s /bin/bash liujun
useradd 指令和 adduser 指令
新建用户
passwd 用户名
修改用户密码
这样输入当前管理员用户密码就可以得到超级用户的权限。但默认的情况下5分钟root权限就失效了
sodu
以管理员权限查看、执行
su 用户名,比如 su root
切换用户
直接查看的命令,你可以通过一个文件或一个文件夹来查看它所拥有的属性就知道了,比如: ll
查看当前用户的权限
见新建用户
在Ubuntu中,可以修改的配置文件和目录主要有两个,分别是/etc/sudoers 和 /etc/suders.d/ 前者是一个配置文件,后者是一个配置文件目录
把当前用户加入root权限组
exit退出
退出用户
用户
分 时 日 月 周 [用户] command
crontab -e
定时任务
send命令接收一个字符串参数,并将该参数发送到进程
send
启动新的进程
spawn
允许用户交互
interact
Linux expect详解
expect
kinit -V
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.9.110
ssh-add -K
Linux机器之间免密登录设置
显示现行终端机下的所有进程,包括其他用户的进程
ps -a
以用户为主的格式来显示进程状况
ps -u root
ps -u
显示所有命令,连带命令行
full
ps -ef
基础
显示所有JAVA进程详情名
long
jps -l
实时监控系统的状态
top命令
用于根据特定条件查询进程PID信息
示例
pgrep
用于查看进程树,以树形结构列出进程信息
pstree
基本指令
ps aux |grep 应用名
lsof -p 应用名对应的ID | grep LISTEN
mac oxs 上查看进程监听的端口号 lsof
通过端口号查看占用的进程id
netstat -nap | grep 端口
通过进程id查看占用的端口
netstat -nap | grep 进程id
查看进程id
ps aux | grep 进程名 (或者 ps -ef | grep 进程名)
linux
yum install net-tools
解决方案
netstat:ccommand not find
mount /dev/sr0(磁盘) /mnt/cdrom(挂载地址)
net无法使用,需要配置已存在的yum源,即挂载磁盘
(list open files)是一个列出当前系统打开文件的工具
必须以 root 用户的身份运行它
lsof -i:端口号
如果出现pid为空的情况,这种时候用:lsof -i:端口号
可能出现的问题
netstat -ano | findstr 8007端口
根据上面查出来的端口最后一行占用的进程号进一步查询是那个服务占用的tasklist | findstr 进程号
windows
进程查询操作
kill -1 PID 重启服务kill -9 PID 强行杀死进程kill -15 PID 正常结束
杀进程
pkill nginx
进程的终止
ps -ef | 全格式显示当前所有进程
grep cusip_full_is 滤出''cusip_full_is''的进程
grep -v grep 把''grep''这个进程忽略掉
wc -l 看看有多少个进程
awk '{ print $1; }' 输出第一列
ps -ef | grep cusip_full_is | grep -v grep | wc -l | awk '{ print $1; }'
signal :代表给予后面接的那个工作什么样的指示啰!用 man 7 signal 可知: -1 :重新读取一次参数的设定档 (类似 reload); \t\t-2 :代表与由键盘输入 [ctrl]-c 同样的动作; \t\t-9 :立刻强制删除一个工作; \t\t-15:以正常的程序方式终止一项工作。与 -9 是不一样的。
[root@linux ~]# jobs [1]+ Stopped vim bashrc [root@linux ~]# kill -9 %1 [1]+ 已砍掉 vim bashrc
kill -signal %jobnumber(进程号)
语句解析
进程
curl www.baidu.com
curl
连通性测试
ping www.baidu.com;ping localhost
ping IP -n 20:执行特定次数(此处是 20)的 ping 命令
ping IP -l 2000:指定 ping 命令中的特定数据长度(此处为 2000 字节),而不是缺省的 32 字节。
随着防火墙功能在网络中的广泛使用,当你 ping 其他主机或其他主机 ping 你的主机时,而显示主机不可达的时候,不要草率地下结论。最好与对某台 “设置良好” 主机的 ping 结果进行对比。
注意:
ping
ipconfig /all
输入 ipconfig /release,那么所有接口的租用 IP 地址便重新交付给 DHCP 服务器(归还 IP 地址)
输入 ipconfig /renew,那么本地计算机便设法与 DHCP 服务器取得联系,并租用一个 IP 地址。大多数情况下网卡将被重新赋予和以前所赋予的相同的 IP 地址
ipconfig /release 和 ipconfig /renew
ipconfig
arp –a:用于查看高速缓存中的所有项目
② arp -a IP:如果有多个网卡,那么使用 arp -a 加上接口的 IP 地址,就可以只显示与该接口相关的 ARP 缓存项目。③ arp -s IP 物理地址:向 ARP 高速缓存中人工输入一个静态项目。 该项目在计算机引导过程中将保持有效状态,或者在出现错误时, 人工配置的物理地址将自动更新该项目。④ arp -d IP:使用本命令能够人工删除一个静态项目。
arp
显示数据包到达目的主机所经过的路径
tracert www.baidu.com
traceroute
显示路由表中的当前项目
route print
使用本命令,可以将路由项目添加给路由表。例如,如果要设定一个到目的网络 209.99.32.33 的路由,其间要经过 5 个路由器网段,首先要经过本地网络上的一个路由器 IP 为 202.96.123.5,子网掩码为 255.255.255.224,那么用户应该输入以下命令:route add 209.99.32.33 mask 255.255.255.224 202.96.123.5 metric 5
route add
可以使用本命令来修改数据的传输路由,不过,用户不能使用本命令来改变数据的目的地。下面这个例子将上例路由改变采用一条包含 3 个网段的路径:route add 209.99.32.33 mask 255.255.255.224 202.96.123.250 metric 3
route change
route delete: 使用本命令可以从路由表中删除路由。例如:route delete 209.99.32.33
route
查询任何一台机器的 IP 地址和其对应的域名
nslookup
查看计算机上网络配置的一些信息
nbtstat
netstat 命令能够显示活动的 TCP 连接、计算机侦听的端口、以太网统计信息、IP 路由表、IPv4 统计信息(对于 IP、ICMP、TCP 和 UDP 协议)以及 IPv6 统计信息(对于 IPv6、ICMPv6、通过 IPv6 的 TCP 以及 UDP 协议)。使用时如果不带参数,netstat 显示活动的 TCP 连接
打印当前系统启动哪些端口
netstat -lnp
打印网络连接状况
如果你所管理的服务器是一台提供web服务(80端口)的服务器,可以使用 netstat -an |grep 80 查看当前连接web服务的有哪些IP
windows上是 netstat -n | findstr 80
netstat -an |grep 80
-a 选项显示所有的有效连接信息列表,包括已建立的连接(ESTABLISHED),也包括监听连接请求(LISTENING)的那些连接
–n:以点分十进制的形式列出 IP 地址,而不是象征性的主机名和网络名
netstat -an
-e 选项用于显示关于以太网的统计数据。它列出的项目包括传送的数据包的总字节数、错误数、删除数、数据包的数量和广播的数量。这些统计数据既有发送的数据包数量,也有接收的数据包数量。使用这个选项可以统计一些基本的网络流量
-r 选项可以显示关于路由表的信息,类似于 route print 命令时看到的信息。除了显示有效路由外,还显示当前有效的连接。
-s 选项能够按照各个协议分别显示其统计数据。这样就可以看到当前计算机在网络上存在哪些连接,以及数据包发送和接收的详细情况等等。如果应用程序(如 Web 浏览器)运行速度比较慢,或者不能显示 Web 页之类的数据,那么可以用本选项来查看一下所显示的信息。仔细查看统计数据的各行,找到出错的关键字,进而确定问题所在
netstat
NET 命令可以在一个地方提供所有信息,并可以把结果重定向到打印机或一个标准的文本文件中。许多服务所使用的网络命令都以 net 开头,这些 net 命令有一些公用属性。要看到所有可用的 net 命令的列表,可以在命令提示符窗口键入 net/? 得到
net
查看使用者: who 或 who i am
java 执行路径:which Java(当前执行的是哪个Java)
找Java 路径:whereis java
找 JAVA_HOME:echo $JAVA_HOME
找PATH::echo $PATH
路径类查找
查看内存使用多少,剩余多少请看第二行的数据。
加-m或-h 或者-g选项分别以M或G为单位打印内存使用状况:
free
查看内存
iostat -x
磁盘使用
查看该配置模式下的开机启动项:chkconfig --list
1、将启动文件或启动配置文件复制到 /etc/init.d 或 /etc/rc.d/init.d , 并配置好相关参数2、chmod +x /etc/rc.d/init.d/你的启动文件3、以下两者任选其一 chkconfig --add 你的服务名 chkconfig 你的服务名 on4、service 你的服务名 start/stop/restart
查看该配置模式下的开机启动项:systemctl list-unit-files | grep enable
vim /etc/systemd/system/yourServiceName.service
[Unit]Description=yourServiceNameAfter=syslog.target [Service]User=myappExecStart=/var/myapp/myapp.jarSuccessExitStatus=143 [Install]WantedBy=multi-user.target
3、systemctl daemon-reload4、systemctl enable yourServiceName.service 【注册为自启动服务】 相对应的: systemctl disable yourServiceName.service 【撤销开机启动】5、systemctl start yourServiceName.service systemctl status yourServiceName.service systemctl stop yourServiceName.service service yourServiceName restart ----也可以用第一种方式的命令【systemctl 和 service 命令可看成等效】
方式二(建议)
将脚本添加到 /etc/rc.d/rc.local 文件最后一行
使用 crontab + @reboot
使用 systemd 服务
开机自启的三种方式
将服务做成系统服务
显示日历
cal
其他
标准错误输出和标准输出都定向输出
2>&1
管道
Linux基础指令
find 查出所有的java代码
xargs是给命令传递参数的一个过滤器
xargs命令
wc -l 统计行数
find . -name \"*.py\" |wc -l
统计当前目录下,py文件数量:
find . -name \"*.py\" |xargs cat|wc -l
统计当前目录下,所有py文件行数:
find . -name \"*.py\" | xargs cat| grep -v ^$| wc -l
统计当前目录下,所有py文件行数,并过滤空行:
find ./ -iname *.java |xargs nl| wc -l
find ./ -type f | xargs cat |wc -l
统计文件行数
git统计代码提交行数
git log --author=\"你的名字\" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf \
统计指定用户提交代码情况
git log --format='%aN' | sort -u | while read name; do echo -en \"$name\\t\"; git log --author=\"$name\" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf \
统计每个人的代码提交情况
注意这个符号 ————> `注意tformat后面的 ————> :注意printf后面的 ————> \"注意%和f之间的 ————> .注意加和的方法 ————> let 注意加和 ————> 不需要加$
addnum=`git log --all --since=$time.day.ago --pretty=tformat: --numstat |awk '{add += $1} END {printf \"%.f\\
git代码统计
统计项目代码行数
Windows下git bash中添加wget
Git Bash下安装使用tree(在windows)
tree 命令打印2层
tree -L 2
带颜色
tree -C
打印至目录级别
tree -d
用法
tree
Windows下使用git bash
ssh user@host 如:ssh pika@192.168.0.111
ssh
Linux组合用法
Linux指令
Linux
二进制安装
注意M1系统进入恢复模式的方式是按住电源键
总是提示“git命令需要使用命令行开发者工具”
git 安装
相当于git add 和 git commit合体
git commit -am \"first init\"
git 和 repo的用法(基础指令)
git log -2 查看最近2次的提交历史记录
git log --author=gbyukg
查看第3行的修改记录,3.3表示起始位置,结束位置
查看某文件,某一行的修改记录
git log查看符合条件的日志
git log --pretty=online 可以显示完整的commit id
git rev-list --all -1 --since=3.month.ago --until=2.month.ago
s='git rev-list --all -1 --since=3.month.ago --until=2.month.ago'$s
获取指定版本的信息,并回退至该版本,liuj=$(git rev-list --all -1 --since=3.month.ago --until=2.month.ago)git reset $liuj
GIT 获取指定历史版本代码(根据时间获取commit或者查看git log)
知道commit是和哪一个分支或tag关联的
git config --global alias.log 'log --decorate'
错误
git config --global alias.l 'log --decorate'
正确
设置别名的时候注意,不要对已有的指令进行设置
git log --decorate
列出简略的统计数据
git log --stat
列出代码新增和减少的数量
配合 --pretty=tformat去掉冗余信息,只显示文件的变化量
git log --numstat
%an: 作者名字%aN: mailmap的作者名字 (.mailmap对应,详情参照[git-shortlog(1)](http://linux.die.net/man/1/git-shortlog)或者[git-blame(1)](http://linux.die.net/man/1/git-blame))%ae: 作者邮箱%aE: 作者邮箱 (.mailmap对应,详情参照[git-shortlog(1)](http://linux.die.net/man/1/git-shortlog)或者[git-blame(1)](http://linux.die.net/man/1/git-blame))%cn: 提交者名字%cN: 提交者名字 (.mailmap对应,详情参照[git-shortlog(1)](http://linux.die.net/man/1/git-shortlog)或者[git-blame(1)](http://linux.die.net/man/1/git-blame))%ce: 提交者 email%cE: 提交者 email (.mailmap对应,详情参照[git-shortlog(1)](http://linux.die.net/man/1/git-shortlog)或者[git-blame(1)](http://linux.die.net/man/1/git-blame))
详解
git log --graph --data=relative --pretty=tformat:'%Cred%h %C(auto)%d %s'
范例
Git log pretty
git log --all |grep -C 10 \"change to order asc\"
根据commit描述 查找commitID
git branch --contains 06cce0f9dc8e3 --all
根据commitID 查找分支
如何查找某个镜像属于那个分支打包出来的
git log的高级用法
git diff --cachedgit diff --staged
查看已经暂存起来的文件(staged)和上次提交时的快照之间(HEAD)的差异
git diff --stat
查看简单的diff结果,可以加上--stat参数
git diff
1. 显示出branch1和branch2中差异的部分git diff branch1 branch2 --stat2. 显示指定文件的详细差异git diff branch1 branch2 具体文件路径3. 显示出所有有差异的文件的详细差异git diff branch1 branch2
4. 查看branch1分支有,而branch2中没有的loggit log branch1 ^branch25. 查看branch2中比branch1中多提交了哪些内容git log branch1..branch2注意,列出来的是两个点后边(此处即dev)多提交的内容。6. 不知道谁提交的多谁提交的少,单纯想知道有是吗不一样git log branch1...branch27. 在上述情况下,在显示出没个提交是在哪个分支上git log --lefg-right branch1...branch2注意 commit 后面的箭头,根据我们在 –left-right branch1…branch2 的顺序,左箭头 < 表示是 branch1 的,右箭头 > 表示是branch2的。
git diff 和 git log分支文件的差异对比
创建轻量标签git tag v0.1.2
创建附注标签$ git tag -a v0.1.2 -m “0.1.2版本”
git标签分为两种类型:轻量标签和附注标签。轻量标签是指向提交对象的引用,附注标签则是仓库中的一个独立对象。建议使用附注标签
在之前的版本上打$ git tag -a v0.1.1 9fbc3d0
查看标签git tag
创建标签git tag 标签名字 -m '消息内容'
推送标签git push origin 标签名字
删除标签git tag -d 标签名字
git tag
存于栈中,可以在任意分支弹出
git stash
作用等同于git stash,区别是可以加一些注释
git stash save “command”
保存修改内容至栈
git stash list
查看堆栈中最新保存的stash和当前目录的差异
git stash show stash@{1}查看指定的stash和当前目录差异
git stash show -p 查看详细的不同
git stash show
查看stash
将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。注:该命令将堆栈中最近保存的内容删除(栈是先进后出)
git stash pop + stash名字(如stash@{1})指定恢复哪个stash到当前的工作目录
git stash pop
不同于git stash pop,该命令不会将内容从堆栈中删除
git stash apply + stash名字(如stash@{1})指定恢复哪个stash到当前的工作目录
git stash apply
栈内容弹出
从堆栈中移除某个指定的stash
git stash drop + 名称
清除堆栈中的所有 内容
git stash clear
清除栈
通过新建分支来解决
git stash branch
栈内容冲突
git stash 无法跟踪新添加的文件,需要先 git add
git stash用法
# 删除 untracked filesgit clean -f# 连 untracked 的目录也一起删掉git clean -fd# 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)git clean -xfd# 在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删git clean -nxfdgit clean -nfgit clean -nfd
git怎样删除未监视的文件untracked files
git clean
git指令
git remote -v
git remote show
git remote show origin
查看远程仓库地址
git remote rm origin
先删除
git remote add origin xxxxxxurl
再添加
mv aaa bbb
本地仓改名
远程仓库更名
git remote add origin remote_address(远程url)
初始化跟随远程仓库
git 仓管理
git initgit add README.mdgit commit -m \"first commit\"git remote add origin git@github.com:ljfirst/MiddleSoftwarePractice.gitgit push -u origin master
git pull origin branch --allow-unrelated-histories
origin: 默认的远程仓库的名字
git远程分支查看
先用git fetch命令更新remote索引
或者 git remote # 列出所有远程主机git remote update origin --prune # 更新远程主机origin 整理分支
git branch -a看不到远程分支
查看
git branch --set-upstream-to=origin/develop develop
若遇报错: branch 'develop' does not exist
解决办法:git pull origin branch --allow-unrelated-histories
关联本地仓库分支与远程仓库分支
作用是checkout远程的dev分支,在本地起名为dev分支,并切换到本地的dev分支
git checkout -b dev origin/dev
拉取远程分支并同时创建对应的本地分支
git checkout -b 本地分支名x origin/远程分支名x
切换并跟随远程分支
git remote set-url origin http://192.168.100.235:9xxxxxxxx
项目中git地址修改了怎么办
跟随
git push [remoteName] [localBranchName]
推送远程仓库
git 更新远程分支列表,切换并合并已有分支到当前分支
如果想要把local_a提交到remote_a;使用git push origin local_a:remote_a;
如果想要把local_b提交到remote_b;使用git push origin local_b:remote_b;
如果想要把local_a提交到remote_b;使用git push origin local_a:remote_b;
如果想要把local_b提交到remote_a;使用git push origin local_b:remote_a;
local_a是本地分支,remote_b是远程分支
git push origin local_a:remote_b
新建
冒号前不写,就删除远程分支remote_b
git push origin :remote_b
删除
上传 本地当前分支 代码到 master分支
git push origin master
缩写
特例
1.本地创建并切换分支git checkout -b dev2.将dev分支推送到远程git push origin dev:dev //推送本地的dev(冒号前面的)分支到远程origin的dev(冒号后面的)分支(没有会自动创建)3.建立本地到上游(远端)仓的链接,这样代码才能提交上去git branch --set-upstream-to=origin/dev4.取消对master分支的跟踪git branch --unset-upstream master
git本地创建新分支并推送到远程
推送
基于当前所在分支,拉取远程branchName分支的代码
dev更新至最新,master不变
这条指令只能在dev上执行,如果在master上执行,master分支也会更新
git pull origin dev:dev
如何把远程 dev 上的代码拉取到本地font color=\"#fdb813\
1、本地切换分支到dev2
2、git pull origin dev1
这样可以保证本地其他分支不受影响,仅把远程dev1上的代码拉取到本地dev2上
如何把远程 dev1 上的代码拉取到本地dev2上
git pull origin branchName(远程分支名)
git fetch : 只是将远程的文件拉下来,不会与本地的分支进行合并
git pull = git fetch + git mergegit pull --rebase = git fetch + git rebase
git merge和git rebase的区别
git fatch/git pull/git pull --rebase的关系
拉取
git push origin --delete 远程分支名 //先删除远程git branch -D 本地分支名 //再删除本地
git push origin :远程分支名 //先删除远程,注意origin后的空格,空格后是:git branch -D 本地分支名 //再删除本地
删除远程 分支
git rm --cached xx.tetvim .gitignore //进入.gitignore文件,加入需要屏蔽的文件
解决办法:修改指令:git rm -r -cached bin/
出现错误:fatal: not removing 'bin/' recursively without -r
删除远程 文件,并添加到.gitignore
git push origin [name]
创建远程分支
创建
git remote prune origin
git remote update origin --prune
刷新
远程分支管理
区间左开右闭
git diff 【commit sha1 id】 【commit sha2 id】 > 【diff文件名】
这个diff是从 commit sha1 id 到 commit sha2 id,除非特殊需求,否则顺序不要反了
用git apply xx.diff 之后,不生产comit,只会生成和修改变化的文件
某两次提交之间的所有patchgit format-patch 【commit sha1 id】..【commit sha1 id】
某次提交(含)之前的几次提交git format-patch 【commit sha1 id】-n
git format-patch
检查patch/diff是否能正常打入git apply --check 【path/to/xxx.patch】git apply --check 【path/to/xxx.diff】
git apply 【path/to/xxx.patch】git apply 【path/to/xxx.diff】
git apply
git am 【path/to/xxx.patch】
git am
git apply --reject <patch_name>
patch 冲突
git diff生成的UNIX标准补丁.diff文件
git format-patch生成的Git专用.patch 文件
patch 和 diff 的使用
apply不恢复commit信息,am恢复commit信息
am失败,可以使用apply来处理
apply和am的区别
使用git patch 生成带commit信息的文件,再用git am 恢复commit信息,使用git diff 生成不带commit信息的文件,再用git apply 将所有commit作为一次提交这两者都需要用 --check 来验证
打patch注意事项
git patch
先切换到目标分支(master)执行命令:git merge devel删除旧分支(可以在上面一同做):git branch -D devel提交到远程分支:git push origin master
普通 Merge
devel上的提交合并为一个
以 squash 的形式 merge:git merge --squash devel
先切换到 devel 分支(不一样咯):git checkout devel变基:git rebase -i master切换回目标分支:git checkout master合并: git merge devel
rebase merge
视情况而定
先merge,然后rebase
merge
推荐这种,变基,主干清晰
git rebase
分支合并
查看分支1的git log,获取commitID切换到分支2,使用 git cherry-pick 分支1的某个commitID
git cherry-pick 用法。
分支合并其他分支的某次commit
一定要留下一个pick作为commit点
对于merge生成的点,本身是没有pick的,显示的pick是源commit,如果rebase merge的内容,需要注意是否只有一个pick,那么不要将pick该为squash
git合并多个本地commit作为一次提交。
git rebase
git branch -m old_branch new_branch
改完名需要再跟随一下
分支改名
本地分之管理
分支管理branch
版本回退到该ID已经commit的状态,但是ID跟最新版本之间的内容 消失了
将HEAD从顶端的commit往下移动两个更早的commit
git reset HEAD~2
git reflog进行版本回退
抢救
git reset --hard ID
版本回退到 该ID已经commit的状态font color=\"#381e11\
git reset --soft ID
不加参数表示默认,相当于git reset --mixed ID
版本回退到该ID已经commit的状态,但是该ID跟最新版本之间的内容还在,在工作区,这些内容的状态是 已修改、未添加、未提交
git reset ID
(1)git reflog(2)git reset 到某个ID(3)git log 查看恢复的commitID(4)git checkout . 清除所有修改。
git reset --hard 后如何修复。
相关问题
reset:本地库
只删除某次提交,直接commit
git revert commitID
只删除某次提交,不进入commit,进入REVERTING界面进行选择性操作后,再提交
git revert -n commitIDgit revert --continue
git revert -m 1 xxxxx
git revert 之前的revert
删除某个提交
注意: revert 命令会对每个撤销的 commit 进行一次提交,--no-commit 后可以最后一起手动提交,不加会导致多个提交
git revert --no-commit commitID2..commitID4
删除某连续提交
遇见合并分之的时候,会使用-m参数,-m参数包括1和2,1是当前你所在的分支为主,不一定是master,2是合并来的分支,使用的时候一定要先使用git show 看清楚,
git revert -m
revert:远程库
版本回退reset/revert
date -d -2hour +%Y-%m-%ddate是时间-2hour是前2小时注意:大写的Y ,小写的m和dgit --after 表示某个时间点之前
git log --after=\"date -d -\"$time\"hour +%Y-%m-%d\"可以被git log --since=$time.day.ago 代替
echo \"是否执行检查\"read //用于确认 //获取用户输入的查询时间read -p \"查询时间:\" time cd /d/dailybuildlistname=$(ls ./)for line in $listname //判断循环do cd $line echo \"========\"$line\"========\" git pull --rebase git log --after=\"date -d -\"$time\"hour +%Y-%m-%d\" cd ../donecd /d/dailybuild //结束返回echo \"检查结束\"read
dailybuild
git管理
ide 编辑器占用,没有保存等可能相关的操作
关闭ide
子主题
git add permission denied
add
首先新建分支跟随想要提交的远程分支,解决可能存在的跟随问题,1、git pull --rebase2、解决冲突,3、git push origin test:DEV_TEST
Updates were rejected because the tip of your current branch is behind
update
是因为本地分支和远程分支没有建立联系 (使用git branch -vv 可以查看本地分支和远程分支的关联关系)
git branch --set-upstream-to=origin/远程分支的名字 本地分支的名字
git pull报错:There is no tracking information for the current branch
pull
原因是远程仓库中的文件和我们本地的仓库有差异
git pull --rebase
这里的master根据需要,替换成本地的提交分支(注意需要对应远程分支)
git pull --rebase origin master
git pull origin master --allow-unrelated-histories
还存在一种原因:推代码的人不具备代码仓的创建分支权限
error: failed to push some refs to 'xxxx'
1、git fetch 或者 git pull origin master --allow-unrelated-histories
2、git branch --set-upstream-to=origin/master master
error: the requested upstream branch 'origin/master' does not exist
error
1、配置用户信息git config --global user.name [username]git config --global user.email [email]2、查询用户信息git config --list3、如果push遇到在输入密码是熟错后,就会报这个错误fatal: Authentication failed for解决办法:git config --system --unset credential.helper之后push操作就会提示输入名称和密码
fatal: Authentication failed for
网络问题,切换一下网络
fatal: unable to access 'https:/xxxxxxxdge.git/': Failed to connect to github.com port 443: Timed out
先删除,再重新添加
输入“git remote add origin”提示fatal:remote origin already exists
或者遇见需要HTTPS输入用户名和密码的,一律是因为代理配置的问题
git config --global -e
打开全局配置文件
[url \"git@git.xxx.xxx.com:\"] insteadOf = https://git.xxx.xxx.com/[url \"git@git.cxxx.xxx.com:\"] insteadOf = http://git.xxx.xxx.com/
添加配置信息
fatal: could not read Username for 'https://xx.xx.xxx.com': Device not configured
配置 git 邮箱和用户名
could not read Username for 'https:/xx.xx.xx.com': terminal prompts disa
fatal: could not read Username
权限问题,找人开通权限
fatal: Could not read from remote repository
fatal: 'xxxxl.git':repository not found: xxxxx.git
repository
$git pull origin master --allow-unrelated-histories
fatal: refusing to merge unrelated histories
fatal
git config --get core.ignorecase
查看目前状态
git config core.ignorecase false
Git 忽略文件名大小写导致项目运行失败
需该.git/config 文件,加上 master
Your configuration specifies to merge with the ref 'refs/heads/master'from t
远程仓库存在地址映射问题,访问受限,类似于更换库,锁库
linux 远程连接ssh提示IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY解决
查看并修改host文件,在C:\\Windows\\System32\\drivers\\etc,是否有重复。混乱的DNS
ssh: Could not resolve hostname github.com: No address associated with hostn
其他问题
git错误问题集锦
[user] name = jove.23 email = jove.23@aaa.com[url \"xx@git.xx.com:\"] insteadOf = https://git.xx.com[url \"ssh://github@git.xx.com:1234\"] insteadOf = https://git.xx.com
修改成
vim .gitconfig 或者git config --global -e
代理问题
cd ~/.ssh
检查是否已经存在 id_rsa.pub 或 id_dsa.pub 文件
创建一个 SSH key ssh-keygen -t rsa -C \"your_email@example.com\"
免密ssh
git remote add origin xxxxxxxxxx
git branch --set-upstream-to=origin/<分支名称> master
git pull --rebasegit push
将本地代码上传github
git remote remove origin
git remote add origin git@gitxxxxxxxxxme/Your_Repo_Name.git
git branch --set-upstream-to=origin/master master
GitHub设置ssh key后push还要输入用户名和密码
新建一个.gitcommitmessage.txt
使用指令:git config --global commit.template /d/.gitcommitmessage.txt
指令后面是.txt的文件路径,全局声明,以后可以直接git commit然后修改后使用
git 添加commit 模板
git config --global alias.ci commit
当要输入 git commit 时,只需要输入 git ci
Git 别名
git学习网站(趣味)
git config user.email
查看邮箱
git config --global user.name \"username\"git config --global user.email \"email\"
git配置邮箱
//查看仓库级的 config,命令:git config –local -l//查看全局级的 config,命令:git config –global -l//查看系统级的 config,命令:git config –system -l//查看当前生效的配置, 命令:git config -l
git查看配置信息
git version
which git
查看 git 的版本和安装路径
注意事项:根据mac的执行脚本zsh还是bash,修改git-completion.zsh还是git-completion.bash
sh -c \"$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)\"
r
最佳实践
mac下git自动补全
git 配置
# 项目名字(name)里有 python 的in:name python# 名字(name)里有 python 的并且 stars 大于 3000 的in:name python starts:>3000# 名字(name)里有 python 的并且 stars 大于 3000 、forks 大于 200 的in:name python starts:>3000 forks:>200# 详情(readme)里面有 python 的并且 stars 大于 3000 的in:readme python starts:>3000# 描述(description)里面有 python 的并且 stars 大于 3000 的in:description python starts:>3000# 描述(description)里面有 python 的并且是 python 语言的in:description python language:python# 描述(description)里面有 python 的并且 2019-12-20 号之后有更新过的in:description python pushed:>2019-12-20
github搜索指南
Github无法加载或不显示图片问题
http://tool.chinaz.com/dns/?type=1&host=github.com&ip=
github速度慢
github
git(repo)
练习网站:RegexOne
测试网站:RegExr
json
正则表达式
C#基础指令
C# 解析key值动态的json数据
C#组合用法
C# Task用法
C#异步编程看这篇就够了
task
依赖注入在 dotnet core 中实现与使用:1 基本概念
依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection
DI
网关
C#高级
C#指令
定义数组、哈希表、函数
powershell 传参/脚本执行顺序
注意String首字母大写
[String]::IsNullOrEmpty
字符串判空
注意管道符
| ? 属性名 -Like 参数名
where 可以用 ? 代替
| where 属性名 -Like 参数名
查找指令
加上raw读取更快
$file = Get-Content -path \"d:\\1.txt\" -Raw
读取文件
输出powershell查询结果到D盘1.txt
Get-Process | Out-File D:\\1.txt
打印输出
文件相关
$today = Get-Date$today.ToString('yyyy-MM-dd')
格式化时间
注意$exetime 可以有多种时间提取格式:Seconds、min等
$start = Get-DateGet-HotFix$end = Get-Date$exetime = $end - $startwrite-host $exetime
计算执行时间
时间
注意管道符 |
(get-process | | Measure-Object -Sum).sum
样例
查找结果使用.sum得到
| Measure-Object -Sum
求和运算
PS C:\\Users\\os> $Ran = New-Object System.RandomPS C:\\Users\\os> $Ran.Next(num 最大值)
生成随机数
powershell基础指令
powershell远程登录并调用脚本
$a = get-process$result = & $a
执行一行语句
注意:[scriptblock]::Create
$multipleLine = @\"ping pstips.netget-Date\"@$code = [scriptblock]::Create($multipleLine)& $code
执行代码块
执行由变量组成的语句
# Convert string to base64 stringfunction ConvertTo-Base64String([string]$string){ $byteArray = [System.Text.UnicodeEncoding]::Unicode.GetBytes($string) [Convert]::ToBase64String( $byteArray )}
编码
# Convert base64 string to stringfunction ConvertFrom-Base64String([string]$string){ $byteArray = [Convert]::FromBase64String($string) [System.Text.UnicodeEncoding]::Unicode.GetString($byteArray)}
解码
base64编码
语句执行
powershell组合用法
powershell
netstat -ano | findstr 80
查询端口占用
查询
set X=5,就是令X=5的意思
set /p commit=please input commit:
set
注释命令,在C语言中相当于/*----------*/,它并不会被执行,只是起到一个注释的作用,便于别人及自己将来阅读和维护脚本
::命令与rem是一样
rem
表示执行了这条命令后关闭所有命令(包括本身这条命令)的回显
echo off命令则表示关闭其他所有命令(不包括本身这条命令)的回显,@的作用就是关闭紧跟其后的一条命令的回显
FOR /F [\"options\"] %%i IN (file) DO commandFOR /F [\"options\"] %%i IN (\"string\") DO commandFOR /F [\"options\"] %%i IN ('command') DO command
格式:
@echo off
FOR /F %%i IN (file) DO command
bat for /f用法
在cmd窗口中:for %I in (command1) do command2在批处理文件中:for %%I in (command1) do command2
tokens skip /f delims eol 的用法
单位是s
timeout /T 延迟秒数
实现sleep功能
timeout
| findstr xxx
类似grep的命令
findstr
start http://spdbclacs01.spdbcl.com
直接打开某应用
start
if
基本语法
“启动或关闭Windows功能”界面,勾选telnet客户端,点击确定
如何开启telnet
CTRL+]键
然后按 q
如何退出telnet
点击“启用或关闭Windows Defender 防火墙”,将Windows Defender 防火墙启用
点击“高级设置”,→“入站规则”→“新建规则”→“端口”→ “下一步”
windows如何打开22port
脚本
每次新建一个cmd窗口,通过telnet测试ip和port是否联通,通的IP和PORT会直接退出并关闭窗口,不通的窗口会持续一段时间,每次循环通过判断仍然存在的窗口数量,找出不同的端口。ping -n 3 127.1>nul 用于延时,数字3越大时间延续越长
释义
因为判断依据是测试依旧存在的cmd窗口的名称,而这个名称只显示到ip,所以存在通的端口因为之前存在的不通的端口,而被误判为不通,例如,IP1:20不通,IP1:30通,但是存在IP1的窗口,因此误判30端口不通。
解决办法:内层先循环IP,测试的是同一个端口,这样IP不会引起误判,只要内层循环持续时间超过1分钟左右,窗口关闭,不会印象测试下一个端口
为什么外层循环是port,内层循环是ip
服务拒绝
未开通
连接超时
开通未占用
进入telnet内部
开通
端口存在三中状态:
为什么不通的端口,也会闪退
注意点
Windows测试TCP
Linux下测试其他端口
Windows测试UDP
测试端口是否能用
telnet
bat基础指令
echo \"是否开始同步\"readcd /d/workspacereponame=$(ls ./)for line in $reponamedocd $lineecho \"========\"$line\"=========status====\"git statuscd ../donecd /d/workspaceread
直接在桌面上sh脚本
使用bat执行git命令
BAT读取文件
将正常异常输出到同一文件,dir file.c 1> output.msg 2>&1 用“2>&1”将标准错误输出重定向到标准输出
bat输出重定向
延时
str=%str1%%str2%
非延时
%%i拼接字符串
BAT命令大全
bash高级使用,github
bat组合用法
修改环境变了的path,一般在C:\\Windows\\System32;
ipconfig显示不是命令
cmd 中输入 wmic
memorychip
cpu get
查看电脑内存的型号
cmd bash
~~~Javapublic static void main(){}~~~
代码块
~public static void main~
单行代码
[www.abidu.com](百度网址)
添加链接
井号和空格
#
大标题
符号前置空格
+/-
小标题
标题
锚点: [跳转到个人简介](#个人简介)
锚点目标:<p id=\"个人简介\">这是个人简介</p>
MarkDown中实现目录页面内跳转
md语法
jupyter notebook
python基础指令
python组合用法
Python
代码练习,在线运行
开发语言
1.读取json文件的所有key
2.递归遍历其中value为json的key,拼接字符串
校验json文件是否符合目标模板
本机要访问某个域名,首先会到这个文件里查找,有没有这个域名对应的IP地址,如果有直接就访问这个IP地址了,如果没有才会去向DNS服务器发出域名解析请求
本地域名解析规则
广告都是后台从网络服务器上下载广告资源,然后再在本机显示
下载过程就必须要涉及到域名解析过程
在域名解析阶段,返回错误的IP地址,那么广告资源也就无法下载
屏蔽广告原理
修改了系统的/etc/hosts文件
让广告域名都指向本机IP地址
做法
修改/etc/hosts
ksremote.dex
adclose.png
ksremote.jar
libksrootclient.so
1) 加载图片资源:adclose.png
2) 反射得到ActivityThread类的currentActivityThread()获得当前ActivityThread对象
3) 加载/data/data/com.ijinshan.duba/app_ctrl/libksrootclient.so,并调用native方法StartSocketHook()。这里是在Native层对网络操作函数加Hook。
4) 反射获得当前ActivityThread对象的mInitialApplication成员(Application 类型),从而获得当前包名(Context.getPackageName())
5) 如果发现自己不是\"com.ijinshan.duba\",就开始更新广告规则
6) 替换当前ActivityThread中的mH(Handler类型)的mCallback,用金山自定义的一个callback对象来包裹过原callback并且替换原callback,从而起到hook作用。
SetAppHook()中去执行
KsRemoteCtrl类
ACTIVITYBIND_APPLICATION
RESUME_ACTIVITY
PAUSE_ACTIVITY
RECEIVER
拦截的消息有
1. 非ViewGroup情况下,只用类名规则匹配
2. ViewGroup情况下,以此用类名规则和WebView规则匹配,如果还未匹配上,则用排除规则排除PhoneWindow的情况。接下来就是遍历当前ViewGroup的所有子View,然后递归调用a()。
判断当前View是不是ViewGroup
如何找到view
黑名单是通过IPC从手机毒霸的主进程哪里获得的
1. 类名规则:当前View对象的类名如果与黑名单中的类名匹配,那么就认定为广告。
2. WebView规则:当前View对象是WebView并且满足一定的规则,那么就认定为广告。
3. 排除规则:当ViewGroup对象的类名如含有” com.android.internal.policy.impl.PhoneWindow”, 那么就肯定不是广告。
广告匹配过程中一共使用了3种规则
在广告应用中某个Activity的onResume()触发前,注入的代码会先遍历当前Activity里的所有View,一旦找到广告View,就会调用addView()将添加到广告View的附近。
在Activity的onPause()触发前,会做一些清理工作。
页面注入去除广告
①大部分都是通过后缀来区别的,后缀好像都是高于8个的那种,通过在后缀中选取8个连续的字符当键,然后把对应的规则写到哈希表的值里面,查的时候算法很简单,就是连续抽取8个连续的字符串查找哈希表;
②这部分一般是使用者自己书写的规则,就是在规则前面加上@@…………,表示遇到对应这些规则的链接不阻挡,至于查询算法同上。
③这部分就是通配符匹配(我所需要的就是这部分的算法),这部分主要处理的就是类似于域名的通配符规则,例如:www.baidu.*.com 然后对这些规则通过域名切割,切割成一个一个subdomain:www ,baidu ,com ,subdomain是“ * ”的或者含有的都删除,然后再把第一个域名还有最后一个域名去掉,我给的例子只剩下一个“baidu”然后用这个字符串当做键,查询对应的哈希表中是否已经含有,如果含有查看其一个键对应的N个值得N是否已经达到上限,如果没有直接写入,如果达到上限了就用下一个字符串当做键继续按照上述查找(所给的例子通过域名切割之后只剩下一个字符串当做键,正常情况下可能有多于一个的情况),如果所得到的字符串当做键所对应的N都已经达到上限,那就把这条规则写入特殊规则处理的地方,这个可以因人而异,我的处理是写入一个动态数组到时候遍历查找(Adblock plus和我的实现差不多,区别是它使用js实现这些的)。
规则
判断字符串A中是否有字符串B的一个算法,不过由于js或者别的字符串匹配效率不高的语言处理可能复杂度比较高,所以这个算法是通过把字符串匹配转换成整数比较大小的形式来判断的。例如ABCDEFGHJ转换成123456789,然后进行比较。例如字符串a为“ABCFE”转换成整数12365 字符串b为“BC”转换成23,匹配的时候依次从第一个整数最低位取得两位数和23比较,当然,我的这种举例是最简单最基础的形式,这个算法还有改进的空间就是通过用记忆算法来实现,具体就补多少了。
Rabin-Karp算法
Ablock实现原理
实际解决方案集锦
开发工具
开发
物理网络,它由物理设备和物理链路组成。常见的物理设备有交换机、路由器、防火墙、负载均衡、入侵检测、行为管理等,这些设备通过特定的链路连接起来形成了一个传统的物理网络,这样的物理网络,我们称之为UnderLay网络
UnderLay
OverLay
SDN中的OverLay与UnderLay技术
windows2008服务器设置系统启动时程序自动运行
项目部署问题集锦
高可用、双活、灾备的区别和联系
以淘宝作为例子。在网站最初时,应用数量与用户数都较少,可以把Tomcat和数据库部署在同一台服务器上。浏览器往www.taobao.com发起请求时,首先经过DNS服务器(域名系统)把域名转换为实际IP地址10.102.4.1,浏览器转而访问该IP对应的Tomcat。
架构方案
随着用户数的增长,Tomcat和数据库之间竞争资源,单机性能不足以支撑业务
Tomcat与数据库分开部署
改进方案
存在的问题
Tomcat
数据库
涉及的技术点
1、单机架构
Tomcat和数据库分别独占服务器资源,两者通过restful方式访问,显著提高两者各自性能
随着用户数的增长,并发读写数据库成为瓶颈
引入本地缓存和分布式缓存
restful风格的编码和访问方式
2、Tomcat与数据库分开部署
缓存热门商品信息或热门商品的html页面等。通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。
其中涉及的技术包括:使用memcached作为本地缓存,使用Redis作为分布式缓存,还会涉及缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题
在Tomcat同服务器上或同JVM中增加本地缓存,并在外部增加分布式缓存
缓存抗住了大部分的访问请求,随着用户数的增长,并发压力主要落在单机的Tomcat上,响应逐渐变慢
引入反向代理实现负载均衡
memcached
Redis
3、引入本地缓存和分布式缓存
此处假设Tomcat最多支持100个并发,Nginx最多支持50000个并发,那么理论上Nginx把请求分发到500个Tomcat上,就能抗住50000个并发。
其中涉及的技术包括:Nginx、HAProxy,两者都是工作在网络第七层的反向代理软件,主要支持http协议,还会涉及session共享、文件上传下载的问题
在多台服务器上分别部署Tomcat,使用反向代理软件(Nginx)把请求均匀分发到每个Tomcat中
反向代理使应用服务器可支持的并发量大大增加,但并发量的增长也意味着更多请求穿透到数据库,单机的数据库最终成为瓶颈
数据库读写分离
Nginx
HAProxy
session共享
文件上传下载
4、引入反向代理实现负载均衡
读库可以有多个,通过同步机制把写库的数据同步到读库
对于需要查询最新写入数据场景,可通过在缓存中多写一份,通过缓存获得最新数据
其中涉及的技术包括:Mycat,它是数据库中间件,可通过它来组织数据库的分离读写和分库分表,客户端通过它来访问下层数据库,还会涉及数据同步,数据一致性的问题
把数据库划分为读库和写库
业务逐渐变多,不同业务之间的访问量差距较大,不同业务直接竞争数据库,相互影响性能
数据库按业务分库
Mycat
数据同步
数据一致性
消息队列
5、数据库读写分离
把不同业务的数据保存到不同的数据库中,使业务之间的资源竞争降低,对于访问量大的业务,可以部署更多的服务器来支撑。
这样同时导致跨业务的表无法直接做关联分析,需要通过其他途径来解决,但这不是本文讨论的重点,有兴趣的可以自行搜索解决方案
存在的次要问题
随着用户数的增长,单机的写库会逐渐会达到性能瓶颈
把大表拆分为小表
数据库分库分表
分库分表关联分析
6、数据库按业务分库
针对评论数据,可按照商品ID进行hash,路由到对应的表中存储;
针对支付记录,可按照小时创建表,每个小时表继续拆分为小表,使用用户ID或记录编号来路由数据
只要实时操作的表数据量足够小,请求能够足够均匀的分发到多台服务器上的小表,那数据库就能通过水平扩展的方式来提高性能。其中前面提到的Mycat也支持在大表拆分为小表情况下的访问控制。
同类业务拆分成小表
这种做法显著的增加了数据库运维的难度,对DBA的要求较高。数据库设计到这种结构时,已经可以称为分布式数据库,但是这只是一个逻辑的数据库整体,数据库里不同的组成部分是由不同的组件单独来实现的,这种架构其实是MPP(大规模并行处理)架构的一类实现。
开源中比较流行的有Greenplum、TiDB、Postgresql XC、HAWQ等
商用的如南大通用的GBase、睿帆科技的雪球DB、华为的LibrA等
开源和商用
如TiDB更侧重于分布式OLTP场景,
Greenplum更侧重于分布式OLAP场景
不同的MPP数据库的侧重点也不一样,
这些MPP数据库基本都提供了类似Postgresql、Oracle、MySQL那样的SQL标准支持能力,能把一个查询解析为分布式的执行计划分发到每台机器上并行执行,最终由数据库本身汇总数据进行返回
也提供了诸如权限管理、分库分表、事务、数据副本等能力
支持能力
并且大多能够支持100个节点以上的集群,大大降低了数据库运维的成本,并且使数据库也能够实现水平扩展
集群
MPP数据库
如分库分表的管理和请求分发,由Mycat实现,
SQL的解析由单机的数据库实现,
读写分离可能由网关和消息队列来实现,
查询结果的汇总可能由数据库接口层来实现等等,
MPP(大规模并行处理)架构的实现
分布式数据库
数据库和Tomcat都能够水平扩展,可支撑的并发大幅提高,随着用户数的增长,最终单机的Nginx会成为瓶颈
使用LVS或F5来使多个Nginx负载均衡
7、把大表拆分为小表
由于瓶颈在Nginx,因此无法通过两层的Nginx来实现多个Nginx的负载均衡。图中的LVS和F5是工作在网络第四层的负载均衡解决方案
LVS是软件,运行在操作系统内核态,可对TCP请求或更高层级的网络协议进行转发,因此支持的协议更丰富,并且性能也远高于Nginx,可假设单机的LVS可支持几十万个并发的请求转发;
LVS
F5是一种负载均衡硬件,与LVS提供的能力类似,性能比LVS更高,但价格昂贵
F5
由于LVS是单机版的软件,若LVS所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点
可使用keepalived软件模拟出虚拟IP,然后把虚拟IP绑定到多台LVS服务器上,浏览器访问虚拟IP时,会被路由器重定向到真实的LVS服务器
当主LVS服务器宕机时,keepalived软件会自动更新路由器中的路由表,把虚拟IP重定向到另外一台正常的LVS服务器,从而达到LVS服务器高可用的效果
VIP
此处需要注意的是,上图中从Nginx层到Tomcat层这样画并不代表全部Nginx都转发请求到全部的Tomcat,在实际使用时,可能会是几个Nginx下面接一部分的Tomcat,这些Nginx之间通过keepalived实现高可用,其他的Nginx接另外的Tomcat,这样可接入的Tomcat数量就能成倍的增加
由于LVS也是单机的,随着并发数增长到几十万时,LVS服务器最终会达到瓶颈,此时用户数达到千万甚至上亿级别,用户分布在不同的地区,与服务器机房距离不同,导致了访问的延迟会明显不同
通过DNS轮询实现机房间的负载均衡
8、使用LVS或F5来使多个Nginx负载均衡
在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP。
当用户访问www.taobao.com时,DNS服务器会使用轮询策略或其他策略,来选择某个IP供用户访问。此方式能实现机房间的负载均衡
至此,系统可做到机房级别的水平扩展,千万级到亿级的并发量都可通过增加机房来解决,系统入口处的请求并发量不再是问题
随着数据的丰富程度和业务的发展,检索、分析等需求越来越丰富,单单依靠数据库无法解决如此丰富的需求
引入NoSQL数据库和搜索引擎等技术
9、通过DNS轮询实现机房间的负载均衡
在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢
统计报表场景
数据库天生不适用
全文检索、可变数据结构等场景
数据库的缺点
可通过分布式文件系统HDFS解决
海量文件存储
可通过HBase和Redis等方案解决
key value类型的数据
可通过搜索引擎如ElasticSearch解决
全文检索场景
可通过Kylin或Druid等方案解决
多维分析场景
本方案的优点
引入更多组件同时会提高系统的复杂度,不同的组件保存的数据需要同步,需要考虑一致性的问题,需要有更多的运维手段来管理这些组件等
当数据库中的数据多到一定规模时,数据库就不适用于复杂的查询了,往往只能满足普通查询的场景
引入更多组件解决了丰富的需求,业务维度能够极大扩充,随之而来的是一个应用中包含了太多的业务代码,业务的升级迭代变得困难
大应用拆分为小应用
10、引入NoSQL数据库和搜索引擎等技术
按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。
这时候应用之间可能会涉及到一些公共配置,可以通过分布式配置中心Zookeeper来解决
不同应用之间存在共用的模块,由应用单独管理会导致相同代码存在多份,导致公共功能升级时全部应用代码都要跟着升级
复用的功能抽离成微服务
11、大应用拆分为小应用
如用户管理、订单、支付、鉴权等功能在多个应用中都存在,那么可以把这些功能的代码单独抽取出来形成一个单独的服务来管理,这样的服务就是所谓的微服务
应用和服务之间通过HTTP、TCP或RPC请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理
可以通过Dubbo、SpringCloud等框架实现服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性
不同服务的接口访问方式不同,应用代码需要适配多种访问方式才能使用服务,此外,应用访问服务,服务之间也可能相互访问,调用链将会变得非常复杂,逻辑变得混乱
引入企业服务总线ESB屏蔽服务接口的访问差异
12、复用的功能抽离成微服务
通过ESB统一进行访问协议转换,应用统一通过ESB来访问后端服务,服务与服务之间也通过ESB来相互调用,以此降低系统的耦合程度。
这种单个应用拆分为多个应用,公共服务单独抽取出来来管理,并使用企业消息总线来解除服务之间耦合问题的架构,就是所谓的SOA(面向服务)架构,
这种架构与微服务架构容易混淆,因为表现形式十分相似。个人理解,微服务架构更多是指把系统里的公共服务抽取出来单独运维管理的思想,而SOA架构则是指一种拆分服务并使服务接口访问变得统一的架构思想,SOA架构中包含了微服务的思想
业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂,同一台服务器上部署多个服务还要解决运行环境冲突的问题,此外,对于如大促这类需要动态扩缩容的场景,需要水平扩展服务的性能,就需要在新增的服务上准备运行环境,部署服务等,运维将变得十分困难
引入容器化技术实现运行环境隔离与动态服务管理
13、引入企业服务总线ESB屏蔽服务接口的访问差异
目前最流行的容器化技术是Docker,最流行的容器管理服务是Kubernetes(K8S),应用/服务可以打包为Docker镜像,通过K8S来动态分发和部署镜像。Docker镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用/服务的运行代码,运行环境根据实际的需要设置好。把整个“操作系统”打包为一个镜像后,就可以分发到需要部署相关服务的机器上,直接启动Docker镜像就可以把服务起起来,使服务的部署和运维变得简单
在大促的之前,可以在现有的机器集群上划分出服务器来启动Docker镜像,增强服务的性能,大促过后就可以关闭镜像,对机器上的其他服务不造成影响(在此之前,服务运行在新增机器上需要修改系统配置来适配服务,这会导致机器上其他服务需要的运行环境被破坏)。
使用容器化技术后服务动态扩缩容问题得以解决,但是机器还是需要公司自身来管理,在非大促的时候,还是需要闲置着大量的机器资源来应对大促,机器自身成本和运维成本都极高,资源利用率低
以云平台承载系统
14、引入容器化技术实现运行环境隔离与动态服务管理
系统可部署到公有云上,利用公有云的海量机器资源,解决动态硬件资源的问题,在大促的时间段里,在云平台中临时申请更多的资源,结合Docker和K8S来快速部署服务,在大促结束后释放资源,真正做到按需付费,资源利用率大大提高,同时大大降低了运维成本
所谓的云平台,就是把海量机器资源,通过统一的资源管理,抽象为一个资源整体,在之上可按需动态申请硬件资源(如CPU、内存、网络等),并且之上提供通用的操作系统,提供常用的技术组件(如Hadoop技术栈,MPP数据库等)供用户使用,甚至提供开发好的应用,用户不需要关系应用内部使用了什么技术,就能够解决需求(如音视频转码服务、邮件服务、个人博客等)
基础设施即服务。对应于上面所说的机器资源统一为资源整体,可动态申请硬件资源的层面
IaaS
平台即服务。对应于上面所说的提供常用的技术组件方便系统的开发和维护;
PaaS
软件即服务。对应于上面所说的提供开发好的应用或服务,按功能或性能要求付费
SaaS
云平台
N+1设计。系统中的每个组件都应做到没有单点故障;
架构设计的原则
15、以云平台承载系统
服务端高并发分布式架构演进之路
CI
CD
CI/CD
实用分支管理策略
部署
You-get
如何下载网页上的视频?
视频下载
HWRFF-2FFYX-XFXP2-DYFC3-BX3B7 YT9K9-4R938-3TVXX-3Q3QT-9HBXM C3X7Y-R6WWH-BRXRD-FY84C-FXWHK XJBR4-M42Q4-QPJ9C-BRDRJ-KHPVY TF3Q7-YYP8R-D78R7-W9Q9M-DXVBK J8D39-J2WM3-6368H-JV8G9-BYJJQ P3H89-V3P2R-JVBTF-YM2J2-FTMT3 RGM4T-3VT6B-GTYPY-3FHP2-HV2YJ TTY4D-RDKK9-TYB2T-68WJW-M69KJ BWPX2-XK2T8-3GV2W-KHQVP-QXCDV
Professional
J783Y-JKQWR-677Q8-KCXTF-BHWGC C4M9W-WPRDG-QBB3F-VM9K8-KDQ9Y 2VCGQ-BRVJ4-2HGJ2-K36X9-J66JG MGX79-TPQB9-KQ248-KXR2V-DHRTD FJHWT-KDGHY-K2384-93CT7-323RC THHH2-RKK9T-FX6HM-QXT86-MGBCP KH2J9-PC326-T44D4-39H6V-TVPBY D8BMB-BVGMF-M9PTV-HWDQW-HPCXX TFP9Y-VCY3P-VVH3T-8XXCC-MF4YK 6MHH-TRRPT-74TDC-FHRMV-XB88W
Ultimate
P4DBR-8YPT6-KHRB8-6T7RW-GMXGV FGTCF-8JBG2-4BK4G-36JWB-PFQXB CW4KD-MK47X-JYQ7Y-DKKTR-86TH7 37X8Q-CJ46F-RB8XP-GJ6RK-RHYT7 GDK6B-87QP9-F9WYK-PP327-BQ622 72C8D-KQ9Y4-FGBCD-WY9WG-BD92C GV7X4-92M4D-6F69V-RFGP9-3FBBD 4JCWB-FVHJJ-XCPKC-CTWDP-QQQ9M WXM3Y-H2GDY-TKFQH-6GQQF-7VG8P V6V3G-9DB2T-BD4VC-44JVQ-6BVR2
Home Basic
Windows 7旗舰版产品密钥
windows操作系统镜像
密钥
实用小技巧
开发、部署
SoftwareBasic
0 条评论
下一页