【问底】夏俊:深入网站服务端技术(一)

注:本文首发于CSDN,转载请标明出处。

【编者按】 本文来自拥有十年IT从业经验、擅长网站架构设计、Web前端技术以及Java企业级开发的夏俊,此文也是《关于大型网站技术演进的思考》系列文章的最新出炉内容,首发于CSDN,各位技术人员不容错过。

以下为正文:

一、 引子

《关于大型网站技术演进的思考》已经连载完了两个系列,它们分别是《存储的瓶颈》和《网站静态化的处理》,这两个系列对应到网站里的组件就是存储端和浏览器端,网站除了这两端外,还有一端那就是服务端了,服务端上接浏览器端,下承存储端,所以当我们想让网站的浏览器端或存储端性能更加优秀的时候,就不得不去考虑服务端的问题,因为服务端和它们永远都是剪不断理还乱的关联性。现在我要开启《关于大型网站技术演进的思考》这个主题下最后一个系列,这个系列就是讨论网站组件里最后一端服务端了,由于服务端和浏览器端以及存储端存在着一种永远都剪不断的关系,所以本系列还会讲解和其他两端相关联的技术,不过本系列的讲述的深度会更高些,希望通过这种深入的研究让我们更加深入的理解那些能作用于浏览器端和存储端的服务端技术,当然服务端除了上接浏览器端,下承存储端作用外,它自身还有自己的技术范畴,那就是如何使用服务端技术实现网站的业务逻辑了,以上这些就是本系列将要讨论的主题了。

本系列大概会按以下思路进行讨论:

当然上面的知识都是我自己多年经验和自己所掌握知识的总结,现在还没有完整的知识雏形,所以在写的过程里很有可能会根据实际情况进行调整,不管最后结果如何,上面的列举的大方向我都会尽力讲到的。

二、关于网站并发的问题

下面就我开始讲服务端和浏览器端相关部分的技术了,首先从网站的并发性开始讲起吧。

1)《关于大型网站技术演进的思考》前两系列的内容

存储的瓶颈和网站静态化处理参见本人的博客。

2)网站并发问题概述

什么是网站的并发?这个问题答案很简单,网站的并发就是指网站在同一个时间可以同时处理多个用户请求。谈到网站的并发,很多朋友很自然的会想到多线程技术,多线程可以使得一个应用程序并行处理多个计算任务,这个技术的作用类推到Web应用里那就是多线程技术可以让网站并行处理多个请求,因此多线程技术是可以用来处理网站的并发问题的。所以当我们要去理解网站的并发问题时候,首先要解决的问题就是如何使用多线程技术。当我们学好了多线程技术,是不是就可以解决网站的并发问题了?回答当然是可以的,不过一个网站对并发的要求绝对不是仅仅要求我们会使用多线程技术那么简单了,当网站并发的问题解决后,我们马上就要面临一个同样迫切的问题了,那就是如何提升网站的并发能力,这个问题落到实处就是如何让网站在有限的系统资源下并发能力变得更强,换句话说就是如何让有限的系统资源下,网站的并发数更大,当网站并发数变大以后,我们又要考虑如何让单个请求处理效率更高。这两个内容就是本篇文章的主题了。

本篇文章主要是谈论如何提升单台服务器的并发能力问题,下一篇文章谈论的是当网站处理用户请求的服务端使用了集群技术后,针对并发的处理会发生怎样的变化呢。

3)多线程技术

并发技术对应的是多线程技术,而多线程技术又是建立在线程技术上,那么我们这里首先谈谈线程技术的问题。

第一步我要做的是明确什么是线程,下面是百度百科里对线程的解释,具体如下:

线程,有时被称为轻量级进程(LightweightProcess,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。

从这个定义里我们知道线程有如下特点:

单个线程就是一个独立的程序执行流,我们在学习计算机语言,写的练习代码都是在一个单线程的场景下进行的,单个线程放到网站并发处理的范畴里,它有个问题是我们一定要注意的,那就是如何提升单个线程的执行效率问题,也就是说我们如何让一个线程运行的更快同时还要让一个线程执行时候所消耗的系统资源更低。为了解决这个问题,我们就要分析下单个线程的运作特点,看看线程运作流程里那些方面会影响到线程的运行效率问题。

线程运作流程很简单,我们使用线程时候首先是创建一个线程,线程创建好以后就是使用它了,线程使用完毕以后就要销毁它了。把这个流程放到请求处理场景里,我们就会发现线程的创建过程和线程的销毁过程其实是和处理请求的逻辑无关,但是一个线程又必须经历这三个阶段,因此线程创建的时间和线程销毁的时间也会被统计到请求处理时间里,那么我们就会想有没有办法可以消除线程创建和销毁所花的时间对请求处理的影响呢?

曾经有人在Linux上做过一个测试,这个测试结果就是一个线程创建和消耗至少要消耗2MB的内存,按照这个结论,如果我们在Linux上创建1000个线程那么系统至少要消耗2G以上的内存,这个消耗是非常惊人,如果我们每次使用一个线程就来个创建销毁,那么请求处理时候就会要新增很多无谓的系统资源消耗,假如碰到服务器系统资源很紧张时候,线程的频繁创建和销毁的过程就会侵占更多系统资源从而影响到线程的执行,这个问题我们又该如何来解决了?

要解决这个问题我们首先要回顾下线程的运作流程,这个结果如下图所示:

这张图不是我们希望看到的,我们希望看到下面这样的流程图,如下图所示:

我们希望请求处理流程只是作用在线程执行这块,那么在实际的生产实践里我们又是如何来解决这个问题了?解决方案就是使用线程池技术,线程池技术就是基于线程创建和销毁操作影响性能的角度来设计的,不过线程池技术并非简单的事先创建好一批线程,然后统一销毁一批线程那么简单,这里我以Java的JDK里自带的线程池技术为例来讲讲关于线程池技术的使用,内容具体如下:

人生就是一次充满未知的旅行,在乎的是沿途的风景,

【问底】夏俊:深入网站服务端技术(一)

相关文章:

你感兴趣的文章:

标签云: