hualinux 编程概念 3.4:程序是怎么变慢和崩溃的

 

这章节将概述一下web应用怎么变慢,最后是怎么崩溃的,虽然有点儿开发概念,如果没有看不懂也不关系的。到以后再回看也行,不影响。

我们使用的web服务器,这里主要是指linux服务器,基本上都是多进程或多线程的

nginx在linux上使用的是多进程方式,fork,一个主进程,多个子进程的方式。

tomcat使用的是多线程的方式

执行CPU的最小单位是线程,这些线程共享CPU,逻辑上看,是同时在运行的,每个线程有自己的线程栈,所有的线程栈都是完全隔离的,也就是每个方法的参数和方法内的局部变量都是隔离的,一个线程无法访问到其他线程的栈内数据。

如果有多个线程在同时修改内存堆里的数据的时候,会出现问题,比如,两个线程同时对一个堆中的数据执行 +1 操作,最终这个数据只会被加一次,这就是人们常说的线程安全问题,实际上线程的结果应该是依次加一,即最终的结果应该是 +2。

如果多线程同时修改一个个堆数据就会造成数据出现不可预测的结果,这就是线程安全问题。

ps:没有“进程安全”这概念

在LINUX中,子进程继承父进程的全局变量的值,但是子进程和父进程不是共享同一个全局变量

子进程是完全复制父进程的子进程和父进程对变量只读,也就是说变量不会被改变,这时候,变量表现为共享的,此时物理空间只有一份。如果说父进程或者子进程需要改变变量,那么进程将会对物理内存进行复制,这个时候变量是独立的,也就是说,物理内存中存在两份空间。

多个线程访问共享资源的这段代码被称为临界区,解决线程安全问题的主要方法是使用锁,将临界区的代码加锁,只有获得锁的线程才能执行临界区代码,如下:

lock.lock();  // 线程获得锁
i++;  // 临界区代码,i 位于堆中
lock.unlock();  // 线程释放锁

如果当前线程执行到第一行,获得锁的代码的时候,锁已经被其他线程获取并没有释放,那么这个线程就会进入阻塞状态,等待前面释放锁的线程将自己唤醒重新获得锁。

锁会引起线程阻塞,如果有很多线程同时在运行,那么就会出现线程排队等待锁的情况,线程无法并行执行,系统响应速度就会变慢。此外 I/O 操作也会引起阻塞,对数据库连接的获取也可能会引起阻塞。目前典型的 web 应用都是基于 RDBMS 关系数据库的,web 应用要想访问数据库,必须获得数据库连接,而受数据库资源限制,每个 web 应用能建立的数据库的连接是有限的,如果并发线程数超过了连接数,那么就会有部分线程无法获得连接而进入阻塞,等待其他线程释放连接后才能访问数据库,并发的线程数越多,等待连接的时间也越多,从 web 请求者角度看,响应时间变长,系统变慢。

多进程也差不多的,也有进程锁。有兴趣的可以搜索了解一下。

被阻塞的线程越多,占据的系统资源也越多,这些被阻塞的线程既不能继续执行,也不能释放当前已经占据的资源,在系统中一边等待一边消耗资源,如果阻塞的线程数超过了某个系统资源的极限,就会导致系统宕机,应用崩溃

解决系统因高并发而导致的响应变慢、应用崩溃的主要手段是使用分布式系统架构,用更多的服务器构成一个集群,以便共同处理用户的并发请求,保证每台服务器的并发负载不会太高。此外必要时还需要在请求入口处进行限流,减小系统的并发请求数;在应用内进行业务降级,减小线程的资源消耗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值