前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Nginx + VFP FastCGI初起步

Nginx + VFP FastCGI初起步

作者头像
加菲猫的VFP
发布于 2021-08-16 06:30:59
发布于 2021-08-16 06:30:59
1.2K0
举报
文章被收录于专栏:加菲猫的VFP加菲猫的VFP

此文和资源来自木瓜大侠

1.为什么放弃IIS+CGI / IIS+FastCGI

众所周知IIS的性能令人诟病,早期VFP开发WEB也没更好的方案,采用了CGI的方式运行于IIS内,好处是每次WEB调用,VFP程序运行后就结束,不存在内存泄漏,变量冲突等,也不会引起宿主IIS崩溃,但坏处就是频繁的启动进程,性能不理想。但FastCGI程序不同,执行完请求后,不会立即结束,而是留在内存等待下一次请求,减少了大量进程初始化的过程,性能就大大提高,缺点就是VFP开发人员要注意,大量的全局变量,不规范的变量使用等,会“污染”下一次请求。

2.为什么选择Nginx

Nginx恐怕是目前性能最强悍的WEB服务器、反向代理服务器,只有几M大小,而且是开源的,支持linux,windows等多平台,只需简单的几行配置就可以完成负载均衡、url rewrite等功能 。另外,网上关于nginx的资源丰富,基本都是修改配置文件来实现不同的功能,linux界的大牛很多,你需要的配置不管是windows和linux都是相同的。

目前淘宝采用的就是Nginx服务器,看看双11产生的海量并发就可以感受这是一个多么牛的程序。

感兴趣可以搜索下看看大家的评论,几个主流服务器lighttpd,apache,iis的对比。

官方地址:http://nginx.org/

使用Nginx的缺点就是没有图型化的配置界面,需要手动修改配置文件,但是,网上这方面资源还是很多的,网上搜下,想要怎么配置都有详细的说明。

3.Nginx如何与FastCGI程序通信

Nginx本身只支持静态资源,比如html,jpg等,不支持php,asp,python ,lua等脚本语言,目前,如日中天的php,python都是通过fastcgi协议运行于Nginx下,可以通过一条指令fastcgi_pass来指定转发,例如

以上面配置为例,FastCGI程序通过监听9000端口,接受nginx的转发请求,处理完后返回给Nginx,Nginx再返回给浏览器,FastCGI程序并不退出进程,继续监听下一次请求,整个通信过程是这样的:

其中,1,4采用的是HTTP协议,2,3采用的是FastCGI协议

当然,这样会产生一个问题,这就是FastCGI程序本身需要管理来自Nginx产生的并发,增加了开发的难度。然而,办法总是有的,这就是一个叫FPM的中间层 (FastCGI Process Manager),由FPM来管理 FastCGI程序,FastCGI程序本身只用专注于业务逻辑,不用关心具体的通信细节。

增加了中间层的结构是这样的:

那么这个FPM需要自己来开发吗?当然不需要,网上已经有大量现成熟可靠的管理工具,不需要你再造轮子。推荐两个: php-cgi-spawner 和 xxfpm,源码地址:

php-cgi-spawner

https://github.com/deemru/php-cgi-spawner

xxfpm

http://xiaoxia.org/2011/02/01/xxfpm-wrote-a-fastcgi-process-manager/

https://github.com/78/xxfpm

4.使用VFP要如何开发FastCGI程序

早期使用FWS开发CGI程序,只需要简单的一句输出就可以了:

程序结束就向浏览器输出了 hello world

前面讲过,FastCGI程序每一次请求,并不会退出程序,而是等待下一次请求,那么代码是这样写的:

你没看错,旧的CGI程序只需要增加条循环语句,即可改造成FastCGI程序,FWS保持向后兼容,这段程序编译后,可以同时运行于CGI和FastCGI模式。

如果你想继续使用IIS,可以把模块映射修改为FastCGIModule即可。

