python中的数据类类型
Python3 中有六个标准的数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
Python3 的六个标准数据类型中:
- 不可变数据(3 个): Number(数字)、String(字符串)、Tuple(元组);
- 可变数据(3 个): List(列表)、Dictionary(字典)、Set(集合)
Python中存在三种内存回收机制:
1. 引用计数
在python中维护了一个refchain的双向环状链表,这个链表存储程序中创建的所有对象,每种类型的对象都有一个 ob_refcnt 的引用计数器的值,对象被引用,则计数器的值 +1,引用被删除则计数器的值 -1,最后引用计数的值为 0 时,会进行垃圾回收(对象销毁、从refchain中移除),
2. 标记清除
但是,在python中对于那些可以有多个元素组成的对象可能会存在循环引用问题,为了解决这个问题python引入了 标记清除
,在其内部再维护了一个链表,专门放那些可能存在循环引用的对象 (list/tuple/dict/set), 某种情况下
触发,会去扫描 可能存在循环引用的链表
中的每一个元素,检查是否有循环引用,如果有则双方的引用计数器 -1,如果是 0 则垃圾回收,
3. 分代回收
然而,又有一个新的问题产生,就是什么时候扫描?可能存在循环引用的链表扫描代价较大,每次扫描耗时久,所以又引入了 分代回收
,将可能存在循环引用对象维护成 3 个链表,分别是 0代,1代,2代,所有可能存在循环引用的对象都存储在 0代链表,当对象个数达到700个的时候扫描一次,是垃圾则回收,不是则移入 1代,依次类推,0代扫描10次,1代扫描一次,1代扫描10次,2代扫描1次。
多进程、多线程、多协程
1. 多进程
利用CPU多核的能力,真正的并行执行任务,python中有multiprocessing库,适用于CPU密集型计算,
一个运行程序就是一个进程,一个进程至少包含一个线程,进程是由操作系统分配资源,进程之间的内存是相互独立的,如果需要在多个进程间通信的话,可以使用管道/队列/共享内存/信号/linux socket
缺点是占用资源较多
2. 多线程
利用CPU和IO可以同时执行的原理,不会让CPU干巴巴的等待IO完成,python中有threading库,适用于IO密集型计算,
-
线程是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。
-
线程自己不拥有系统资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
这样就会出现内存资源的安全问题,python为了线程安全,就设置了全局解释器锁(GIL)机制,既一个进程中同时只能有一个线程访问cpu
缺点是:
相比进程,多线程只能并发执行,并不能利用多CPU(GIL)
相比协程,启动数目有限制,占用内存资源,有线程切换开销
3. 多协程
协程又称 微线程,在单线程利用CPU和IO同时执行的原理,实现函数异步执行
协程看上去像子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行
协程最大的优势就是有极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。
4. 全局解释器锁
全局解释器锁(Global Interpreter Lock)
同步线程的一种机制,它使得任何时刻仅有一个线程在执行
Python中对象的管理,是使用引用计数器进行的,引用数为0则释放对象,所以为了解决线程之间数据完整性和状态同步问题引入GIL,它简化了python对共享资源的管理,因此多线程一般用于IO密集型计算。
HTTP协议
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP是基于TCP/IP通信协议来传递数据的(HTML 文件, 图片文件, 查询结果等)。
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
1. 请求方法:
常用:
GET(SELECT):从服务器取出资源(一项或多项)。(它本身不会对资源本身产生影响,因此满足 幂等性)
POST(CREATE):在服务器新建一个资源。 (它会对资源本身产生影响,每次调用都会有新的资源产生,因此 非幂等性)
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。(它直接把实体部分的数据替换到服务器的资源,多次调用它,只会产生一次影响,所以满足 幂等性)
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。(非幂等)
DELETE(DELETE):从服务器删除资源。 (调用一次和多次对资源产生影响是相同的,所以也满足 幂等性)不常用:
HEAD:获取资源的元数据。
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的(跨域时易见到)。
幂等性:
HTTP 幂等方法,是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次,还是调用一百次,一千次,结果都是相同的
2. HTTP工作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。
-
客户端向服务器发送一个请求报文,请求报文包含:
- 请求的方法、URL、协议版本、请求头部和请求数据。
-
服务器以一个状态行作为响应,响应的内容包括:
- 协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2、解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
3、浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
5、释放 TCP连接;
6、浏览器将该 html 文本渲染并显示内容;
3. HTTP版本介绍
3.1 HTTP/0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。
3.2 HTTP/1.0
请求行必须在尾部添加协议版本字段(http/1.0);必须包含头消息
在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive。
TCP连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。
为了解决这个问题,有些浏览器在请求时,用了一个非标准的Connection
字段。
3.3 HTTP/1.1
1.1 版的最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive
。解决了1.0版本的keepalive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求;
客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close
,明确要求服务器关闭TCP连接。
目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。降低了延迟同时提高了带宽的利用率。
加入了管道机制,在同一个TCP连接里,允许多个请求同时发送,增加了并发性,进一步改善了HTTP协议的效率;举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
新增了请求方式PUT、PATCH、OPTIONS、DELETE等。
TCP/IP协议
TCP/IP协议在一定程度上参考了OSI的体系结构。OSI模型共有七层,从上到下分别是应用层、表示层、会话层、运输层、网络层、数据链路层、物理层
。但是这显然是有些复杂的,所以在TCP/IP协议中,它们被简化为了四个层次。
(1)应用层、表示层、会话层三个层次提供的服务相差不是很大,所以在TCP/IP协议中,它们被合并为应用层一个层次。
(2)由于运输层和网络层在网络协议中的地位十分重要,所以在TCP/IP协议中它们被作为独立的两个层次。
(3)因为数据链路层和物理层的内容相差不多,所以在TCP/IP协议中它们被归并在网络接口层
一个层次里。只有四层体系结构的TCP/IP协议,与有七层体系结构的OSI相比要简单了不少,也正是这样,TCP/IP协议在实际的应用中效率更高,成本更低。
应用层:直接为应用进程提供服务,对不同种类的应用程序它们会根据自己的需要来使用应用层的不同协议,邮件传输应用使用了SMTP协议、万维网应用使用了HTTP协议,还能加密、解密、格式化数据等。
运输层:TCP和UDP起到了中流砥柱的作用。
网络层:可以进行网络连接的建立和终止以及IP地址的寻找等功能。
网络接口层:由于网络接口层兼并了物理层和数据链路层所以,网络接口层既是传输数据的物理媒介,也可以为网络层提供一条准确无误的线路。
1. TCP和UDP之间的区别
TCP: Transmission Control Protocol 传输控制协议,基于字节流的传输层通信协议
a. 可靠的【确保接收方完全正确地获取发送方所发送的全部数据】
b. 面向连接的【面向连接的协议,数据传输必须建立连接,所以TCP需要连接时间】要任何装饰器
c. 数据传输的效率较低
d. 传输数据大小限制,一旦连接建立,双方可以按统一的格式传输大的数据UDP: Transmission Control User Datagram Protocol的简称,用户数据包协议,提供面向事务的简单不可靠信息传送服务
a. 不可靠的【所发送的数据报并不一定以相同的次序到达接收方,UDP将数据包发送给对方,对方不一定能接受到】,比如:飞秋
b. 无连接的【每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接】
c. 效率高,速度快
d. UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内
2. TCP/IP协议三次握手和四次挥手
三次握手:
概念:指在发送数据的准备阶段,服务器和客户端之间需要三次 第一次握手:建立连接时,客户端向服务器发送一个SYN包,并进入SYN_SENT状态,等待服务器确认 第二次握手:当服务器收到客户端的请求后,此时要给客户端给一个确认信息ACK,同时发送SYN包,此时服务器进入 SYN_RECV状态 第三次握手:客户端收到服务器发的ACK+SYN包后,向服务器发送ACK,发送完毕之后,客户端和服务器进入 ESTABLISHED(TCP连接成功)状态,完成三次握手socket里面的客户端的connect + 服务端的accept 就实现了三次握手
四次挥手:
概念:四次挥手就是说关闭TCP连接的过程,当断开一个TCP连接时,需要客户端和服务器共发送四个包确认 第一次挥手:客户端发送一个FIN,用来关闭客户端到服务器的数据传输,客户端进入FIN_WAIT_1状态 第二次挥手:服务器收到FIN后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序 号),服务器进入CLOSE_WAIT状态 第三次挥手:服务器发送一个FIN,用来关闭服务器到客户端的数据传输,服务器进入LAST_ACK状态 第四次挥手:客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个AKC给服务器,确认序号为收到序号+1,服务器进入CLOSED状态,完成四次挥手socket里面的客户端的colse和服务端(conn)的colse实现四次挥手
3. socket
socket就是做网络通信用的
所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响应,按照http协议的请求协议发送请求,服务端按照http协议的响应协议来响应请求,这样的网络通信,我们就可以自己实现Web框架了。
socket参数的详解:
socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)# 创建socket对象的参数说明:
family | 地址系列应为AF_INET(默认值),AF_INET6,AF_UNIX,AF_CAN或AF_RDS。 (AF_UNIX 域实际上是使用本地 socket 文件来通信) |
---|---|
type | 套接字类型应为SOCK_STREAM(默认值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。 SOCK_STREAM 是基于TCP的,有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料传送。 SOCK_DGRAM 是基于UDP的,无保障的面向消息的socket,多用于在网络上发广播信息。 |
proto | 协议号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议应为CAN_RAW或CAN_BCM之一。 |
fileno | 如果指定了fileno,则其他参数将被忽略,导致带有指定文件描述符的套接字返回。 与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复的。 这可能有助于使用socket.close()关闭一个独立的插座。 |
server.py
import socketsk = socket.socket() # 创建一个server端的对象
sk.bind(('127.0.0.1',9001)) # 给server端绑定一个地址
sk.listen() # 开始监听(可以接收)客户端给我的连接了conn,addr = sk.accept() # 建立连接 conn是连接
conn.send(b'hello') # 发送消息
msg = conn.recv(1024) # 接收消息
print(msg)
conn.close() # 关闭连接sk.close()
client.py
import socketsk = socket.socket()
sk.connect(('127.0.0.1',9001))msg = sk.recv(1024)
print(msg)
sk.send(b'byebye')sk.close()
MysQL 优化
MySQL 优化主要有以下几个方面:
设计:存储引擎、字段类型
功能:索引、缓存、分区分表
架构:主从复制、读写分离、负载均衡
合理SQL:SQL语句优化
1. 存储引擎
在创建表的时候我们使用sql语句,Create table tableName () engine=myisam|innodb;
这里就指明了存储引擎是myisam还是innodb。存储引擎是一种用来存储MySQL中对象(记录和索引)的一种特定的结构(文件结构),处于MySQL服务器的最底层,直接存储数据。导致上层的操作,依赖于存储引擎的选择。
本质:存储引擎就是特定的数据存储格式(方案)。
可以使用 show engines
命令来查看当前MySQL支持的存储引擎列表。
1.1 InnoDB
Mysql版本>=5.5 默认的存储引擎,MySQL推荐使用的存储引擎。支持事务,行级锁定,外键约束。事务安全型存储引擎。更加注重数据的完整性和安全性。
1.1.1 存储格式
数据、索引集中存储,存储于同一个表空间文件中。
数据:记录行。
索引:一种检索机制,也需要一定的空间,就相当于一本字典的目录。
1.1.2 数据按照主键顺序存储
插入数据时做排序工作,效率低。
1.1.3 特定功能
事务、外键约束:都是为了维护数据的完整性。
并发性处理:
nnodb擅长处理并发的。因为它使用了行级锁定,只该行锁了,其它行没有锁。
行级锁定: row-level locking,实现了行级锁定,在一定情况下,可以选择行级锁来提升并发性。也支持表级锁定,Innodb会自带锁,不需要我们自己设置。
1.1.4 总结
innodb擅长事务、数据的完整性及高并发处理,不擅长快速插入(插入前要排序,消耗时间)和检索。
1.2 MyISAM
MySQL<= 5.5 MySQL默认的存储引擎。
ISAM:Indexed Sequential Access Method索引顺序存取方法的缩写,是一种文件系统。
擅长与处理,高速读与写。
1.2.1 存储方式
数据和索引分别存储于不同的文件中。
1.2.2 数据的存储顺序为插入顺序(没有经过排序)
插入速度快,空间占用量小。
1.2.3 功能
a.全文索引支持。(mysql>=5.6时innodb 也支持)
b.数据的压缩存储。.MYD文件的压缩存储。
- 压缩优势:节省磁盘空间,减少磁盘IO开销。
- 特点:压缩后的表变成了只读表,不可写。如果需要更新数据,则需要先解压后更新。利用工具:myisamchk –unpack 表名 进行解压
c.并发性:
-
仅仅支持表级锁定,不支持高并发。
-
支持并发插入。写操作中的插入操作,不会阻塞读操作(其他操作)
1.3 关于Innodb 和myisam的取舍
Innodb :数据完整性,并发性处理,擅长更新,删除。
myisam:高速查询及插入。擅长插入和查询。
具体举例:那么对于微博项目来看,选择哪一个存储引擎呢?
a.微博主要是插入微博和查询微博列表,较为适合MyISAM;
b.微博在更新微博和删除微博,要少的多,较为适合MyISAM;
c.对数据完整性的需求并没有那么强烈,比如用户删除微博,关联的转播和评论并不要求都做相应的行为,较为适合MyISAM;
那么对于记账财务系统,选择哪一款存储引擎呢?
a.财务系统除了读取和插入,经常要进行数据的修改和删除,较为适合InnoDB;
b.在进行财务变更的时候,如果失败需要回滚必须用到事务,较为适合InnoDB;
c.每个用户的财务数据完整性和同步性非常重要,需要外键支持,否则财务将会混乱,较为适合InnoDB。
1.4 锁的概念
当客户端操作表(记录)时,为了保证操作的隔离性(多个客户端操作不能互相影响),通过加锁来处理。
操作方面:
读锁:读操作时增加的锁,也叫共享锁,S-lock。特征是阻塞其他客户端的写操作,不阻塞读操作。(并发读)
写锁:写操作时增加的锁,也叫独占锁或排他锁,X-lock。特征是阻塞其他客户端的读、写操作。
锁定粒度(范围):
行级:提升并发性,锁本身开销大
表级:不利于并发性,锁本身开销小。
2. 字段类型选择
字段类型应该要满足需求,尽量要满足以下需求。
尽可能小(占用存储空间少)、尽可能定长(占用存储空间固定)、尽可能使用整数。
3. 索引
3.1 索引概述
利用关键字,就是记录的部分数据(某个字段,某些字段,某个字段的一部分),建立与记录位置的对应关系,就是索引。索引的关键字一定是排序的。索引本质上是表字段的有序子集,它是提高查询速度最有效的方法。一个没有建立任何索引的表,就相当于一本没有目录的书,在每次查询时就会进行全表扫描,这样会导致查询效率极低、速度也极慢。如果建立索引,那么就好比一本添加的目录,通过目录的指引,迅速翻阅到指定的章节,提升的查询性能,节约了查询资源。
3.2 索引使用原则
a、不要过度索引。索引越多,占用空间越大,反而性能变慢;
b.只对WHERE子句中频繁使用的建立索引;
c.尽可能使用唯一索引,重复值越少,索引效果越强;
d.使用短索引,如果char(255)太大,应该给它指定一个前缀长度,大部分情况下前10位或20位值基本是唯一的,那么就不要对整个列进行索引;
e.充分利用左前缀,这是针对复合索引,因为WHERE语句如果有AND并列,只能识别一个索引(获取记录最少的那个),索引需要使用复合索引,那么应该将WHERE最频繁的放置在左边。
f.索引存在,如果没有满足使用原则,也会导致索引无效:
4. 查询缓存query_cache
开启MySQL的查询缓存,当执行完全相同的SQL语句的时候,服务器就会直接从缓存中读取结果,当数据被修改,之前的缓存失效,修改比较频繁的表不适合做查询缓存
5. 分区分表
日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。
5.1 分区
partition,分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字,db自动去组织分区的数据。
注意:分区与存储引擎无关,是MySQL逻辑层完成的
5.1 分表
分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表可以分布在同一块磁盘上,也可以在不同的机器上。app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它。分表技术是比较麻烦的,需要手动去创建子表,app服务端读写时候需要计算子表名。采用merge好一些,但也要创建子表和配置子表间的union关系。(需要手动分表)
分表是分区之前用的,MYSQL5.1后,就开始用分区代替分表了。分表很少用了。
水平分表:创建结构相同的N个表
垂直分表:
一张表中存在多个字段。这些字段可以分为常用字段和非常用字段,为了提高查表速度,我们可以把这两类字段分开来存储。主要目的,减少每条记录的长度。
通常我们按以下原则进行垂直拆分:把不常用的字段单独放在一张表;把text,blog等大字段拆分出来放在附表中;经常组合查询的列放在一张表中;
6. 服务器架构
服务器架构,不仅仅是用一台MySQL
6.1 主从复制:
Mysql服务器内部支持复制功能,仅仅需要通过配置完成下面的拓扑结构。一主多从典型结果:主服务器负责写数据。从服务器负责读数据。复制功能mysql会自带。
6.2 读写分离,负载均衡:
不再操作MYSQL数据库服务器,而是去操作读写分离、负载均衡服务器,只要服务器安装了mysql proxy或Ameoba软件就可以实现读写分离和负载均衡,读写分离是指该服务器会判断客户端的操作是读还是写,从而选择操作mysql主服务器还是从服务器。负载均衡算法是指,客户端读操作时,该服务器会根据取余算法去选择一台从服务器。
python高并发
高并发的接口/系统有一个共同的特性,那就是”快”。
在系统其它条件既定的情况下,系统处理请求越快,用户得到反馈的时间就越短,单位时间内服务器能够处理请求的数量就会越多。所以”快”几乎可以算是高并发系统的要满足的必要条件,要评估一个系统性能如何,某次优化是否提高系统的容量,”快”是一个很直观的衡量标准。
高并发系统设计原则:
- 高并发的接口:一个接口负责的功能越少,读取信息量越少,速度越快
- nginx 本身支持高并发,代理实现负载均衡
通过配置完成下面的拓扑结构。一主多从典型结果:主服务器负责写数据。从服务器负责读数据。复制功能mysql会自带。
6.2 读写分离,负载均衡:
不再操作MYSQL数据库服务器,而是去操作读写分离、负载均衡服务器,只要服务器安装了mysql proxy或Ameoba软件就可以实现读写分离和负载均衡,读写分离是指该服务器会判断客户端的操作是读还是写,从而选择操作mysql主服务器还是从服务器。负载均衡算法是指,客户端读操作时,该服务器会根据取余算法去选择一台从服务器。
python高并发
高并发的接口/系统有一个共同的特性,那就是”快”。
在系统其它条件既定的情况下,系统处理请求越快,用户得到反馈的时间就越短,单位时间内服务器能够处理请求的数量就会越多。所以”快”几乎可以算是高并发系统的要满足的必要条件,要评估一个系统性能如何,某次优化是否提高系统的容量,”快”是一个很直观的衡量标准。
高并发系统设计原则:
- 高并发的接口:一个接口负责的功能越少,读取信息量越少,速度越快
- nginx 本身支持高并发,代理实现负载均衡