传奇客户端闪退问题端的问题

【问底】夏俊:深入网站服务端技术(一)----网站并发的问题
发表于 10:30|
来源作者投稿|
摘要:本文来自拥有十年IT从业经验、擅长网站架构设计、Web前端技术以及Java企业级开发的夏俊,此文也是《关于大型网站技术演进的思考》系列文章的最新出炉内容,首发于CSDN,各位技术人员不容错过。
注:本文首发于CSDN,转载请标明出处。
【编者按】 本文来自拥有十年IT从业经验、擅长网站架构设计、Web前端技术以及Java企业级开发的夏俊,此文也是《关于大型网站技术演进的思考》系列文章的最新出炉内容,首发于CSDN,各位技术人员不容错过。
以下为正文:
《关于大型网站技术演进的思考》已经连载完了两个系列,它们分别是《存储的瓶颈》和《网站静态化的处理》,这两个系列对应到网站里的组件就是存储端和浏览器端,网站除了这两端外,还有一端那就是服务端了,服务端上接浏览器端,下承存储端,所以当我们想让网站的浏览器端或存储端性能更加优秀的时候,就不得不去考虑服务端的问题,因为服务端和它们永远都是剪不断理还乱的关联性。现在我要开启《关于大型网站技术演进的思考》这个主题下最后一个系列,这个系列就是
讨论网站组件里最后一端服务端了,由于服务端和浏览器端以及存储端存在着一种永远都剪不断的关系,所以本系列还会讲解和其他两端相关联的技术,不过本系列的讲述的深度会更高些,希望通过这种深入的研究让我们更加深入的理解那些能作用于浏览器端和存储端的服务端技术,当然服务端除了上接浏览器端,下承存储端作用外,它自身还有自己的技术范畴,那就是如何使用服务端技术实现网站的业务逻辑了,以上这些就是本系列将要讨论的主题了。
本系列大概会按以下思路进行讨论:
首先是从和浏览器端相连的服务端技术讲起,这块知识映射到MVC模式那就是控制层的相关技术,这里主要包含:并发性,并发和集群的问题,HTTP协议的转化问题等等,最后我将以MVC里C层即控制层的作用来总结下这块的技术;
接下来就是讲解服务端实现业务逻辑层的技术,这个映射到MVC模式就是M层即模型层的问题了,这里面我不会去讨论如何使用服务端技术写业务逻辑,而是以模型层和控制层关系的角度、模型层和存储层关系的角度以及模型层的服务治理的角度来讨论模型层架构设计的问题;
然后就是服务端和存储端相关的技术了,这里面主要就是我在存储瓶颈系列里提到的数据访问层,该层的作用是为了迁移存储层的计算功能,从而达到减轻存储层系统压力的目的,上面内容讲完以后我会参照以上的技术总结下大型网站分布式系统和网站SOA应用的特点。
当然上面的知识都是我自己多年经验和自己所掌握知识的总结,现在还没有完整的知识雏形,所以在写的过程里很有可能会根据实际情况进行调整,不管最后结果如何,上面的列举的大方向我都会尽力讲到的。
二、关于网站并发的问题
下面就我开始讲服务端和浏览器端相关部分的技术了,首先从网站的并发性开始讲起吧。
1)《关于大型网站技术演进的思考》前两系列的内容
存储的瓶颈和网站静态化处理参见本人的
2)网站并发问题概述
什么是网站的并发?这个问题***很简单,网站的并发就是指网站在同一个时间可以同时处理多个用户请求。谈到网站的并发,很多朋友很自然的会想到多线程技术,多线程可以使得一个应用程序并行处理多个计算任务,这个技术的作用类推到Web应用里那就是多线程技术可以让网站并行处理多个请求,因此多线程技术是可以用来处理网站的并发问题的。所以当我们要去理解网站的并发问题时候,首先要解决的问题就是如何使用多线程技术。当我们学好了多线程技术,是不是就可以解决网站的并发问题了?回答当然是可以的,不过一个网站对并发的要求绝对不是仅仅要求我们会使用多线程技术那么简单了,当网站并发的问题解决后,我们马上就要面临一个同样迫切的问题了,那就是如何提升网站的并发能力,这个问题落到实处就是如何让网站在有限的系统资源下并发能力变得更强,换句话说就是如何让有限的系统资源下,网站的并发数更大,当网站并发数变大以后,我们又要考虑如何让单个请求处理效率更高。这两个内容就是本篇文章的主题了。
本篇文章主要是谈论如何提升单台服务器的并发能力问题,下一篇文章谈论的是当网站处理用户请求的服务端使用了集群技术后,针对并发的处理会发生怎样的变化呢。
3)多线程技术
并发技术对应的是多线程技术,而多线程技术又是建立在线程技术上,那么我们这里首先谈谈线程技术的问题。
第一步我要做的是明确什么是线程,下面是百度百科里对线程的解释,具体如下:
线程,有时被称为轻量级进程(Lightweight&Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
从这个定义里我们知道线程有如下特点:
特点一:线程是进程的一个实体,也就是说线程的母体是进程,这是线程的范畴问题。
特点二:线程是轻量级的,它自己不拥有系统资源,但是我们知道线程执行时候是可以操作硬盘的文件,也可以操作内存的数据,那么这些被线程操作的资源从哪里来的呢?上面的解释里回答了这个问题,那就是线程可以共享进程的资源,换句话说线程操作的资源是进程的资源。
特点三:线程自己也有寄存器和堆栈,这些东西本身也是可以存储数据的,数据也是要占用系统的部分资源,那么这个解释也就说明,线程本身也是可以占一定系统资源了,只不过这个资源比较少而已,所以这个解释就补充了特点二的场景:线程操作的资源除了它所在进程的资源外还有它自身能控制的资源,这一点比较重要,我会在后面讲线程安全问题里提到线程自有资源的使用问题的。
单个线程就是一个独立的程序执行流,我们在学习计算机语言,写的练习代码都是在一个单线程的场景下进行的,单个线程放到网站并发处理的范畴里,它有个问题是我们一定要注意的,那就是如何提升单个线程的执行效率问题,也就是说我们如何让一个线程运行的更快同时还要让一个线程执行时候所消耗的系统资源更低。为了解决这个问题,我们就要分析下单个线程的运作特点,看看线程运作流程里那些方面会影响到线程的运行效率问题。
线程运作流程很简单,我们使用线程时候首先是创建一个线程,线程创建好以后就是使用它了,线程使用完毕以后就要销毁它了。把这个流程放到请求处理场景里,我们就会发现线程的创建过程和线程的销毁过程其实是和处理请求的逻辑无关,但是一个线程又必须经历这三个阶段,因此线程创建的时间和线程销毁的时间也会被统计到请求处理时间里,那么我们就会想有没有办法可以消除线程创建和销毁所花的时间对请求处理的影响呢?
曾经有人在Linux上做过一个测试,这个测试结果就是一个线程创建和消耗至少要消耗2MB的内存,按照这个结论,如果我们在Linux上创建1000个线程那么系统至少要消耗2G以上的内存,这个消耗是非常惊人,如果我们每次使用一个线程就来个创建销毁,那么请求处理时候就会要新增很多无谓的系统资源消耗,假如碰到服务器系统资源很紧张时候,线程的频繁创建和销毁的过程就会侵占更多系统资源从而影响到线程的执行,这个问题我们又该如何来解决了?
要解决这个问题我们首先要回顾下线程的运作流程,这个结果如下图所示:
这张图不是我们希望看到的,我们希望看到下面这样的流程图,如下图所示:
我们希望请求处理流程只是作用在线程执行这块,那么在实际的生产实践里我们又是如何来解决这个问题了?解决方案就是使用线程池技术,线程池技术就是基于线程创建和销毁操作影响性能的角度来设计的,不过线程池技术并非简单的事先创建好一批线程,然后统一销毁一批线程那么简单,这里我以Java的JDK里自带的线程池技术为例来讲讲关于线程池技术的使用,内容具体如下:
JDK里的线程池对线程池大小的设定使用了两个参数,一个是核心线程个数,一个是最大线程个数,核心线程在系统启动时候就会被创建,如果用户请求没有超过核心线程处理能力,那么线程池不会再创建新线程,如果核心线程个数已经处理不过来了,线程池就会开启新线程,新线程第一次创建后,使用完毕后也不是立即对其销毁,也是被会收到线程池里,当线程池里的线程总数超过了最大线程个数,线程池将不会再创建新线程,这种做法让线程数量根据实际请求的情况进行调整,这样既达到了充分利用计算机资源的目的,同时也避免了系统资源的浪费,JDK的线程池还有个超时时间,当超出核心线程的线程在一定时间内一直未被使用,那么这些线程将会被销毁,资源就会被释放,这样就让线程池的线程的数量总是处在一个合理的范围里;如果请求实在太多了,线程池里的线程暂时处理不过来了,JDK的线程池还提供一个队列机制,让这些请求排队等待,当某个线程处理完毕,该线程又会从这个队列里取出一个请求进行处理,这样就避免请求的丢失,jdk的线程池对队列的管理有很多策略,有兴趣的童鞋可以查查百度,这里我还要说的是jdk线程池的安全策略做的很好,如果队列的容量超出了计算机的处理能力,队列会抛弃无法处理的请求,这个也叫做线程池的拒绝策略。
由上面对JDK自带线程池的介绍,我们发现使用线程池我们要考虑如下的问题,具体如下:
问题一:线程池初始化的时候我们到底要事先创建多少个线程放在池子里比较合适。
问题二:线程池初始化时候如果创建的线程过多会有什么问题。
问题三:一台服务器由于受限于自身能力的限制例如CPU的能力,内存的能力等等,那么一台服务器可以创建多少个有效线程的数量其实是有个临界值的,那么当业务方要求创建超出临界值的线程时候我们的处理策略是怎样的呢。
问题三的我在介绍JDK里线程池的设计方案时候已经提到了,解决方法就是当业务方要求超出临界值时候,具体就是超出线程池最大线程数的时候,我们用一个队列先缓存这些请求,等线程池里的线程空闲出来后,再去从队列里取出业务请求交付给线程进行处理。
至于问题一和问题二,这个就和多线程的技术相关了,为了更好的解答它,我这里先来介绍下多线程技术。多线程技术的核心就是让多个线程同时被执行,用户的感受就是计算机可以并行执行计算任务,那么我们首先要理解下多个线程是如何进行并发操作的。具体如下:
一个程序包含两个部分,它们就是计算和存储了,好的程序就和一个活生生的人一样,存储相当于人的臭皮囊也就是身体了,而计算就是人的大脑了,而程序的计算是通过CPU来完成的,所以线程的并行执行效果就是看CPU是如何并行处理多个线程的机制了。那么CPU如何做到并行处理呢?其实CPU并不能做到并行处理,CPU只能一次执行一个计算指令,听到这个回答,我们的头是不是一下子变大了,CPU没法做到并行处理,那我们看到活生生的并行操作到底是怎么回事呢?
线程技术里有个概念叫做时间片,要解释时间片我们就要从进程说起了,当一个进程被操作系统运行时候,CPU会给这个进程分配一段执行时间,当进程里面创建了线程以后,操作系统会把进程分配到的执行时间分成片段赋予给线程,假如进程里只有一个线程,那么这个线程的时间片的长度就和进程的时间段基本一致,如果进程里开启的线程有多个,如果这些线程没有设置什么优先级策略,那么每个线程就会平分到相同的时间片,时间片就是线程被CPU执行的单位时间,当CPU按照时间片规定的时间执行了某个线程后,如果线程的CPU计算没有全部执行完毕,那么CPU就会让线程先挂起来等于是让线程处于一个等待状态,CPU的调度机制找到下一个线程,当下一个线程时间片所规定的时间执行完毕后,CPU就会让这个线程挂起来,再去找第三个线程,这个过程依次进行下去,等进程里开启的线程都执行完毕后,第一个线程才会重新开始执行,这个机制就是线程的轮询机制了,也是我们常说的线程切换机制背后的原理了。该机制可以保障在一个固定时间范围内,所有线程都能得到执行,由于线程的执行速度非常快,所以给用户的感觉就是多个线程是可以并行执行的。
由上面的原理我们来看看这个实例,具体如下:
有一个线程被分配到的时间片长度是10毫秒,如果这个线程没有其他干扰,它执行完毕需要花费50毫秒,那就等于要执行5次时间片,假如我们再新增了一个线程,该线程时间片也是10毫秒,也要执行50毫秒才能执行完毕,那么其中一个线程执行完一次时间片,按照轮询机制另外一个线程也要被执行,最后我们就会发现第一个线程执行时间就变成了100毫秒,如果我们再加上CPU的调度所花的时间,该线程的执行时间就会远远大于100毫秒,虽然100多毫秒人的感官是很难觉察到,但是这个做法毕竟让单个线程的执行效率大幅度降低了,如果我们线程开启的更多,那么单个线程执行效率也就会变得更低。
有了这个结论我们再去看看线程池问题一和问题二,如果我们一开始创建了太多线程,而且这些线程大部分都会被闲置,那么这些闲置的线程就会让有效线程的执行效率大大降低,同时闲置的线程还会消耗系统资源,而这些被消耗的系统资源都没有用到业务处理上,所以成熟的线程池方案就会设计核心线程和最大线程的概念,它们可以让线程池根据实际业务需求和系统负载能力做到动态调节,这样就可以减少开启更多线程影响线程执行效率的问题,也可以让计算机的系统资源得到更加有效的利用。
4)网站的并发与多线程技术
多线程技术可以实现并发操作,网站的并发场景非常适合使用多线程技术,那么我们就先来谈谈如何使用多线程技术来实现网站并发,首先我们从单个网站请求处理场景开始说起吧。
单个网络请求是从浏览器端发送,通过网络传输到服务端,服务端接收到数据后进行处理,处理完毕后服务端再把响应通过网络发送给浏览器端。而这个过程都是使用服务端一个线程全程陪同的完成,这个做法似乎没什么问题,这里我先给大家看一个表格,这个表格是Node.js&的作者&Ryan&Dahl&为&JSConf&大会所作的演讲里提供的,具体如下所示:
CPU&调用周期
CPU一级缓存
CPU二级缓存
从这个表格里我们发现,网络IO的处理时间是CPU一级缓存处理时间的一亿倍,假如我们把CPU一级缓存的处理速度等同于CPU的计算速度,这里我假设CPU执行时间是1毫秒,那么当一个线程里有网络操作时候,CPU要等待将近1亿毫秒的时间才被执行,这1亿毫秒时间里CPU不知道可以做多少事情啊。
我们再以Java的网络编程为例进一步说明这个问题,网站的网络传输协议是HTTP协议,HTTP协议使用的是TCP协议进行网络通讯的,java里使用socket技术来编写TCP通讯程序,最基本的socket编程里当客户端有数据传递到服务端后,服务端的ServerSocket就会开启一个线程处理这个请求了,但是服务端的处理需要客户端把全部数据传输完毕后才能做后续处理,所以当客户端数据还没传输完毕,处理线程就要在哪里等待数据传输完毕,我们由上表可以知道线程的等待时间相对于CPU执行时间是何等长了,等待的线程什么都没有做的时候还要参入线程的轮询处理里,因此它还会影响其他线程的执行效率。单个服务器本身所能承载的线程数量是有限的,假如某个线程就这样的被闲置起来就会导致线程的利用率十分低下。这些问题我们到底该如何来解决了?
5)如何提升线程的使用效率?
要解答标题的问题,我们首先要分析下网站请求的特点,网站的请求其实包含两个操作步奏,这两个步奏分别是IO操作和CPU操作,而线程的作用主要是体现在CPU的操作上,如果我们在一个线程里包含IO操作和CPU操作,特别是使用到很慢的网络IO操作时候,那么IO操作的效率就会影响到CPU操作的执行效率,如果我们能把这两个操作***开来,让线程只去关心CPU操作,这样单个线程就能被更加充分的利用起来,可是IO操作毕竟是请求操作里不可分割的操作,那么我们到底该如何破这个局了?
破这个局的方法就是使用赫赫有名的reactor设计模式,我们来看看reactor模式的设计图,如下图所示:
reactor模式里有一个组件就是reactor组件,它其实是一个单独的线程,客户端的请求首先是发送到服务端的reactor线程进行处理,reactor线程采取轮询的方式轮询客户端的请求,当它发现某一个请求的数据传输完毕后,reactor就以事件通知的方式从线程池里取出一个线程进行后续处理,这样线程池里的每个线程都能被充分的使用。
我们再仔细分析下reactor模式,我们发现啊,reactor模式其实并没有提升一个请求的整体运行效率,而是把请求里效率最低的IO操作和CPU计算操作分成两步进行执行,这个方式就等于是把同步请求操作成了一个异步执行操作,虽然该方式没有提升请求整体的处理效率,但是它能让服务端的线程利用率更高,这也就变相的让网站的并发处理能力增强了,而且该方式可以避免线程被闲置在那里空转的问题,假如我们能有效的控制好线程的合理数量,那么该方式还是有可能提升单个请求的执行效率的。
Reactor模式处理请求的模式和上节里讲到请求处理模式,它们的核心问题都是发生在请求的IO处理问题上,所以上节的IO处理场景在java技术领域里有个专有名词表述那就是BIO,中文解释就是阻塞的IO,这个阻塞的含义就是指当一个IO操作执行时候它会独占IO处理的线程,其他IO操作就被此IO操作阻塞起来,而Reactor模式下的IO操作在java技术里也有个专有名词那就是NIO,NIO最早出现在JDK1.4版,当时官方解释是New&IO,通过我们上面的论述我们发现NIO其实是针对BIO的阻塞问题设计的,所以我们习惯把NIO称之为非阻塞IO,非阻塞IO操作不会阻塞线程的操作。
古老的Apache服务器和java里的tomcat容器新版本都采取了NIO技术,但是Apache和它同类型的ngnix服务器相比,所能承载的并发能力实在差太多了,实际场景下Apache能支持5000个并发就要惊为天人了,而ngnix官方文档里就说它可以支持5万并发,而实际场景里支持3万并发那是一点问题都没有的。为什么ngnix可以达到如此高的性能呢?它有什么独门绝技呢?
6)C10K的目标
业界有一个C10K的目标,所谓c10k问题,指的是服务器同时支持成千上万个客户端的问题,也就是concurrent&10&000&connection(这也是c10k这个名字的由来)。
我们想让Apache同时支持上万并发这个在实际场景下是一件基本无法完成的事情,听到我的说法不知道会不会有朋友不服气,我要是把服务器的配置搞得高高的,我就不信Apache不能支持上万并发,如果我们这么做了我们就会发现服务器硬件的提升并不能导致Apache并发能力的线性提升,假如我们设定Apache在5000并发下我们通过增加硬件性能可以近似的提升Apache的并发能力,当Apache并发达到5000后,我们再把硬件性能提升一倍,最终我们一定会发现Apache的并发数并不会变成1万,它能支持到7000以上就谢天谢地了,而且Apache的并发越高,其单个连接的处理性能下降的也非常厉害。而这个场景迁移到ngnix上,结果就大不相同了,ngnix基本可以做到硬件性能提升,其并发性能也能达到线性提升的目的。
由此可见ngnix实在太优秀了,它到底用什么独门秘籍了?大家是不是很急迫的想知道了,下面我就来讲讲ngnix的设计思想了。
首先我们要分析下多线程做并发的问题,线程本身是要消耗系统资源的,如果我们开启线程很多,计算机就得抽取更多资源维护这些线程,所以线程越多浪费掉的系统资源也就更多,这是多线程做并发的第一个问题。多线程做并发第二个问题就是多线程的并行处理机制了,线程的并发要通过线程轮询或者说线程切换来保证,而线程的切换会影响单个线程的执行效率,而且CPU管理线程切换也会消耗CPU的计算能力,所以当我们线程开启的越多,单个线程的执行效率也会随之下降。这也就是Apache容器在高并发下表现出来的问题。
明确了问题,解决方法就出来了,我们如果想让线程执行效率更高我们就不要创建太多线程,这样就可以减少维护线程的开销,同时也能减少线程切换的开销,最理想的方案是我们只使用一个线程来处理所有并发,如果一个线程可以处理好所有并发,那么线程的开销问题就基本可以忽略不计了。按照这个思路我们就要抛弃多线程处理并发的思路了,这样的想法咋一看是不是有点毁人三观了。那么一个线程到底可不可以处理并发了?问题的***是肯定的。
这里我先不讲解ngnix的设计,我们先讲讲Node.js技术,Node.js作者之所以要创建Node.js,源自于他对如何设计一个高效的Web容器的思考,他认为高效的Web容器要采取异步机制,事件驱动机制和非阻塞的IO处理,看到这个描述我们发现这个和我前面讲到reactor模式是何其的相似,但是Node.js在异步机制和事件驱动做的比上面的reactor模式方案更加优秀,在网络IO处理上,Node.js和reactor模式基本一致,在Node.js有一个专门的模块异步处理IO操作,不过Node.js对IO操作已经完成的请求的后续处理就和reactor模式大不相同了,Node.js只用一个线程完成这个请求的后续处理,这个线程处理请求的方式借鉴了多线程里并行处理的原理,因为请求最耗时的IO操作被抽取出来异步处理,所以处理后续请求的单线程只需要执行请求环节里效率最高的部分,这就让每个请求的处理速度变得非常快了,人眼基本感觉不出这个顺序性操作,不过Node.js单线程处理请求的方式和多线程的轮询机制是不太一样的,首先轮询本身的效率是很低下的,为了轮询,操作系统把线程拆分成若干个步奏执行,这个做法就增加了我们对多线程处理的难度,如果碰到不同线程操作一个共享资源,因为步奏的拆分就很有可能产生错误的操作共享资源的行为,这也就是线程安全问题的源头了,这个问题我后面会将详细讨论,这里就不展开论述了。Node.js吸取了多线程方案的经验教训,它没有采取轮询方式处理请求,而是以队列方式一个个执行请求,这样就可以充分利用CPU的操作时间,同时也规避了线程安全的问题,而且采取这个方式,当一个请求到达服务端后服务端增加的系统资源消耗基本和请求本身的系统资源消耗一致,所以和Node.js机制类似的ngnix服务器当并发上去后,请求处理性能也不会像Apache那样陡降下去。
不过Node.js处理机制里还有一个细节我们要特别注意下,那就是异步IO操作如何和主线程处理协同起来的,也就是当IO处理完毕后我们如何把后续操作插入到主线程下,这个问题看起来很简单,我们直接把新的请求放到请求队列的最后不就行了吗,那么问题来了,这个问题就和Ajax技术的问题类似,Ajax可以异步请求,但是因为请求要通过网络给服务端处理,所以Ajax从开始执行到最后获取响应处理响应结果之间就存在很大的时间差,而这个时间差是很难把控的,也许有时是1秒,有时就变成了3秒,如果我们简单把结果代码放在Ajax处理后面,那么我们只能烧香拜佛希望响应能在代码执行到结果处理位置时候到达,那么Ajax技术是如何解决这个问题呢?Ajax使用回调函数机制来破这个题,当服务端响应完全返回到客户端后,javascript里有相关的事件就会通知回调函数马上执行,这其实就把请求发送和响应处理做成了一个异步模式,这也就是Node.js解释里提到的异步机制和事件驱动了,异步机制其实就是指的是回调函数的使用,这个机制放到Node.js对主线程请求队列的操作里,那就是异步IO处理完毕后,事件机制就会把请求后续操作以回调函数的方式放在请求队列的后面,这样就能有效的保证请求处理的时序性了。
Ngnix的设计思想和Node.js的设计思想类似,不过ngnix使用的不是谷歌的V8引擎完成这个机制的,而是直接使用操作系统的类似机制完成,所以ngnix的并发能力比Node.js会强很多,它和Apache相比那就是质的飞越了。
好了,本篇内容讲完了,下篇文章我开始再补充下单台服务器并发处理的内容,之后我就要讨论并发和集群之间的问题了。
(责编/钱曙光)
作者简介:夏俊,拥有十年的IT从业经验,擅长的技术领域有网站的架构设计、Web前端技术以及java企业级开发,热爱技术,喜欢分享自己的技术研究成果和经验
由“2015 OpenStack技术大会”、“2015 Spark技术峰会”、“2015 Container技术峰会”&所组成的&大会于4月17-18日在北京召开。
!懂行的人都在这里!(票价期,速来)
更多《问底》内容:
《问底》是CSDN云计算频道新建栏目,以实践为本,分享个人对于新时代软件架构与研发的深刻见解。在含有“【问底】”字样标题的文章中,你会看到某个国外IT巨头的架构分享,会看到国内资深工程师对某个技术的实践总结,更会看到一系列关于某个新技术的探索。
《问底》邀请对技术具有独特/深刻见解的你一起打造一片只属于技术的天空,详情可邮件至。
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章http状态码汇总及问题经验总结
投稿:mdxy-dxy
字体:[ ] 类型:转载 时间:
网站的http状态对于网站维护人员来说是相当重要的,当网站出现问题的时候,我们首先要诊断一下网站的http状态,从而进一步确认哪里出现的问题
我们经常会遇到404、500、302等提示,它们究竟是什么意思呢?除了这几个常见的状态码外,还有哪些我们没有遇到过的但有可能出现的状态码呢?这里本人做了一个汇总,与大家分享一下。
常见的HTTP错误可以分为以下四大类。每一大类又细分为很多类小错误。当您打不开网站或者打开网站报错时首先检查您输入的网站是否有误,检查网络是否有问题或者DNS是否可以解析。确定没有问题时再看下面http常见错误分析:
1、400错误
问题原因:
您所要打开的网页不存在或你填写的身份验证信息不正确。
解决方法:
重新尝试依然错误后提交工单。
2、401错误
最常见的出错提示:401 UNAUTHORIZED
问题原因:
您试图访问受限页面但未经授权时,网站返回HTTP 401错误。错误登录尝试是导致这一错误的主因。
解决方法:
联系网站管理员获得正确的账户。
提交工单联系技术人员处理。
3、403错误
最常见的出错提示:403 FORBIDDEN
问题原因:
一般是网站没有绑定默认首页或者绑定默认首页错误。
解决方法:
您检查自己程序的默认首页是哪种,后台添加默认首页即可。
4、404错误
最常见的出错提示:404 NOT FOUND
问题原因:
打开网站时找不到你所要求的文件(即网页),该文件可能被移到别的地方去了,或根本就不存在。
解决方案:
(1)请您登陆ftp检查文件或网页是否不存在,把缺少的网页文件恢复到正确的位置。
(2)提交工单恢复您一周内某天的数据。
5、500错误
最常见的出错提示:500 SERVER ERROR
问题原因:
(1)服务器端的网站程序设计有问题并且服务器没有打开详细错误提示。
解决方法:
(1)下载程序到本地,然后检查程序,上传完整正确网站程序。
(2)提交工单联系技术人员处理。
6、503错误
由于程序网站程序配置不兼容等原因造成应用程序池关闭或者是流量用完了。
解决方法:
(1) Linux虚拟主机通过后台重启站点即可恢复正常。如果不行请提交工单。
(2) widows虚拟主机请提交工单联系技术人员处理。
HTTP状态码&&&&&&& 摘要说明
-----------------------------------------------------------------------------------------------------------
成功2XX&&&&&&& 成功处理了请求的状态码。
200&&&&&&&&&&&&&&&&&& 服务器已成功处理了请求并提供了请求的网页。
204&&&&&&&&&&&&&&&&&& 服务器成功处理了请求,但没有返回任何内容。&&&&&&&&&&&&&&&&&&&&&&&&
重定向3XX&&&&& 每次请求中使用重定向不要超过 5 次。
301&&&&&&&&&&&&&&&&&& 请求的网页已永久移动到新位置。当URLs发生变化时,使用301代码。搜索引擎索引中保存新的URL。
302&&&&&&&&&&&&&&&&&& 请求的网页临时移动到新位置。搜索引擎索引中保存原来的URL。
304&&&&&&&&&&&&&&&&&& 如果网页自请求者上次请求后没有更新,则用304代码告诉搜索引擎机器人,可节省带宽和开销。
客户端错误4XX& 表示请求可能出错,妨碍了服务器的处理。
400&&&&&&&&&&&&&&&&&& 服务器不理解请求的语法。
403&&&&&&&&&&&&&&&&&& 服务器拒绝请求。
404&&&&&&&&&&&&&&&&&& 服务器找不到请求的网页。服务器上不存在的网页经常会返回此代码。
410&&&&&&&&&&&&&&&&&& 请求的资源永久删除后,服务器返回此响应。该代码与 404(未找到)代码相似,
但在资源以前存在而现在不存在的情况下,有时用来替代404 代码。如果资源已永久删除,应当使用 301 指定资源的新位置。
服务器错误5XX& 表示服务器在处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
500&&&&&&&&&&&&&&&&&& 服务器遇到错误,无法完成请求。
503&&&&&&&&&&&&&&&&&& 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
详细***:
200& 正常;请求已完成。
201& 正常;紧接 POST 命令。
202& 正常;已接受用于处理,但处理尚未完成。
203& 正常;部分信息 — 返回的信息只是一部分。
204& 正常;无响应 — 已接收请求,但不存在要回送的信息。
3XX& 重定向
301& 已移动 — 请求的数据具有新的位置且更改是永久的。
302& 已找到 — 请求的数据临时具有不同 URI。
303& 请参阅其它 — 可在另一 URI 下找到对请求的响应,且应使用 GET 方法检索此响应。
304& 未修改 — 未按预期修改文档。
305& 使用代理 — 必须通过位置字段中提供的代理来访问请求的资源。
306& 未使用 — 不再使用;保留此代码以便将来使用。
4XX& 客户机中出现的错误
400& 错误请求 — 请求中有语法问题,或不能满足请求。
401& 未授权 — 未授权客户机访问数据。
402& 需要付款 — 表示计费系统已有效。
403& 禁止 — 即使有授权也不需要访问。
404& 找不到 — 服务器找不到给定的资源;文档不存在。
407& 代理认证请求 — 客户机首先必须使用代理认证自身。
415& 介质类型不受支持 — 服务器拒绝服务请求,因为不支持请求实体的格式。
5XX& 服务器中出现的错误
500& 内部错误 — 因为意外情况,服务器不能完成请求。
501& 未执行 — 服务器不支持请求的工具。
502& 错误网关 — 服务器接收到来自上游服务器的无效响应。
503& 无法获得服务 — 由于临时过载或维护,服务器无法处理请求。
504 Gateway Timeout
作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。
注意:某些代理服务器在DNS查询超时时会返回400或者500错误
505 HTTP Version Not Supported
服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。
506 Variant Also Negotiates
由《透明内容协商协议》(RFC 2295)扩展,代表服务器存在内部配置错误:被请求的协商变元资源被配置为在透明内容协商中使用自己,因此在一个协商处理中不是一个合适的重点。
507 Insufficient Storage
服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebD*** (RFC 4918)
508 Loop Detected
服务器发现请求中出现一个无穷循环
509 Bandwidth Limit Exceeded
服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用。
510 Not Extended
获取资源所需要的策略并没有没满足。(RFC 2774)
常见错误的处理方法
500错误是站长经常遇到的问题,就本人的经验,原因及解决方法归纳如下:
1、运行的用户数过多,对服务器造成的压力过大,服务器无法响应,则报HTTP500错误。
这个原因是网站报500错误的最主要原因,很多网站为什么突然会报500错误(service unavailable)呢?90%是由于空间压力过大,超出了空间商设定的上限而造成的。
遇到这个问题,最好是第一时间找到空间商的售后服务,他们一般会帮你回收一下应用程序池,问题便得到解决。如果没有找到售后服务,可以自己在空间管理后台,找到“回收应用程序池”那个项目,自己手动执行一下即可。不过,一些空间管理后台并没有提供该项服务。
2、如果排除了第1的可能性,那么很大原因便是程序上出现了问题。
可以做个简单的测试页面,看是否能运行成功,再检测报错的页面,从而针对性的进行修改。
该做关联的地方没有去做关联,则报HTTP500错误。进行手工或者自动关联,问题得到解决。
3、如果测试中所进行的操作需要向数据库中插入数据,若大数据量的情况下导致数据库中表空间已满,或者缓冲池较小无法满足数据的存取等,都有可能导致HTTP500错误。
解决方法是调整数据库、修改连接池大小等等,根据个人具体情况进行修正即可。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

参考资料

 

随机推荐