BlankLin

lazy and boring

0%

CGI

通用网关接口(Common Gateway Interface/CGI)描述了客户端和服务器程序之间传输数据的一种标准,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI 独立于任何语言的,CGI 程序可以用任何脚本语言或者是完全独立编程语言实现,只要这个语言可以在这个系统上运行。

cgi
从上面这站图我们可以窥知几个重点的阶段
1、web browser 收到 Http request 后,将 request 转给 web server
2、web server 启动 CGI 程序,并通过环境变量、标准输入传递数据
3、cgi 进程启动解析器、加载配置(如业务相关配置)、连接其它服务器(如数据库服务器)、逻辑处理等
4、cgi 程将处理结果通过标准输出、标准错误,传递给 web server
5、 web server 收到 cgi 返回的结果,构建 Http Response 返回给客户端,并杀死 cgi 进程

web erver 与 cgi 通过环境变量、标准输入、标准输出、标准错误互相传递数据这就是 fork and execute 模式,有多少的 http request,就会 fork 出多少的子进程去处理,而每个子进程都需要启动 cgi 解释器、加载配置、链接其他服务器等初始化工作,所以这就是 cgi 性能低下的根本原因,当用户请求非常多的时候,会大量挤占系统的资源如:内存、cpu 时间等。

以下是一些 get 请求常见的环境变量

环境变量 内容
REMOTE_ADDR client 端的 host 名称。
REMOTE_METHOD client 端发出请求的方法(如 get、post)。
SCRIPT_NAME CGI 程式所在的虚拟路径,如/cgi-bin/echo。
SERVER_NAME server 的 host 名称或 IP 地址。
QUERY_STRING 传递给 CGI 程式的请求参数,也就是用”?”隔开,添加在 URL 后面的字串。

标准输入

环境变量的大小是有一定的限制的,当需要传送的数据量大时,储存环境变量的空间可能会不足,造成数据接收不完全,甚至无法执行 CGI 程序。因此后来又发展出另外一种方法:POST,也就是利用 I/O 重新导向的技巧,让 CGI 程序可以由 STDIN 和 STDOUT 直接跟浏览器沟通。
当我们指定用这种方法传递请求的数据时,web 服务器收到数据后会先放在一块输入缓冲区中,并且将数据的大小记录在 CONTENT_LENGTH 这个环境变数,然后调用 CGI 程式并将 CGI 程序的 STDIN 指向这块缓冲区,于是我们就可以很顺利的通过 STDIN 和环境变数 CONTENT_LENGTH 得到所有的资料,再没有资料大小的限制了。
总结:CGI 使外部程序与 Web 服务器之间交互成为可能。CGI 程式运行在独立的进程中,并对每个 Web 请求建立一个进程,这种方法非常容易实现,但效率很差,难以扩展。面对大量请求,进程的大量建立和消亡使操作系统性能大大下降。此外,由于地址空间无法共享,也限制了资源重用。

FastCGI

快速通用网关接口(Fast Common Gateway Interface/FastCGI)是通用网关接口(CGI)的改进,描述了客户端和服务器程序之间传输数据的一种标准。FastCGI 致力于减少 Web 服务器与 CGI 程式之间互动的开销,从而使服务器可以同时处理更多的 Web 请求。与为每个请求创建一个新的进程不同,FastCGI 使用持续的进程来处理一连串的请求。这些进程由 FastCGI 进程管理器管理,而不是 web 服务器。
fastcgi
1、Web 服务器启动时载入初始化 FastCGI 执行环境 。 例如 IIS ISAPI、apache mod_fastcgi、nginx ngx_http_fastcgi_module、lighttpd mod_fastcgi

2、FastCGI 进程管理器自身初始化,启动多个 CGI 解释器进程并等待来自 Web 服务器的连接。启动 FastCGI 进程时,可以配置以 ip 和 UNIX 域 socket 两种方式启动。

3、当客户端请求到达 Web 服务器时, Web 服务器将请求采用 socket 方式转发到 FastCGI 主进程,FastCGI 主进程选择并连接到一个 CGI 解释器。Web 服务器将 CGI 环境变量和标准输入发送到 FastCGI 子进程。

4、FastCGI 子进程完成处理后将标准输出和错误信息从同一 socket 连接返回 Web 服务器。当 FastCGI 子进程关闭连接时,请求便处理完成。

5、FastCGI 子进程接着等待并处理来自 Web 服务器的下一个连接。

由于 FastCGI 程序并不需要不断的产生新进程,可以大大降低服务器的压力并且产生较高的应用效率。它的速度效率最少要比 CGI 技术提高 5 倍以上。它还支持分布式的部署, 即 FastCGI 程序可以在 web 服务器以外的主机上执行。