由于FASTCGI是并发运行的,为了能够在浏览器里查看是哪个进程返回的数据,我们把前面的程序修改如下:

你在浏览器中看到的会是这样:

代码写好了,编译成exe即可,注意别忘了加入vfp的config.fpw文件一块编译。

文件清单:

5.配置与发布

本文所有项目均放在d:\FWS文件夹,当然,可根据需求自己需要调整

  1. 源码存放在Source文件夹
  2. Nginx存放在 Nginx文件夹
  3. FPM管理器存放在FPM文件夹
  4. 发行文件存放在Release文件夹

Nginx下载与设置

从Nginx官网下载最新版本,当前版本1.17.5

下载后是个zip压缩包,直接解压到我们的nginx文件夹就好

Nginx的配置文件在conf文件夹下的nginx.conf文件,这个可以直接用记事本打开编辑就好:

可以看到,它默认的配置是监听80端口,默认的主目录是在 html文件夹,如果此时双击打开nginx.exe,在浏览器地址栏里输入127.0.0.1 就可以看到它的初始页面:

当然,防火墙会跳出来提示你,允许就好。

看到这个画面,说明nginx已经正常运行了。所有放在 nginx\html\下的静态资源都可以访问。

下面来修改配置,让 http://127.0.0.1/fws这个文件夹指向我们VFP开发的程序

其中:location /fws 表示当访问网站根目录 / 下面的 fws时,执行下面的配置,

比如

http://127.0.0.1/fws

http://127.0.0.1/fws/

http://127.0.0.1/fws/abc

http://127.0.0.1/fws/a.prg

http://127.0.0.1/fws/a.prg?name=test

这些web请求都会进入我们的vfp程序,而我们的VFP程序则需要判断URL或者其他参数来执行对应的操作

fastcgi_pass 127.0.0.1:9000;

这句意思是,按照fastcgi协议,转发给9000这个端口即可。

当然,本机,可以直接使用127.0.0.1这个IP,如果是局域网的其他机器,这里换成其他IP也是可以的。

所以,web服务可以运行于一台独立的服务器(不仅限于windows),我们的VFP程序,可以运行于另一台独立的服务器,可以更好的进行处理并发。

include fastcgi.conf;

这句是加入fastcgi的配置参数一并转发给fastcgi程序,include相当于vfp的宏#include,可以包含一个文件进来,有兴趣可以看下fastcgi.conf这个文件内容是什么,位于nginx.conf相同的文件夹

注意下,由于历史原因,你可能会看到有人使用 include fastcgi_params这个写法,这是历史原因,不需要再使用。

注:如果修改了配置,需要从任务管理器终止nginx进程,它有两个进程,都要终止

当然,也可以用命令重新加载配置:

nginx -s reload

你可以使用-h参数查看帮助

FPM下载与用法

xxfpm是有编译好的二进制程序,php-cgi-spawner下载到的是源码,这里以xxfpm为例:

https://github.com/78/xxfpm

我们只需要压缩包里的xxfpm.exe和pthreadGC2.dll两个文件,把它解压到fpm文件夹

如果你有安装C编译器,可以自行编译 src\main.c文件。

xxfpm的语法

Usage: xxfpm path [-n number] [-i ip] [-p port]

Manage FastCGI processes.

-n, –number number of processes to keep

-i, –ip ip address to bind

-p, –port port to bind, default is 8000

-u, –user start processes using specified linux user

-g, –group start processes using specified linux group

-r, –root change root direcotry for the processes

-h, –help output usage information and exit

-v, –version output version information and exit

我们可以在source文件夹建一个bat文件来执行xxfpm

命令如下:

..\fpm\xxfpm.exe "FWS.exe" -n 2 -p 9000

注意,这里都使用了相对路径,如果你的文件夹不一致,请使用绝对路径 如

D:\fws\fpm\xxfpm.exe "d:\fws\source\FWS.exe" -n 2 -p 9000

