关于 web 服务器架构的一点疑问

2022-01-07 15:55:24 +08:00
yezheyu  yezheyu

在传统的 web 架构中,浏览器发送 http 请求,web 服务器返回网页

而在前后端分离架构中,好像多了个前端服务器,我想问下这个前端服务器有什么用?

是接收后端返回的 json 数据,然后渲染成网页,再返回给浏览器吗?

就是说后端服务器只负责处理数据,前端服务器负责渲染成网页是吗?

那 ajax 是不是可以理解为一个微型的前端服务器,接收后端服务器返回的 json 数据,然后渲染到网页上



第二个问题:在下面 web 架构图中,各个软件负责啥工作?

我上面写的流程有问题吗?

现在服务器架构是使用 IO 多路复用 + 线程池处理吗?



6053 次点击
所在节点   程序员  程序员
37 条回复
Donahue
Donahue
2022-01-07 22:24:45 +08:00
@darkengine 我的意思是说 django 内置的 web 服务器是开发调试用的,当你使用 python3 manage.py runserver 0.0.0.0:8000 的时候,启动了 django 内建的 web 服务器, 这个内建的服务器是开发调试用的~django 文档里面写着了。

所以你原来的‘‘web 服务器’’不是必须的这个说法我觉得是不对的~ 它实际上还在

另外,哪怕你用 socket 实现 http 协议,然后处理请求,把所有程序都弄在一起了,那么这个程序本身就是一个 web 服务器了啊,只是没有了上面架构的分层
Donahue
Donahue
2022-01-07 22:26:47 +08:00
@darkengine 内建的 web 服务器也是符合 wsgi 协议的,不然跟 django 框架进行交互的时候就要另外实现一套协议了
kekxv
kekxv
2022-01-07 23:15:58 +08:00
你所谓的 前端服务器( vue 那个)是没有必要的,他所做的事情只是帮你快速编译你的 vue 为浏览器能跑起来的 html ,javascript ,css 代码,实际部署的时候,大多数情况下都是一个服务器,至于上面的人说的,我觉得你还不到理解这个的时候
对了,vue 里面也有一个 proxy 的东东,这个出现的原因最初的原因应该是解决跨域
kekxv
kekxv
2022-01-07 23:18:47 +08:00
另外,我感觉你说的渲染有歧义:
1. 渲染为 html 代码
2. 渲染为实际看到的网页(浏览器干的事情)

我感觉你的意思是第二个,上面的回答都是第一个 🤔️
unco020511
unco020511
2022-01-08 01:52:16 +08:00
这么说吧,前端服务器可以理解为分发静态资源的服务器,你请求后浏览器拿到了 html 模板和 js 代码,然后执行 js,js 会从 api 服务器去拿数据,拿完数据通过操作 dom 来更新页面,你问题的谁来渲染,肯定是浏览器啊
AItsuki
2022-01-08 02:08:08 +08:00
PS:以下 “WEB 服务器”,“前端服务器”,“WEB 应用” 等词汇可能描述不太准确……

WEB 服务器用来存储静态文件,包括 js ,html ,css 等。你浏览器访问 web 服务器其实就是下载这些静态文件,然后交给浏览器执行。所以并不是 web 服务器 --> 访问转发 --> web 应用,而是 浏览器 --> 访问 --> web 应用。

- 浏览器:拉取 url 对应的资源,然后渲染 html 和执行 js
- web 服务器:存放静态资源
- web 应用:处理和响应请求

把你的图片改成下面这样,你估计就比较好理解了:

web 服务器 <——> 浏览器 <——> web 应用

另外,你说的 Vue 前端服务器,实际上就是运行在你本地的一个 web 服务器。
darkengine
2022-01-08 04:58:45 +08:00
@Donahue 已经习惯了把提供接口的后端程序称为“API 服务器”了。。。
yezheyu
2022-01-08 06:13:45 +08:00
@darkengine
@Donahue

多谢你们的解释,对于 django 和 wsgi 服务器的关系我有点理不清,能帮我参考下吗?


django 本身是分为内置开发服务器和 web 应用

内置开发服务器就是一个实现 wsgi 协议的 socket 模块,其作用就是接收 socket IO 事件,然后按 http 协议字段拆分成 environment 参数列表,交给 web 应用

而 web 应用是一个纯粹的处理 env 的数据处理模块,我们编写代码都是在其预留的编程接口上处理数据而已

对于内置的开发服务器,我们可以把它替换成任意一个实现 wsgi 协议的服务器,如 uwsgi


