SAE PHP调研
目录
1 web服务器...1
2 沙箱隔离...1
3 应用配置...2
4 本地io.2
5 Runtime相关模块...2
6 日志相关...2
7 网络io.3
8 邮件...3
9 禁用函数...3
SAE平台的Web服务器使用的是Apache2.2.x,PHP5.3.x作为Apache的一个模块存在,用于处理应用的PHP脚本。Web服务器运行在64位下,不用担心整型溢出问题。Apache运行在Prefork模式下,即每个请求都会对应一个Apache进程,请求结束后该进程才能服务于下一个请求。平台通过模块方式扩展了Apache和PHP的相关功能。
pre-fork服务器和fork服务器相似,也是通过一个单独的进程来处理每条请求。但是,不同的是,pre-fork服务器会通过预先开启大量的进程,等待并处理接到的请求。由于采用了这种方式来开启进程,服务器并不需要等待新的进程启动而消耗时间,因而能够以更快的速度应付多用户请求。另外,pre-fork服务器在遇到极大的高峰负载时仍能保持良好的性能状态。这是因为不管什么时候,只要预先设定的所有进程都已被用来处理请求时,服务器仍可追加额外的进程。
pre-fork服务器相当独特的运行状态曲线。和先前提到的fork模式类似的是,pre-fork服务器也是通过独立的http服务器进程来处理每一个请求,但是,和fork服务器不同的是,pre-fork服务器会随着请求数量的增加而启动若干新的进程。这种方法的优点是,能在对http通讯保持一定响应能力的同时,给服务器提供少许的“喘息”时间。缺点是,当遇到高峰负载时,由于要启动新的服务器进程,不可避免地会带来响应的延迟。
SAE作为公有云平台,首先面临的问题是应用的隔离,缺乏良好的隔离机制,平台必然无法长期稳定地运行。目前SAE的隔离性主要体现在以下几个方面:
代码和数据的隔离:每个应用在运行期间,只能“看”到自己的代码和数据,即A应用无法访问B应用的代码和数据。注意,这里提到的在Web服务器上的数据,往往指一些中间处理过程的临时数据,并非最终落地的数据,比如用户上传照片会临时存储到TmpFS。
【linux用户分配】
连接数的隔离:我们知道,程序写的不好,很容易导致阻塞,并进一步导致连接数的飙升。单个应用过多占用Apache连接数,原因往往是多方面的,应用请求外部资源被阻塞是一个最为常见的因素,另外应用页面过大浏览器下载慢也是常见因素之一。公有云平台同一时刻往往运行着大量的应用,如果某一应用出现连接数异常,最直接的后果是整个平台上的所有应用都将陷入瘫痪。SAE平台目前有设置“应用最大HTTP并发连接数”,目前这个值是500,如果应用平均单个请求处理时长是100ms,那么该应用每秒的HTTP并发连接将可以到达5000,每天的请求超过1亿没有问题。但如果您的应用平均每个请求处理时长2秒,那么该应用每秒的HTTP并发连接只能到达250,每天支撑的请求数将在千万。总体而言,尽量迅速处理完请求对应用是有利的,而且也是平台所鼓励的。【apache虚拟主机限制IP连接数】
内存隔离:目前SAE平台上对单个PHP脚本的处理,设置了64MB的上限(max_memory,ini_set不可修改)【php.ini的设置】,我们认为这个设置是一个相对很高的值,可以说能够满足绝大部分应用的需求。设想一台服务器8G内存,如果每个PHP处理都消耗64M内存,那么该服务器最多只能同时运行128个PHP脚本。SAE引入了”应用最大并发内存数“的概念,目前的设置是4GB。如果应用程序单个请求的内存消耗平均在16MB,那么可同时运行256个请求,这和上面的并发连接数的设定是基本一致的。
CPU隔离:这主要是通过SAE的配额系统来达到CPU时间的隔离。每个应用都有CPU时间消耗的分钟速度限制,避免了某一应用过多非法获取CPU资源导致其它应用响应慢的问题。 目前SAE平台上允许的“单请求最大存活时长”是300秒。max_execution_time 【php.ini的设置】
AppConfig类似于Apache的htaccess功能,用户可以自定义应用在Web服务器上的各项配置,AppConfig的作用域只是Web服务器,涉及到PHP配置请使用ini_set设置允许修改项,涉及到服务相关请通过SAE网站的应用管理面板管理对应服务。
目前AppConfig可以设置:目录默认页面、自定义错误页面、压缩、页面重定向(rewrite、301/302)、页面过期、响应头的content-type、页面访问权限
SAE由于考虑到安全和分布式问题,所以本地IO写是禁止的。首先代码目录是不可写的,SAE遵循代码目录的”写执行权限互斥“的原则,这样即使代码出现漏洞,也无法篡改代码,最大程度保证代码的安全。其次存储也是严禁写本地,由于分布式的特点,文件存储请使用saestorage服务。如果应用有文件缓存需求,在SAE上是无法提供本地文件缓存服务的,我们认为IO能力属于稀缺资源,不应当用于缓存业务,你可以选择使用mc来做缓存,mc缓存更加高效而且避免了在多台服务器上多次重复缓存的问题。由于很多php函数的参数依赖文件名,所以SAE也提供了tmpfs临时存储用于解决”中间数据交换“的需求。
为最大程度降低应用移植的难度,SAE为Storage、Memcache提供了wrapper封装,分别对应”saestor://”和”saemc://”,对于大部分应用,只需要修改目录前缀即可完成代码迁移。
为了尽量保持兼容性,我们并没有禁用fwrite,file_put_contents等写操作函数,但与传统的LAMP环境下语义上有差异:数据并不会永久地写到“本地”,而是通过以下两个方法写到临时存储或Storage/MC服务中:
· TmpFS,用于处理临时文件需求。
· Wrapper,让你只需要修改文件路径就可以将数据写入到Storage服务或者Memcache服务中。
【这里这个 Wrapper貌似就是指SAE中中国特色的封装】
MySQL相关
SAE提供的MySQL驱动是原生的,支持mysql、mysqli和pdo_mysql三个模块,底层基于mysqlnd驱动,使用mysqlnd的好处在于扩展开发更加容易。SAE即将上线的主从分离就是基于mysqlnd扩展开发。
Session
SAE提供了sessioncluster,使用标准的session相关函数即可。
Memcache
SAE提供的memcache模块,有一点微小改动,即连接memcache时,使用memcache_init获得连接句柄。其他完全一致。Memcache的hash使用的是一致性hash。
GD
为保证兼容性,我们也提供了原生的GD模块,但由于GD效率问题,我们并不很鼓励使用。
cURL
cURL目前已经基本做到了基本兼容。注意SAE的cURL是重载了FetchURL服务的,所以使用cURL本质上会不断消耗带宽资源。
XhProf
为方便开发者调试程序,我们也提供了XHProf模块,具体使用见面板的”XHProf”即可。
SAE提供了实时的日志检阅功能,方便开发者在线调试分析。
Runtime中输出的日志类型有:access、warning、error、notice、debug等,具体在管理面板的日志中心可以查阅。
【xhprof
XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。一个函数的开销,可细分成调用者和被调用者的开销,XHProf数据收集阶段,它记录调用次数的追踪和包容性的指标弧在动态callgraph的一个程序。它独有的数据计算的报告/后处理阶段。在数据收集时,XHProfd通过检测循环来处理递归的函数调用,并通过给递归调用中每个深度的调用一个有用的命名来避开死循环。XHProf分析报告有助于理解被执行的代码的结构,它有一个简单的HTML的用户界面( PHP写成的)。基于浏览器的性能分析用户界面能更容易查看,或是与同行们分享成果。也能绘制调用关系图。】
对外的数据抓取上,以前的SAE需要自行调用FetchURL服务,现在我们已经把对FetchURL服务的调用内置到php cURL下了。使用cURL进行数据抓取的程序,不需要任何修改就可以在SAE上运行了。
这里有一点要注意,目前的cURL不支持Proxy方式,另外,出于安全性考虑,在SAE使用cURL不能够抓取内网IP。
最近我们增加了Socket服务,你可以通过PHP的Socket相关函数(fsockopen,fread, fwrite)进行操作。目前该服务只支持TCP,并且不支持SSL等加密格式。
图像处理已经可以使用原生的GD函数接口,但发送邮件,还是需要使用SAE的Mail服务,通过SMTP方式进行邮件发送。不能直接使用PHP的Mail函数。如果你没有可用的SMTP服务账号,可以使用新浪邮箱(mail.sina.cn)申请。
出于平台安全性考虑,我们禁用了以下函数和类,禁用的标准主要有四点:
1、出于对安全性的考虑
2、出于对资源管理的考虑
3、不常用的API
4、我们提供更好替代方案的API
禁用的函数:
· php_real_logo_guid
· php_egg_logo_guid
· php_ini_scanned_files
· php_ini_loaded_file
· readlink
· linkinfo
· symlink
· link
· set_file_buffer
· exec
· system
· escapeshellcmd
· escapeshellarg
· passthru
· shell_exec
· proc_open
· proc_close
· proc_terminate
· proc_get_status
· proc_nice
· getmyuid
· getmygid
· getmyinode
· putenv
· getopt
· sys_getloadavg
· getrusage
· get_current_user
· magic_quotes_runtime
· set_magic_quotes_runtime
· import_request_variables
· debug_zval_dump
· ini_alter
· dl
· pclose
· popen
· stream_socket_client
· stream_socket_server
· stream_socket_accept
· stream_socket_pair
· stream_get_transports
· stream_wrapper_restore
· get_headers
· mb_send_mail
· openlog
· syslog
· closelog
· apc_add
· apc_bin_dump
· apc_bin_dumpfile
· apc_bin_load
· apc_bin_loadfile
· apc_cache_info
· apc_cas
· apc_clear_cache
· apc_compile_file
· apc_dec
· apc_define_constants
· apc_delete_file
· apc_delete
· apc_exists
· apc_fetch
· apc_inc
· apc_load_constants
· apc_sma_info
· apc_store
· flock
· pfsockopen
· posix_kill
· apache_child_terminate
·