总结:CGI 就是所谓的短生存期应用程序,FastCGI 就是所谓的长生存期应用程序。FastCGI 像是一个常驻(long-live)型的 CGI,它可以一直执行着,不会每次都要花费时间去 fork 一次(这是 CGI 最为人诟病的 fork-and-execute 模式)。

消息类型

FastCGI 协议分为了 10 种类型,具体定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
typedef enum _fcgi_request_type {
FCGI_BEGIN_REQUEST = 1, /* [in] */
FCGI_ABORT_REQUEST = 2, /* [in] (not supported) */
FCGI_END_REQUEST = 3, /* [out] */
FCGI_PARAMS = 4, /* [in] environment variables */
FCGI_STDIN = 5, /* [in] post data */
FCGI_STDOUT = 6, /* [out] response */
FCGI_STDERR = 7, /* [out] errors */
FCGI_DATA = 8, /* [in] filter data (not supported) */
FCGI_GET_VALUES = 9, /* [in] */
FCGI_GET_VALUES_RESULT = 10 /* [out] */
} fcgi_request_type;

整个 FastCGI 是二进制连续传递的,定义了一个统一结构的消息头,用来读取每个消息的消息体,方便消息包的切割。一般情况下,最先发送的是 FCGI_BEGIN_REQUEST 类型的消息,然后是 FCGI_PARAMS 和 FCGI_STDIN 类型的消息,当 FastCGI 响应处理完后,将发送 FCGI_STDOUT 和 FCGI_STDERR 类型的消息,最后以 FCGI_END_REQUEST 表示请求的结束。FCGI_BEGIN_REQUEST 和 FCGI_END_REQUEST 分别表示请求的开始和结束,与整个协议相关。

php-fpm

PHP-FPM(FastCGI Process Manager:FastCGI 进程管理器)是一个 PHPFastCGI 管理器,是 FastCGI 的实现,并提供了进程管理的功能。进程包含 master 进程和 worker 进程两种进程。master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置 pm.max_children = 5),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。
fastcgi

nginx

Nginx 不只有处理 http 请求的功能,还能做反向代理。Nginx 通过反向代理功能将动态请求转向后端 Php-fpm.
下面我们简单解释一下 nginx 的 server 模块是如何配置的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 80; #监听80端口,接收http请求
server_name www.example.com; #就是网站地址
root /usr/local/etc/nginx/www/example; # 准备存放代码工程的路径
#路由到网站根目录www.example.com时候的处理
location / {
index index.php; #跳转到www.example.com/index.php
}
#当请求网站下php文件的时候,反向代理到php-fpm
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;#nginx fastcgi进程监听的IP地址和端口
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; #加载nginx的fastcgi模块
}
}

新建项目

首先在 GitHub 新建一个仓库(Repository),名称为 {username}.github.io,注意这个名比较特殊,必须要是 github.io 为后缀结尾的。比如 我 的 GitHub 用户名就叫 blanklin030,那我就新建一个 blanklin030.github.io,新建完成之后就可以进行后续操作了。

另外如果 GitHub 没有配置 SSH 连接的建议配置一下,这样后面在部署博客的时候会更方便。

安装环境

首先在自己的电脑上安装 Node.js,下载地址:https://nodejs.org/zh-cn/download/,可以安装 Stable 版本。

安装完毕之后,确保环境变量配置好,能正常使用 npm 命令。

安装 Hexo

接下来就需要安装 Hexo 了,这是一个博客框架,Hexo 官方还提供了一个命令行工具,用于快速创建项目、页面、编译、部署 Hexo 博客,所以在这之前我们需要先安装 Hexo 的命令行工具。

命令如下:

1
npm install -g hexo-cli

安装完毕之后,确保环境变量配置好,能正常使用 hexo 命令。

初始化项目

接下来我们使用 Hexo 的命令行创建一个项目,并将其在本地跑起来,整体跑通看看。
首先使用如下命令创建项目:

1
hexo init {name}

这里的 name 就是项目名,我这里要创建 blanklin 的博客,我就把项目取名为 blanklin 了,用了纯小写,命令如下:

1
hexo init blinklin

这样 nightteam 文件夹下就会出现 Hexo 的初始化文件,包括 themes、scaffolds、source 等文件夹,这些内容暂且先不用管是做什么的,我们先知道有什么,然后一步步走下去看看都发生了什么变化。

接下来我们首先进入新生成的文件夹里面,然后调用 Hexo 的 generate 命令,将 Hexo 编译生成 HTML 代码,命令如下:

1
hexo generate

可以看到输出结果里面包含了 js、css、font 等内容,并发现他们都处在了项目根目录下的 public 文件夹下面了。