其中参数 –n 2 是指立即启动两个进程常驻内存

参数 -p 9000 是指监听9000端口,要与前面nginx里指定的端口一致。

php-cgi-spawner

这个程序没有提供编译好的程序,有兴趣可以自己编译下,我在附件中提供这个编译好的程序,它的语法是:

..\fpm\fcgi-spawn.exe "FWS.exe" 9000 4+16

其中,9000是监听端口,4+16意思是指,常驻内存4个进程,上限16个

至此,fastcgi程序准备好了,nginx启动好,fpm启动好,工作完成,打开浏览器试试吧:

VFP程序发布

Vfp程序发布比较简单,只需要你的EXE+fws.dll和VFP运行库,以及你使用的其他数据、扩展库等,本例中只需要fws.exe和fws.dll即可,发布服务器要注意修改fpm启动的参数。

基本原理和配置工作完成,可以专注于业务逻辑的开发了。

6.VFP FastCGI程序详解

代码比较简单,但想想还是要详细解释下,因为VFP里有太多似是而非的东西。

第一行:Lparameters cCmdline

我们都知道,所有程序都有命令行参数,但VFP程序一般都是有界面的,很少人以命令方式去运行,这行代码就是接受命令行的参数,但有人会问:我又不需要处理命令行,这句有必要吗?

做个试验,在文件夹中拖动个文件到你的EXE图标上,你的程序立马报错:

看到了吗?你的程序还没有运行就报错了,连你的错误处理程序on error都没运行就报错了,而加了这行代码,你的程序就不会出错了。

第二行 On Error quit

在运行时,我们不希望产生错误而让这个程序直接挂在服务器上,产生错误要立即退出程序。因为这个时候,fws还没加载,你自己的一些设置可能都还没准备好,不能在这个时候产生错误。

当然,我真正需要捕捉错误应该怎么做呢?那是应该要等到FWS加载成功后,可以向浏览器输出信息时,再设置 On Error 程序。

第三行 Set Path To (JustPath(_vfp.ServerName))

我们的VFP程序运行的当前路径,都是WEB服务器设定文件夹(当前NGINX设置的文件夹是 d:\fws\nginx\html),但是我们运行时需要的dll,数据,配置等信息一般跟EXE放在相同的位置,如果此时使用Set Library To fws.dll ADDITIVE 打开扩展库,vfp会先从当前目录、system32目录搜索,如果找不到,就报错了。

当我们用Set Path To设置一个文件夹时,就继续会到这个文件夹去搜索,这样才能保证第四句不会出错。

当然,你可以直接切换到程序所在文件夹,你可以把这行代码改成:

Set Default To (JustPath(_vfp.ServerName))

程序的当前目录就直接切换到你的exe所在位置了,但开发环境不要这样,因为它会切换到vfp9.exe所在位置,这是因为_vfp.ServerName 这个全局对像的属性,在开发环境下是 c:\program files\…\vfp9.exe,而运行环境下就是你的exe的完整路径。

另外,千万不要使用 Set Default To Sys(5)+Sys(2003)设置当前工作路径,太多人被这个错误的用法误导,Sys(5)+Sys(2003)是用来获取当前位置,既然是当前路径还要设为默认值,这句不是多余吗?

另外,或许你注意到了 JustPath()外面又套了层括号,但我建议你这样做,因为你难保证你什么时候就写出了这样的代码:

str="d:\fws"

Set Default To str

这句在VFP里是报错的,也许你想不明白,直接用 Set Default To "d:\fws" 就可以,为什么改成变量却报错了呢?这也许是VFP的历史遗留问题,你直接写Set Default To d:\fws 也不会报错,后面这个d:\fws也不是字符串,算什么呢?

所以这样修改下,就不会报错了:

Set Default To (str)

当然,你也可以使用 &,但我不建议这么做。

后面的几行需要连在一起解释:

Do while fws_Accept()>=0

……

EndDo