我这样理解对吗?
darkengine
2022-01-08 06:38:23 +08:00
@yezheyu 刚搜了下,发现我之前也有个概念没搞懂,@Donahue 老哥说的是对的。

这样理解就没问题了:

uWSGI 和 Gunicorn 是实现了 WSGI server 协议的服务器

Django ,Flask 是实现了 WSGI application 协议的 web 框架

浏览器 <-http 协议-> nginx(非必要) <-http 协议-> uWSGI/Gunicorn <-WSGI 协议-> Django/Flask

参考: https://blog.css8.cn/post/9378118.html
sudoy
2022-01-08 08:52:21 +08:00
问题:“而在前后端分离架构中,好像多了个前端服务器,我想问下这个前端服务器有什么用?”
回答:我猜楼主应该是刚刚接触前端没多久吧,那就得用初学者的思维跟你讲(没有任何恶意,谁都是从初学者过来的不是吗)。你应该用过 VS code 代码编辑器以及这个编辑器自带的 live server 插件吧,没有用过的话下载一个试试,记得把插件装上去,不会就网上搜索一下,我把 vs code 和那个插件的链接放在最后了。你在桌面建一个文件夹,命名为 test (也可以随意命名,不过建议用字母),然后文件夹里面新建一个叫 index.html 文档,文档里面写以下内容然后保存:

<!DOCTYPE html>
<html>
<body>
<h1>Hello world!</h1>
</body>
</html>


然后你尝试两种方法:
1 )直接把这个 index.html 文档拖到浏览器去;
2 )用 VS Code 打开这个文件夹,然后点击右下角 Go Live ;

你会发现这两种方法都能正常显示你的 html 静态页面。第一种方法就跟用 word 打开 word 文档一样,是直接访问本地文件;第二种方法,就是 vs code 给你搭建一个简易的 http 服务器,然后通过这个服务器来运行你的 html 静态页面。好了,现在回到你的问题,你问题里面的“前端服务器”跟这个编辑器自带的 http 服务器本质上是一样的,他只是 host 你的静态页面而已。

上面是最简单的演示,你也可以在 test 文件夹里面加入 css 和 js 文件,当然 js 文件里面也可以用上 ajax 或者 fetch ,然后在 html 里面引入他们,然后在用以上两种方法操作一遍,你会发现也是一样的。就是说,你可以不用“前端服务器”直接用浏览器打开本地文件,也能搭建一个完整的网页程序。是不是很激动,有没有!有没有!

如果你想在其他电脑访问你这个前端静态页面,你总不能让人家开个 teamviewer 远程访问你这个电脑来查看 web 页面吧。所以“前端服务器”你可以简单理解为,他只是为了方便在任何一台电脑访问你这个前端静态页面。至于把后端数据渲染到 html 页面啥的,那都是浏览器干的事情。我去,一步小心码了这么多字。。。。


VS CODE: https://code.visualstudio.com
Live Server: https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer
seanzxx
2022-01-08 09:22:21 +08:00
前端服务器主要是用来处理静态资源的,比如图片,css ,scripts ,他们一般性能更好,而且静态资源一般不需要状态信息,比如 cookie ,浏览器就不需要发送不需要的信息,简化 http 请求,提高速度

web 服务器(应用服务器)主要是处理动态逻辑的,比如数据库访问
Donahue
2022-01-08 12:28:00 +08:00
@yezheyu 对的,可以看看 django 源码,
django 框架本身是一个 wsgi 协议的 application, django 的作用就是为我们解决了 url 路由等后端开发中常用的组件,以及将 environment 参数列表封装成 request 对象,返回值封装为 response 对象,简化后端开发流程。

启动一个 wsgi 服务器,会实例化一个 WSGIHandler 对象, 这个对象的__call__(self, environ, start_response)就是请求处理的入口,每一个请求到 web 服务器,如果是动态请求就会被转发到 wsgi 服务器,wsgi 服务器将请求相关参数封装成 environ ,调用 wsgiHandler 对象的__call__()函数处理请求,django 框架从这里开始为我们封装请求对象、进行路由转发等操作

其中 web 服务器到 wsgi 服务器是怎么转发的,多线程 /多进程下会实例化多少个 WSGIHandler 对象这两个问题我还不懂,也想知道
zpf124
2022-01-08 13:53:28 +08:00
前后端分离指的主要是渲染视图和数据分离, 不一定前端非得有专门的服务器。