然后我们利用 Hexo 提供的 serve 命令把博客在本地运行起来,命令如下:

1
hexo serve

运行之后命令行输出如下:

1
2
INFO  Start processing
INFO Hexo is running at http://localhost:4000 . Press Ctrl+C to stop.

部署

接下来我们来将这个初始化的博客进行一下部署,放到 GitHub Pages 上面验证一下其可用性。成功之后我们可以再进行后续的修改,比如修改主题、修改页面配置等等。

那么怎么把这个页面部署到 GitHub Pages 上面呢,其实 Hexo 已经给我们提供一个命令,利用它我们可以直接将博客一键部署,不需要手动去配置服务器或进行其他的各项配置。

部署命令如下:

1
hexo deploy

在部署之前,我们需要先知道博客的部署地址,它需要对应 GitHub 的一个 Repository 的地址,这个信息需要我们来配置一下。

打开根目录下的 _config.yml 文件,找到 Deployment 这个地方,把刚才新建的 Repository 的地址贴过来,然后指定分支为 master 分支,最终修改为如下内容:

1
2
3
4
5
6
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
type: git
repo: {git repo ssh address}
branch: master

另外我们还需要额外安装一个支持 Git 的部署插件,名字叫做 hexo-deployer-git,有了它我们才可以顺利将其部署到 GitHub 上面

1
npm install hexo-deployer-git --save

安装成功之后,执行部署命令:

1
hexo deploy

如果没有报错,那说明 hexo deploy 操作就做了两个动作,1 个是 build 文件到 public 目录,还有 1 个就是 git add && git commit && git push 后到 GitHub 仓库了。
这时候我们去 GitHub 上面看看 Hexo 上传了什么内容,打开之后可以看到 master 分支就可以看到其实就是把 public 目录 push 到 repository 了。

这时候可能就有人有疑问了,那我博客的源码也想放到 GitHub 上面怎么办呢?其实很简单,新建一个其他的分支就好了,比如我这边就新建了一个 source 分支,代表博客源码的意思。

具体的添加过程就很简单了,就是增加一个 source 分支,记录的博客的源码,参加如下命令:

1
2
3
4
5
6
7

git init
git checkout -b source
git add -A
git commit -m "init blog"
git remote add origin git@github.com:{username}/{username}.github.io.git
git push origin source

成功之后,可以到 GitHub 上再切换下默认分支,比如我就把默认的分支设置为了 source,当然不换也可以。

配置站点信息

下面我就以自己的站点 NightTeam 为例,修改一些基本的配置,比如站点名、站点描述等等。

修改根目录下的 _config.yml 文件,找到 Site 区域,这里面可以配置站点标题 title、副标题 subtitle 等内容、关键字 keywords 等内容,比如我的就修改为如下内容:

1
2
3
4
5
6
# Site
title: NightTeam
subtitle: 一个专注技术的组织
description: 涉猎的主要编程语言为 Python、Rust、C++、Go,领域涵盖爬虫、深度学习、服务研发和对象存储等。
keywords: "Python, Rust, C++, Go, 爬虫, 深度学习, 服务研发, 对象存储"
author: NightTeam

这里大家可以参照格式把内容改成自己的。

另外还可以设置一下语言,如果要设置为汉语的话可以将 language 的字段设置为 zh-CN,修改如下:

1
language: zh-CN

修改主题

目前 Hexo 里面应用最多的主题基本就是 Next 主题了,个人感觉这个主题还是挺好看的,另外它支持的插件和功能也极为丰富,配置了这个主题,我们的博客可以支持更多的扩展功能,比如阅览进度条、中英文空格排版、图片懒加载等等。

那么首先就让我们来安装下 Next 这个主题吧,目前 Next 主题已经更新到 7.x 版本了,我们可以直接到 Next 主题的 GitHub Repository 上把这个主题下载下来。

主题的 GitHub 地址是:https://github.com/theme-next/hexo-theme-next,我们可以直接把 master 分支 Clone 下来。

首先命令行进入到项目的根目录,执行如下命令即可:

1
git clone https://github.com/theme-next/hexo-theme-next themes/next

执行完毕之后 Next 主题的源码就会出现在项目的 themes/next 文件夹下。

然后我们需要修改下博客所用的主题名称,修改项目根目录下的 _config.yml 文件,找到 theme 字段,修改为 next 即可,修改如下:

1
theme: next

然后本地重新开启服务,访问刷新下页面,就可以看到 next 主题就切换成功了

主题配置

现在我们已经成功切换到 next 主题上面了,接下来我们就对主题进行进一步地详细配置吧,比如修改样式、增加其他各项功能的支持,下面逐项道来。