这是个死循环,就是等待一次浏览器的请求,处理请求,继续下一次等待。那么我们的程序如何结束呢?只有通过任务管理器强制终止了。

Fws_Accept()函数是个阻塞函数,等待客户端连接,如果有连接进来,会返回一个大于等于0的值,如果返回了负值,则说明FPM管理器通知你要结束了。当运行于CGI模式时,这个函数只会第一次返回大于等于0的值,第二次执行就返回了负值,这样进程就自动结束了,从而保证你的程序兼容CGI模式。

当然,为了保证程序的稳定,运行一段时间最好重启一下,就可以用计数器来控制下,比如PHP中常用的手法是执行5000次后这个进程自动退出,我们就可以修改成这样:

nCounter=1

Do while fws_Accept()>=0

If nCounter>5000

Exit

EndIf

……

nCounter = nCounter + 1

EndDo

第5000次调用后,退出循环,进程自动终止。这时FPM管理器会监视到内存中的进程少了一个,会自动再启动一个进程,起到了类似刷新的机制。

也许你会奇怪为什么没有 Read EVENTS语句,这是我们传统VFP程序必需要写的一句,否则就会“一闪而过”,这是因为它只适用于桌面程序,需要此语句来激活Windows消息处理循环,响应键盘、鼠标的控制消息。我们的WEB程序是没有界面的,而且也不依赖Windows消息循环。当你在最后加上这句会怎样?实际上是不会出错的,但这个程序就成了僵尸程序,因为收不到桌面的通知,一直运行后台等待有人通知他,你只能通过任务管理器来终止此进程。

此演示程序仅仅是调用 fws_write()输出了字符串,实际应用,你需要调用其他函数来获取浏览器发过来的所有信息进行分析处理,这不在本文解释范围。

7.如何调试VFP FastCGI程序

早期CGI程序调试是非常痛苦的,只有编译成EXE后,设计复杂的日志来调试,当然也有各位前辈设计了SOCKET调试服务器来实现,但新的FWS利用FASTCGI的通信特点,增加了监听函数,这样可以直接接受nginx的连接(IIS暂时难以使用此方法):

fws_listen(IP,端口)

当然,这个函数仅用于开发模式,不依赖FPM,运行模式时不需要,那么我们的代码需要改成这样:

If _vfp.StartMode=0 此句检测是否是开发环境,如果是开发环境,则执行。这样就可以直接设置断点,监控整个通信过程了。

