web服务器[通俗易懂]

web服务器

大家好,又见面了,我是全栈君。

        Web服务器由于要同时为多个客户提供服务,就必须使用某种方式来支持这种多任务的服务方式。一般情况下可以有以下三种方式来选择,多进程方式、多线程方式及异步方式。其中,多进程方式中服务器对一个客户要使用一个进程来提供服务,由于在操作系统中,生成一个进程需要进程内存复制等额外的开销,这样在客户较多时的性能就会降低。为了克服这种生成进程的额外开销,可以使用多线程方式或异步方式。在多线程方式中,使用进程中的多个线程提供服务, 由于线程的开销较小,性能就会提高。事实上,不需要任何额外开销的方式还是异步方式,它使用非阻塞的方式与每个客户通信,服务器使用一个进程进行轮询就行了。虽然异步方式最为高效,但它也有自己的缺点。因为异步方式下,多个任务之间的调度是由服务器程序自身来完成的,而且一旦一个地方出现问题则整个服务器就会出现问题。因此,向这种服务器增加功能,一方面要遵从该服务器自身特定的任务调度方式,另一方面要确保代码中没有错误存在,这就限制了服务器的功能,使得异步方式的Web服务器的效率最高,但功能简单,如Nginx服务器。

      由于多线程方式使用线程进行任务调度,这样服务器的开发由于遵从标准,从而变得简单并有利于多人协作。然而多个线程位于同一个进程内,可以访问同样的内存空间,因此存在线程之间的影响,并且申请的内存必须确保申请和释放。对于服务器系统来讲,由于它要数天、数月甚至数年连续不停的运转,一点点错误就会逐渐积累而最终导致影响服务器的正常运转,因此很难编写一个高稳定性的多线程服务器程序。但是,不是不能做到时。Apache的worker模块就能很好的支持多线程的方式。

     多进程方式的优势就在于稳定性,因为一个进程退出的时候,操作系统会回收其占用的资源,从而使它不会留下任何垃圾。即便程序中出现错误,由于进程是相互隔离的,那么这个错误不会积累起来,而是随着这个进程的退出而得到清除。Apache的prefork模块就是支持多进程的模块。

     

    Web服务器总的来说提供服务的方式有三种,多进程方式,多线程的方式,异步方式。其中效率最高的是异步的方式,最稳定的是多进程方式,占用资源较少的是多线程的方式。

1.多进程

       此种架构方式中,web服务器生成多个进程并行处理多个用户请求,进程可以按需或事先生成。有的web服务器应用程序为每个用户请求生成一个单独的进程来进行响应,不过,一旦并发请求数量达到成千上万时,多个同时运行的进程将会消耗大量的系统资源。(即每个进程只能响应一个请求或多个进程对应多个请求)

优点:

  • 最大的优势就在于稳定性,一个进程出错不会影响其它进程。如,服务器同时连接100个请求对就的是100个进程,其中一个进程出错,只会杀死一个进程,还有99个进程继续响应用户请求。每个进程响应一个请求

缺点:

  • 进程量大,进程切换次数过多,导致CPU资源使用效率低,每个进程的地址空间是独立的,很多空间中重复的数据,所以内存使用效率低,进程切换由于内核完成,占用CPU资源。

2.多线程

       在多线程方式中,每个线程来响应一下请求,由于线程之间共享进程的数据,所以线程的开销较小,性能就会提高。

优点:

  • 线程间共享进程数据,每个线程响应一个请求,线程切换不可避免(切换量级比较轻量),同一进程的线程可以共享进程的诸多资源,对内存的需求较之进程有很大下降,读可以共享,写不可以共享

缺点:

  • 线程快速切换时会带来线程抖动,多线程会导致服务器不稳定

3.异步方式

阻塞

    阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。有人也许会把阻塞调用和同步调用等同起来,实际上它们是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。例如,我们在CSocket中调用Receive函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。如果主窗口和调用函数在同一个线程中,除非你在特殊的界面操作函数中调用,其实主界面还是应该可以刷新。socket接收数据的另外一个函数recv则是一个阻塞调用的例子。当socket工作在阻塞模式的时候, 如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。

 

非阻塞

    非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

     一个进程或线程响应多个请求,不需要任何额外开销的,性能最高,占用资源最少。但也有问题一但进程或线程出错就会导致整个服务器的宕机。

转载于:https://my.oschina.net/phybrain/blog/1609679

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/107749.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • mysql字符串拼接的方法_sql中拼接字符串的方法

    mysql字符串拼接的方法_sql中拼接字符串的方法总是记不住字符串拼接,每次都要百度去搜索,所以在这里记录一下,好方便后续的查找,如有错误和问题可以提出,谢谢。字符串拼接分为几种方式,在这里会一一举例写出:第一种:mysql自带语法CONCAT(string1,string2,…),此处是直接把string1和string2等等的字符串拼接起来(无缝拼接哦)说明:此方法在拼接的时候如果有一个值为NULL,则返回NULL…

  • 实对称矩阵_对称矩阵怎么快速求行列式

    实对称矩阵_对称矩阵怎么快速求行列式实对称矩阵有着很好的性质,如果用一句话概括,就是:n阶实对称矩阵必有n个两两正交的实特征向量。百度百科对实对称矩阵的性质描述如下:1.实对称矩阵A的不同特征值对应的特征向量是正交的。2.实对称

  • (已解决)Unexpected token o in JSON at position 1

    (已解决)Unexpected token o in JSON at position 1讲这个问题之前先普及一下JSON.parse()和JSON.stringify()方面的知识:JSON.parse()方法用于将一个JSON字符串转换为对象,如varstr='{"name":"LeonWu","age":"18"}’JSON.parse(str);//结果为一个Object//age:"18";//name:"LeonWu";

    2022年10月17日
  • 【面试】50道经典计算机网络面试题

    【面试】50道经典计算机网络面试题

  • 十进制小数转化为二进制小数[通俗易懂]

    十进制小数转化为二进制小数[通俗易懂]一、二进制数转换成十进制数由二进制数转换成十进制数的基本做法是,把二进制数首先写成加权系数展开式,然后按十进制加法规则求和。这种做法称为”按权相加”法。例如把二进制数110.11转换成十进制数。二、十进制数转换为二进制数十进制数转换为二进制数时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并。1.十进制整数转换为二进制整数十进制整数转换为二进制整数采用”除2取余,逆序排列”法。具体做法是:用2去除十进制整数,可以得到一个商和余数;再

  • mysql怎么创建账户_mysql添加索引

    mysql怎么创建账户_mysql添加索引1.使用root账户登录到mysql:mysql -uroot -p2.创建用户名和密码:grant all on *.* to 用户名@’127.0.0.1′ identified by "密码";3.创建成功后,需设置访问权限。首先切换到mysql数据库:use mysql;4.修改新建用户的权限:update user set host = ‘%’ where user = ‘attckne…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号