API 无状态数据库访问性能



我有5台数据库服务器(一台在留尼汪岛,一台在毛里求斯,一台在马约特岛,两台在法国大陆。我在马赛服务器上制作了一个API,它将在每个BDD中选取数据(如果我不说愚蠢的话,由于核心网络,我们的其他服务器可以"本地"访问(。 一切正常,但是当您在多个服务器上选择时,它很长

我不知道是否有办法将不同的连接保留在缓存中,或者设置管理连接的服务,或者我不知道是什么,如果有人有解决方案,我就是接受者。 服务器是 PHP 5.4.16、Oracle DBMS、oci_connect 连接器,我做了一个无状态 API,通过 JWT 进行身份验证。 基本上,我们在马赛和其他服务器之间有200毫秒的ping,但是建立连接需要2到3秒。

由于 PHP 基于进程的设计以及无状态请求的使用,OCI8 扩展中没有连接池 API。 相反,您应该使用与oci_pconnect()调用的持久连接。 这样可以保留来自一个 HTTP 请求的连接以供下一个请求使用,因此速度要快得多。

(在 OCI8 实现的内部,持久连接确实使用 Oracle 的调用接口会话池 API,固定池大小仅为一个连接。 即每个 PHP 连接都有自己的池。这很有用,因为会话池是允许使用 DRCP 的技术(请参阅其他注释(,并且 Oracle 关于高可用性的文档建议使用会话池,例如用于 FAN 事件(。

确保不要过大运行的 PHP 进程数。 这将最大限度地减少所需的数据库连接数,从而允许更多的重用。 它还将减少每个数据库服务器上处理连接所需的内存量,因为它们将保持打开状态。 仅当数据库服务器内存不足时,您才会考虑使用 DRCP 池。

减少 Apache 进程重启,删除网络防火墙连接超时,并删除数据库资源限制,以免终止空闲连接。您希望这些"持久连接"是持久的,以便在您的应用程序调用oci_pconnect()时立即可以使用它们。 否则,OCI8 将不得不(在内部(不必要地重新创建连接。

接下来,您需要减少PHP和应用程序数据库之间的"往返",因为在慢速网络上,它们确实会对性能产生影响。 将尽可能多的工作转移到数据库中,例如使用 PL/SQL。

如果在每次oci_pconnect()调用后运行ALTER SESSION等语句,请将它们移动到 LOGON 触发器中。 或者至少用 PL/SQL 块包装它们:

begin
execute immediate
'alter session set nls_date_format = ''YYYY-MM-DD'' nls_language = AMERICAN';
-- other SQL statements could be put here
end;

如果从 PHP 执行,此块只需要一次往返。 如果在 LOGON 触发器中执行相同的操作,则往返次数为零。

对于正常的语句执行,请查看是否可以类似地将调用放入单个匿名 PL/SQL 块并使用单个oci_parse()调用。

接下来,通过调整预取大小来优化提取多行的查询。 同样,这有助于减少往返。

如果要上传数据,请考虑使用oci_bind_array_by_name(),甚至调用 Python(带有 cx_Oracle 扩展名(并使用executemany(),因为这些(再次(减少了往返。

这些是基本提示。 您可能会在手册示例或地下PHP和Oracle手册中找到其他示例。 或者,您可能需要考虑另一种体系结构,也许是批处理请求并在"远程"数据库上执行它们,然后将所有结果发回的体系结构。

与应用程序的性能无关,但由于您有"远程"数据库,因此您可能希望利用 Oracle Net 功能来检测死网络连接,并避免连接"挂起"等待 TCP 超时。 查看创建运行 PHP 应用程序的 sqlnet.ora 文件并使用SQLNET.OUTBOUND_CONNECT_TIMEOUT等选项。 如果无法阻止防火墙终止其他空闲连接,则可以在连接字符串中使用ENABLE=BROKEN

最新更新