我们可以直接在循环体内部设置断点,运行程序后,从浏览器访问,则激活VFP的调试:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加菲猫的VFP 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【黄啊码】连CGI都不懂,还敢说自己精通PHP吗?
CGI common gateway interface (公共网关接口) 请求模式: Web Brower(浏览器) ----(通过http协议传输)----> Http Server(服务器nginx/apache) -----> CGI Program -----> Db Server 与 CGI 通过 STDIN/STDOUT(标准的输入/输出)进行数据传递 nginx(动态加载模块) apache(指定加载模块) CGI工作原理 每当客户请求CGI的时候,WEB服务器就请求操作系统生成
黄啊码
2021/09/26
3400
Windows下Nginx+Mysql+Php(wnmp)环境搭建
前言  最近想在windows下使用nginx搭建web环境,本来想用套件(WNMP)一键安装,但后来放弃了,觉得还是自己动手,丰衣足食的好,而且套件的局限性太大。所以后来就各种搜索,看到前辈写关于wnmp环境的搭建,虽是感觉千篇一律,不过对我这个新手来说,还是有一定的参考价值,非常感谢!但在搭建的过程中,遇到了很多问题,所以决定自己整理一番,以供初学者参考。 Nginx是一个高性能的HTTP和反向代理服务器,同时还是IMAP/POP3/SMTP代理服务器,该程序由俄罗斯Rambler.ru 站点开发,Ng
joshua317
2018/04/09
2.7K0
Windows下Nginx+Mysql+Php(wnmp)环境搭建
FastCGI的认识与使用[通俗易懂]
通用网关接口(Common Gateway Interface、CGI)描述了客户端和服务器程序之间传输数据的一种标准,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI独立于任何语言的,CGI 程序可以用任何脚本语言或者是完全独立编程语言实现,只要这个语言可以在这个系统上运行。Unix shell script、Python、Ruby、PHP、 perl、Tcl、 C/C++和 Visual Basic 都可以用来编写 CGI 程序。
全栈程序员站长
2022/09/14
3.3K0
FastCGI的认识与使用[通俗易懂]
Nginx运行FastCGI程序(ngx_http_fastcgi_module模块、fcgi库、spwan-fcgi进程管理器)
typedef struct { unsigned char version; // 版本号 unsigned char type; // 数据包类型 unsigned char requestIdB1; // 记录 id 高 8 位 unsigned char requestIdB0; // 记录 id 低 8 位 unsigned char contentLengthB1; // 记录内容长度高 8 位(body 长度高 8 位) unsigned char contentLengthB0; // 记录内容长度低 8 位(body 长度低 8 位) unsigned char paddingLength; // 补齐位长度(body 补齐长度) unsigned char reserved; // 补齐位 }FCGI_Header;
全栈程序员站长
2022/09/08
2.8K0
Nginx运行FastCGI程序(ngx_http_fastcgi_module模块、fcgi库、spwan-fcgi进程管理器)
SSRF漏洞之FastCGI利用篇「建议收藏」
SSRF–(Server-side Request Forge, 服务端请求伪造) 定义:由攻击者构造的攻击链接传给服务端执行造成的漏洞,一般用来在外网探测或攻击内网服务
全栈程序员站长
2022/09/14
2.4K0
SSRF漏洞之FastCGI利用篇「建议收藏」
Linux 下 Nginx + PHP 环境的配置
本来想简单地写一写,结果发现越写越长,折腾了将近一个月,整出这篇 10000 多字的超长笔记。。。
zgq354
2019/11/24
3.7K1
win7下搭建nginx+php的开发环境
本来在win7下用的是IIS做web服务器,但近来因项目需求的原因,需要在服务器遇到404错误的时候自动做转向(不是在客户端的跳转,而是在服务器收到客户端请求去某目录下读取文件返回时,如果发现目录或目录下文件不存在,自动转到另一个服务器去取),用IIS发现很难做到这点,于是决定搭建nginx的开发环境,通过配置实现这一点。
风柏杨4711
2021/03/15
5980
nginx+php-fpm工作原理
官方手册:FPM(FastCGI 进程管理器)用于替换 PHP FastCGI 的大部分附加功能,对于高负载网站是非常有用的。 它的功能包括:
猿哥
2020/03/12
1.9K0
PHP - 语言底层运行及生命周期
PHP在业界被调侃,是世界上最好的语言,PHP确实是Web开发里的利器,具体点说,就是一个用C语言实现包含大量组件模块的软件框架。是一个强大的UI框架。
stark张宇
2023/02/07
6800
「PHP」不依赖集成环境,使用Nginx手动配置Thinkphp运行环境
在如今这个时代,互联网可谓是大行其道,由互联网带动的各行各业蓬勃发展,也正是由于及时抓住的互联网带来的发展机遇,成就了一大批科技巨头,他们利用互联网技术推出了一大批科技产品,这些科技产品在给人们带来方便、快捷的生活的同时,也在慢慢改变着世界。
老夫编程说
2020/07/08
1.6K0
「PHP」不依赖集成环境,使用Nginx手动配置Thinkphp运行环境
CGI & FastCGI
  最早的Web服务器简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html。事物总是不 断发展,网站也越来越复杂,所以出现动态技术。但是服务器并不能直接运行 php,asp这样的文件,自己不能做,外包给别人吧,但是要与第三做个约定,我给你什么,然后你给我什么,就是握把请求参数发送给你,然后我接收你的处 理结果给客户端。那这个约定就是 common gateway interface,简称cgi。这个协议可以用vb,c,php,python 来实现。cgi只是接口协议,根本不是什么语言。下面图可以看到流程
WindWant
2020/09/11
1.7K0
详解 Nginx 和 php-fpm 调用方式
PHP 项目使用 Nginx 时,一般通过 php-fpm Nginx+PHP-FPM 形式访问交互,本文将详细解读 Nginx 配置文件、PHP-FPM、PHP-CGI 和 fastCGI 的概念。
Yangsh888
2022/03/28
2.7K0
Nginx与php-fpm之间的通信机制(一)
讲Fastcgi之前需要先讲CGI,CGI是为了保证web server传递过来的数据是标准格式的,它是一个协议。每种动态语言( PHP,Python 等)的代码文件需要通过对应的解析器才能被服务器识别,而 CGI 协议就是用来使解释器与服务器可以互相通信。PHP 文件在服务器上的解析需要用到 PHP 解释器,再加上对应的 CGI 协议,从而使服务器可以解析到 PHP 文件。
兔云小新LM
2019/12/19
2.6K1
Nginx+PHP-FPM打开status
1. 启用 php-fpm 状态功能 修改 php-fpm.conf 文件,如果没有则创建此文件. 在文件夹: php/etc 目录下创建.  pm.status_path=/status listen = 9000 #此处是监听 status 的端口, 可以自定义, 要跟等会在 nginx 中配置的一致. 2. nginx配置 在要监控的主机里添加上 locaction. location ~^/(status|ping)$ { include f
zcqshine
2018/05/11
1.8K0
Windows安装nginx + php + mysql
当前windows下web环境搭建有很多集成工具,比如常用的phpstudy,这里记录下不用集成工具,单独安装每个服务,如同linux环境安装一样;
用户2141488
2021/11/02
7.6K0
FastCgi与PHP-fpm之间的关系
刚开始对这个问题我也挺纠结的,看了《HTTP权威指南》后,感觉清晰了不少。 首先,CGI是干嘛的?CGI是为了保证web server传递过来的数据是标准格式的,方便CGI程序的编写者。 web server(比如说nginx)只是内容的分发者。比如,如果请求/index.html,那么web server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。好了,如果现在请求的是/index.php,根据配置文件,nginx 知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求
wangxl
2018/03/08
1.2K0
困扰已久的问题 cgi、fastcgi、PHP-fpm 汇总
一个模糊的概念 无论是php,python编程语言,还是apache,nginx服务器对于cgi协议是个绕不开的话题。安装,部署都会经常的看到,那么它们到底是干什么的,网上的答案非常的多!今天通过它们
猿哥
2019/07/01
1.3K0
困扰已久的问题 cgi、fastcgi、PHP-fpm 汇总
Windows 下 Nginx + PHP5 的安装与配置
本文转载至:www.phpvim.net/web/php/installing-nginx-with-php5-on-windows.html
meteoric
2018/11/14
1.6K0
PHP 之 FastCGI 与 mod_php
网上对于FastCGI与mod_php的知识比较杂乱而不全面,故在此整理一下,以便入门学习者查阅方便。 背景PHP最常用的方式是以模块的方式(mod_php)运行在Apache中,也是Apache运行PHP的默认方式;但在Nginx中,Nginx又使用的是PHP-FPM,但是PHP-FPM到底是个什么东东?跟php有什么关系?今天我们一起来探究一番。
conanma
2021/12/02
8780
Nginx + FastCGI 程序(C/C++) 搭建高性能web service的Demo及部署发布
由于最近工作的需要,本人学习了一下利用高性能web server - Nginx,来发布C/C++编写的fastCGI程序,详细细节如下。
后端技术探索
2018/08/09
2.2K0
相关推荐
【黄啊码】连CGI都不懂,还敢说自己精通PHP吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档