Next 主题内部也提供了一个配置文件,名字同样叫做 _config.yml,只不过位置不一样,它在 themes/next 文件夹下,Next 主题里面所有的功能都可以通过这个配置文件来控制,下文所述的内容都是修改的 themes/next/_config.yml 文件。

样式

Next 主题还提供了多种样式,风格都是类似黑白的搭配,但整个布局位置不太一样,通过修改配置文件的 scheme 字段即可,我选了 Pisces 样式,修改 _config.yml (注意是 themes/next/_config.yml 文件)如下:

1
2
3
4
5
scheme: Pisces
# 大家可以自行根据喜好选择。
# scheme: Muse
#scheme: Mist
#scheme: Gemini

还有很多其他的配置项,可自己参考修改,在这里就不一一概述了

最后大家修改完配置后请参考文档继续学习如何创建文章。

创建 MD 文章

1
$ hexo new "My New Post"

创建的文章会出现在 source/_posts 文件夹下,是 MarkDown 格式。
在文章开头通过如下格式添加必要信息:

1
2
3
4
5
6
7
8
9
10
11
---
title: 标题 # 自动创建,如 hello-world
date: 日期 # 自动创建,如 2019-09-22 01:47:21
tags:
- 标签1
- 标签2
- 标签3
categories:
- 分类1
- 分类2
---

这样在下次编译的时候就会自动识别标题、时间、类别等等,另外还有其他的一些参数设置,可以参考文档

标签页

我们的博客只有首页、文章页,如果我们想要增加标签页,可以自行添加,这里 Hexo 也给我们提供了这个功能,在根目录执行命令如下:

1
hexo new page tags

执行这个命令之后会自动帮我们生成一个 source/tags/index.md 文件,内容就只有这样子的:

1
2
3
4
---
title: tags
date: 2019-09-26 16:44:17
---

我们可以自行添加一个 type 字段来指定页面的类型:

1
2
type: tags
comments: false

然后再在主题的 _config.yml 文件将这个页面的链接添加到主菜单里面,修改 menu 字段如下:

1
2
3
4
5
6
7
8
9
menu:
home: / || home
#about: /about/ || user
tags: /tags/ || tags
#categories: /categories/ || th
archives: /archives/ || archive
#schedule: /schedule/ || calendar
#sitemap: /sitemap.xml || sitemap
#commonweal: /404/ || heartbeat

分类页

分类功能和标签类似,一个文章可以对应某个分类,如果要增加分类页面可以使用如下命令创建:

1
hexo new page categories

然后同样地,会生成一个 source/categories/index.md 文件。

我们可以自行添加一个 type 字段来指定页面的类型:

1
2
type: categories
comments: false

然后再在主题的 _config.yml 文件将这个页面的链接添加到主菜单里面,修改 menu 字段如下:

1
2
3
4
5
6
7
8
9
menu:
home: / || home
#about: /about/ || user
tags: /tags/ || tags
categories: /categories/ || th
archives: /archives/ || archive
#schedule: /schedule/ || calendar
#sitemap: /sitemap.xml || sitemap
#commonweal: /404/ || heartbeat

搜索页

很多情况下我们需要搜索全站的内容,所以一个搜索功能的支持也是很有必要的。

如果要添加搜索的支持,需要先安装一个插件,叫做 hexo-generator-searchdb,命令如下:

1
npm install hexo-generator-searchdb --save

然后在项目的 _config.yml 里面添加搜索设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Local search
# Dependencies: https://github.com/wzpan/hexo-generator-search
local_search:
enable: true
# If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button.
trigger: auto
# Show top n results per article, show all results by setting to -1
top_n_per_article: 5
# Unescape html strings to the readable one.
unescape: false
# Preload the search data when the page loads.
preload: false

这里用的是 Local Search,如果想启用其他是 Search Service 的话可以参考官方文档:https://theme-next.org/docs/third-party-services/search-services。

404 页面

另外还需要添加一个 404 页面,直接在根目录 source 文件夹新建一个 404.md 文件即可,内容可以仿照如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

---
title: 404 Not Found
date: 2019-09-22 10:41:27
---

<center>
对不起,您所访问的页面不存在或者已删除。
您可以<a href="https://blog.nightteam.cn>">点击此处</a>返回首页。
</center>

<blockquote class="blockquote-center">
NightTeam
</blockquote>

这里面的一些相关信息和链接可以替换成自己的。

增加了这个 404 页面之后就可以

完成了上面的配置基本就完成了大半了,其实 Hexo 还有很多很多功能,这里就介绍不过来了,大家可以直接参考官方文档:https://hexo.io/zh-cn/docs/ 查看更多的配置。

部署脚本

1
2
3
hexo clean
hexo generate
hexo deploy