这本书是2012年的,但讲的都是最基本的原理,到现在还不会过时。
2022-11-27
对一个网站(水平扩展为多个服务器),可以通过SLB(比如nginx)进行负载均衡(负载均衡分为7层和4层)。
nginx的能力是很强的(24GB的服务器,可以支持200万的连接请求)
为了提高nginx可靠性,可以采用双机主备(HA)方案。
为了继续扩展nginx的能力,可以部署多套nginx HA, 然后在DNS中再做一层负载均衡。
备注:nginx 一般支持的是7层代理,支持四层代理一般使用 lvs 或者haprox,但 nginx 从1.9.0 版本开始支持四层代理
nginx 支持四层代理_51CTO博客_nginx四层代理
3.2 CPU并发计算
进程(通过fork这个系统调用创建)
轻量级进程(通过clone这个系统调用创建)
首先说明Linux下的进程与线程比较相近。这么说的一个原因是它们都需要相同的数据结构来表示,即task_struct。区别在于一个有独立的用户空间,一个是共享的用户空间(如果完全没有用户空间则是内核线程,不需要)。
Linux的用户进程不能直接被创建出来,因为不存在这样的API。它只能从某个进程中复制出来,再通过exec这样的API来切换到实际想要运行的程序文件。
复制的API包括三种:fork、clone、vfork。
这三个API的内部实际都是调用一个内核内部函数do_fork,只是填写的参数不同而已。
vfork,其实就是fork的部分过程,用以简化并提高效率。而fork与clone是区别的。fork是进程资源的完全复制,包括进程的PCB、线程的系统堆栈、进程的用户空间、进程打开的设备等。而在clone中其实只有前两项是被复制了的,后两项都与父进程共享。
在四项资源的复制中,用户空间是相对庞大的,如果完全复制则效率会很低。在Linux中采用的“写时复制”技术,也就是说,fork执行时并不真正复制用户空间的所有页面,而只是复制页面表。这样,无论父进程还是子进程,当发生用户空间的写操作时,都会引发“写复制”操作,而另行分配一块可用的用户空间,使其完全独立。这是一种提高效率的非常有效的方法。
而对于clone来说,它们连这些页面表都是与父进程共享,故而是真正意义上的共享,因此对共享数据的保护必须有上层应用来保证。
线程(pthread)
有两种实现( 用户态的线程,不需要内核参与,但在多处理器(smp)中表现差;Linux线程,即轻量级进程,消耗比用户态线程高);Linux下pthread的实现是通过系统调用clone()来实现的。