1

我有一个包含诸如id, type,data等字段的表...我需要在 PHP 中编写一个 Web 服务脚本,该脚本应该将数据插入到表中,然后选择最后 10 条具有相同类型的记录并在 HTTP 正文中返回。

每秒需要 1000 个实例访问此脚本。

我的问题是最好的方法是什么?

这是我的代码。我不确定这是一个很好的做法,并且可以举一个如何使它变得更好的例子......

// Connect to mysql server
$link = mysql_connect(HOST, USER, PASSWORD);
if(!$link) {
    die('Could not connect to server: ' . mysql_error());
}

// Select database
$db = mysql_select_db(DATABASE);
if(!$db) {
    die('Cannot use the database');
}
mysql_set_charset('charset=utf8', $link); 

// Insert data
$query = "INSERT INTO `mytable` (`id`, `type`, `data`) VALUES ('$id', '$type', '$data')";   
mysql_query($query);

// Select data
$query = "SELECT * FROM `mytable` WHERE `type`='$type' ORDER BY DESC LIMIT 10";
$result = mysql_query($query);

while($row = mysql_fetch_assoc($result)) {

    // Create xml to return

}
4

2 回答 2

2

您的 PHP 脚本本身(忽略任何安全问题)不太可能成为将其扩展到您期望的负载的问题。您的基础设施将很重要,并且会在此脚本是否适用于您期望的负载之间产生差异。

您的 MySQL 实例每秒可以支持 1000 个新连接吗?您的 Web 服务器可以每秒运行此脚本 1000 次吗?

解决这个问题的唯一方法是对其进行基准测试,以确定您在哪里,您可以支持哪些负载?如果你不能支持它,那么你需要找到瓶颈,但我怀疑它永远不会是这个脚本。


根据您的评论进行更新,最好的方法是模拟您期望的负载,如果您的设置可以处理这个问题,没有必要担心。如果它不能处理它,那么你需要缩小问题的范围。

首先,下载一个像 Apache JMeter 这样的工具。您可以遵循一些教程来设置模拟以尝试您的设置。

从这里您可以确定问题的范围,如果您可以支持超出您预期的流量,您可能不需要担心。如果你能支持它或者你还有很长的路要走,你需要找到阻碍你达到这个目标的瓶颈。

通过单独测试系统的各个部分来缩小问题范围,这是您回答问题的地方,例如您的 Web 服务器或数据库可以支持多少连接。一旦你确定了瓶颈;阻止您处理更多流量的原因,然后您可以更好地了解您需要做什么。

使用 Apache JMeter:
http
://www.davegardner.me.uk/blog/2010/09/23/effective-load-testing-with-apache-jmeter/ 使用 mysqlslap 加载测试 MySQL:
http://dev.mysql .com/doc/refman/5.1/en/mysqlslap.html

引导说明:可能会有很多东西要学……希望这能让你开始,并且你可以相对轻松地支持你正在寻找的负载。如果不是,则需要大量阅读 Web 服务的可扩展架构、您正在使用的系统的高级配置以及耐心。


使用 PDO

//Connect to mysql server
$host = ""; // Your database host name
$driver = "mysql";
$database = ""; // Your database;
$user = ""; // The user for the database;
$password = ""; // The password for the database;

// Create a DSN string from the above parameters
$dsn = "$driver:host=$host;dbname=$database";

// Create a connection you must have the pdo_mysql
// extension added to your php.ini
try {
    $db = new PDO($dsn, $user, $password);

// The connection could not be made
} catch(PDOException $ex)
    die("Could not connect to server: {$ex->getMessage()}");
}

// Prepare an insert statement
$stmt = $db->prepare("
    INSERT INTO `mytable` (`id`, `type`, `data`) 
    VALUES      (:id, :type, :data)
");    

// I'm guessing at the types here, use the reference
// http://php.net/manual/en/pdo.constants.php to
// select the right datatypes. Using parameter binding
// you ensure that the value is converted and escaped
// correctly for the database
$stmt->bindParam(":id", $id, PDO::PARAM_INT);
$stmt->bindParam(":type", $type, PDO::PARAM_STR);
$stmt->bindParam(":data", $data, PDO::PARAM_LOB);

// Execute the insert statement
$stmt->execute();

// Prepare a select data
$stmt = $db->prepare("
    SELECT   * 
    FROM     `mytable` 
    WHERE    `type` = :type 
    ORDER BY `id` DESC 
    LIMIT 10
");

// Again bind the parameters
$stmt->bindParam(":type", $type, PDO::PARAM_STR);

// Execute the select statement
$stmt->execute();

// There are different ways that fetch can return
// a row, the web page above lists all of the
// different types of fetch as well. In this case
// we are fetching the rows as associative arrays
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

    // Write XML for rows
}

// Finalise and output XML response

使用 PDO: http:
//net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/

于 2012-10-14T14:41:31.183 回答
0

作为一个小改进,您可以在一个查询中完成所有操作:

$query= "
    INSERT INTO `mytable` (`id`, `type`, `data`) 
    VALUES ('$id', '$type', '$data')
    ;    
    SELECT * 
    FROM `mytable` 
    WHERE `type` = '$type' 
    ORDER BY DESC 
    LIMIT 10
    ;";
于 2012-10-14T14:48:57.753 回答