比如完全可以直接生成静态的 html ,用户请求之前这个页面就已经生成完成, 然后由浏览器直接渲染这个完整的 html ,再执行 js ,通过 ajax 读取到数据 A ,再把数据也渲染出来。当用户访问其他页面的时候就是访问另外一个 html ,从页头到页脚都重新读取重新渲染不管一样不一样,然后再去读取另一个数据 B 。


但这样就出现了一个最主要的问题,当是搜索引擎爬虫访问或者用户网络不好的时候,他们只能看到一个空框架没有任何数据内容。
为了解决这个问题,所以才又专门准备一个渲染服务器,也就是你说的前端服务器,html 页不再是直接生成好的空框架页面了, 而是可以先读取空框架模版再由渲染服务器去访问后端服务器获取数据,然后生成包含数据的 html 页,这时候再返回给用户。
psydonki
2022-01-08 13:58:12 +08:00
我之前也是这么理解的,最近接触到 Next.js ,有点颠覆我的认知了
zanelee
2022-01-08 15:13:33 +08:00
F12 ,然后重新刷新下浏览器。标签选到 fetch/xhr,这个一般就是 ajax 请求到后端服务器的。那个 ajax 请求也是 js 运行的一个 http 请求,可以重载刷新整个页面的情况下对部分对象进行修改。一般也通过 nginx 的 location 规则转发,看 V2EX 应该也是 /api 这个前缀来匹配到转发到后端服务器的。js 这些静态资源则是放在另一个前端应用服务器上(放 vue 之类打包好的前端项目,这个也可以直接放到转发的这台 nginx 上)。同一域名基本上是 nginx 接收所有请求(或者一组).
楼上大佬说的服务端渲染不熟。感觉楼主说的渲染是不是说的 django 的模板渲染这个部分和浏览器渲染搞叉了
markgor
2022-01-08 16:48:04 +08:00
我觉得主要是在于理解,上面的流程图可圈可点.....

web 服务----NGINX/iis/....
应用服务---django 、flask 、.....


1 、浏览器是解释 html/js/css 语言的,这个万变不离其宗;
2.1 、涉及转发 /代理类型的,由 web 服务进行转发请求,获取结果后响应给浏览器;
2.2 、不涉及转发,则本地查找静态文件,响应给浏览器;
3 、浏览器根据响应的结果进行渲染

--jQuery 时代[特指前后端混合的时期]
一般所有请求都会转发给应用服务,应用服务会把完整的代码返回给浏览器;
后面 ajax 开始普片,大部分是 html 画个模板,数据通过 ajax 请求返回。

--vue/react 时代
前后端完全分离,前端搭建好框架,所有数据由后端提供;
*此时引出一个问题就是后端和前端的开发并不同步,前端需要测试数据的时候后端还没写好接口,mock 就出现了,伪装返回数据(当然返回数据格式自己写,按和后台的约定即可)。
*另外浏览器访问本地文件是受限的,所以 IDE 一般内置一个小型 web 服务,以此来缩小线上和开发环境的距离,而且方便。

无论 ajax 或 vue/react ,他们共通点都是数据根据 api 接口返回,但搜索引擎无法针对纯 API 返回数据进行高效索引,也无法索引到 vue/react 的代码(因为只有骨架没内容)。所以对搜索引擎收录是不友好的,此时就有针对这个问题的解决方案 SSR ,如果方位时标识为搜索引擎,返回一段简单的 html 代码+数据,如果是正常浏览器访问,则按正常形式返回。

题外话,无论请求流程怎么转,万变不离其宗的就是发出请求,收到响应。
但是我做过一个项目由于图片比较多,且后期才加入 COS 服务的,做法上:
浏览器->CDN->COS-> NGINX-> PHP
浏览器发出请求:1.jpg
CDN:检查是否有 1.jpg 的缓存,没有就去 COS 拉取;
COS:检查是否有 1.jpg 文件,没有就去 NGINX 拉取;
NGINX:检查是否有压缩的 jpg 文件(默认只返回 w750;q.8 的),没有则转发给 PHP;
PHP:返回原图,同时把图片加入 redis_queue 里面,队列形式进行压缩。

不过后来 COS 有图片压缩功能后,直接就把 PHP 那块砍了....

*其实中间经历了什么主要是看你怎么配置,这个不是浏览器关注的,就好比谁做省长我无所谓,我只要做省长夫人即可。
polymerdg
2022-01-08 16:50:28 +08:00
渲染不要 浏览器的 事情嘛?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/826848

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX