Web
Http
特点:无状态:不保存请求和响应的通信数据,通过Cookie、Session(不属于Http协议)等解决;请求只能由客户端发起,通过WebSocket解决(不属于Http协议,属于H5);无连接:每次连接处理一个请求,Http1.1使用长连接解决;
请求步骤:1.浏览器请求DNS解析域名对应的IP;2.根据IP和服务器Http端口(默认80)建立TCP套接字链接;3.通过TCP向服务器发送请求报文;4.服务器解析请求,定位请求资源,将资源写到TCP;5.若connection为close则服务器主动关闭TCP连接,客户端被动关闭连接;若connection为keepalive则连接保持一段时间,在该时间内可以继续接收请求;6.浏览器解析Html并显示;
请求方法:Get、Post、Put、Delete、Head(同Get,不传body)、TRACE(回显服务器收到的请求)、OPTIONS(返回服务器支持的所有Http方法)、CONNECT(管道连接预留);
状态码:1xx(请求已接收,继续处理)、2xx(服务器处理成功)、3xx(重定向,需要后续操作完成)、4xx(客户端错误)、5xx(服务端错误);
格式:请求格式:请求行(请求方法、URI、协议版本)、请求头部、空行、请求正文;响应格式:状态行(协议版本、状态码、状态码描述)、响应头部、响应正文;
长连接:HTTP的长/短连接本质上是TCP的长/短连接,短连接:HTTP1.0中默认(Connection:closed),管理简单,但请求频繁浪费时间和带宽;长连接:HTTP1.1默认(Connection:keep-alive),省去TCP建立关闭操作,减少了时间和浪费,但客户端越多保持的链接越多;
Http2:基于SPDY,优化了Http1.1的请求延迟和安全性;Http1.x基于文本传输,一个长连接请求串行化处理,服务端不能发送请求到客户端;Http2基于二进制传输、多路复用(一个连接就可并发处理,多个请求共享一个连接)、header压缩、服务端推送(服务端将静态资源伴随index.html一起发送到客户端,避免客户端多次重复请求);
前后端交互
方式:Cookie、Ajax(使用XmlHttpRequest对象的send、open等方法实现)、jsonp(跨域交互,依靠script的src属性,不属于Ajax)、服务端渲染(服务端加工好数据给客户端,客户端省去了渲染)、WebSocket(解决Http请求只能由客户端发起的缺陷,兼容Http,可以发送文本和二进制,协议格式ws://);
Cookie:客户端跟踪用户会话,存储在客户端内存或文件,相当于服务端发给客户端的凭证,弥补HTTP协议无状态的不足;不可跨域名使用、中文需UTF8编码,二进制使用BASE64编码;使用流程:客户端正常请求、服务端返回Set-Cookie头告诉客户端创建对应的Cookie、客户端创建或更新Cookie(内存临时保存或文件持久化)、客户端下次请求带上Cookie、服务端使用Cookie;属性:名称、数据、maxAge(正数:过期时间,会持久化,0:删除,负数:临时存储、浏览器关闭失效,存内存,默认-1)、path(使用Cookie的路径,默认/,域名下都可使用)、domain(使用Cookie的域名,默认请求的域名)、secure(只在Https下传输);domain、path、name都相同才认为同一个Cookie(相同domain和path的Cookie存一个文件);Cookie不支持直接删除和修改,删除Cookie(maxAge设为0)、修改Cookie(直接覆盖);个数和大小都有限制;
Session:服务端跟踪用户会话,存储在服务端,依赖Cookie;JSP内置了Session对象可直接使用;创建:先判断请求中是否带sessionId,请求JSP和Servlet会自动创建,或request.getSession(true)创建;过期时间:Tomcat或Web.xml或代码设置;使用流程:服务端随机生成JSESSIONID通过Cookie返回、客户端后续请求带上JSESSIONID、服务端判断JSESSIONID;不支持Cookie时:自动重写URL地址实现(通过查询参数添加或者加到URL最后分号分隔),或者表单隐藏字段提交;浏览器窗口的子窗口会共享父窗口的SessionId;由于只认ID获益不同窗口不一样不是同一Session;
前端技术
Html5:新增元素(section、video、canvas、email等)、废除元素(frame等,不支持frame,只支持iframe)、新增全局属性机制、新增WebSocket、语法改变(简化boolean属性、DOCTYPE、省略属性值的引号等)、新增localStorage机制;
前端存储:cookie(个数限制20,大小限制4K,可内存可文件持久化)、localStorage(大小限制5M、持久化存储,同一域名才能使用)、sessionStorage(类似localStorage,非持久化,会话内共享,会话结束即销毁)、Web SQL(前端关系数据库)、indexedDB(基于JavaScript的数据库,可存储和检索结构化数据);
设计
设计模式
设计原则:开闭原则(对扩展开放,对修改关闭)、里氏替换原则(子类可以扩展父类的功能但不能改变父类原有的功能,即可新增方法不能覆写父类方法)、依赖倒置原则(面向接口编程,降低耦合)、单一职责原则(类单一功能,提高内聚)、接口隔离原则(接口不应过大应拆分成更小更具体的接口,提高内聚)、迪米特法则(最少知识,若两个类不同心则不应该相互调用,应该通过第三方,降低耦合);
模式分类:创建型(描述如何创建对象):单例(一个类一个实例)、原型(复制已有实例)、工厂、建造者(将一个复杂的对象分解为多个简单的对象一步一步构建);结构型(描述如何组织对象成更大的结构:代理(代理真实对象的访问)、适配器(转换不兼容的接口)、桥接(抽象组合不同类型的实现)、装饰(动态增加对象的职责)、门面(为多个不同系统提供统一接口)、享元(提取公共共享)、组合(组合部分整体);行为型(描述对象间协作):模板方法(定义算法骨架)、策略(一系列算法和算法职责分开)、命令(封装分割请求的发出和执行)、责任链(请求处理者通过前一对象记住下一个对象的引用而连成一条链)、状态(分离对象的状态)、观察者(对象状态改变时通知依赖对象)、中介者(定义中介者解耦原有对象的访问);
单例模式:一个类一个实例且由类自己创建;创建方式:饿汉式:static类加载时初始化,避免多线程问题;懒汉式:使用时初始化,线程不安全,可以方法加synchronized解决;双重检查模式:2次判空,第2次再synchronized,需要volatile;静态内部类:推荐使用,使用时再加载,线程安全;
工厂模式:解耦对象创建;简单工厂:根据类型if..else创建,违反了开闭原则,适用于固定,对象较少的场景;工厂方法:一个类型一个工厂,提供方法创建,违反了开闭原则;抽象工厂:类似工厂方法,一个类型一个工厂,但抽象了一系列方法;
UML:结构图:类图、用例图;交互图:时序图、协作图、状态图、活动图;实现图:构建图、部署图;
架构设计
设计原则:抽象(屏蔽内部实现细节、提供统一处理)、共享(复用相同资源,服务单一入口)、自治(组件自我完备,独立运行、部署)、冗余(冗余实例,避免单点故障)、分布(组件可分布部署)、自动(自管理,自优化);
N+1设计(避免组件单点故障)、回滚设计(向前兼容,可回滚)、禁用设计(通过配置快速下线服务)、监控设计(考虑监控的手段)、多活多地数据中心设计、采用成熟的技术、资源隔离设计(避免单一业务占用全部资源)、架构应能水平扩展、快速迭代、无状态设计、使用商用硬件(能有效降低硬件故障的机率);合适原则>简单原则>演化原则;
架构设计点:架构分层:接入层(API管理、限流、安全、监控、日志)、应用层(水平扩展、无状态、灰度发布)、服务层(分级管理:核心服务、重要服务等,幂等、异步、隔离、容错、水平扩展、独立部署测试)、数据层(数据和应用分离、数据异构、读写分离、统一数据视图);服务管理(自动化发布、测试、性能压测、灰度、应急措施)、服务监控(网络流量、系统、日志、应用、业务)、容灾(备份、多活、重试、雪崩);
Linux
目录结构:bin(常用命令)、sbin(管理员程序)、home(普通用户主目录)、root(系统管理员目录)、lib(开机所需的动态链接库)、etc(所有配置文件)、usr(用户应用类似Windows的program files)、boot(启动系统的核心文件)、proc(虚拟目录,系统内存映射,可获取系统信息)、dev(类似设备管理器,把所有的硬件用文件的形式存储)、media(自动识别的设备挂载)、mnt(用户临时挂载)、opt(额外安装软件的目录)、var (经常扩充修改的目录);
文件类型:-(常规文件)、d(目录)、b(块设备文件如硬盘)、c(字符设备文件)、l(符号链接即软连接文件类似快捷方式)、p(管道文件)、s(套接字文件实现进程间通信);终端文件(/dev/tty)、黑洞文件(/dev/null);
常用命令:查看系统信息(cat /proc/xx)、查看文件内容(cat、tac、more、less、head、tail)、文本处理(cat、grep、sed)、权限管理(chmod、chown、chgrp)、文件操作(cd、pwd、ls、mkdir、mv、cp、touch、rm、find)、网络(ifconfig、route、netstat、nslookup)、信息显示(top、free、stat、df)、进程(ps、kill);
脚本解释器:bash(linux标准默认的shell)、sh(Unix标准默认的shell);#!/bin/bash指定解释器;
其他
页面输入URL加载过程
1.浏览器查找当前URL是否存在缓存,并比较缓存是否过期(cache-control,Expires,last-modified);2.DNS域名解析(先找HOSTS文件再找DNS服务器解析IP);3.建立TCP链接(3次握手:客户端发送SYN=j、服务端发送ACK=j+1 SYN=k、客户端发送ACK=k+1);4.浏览器向服务器发送HTTP请求;5.服务器处理并返回响应,浏览器接收响应;6.浏览器解析和渲染页面(DOM和CSS);7.关闭TCP链接(四次挥手:FIN ACK, ACK, FIN ACK, ACK);
一致性Hash
概念:利用hash环改进余数hash,提高伸缩性;首先计算所有服务器的hash,再计算用户ID的hash,找到离该用户hash最近的服务器hash即为需要请求的服务器;特性:单调性(新增请求会落在原有或新增服务器上,不会落在原有其他服务器上)、分散性(尽量避免同一请求落在不同服务器)、平衡性(负载均衡,但存在倾斜即一个服务器处理了过多请求,增加虚拟节点解决);均匀一致性hash:优化虚拟节点算法,使每台服务器负载尽量均衡;
TCP/IP模型
OSI七层模型:物理层(比特传输,将0/1信号与电/光信号互相转化,IEEE 802)、数据链路层(帧传输,物理MAC地址寻址,Ethernet,)、网络层(报文传输,逻辑IP地址寻址,IP/ARP)、传输层(处理数据包实现通信,TCP/UDP)、会话层(建立节点、维护链接,DNS)、表示层(数据格式转换解码,Telnet)、应用层(面向用户,Http);TCP/IP四层模型:网络接口层(物理+数据链路)、网络层、传输层、应用层(会话+表示+应用);
TCP连接:Seq序列号、ACK确认序列号,SYN同步序列号,FIN断开标识位;建立连接3次握手:连接请求(客户端发送SYN=a)、请求确认(服务端发送ACK=a+1 SYN=b)、连接确认(ACK=b+1);断开连接4次挥手:主动断开方发送FIN包请求断开、被动断开方发送ACK、被动断开方发送FIN确认断开、主动断开方发送ACK后断开;
幂等性
概念:一次和多次请求某一个资源对于资源本身应该具有同样的结果,简化了客户端实现,让服务端实现更复杂(增加幂等控制逻辑,并发改串行,降低了效率);实现:乐观锁、防重表、分布式锁、token令牌、缓冲区(异步处理,过滤重复)
无状态:有状态服务可以比较容易地实现事务,在不需要考虑水平扩展时,是比较好的选择;无状态服务的优势在于可以很方便地水平伸缩,但是在实现事务时,需要做一些额外的动作,通过session抽离到公共的地方实现;
零拷贝
传统的读写:4次用户态和内核态的切换,4次数据拷贝;mmap:内存映射,用户空间可以共享内核空间的数据,适合小数据量读写,需要4次上下文切换,3次数据拷贝;sendFile:数据不经过用户态,和用户态完全无关,适合大文件传输,需要3次上下文切换,最少2次数据拷贝;零拷贝:是从操作系统的角度来说的,因为内核缓冲区之间,没有数据是重复的;
Keepalived
Keepalived:一种高性能的服务器高可用或热备解决方案,用来防止服务器单点故障,可实现多个Nginx的负载均衡,通过虚拟IP对外提供服务,内部通过VRRP虚拟路由冗余协议将虚拟IP转发到真实的IP;
Nginx/HAProxy/LVS:Nginx/HAProxy工作在第七层,配置安装简单,LVS工作在第四层,配置复杂,F5/Array是商业硬件负载均衡;HAProxy只是负载均衡软件,Nginx还可作为服务器;Nginx可作为LVS的节点实现负载均衡;性能:Array>F5>LVS>Nginx/HAProxy
架构演进
1. Tomcat+DB同机部署,单体应用;问题:随着用户增长,单机的Tomcat和数据库存在资源竞争;2. Tomcat+DB分开部署,单体应用;问题:数据库并发读写成为瓶颈;3. Tomcat+DB+缓存(本地Memcached+分布式Redis),缓存热点数据,减小数据库压力;问题:随着用户增长,单机Tomcat成为瓶颈;4. 引入Nginx负载均衡,部署多台Tomcat;问题:并发量增加,数据库成为瓶颈;5. 使用数据库中间件MyCat实现数据库读写分离;问题:随着业务增加,不同业务竞争数据库资源,相互影响;6. 数据库按业务分库;问题:随着业务增加,单机写库成为瓶颈;7. 分库分表,使用MyCat和业务数据汇总,至此数据库和Tomcat都实现了水平扩展;问题:单点Ngnix成为瓶颈;8. 使用LVS/F5对外提供虚拟IP实现Nginx的负载均衡;问题:单机LVS成为瓶颈;9. DNS服务器配置多个域名实现LVS的负载均衡;问题:随着数据的丰富程度和业务的发展,检索、分析等需求越来越丰富,单靠数据库无法解决;10. 引入NoSQL和搜索引擎HDFS/Hbase/Redis/MongoDB/ES,至此解决了业务维度的扩充;问题:业务应用升级迭代困难;11. 应用拆分,大应用拆小应用,不同应用的公共部分抽成公共服务;问题:服务间调用复杂,逻辑混乱;12. 引入服务总线或API网关;问题:服务太多,部署困难,不能动态扩容;13. 引入容器化技术实现运行环境隔离与动态服务管理;问题:需要自己管理机器,管理本身和运维困难;14. 以云平台承载系统;
ServiceMesh
微服务架构的核心技术包括负载均衡和服务发现,可以通过代理实现,代理分为3种方式:集中式代理(如Nginx、F5)、客户端代理(如Ribbon、Dubbo)、主机独立进程代理(每个部署服务的机器部署代理进程);
服务网格类似于主机独立进程代理,在每个机器上部署代理(sidecar),由sidecar负责服务发现、负载均衡、容错限流等,组成一个服务网络,叫数据平面;同时会有一个控制平面控制流量路由;
Istio专注在控制面板的架构、功能、以及控制面板和数据面板之间API的标准化,它的控制面板功能主要包括:Istio-Manager:负责服务发现,路由分流,熔断限流等配置数据的管理和下发;Mixer:负责收集代理上采集的度量数据,进行集中监控;Istio-Auth:负责安全控制数据的管理和下发;Envoy是目前Istio主力支持的数据面板代理,其它主流代理如nginx/kong等也正在陆续加入这个阵营;kubernetes是目前Isito主力支持的容器云环境;
云计算
云原生:就是土生土长的意思,在开始设计应用的时候就考虑到应用将来是运行云环境里面的,要充分利用云资源的优点,比如️云服务的弹性和分布式优势;云原生=微服务+DevOps+持续交付+容器化;
云计算特征:基于互联网络、按需服务、资源池化、安全可靠、资源可控、快速弹性、按使用付费;云计算技术视角:云计算=计算/存储的网络, 云计算包含两部分:云设备和云服务。云计算商业视角:云计算=信息电厂;云计算演进:并行计算、分布式计算、网格计算;云计算部署模式:私有云、公有云、混合云(企业重要数据放在私有云,计算能力可借助公有云);云计算商务模式:IaaS、PaaS、SaaS、DaaS、BaaS(后端即服务,提供后端服务)、FaaS(函数即服务,提供无服务器计算)、NaaS(网络即服务) ;
计算机知识

大型网站技术架构

网友评论