Я написал следующий PHP script для работы с прокси-сервером HTTP для фильтрации контента. Прокси-сервер отправляет этот script URL-адрес сайта, который пользователь пытается посетить. script (очевидно) проверяет сайт на ключевые слова, которые должны быть заблокированы, а затем отвечает на прокси. Слишком много времени для перехода между страницами. В настоящее время.... около 3 минут. на страницу.
Вот этот код:
<?php
$location = $_POST['Location'];
$user = $_POST['User'];
if($location == "") {
die("Invalid Request! Missing Parameter 1!");
}
if($user == "") {
die("Invalid Request! Missing Parameter 2!");
}
$con = mysql_connect("MySQL Host", "USER", "PASS") or die(mysql_error());
mysql_select_db("DBName", $con) or die(mysql_error());
$query = "SELECT `Policy` FROM Subscribe WHERE `Username`='$user'";
$result = mysql_query($query) or die(mysql_error());
if(mysql_num_rows($result) == "1") {
$nothing = "nothing";
} else {
die("Invalid User!");
}
while($row = mysql_fetch_assoc($result)) {
$policy = $row['Policy'];
}
if($policy == "0") {
echo "allow";
exit;
}
if($policy == "4") {
$query1 = "SELECT `Address`, `Keyword` FROM Policy WHERE `Owner`='$user'";
$result2 = mysql_query($query1) or die(mysql_error());
while($row = mysql_fetch_assoc($result2)) {
$address = explode(',', $row['Address']);
$keyword = explode(',', $row['Keyword']);
}
} else {
$query2 = "SELECT `Address`, `Keyword` FROM Policies WHERE `Policy`='p".$policy."'";
$result2 = mysql_query($query2) or die(mysql_error());
while($row = mysql_fetch_assoc($result2)) {
$address = explode(',', $row['Address']);
$keyword = explode(',', $row['Keyword']);
}
}
if(in_array($location, $address)) {
echo "deny";
exit;
} else {
$meta = get_meta_tags($location);
$keywords = $meta['keywords'];
$keywords = preg_replace('/\s+/', ' ', $keywords);
$keywords = str_replace(' ', '', $keywords);
$keywords = explode(',', $keywords);
while (list($key, $val) = each($keywords)) {
if(in_array($val, $keyword)) {
echo "deny";
exit;
}
}
$urlk = explode('.', $location);
while (list($key, $val) = each($urlk)) {
if(in_array($val, $keyword)) {
echo "deny";
exit;
}
}
}
echo "allow";
?>
3 минуты/страница очень сомнительна, но часть else
кода:
if (in_array($location, $address))
является узким местом из-за дискового ввода-вывода и соответствия ключевых слов.
Посмотрите, помогает ли это (без кеширования):
else {
$meta=get_meta_tags($location);
$keywords=explode(',',str_replace(' ','',$meta['keywords']));
$urlk=explode('.',$location);
if (array_intersect($keywords,$keyword) || array_intersect($location,$urlk))
echo 'deny';
}
$query1/2
и $result1/2
можно легко перезаписать, называя их с тем же именем. Это не вызовет никаких проблем. Кроме того, результаты mysql очень тяжелые.
Чтобы проверить, является ли переменная пустой, есть собственная функция php, которая также проверяет, равна ли эта переменная NULL, '' или вообще не задана: empty($var)
. Я бы использовал его для первой части вашего кода вместо $var == ''
, которая тоже не изящна.
Также mysql_num_rows()
возвращает целое число, и вы сравниваете этот результат со строкой со значением "1". Я исправлю его с помощью mysql_num_rows($result) == 1
.
Мы имеем также проблему
echo "deny";
exit;
который можно заменить на exit('deny');
Я все еще сомневаюсь, что на страницу требуется 3 минуты, может быть, 3 секунды?
Вы пытались использовать GET вместо POST? Технически они должны быть одинаковой скорости, но прокси-сервер может делать что-то странное с помощью POST, чтобы предотвратить несколько запросов.
Вот пример использования GET вместо urllib: http://docs.python.org/library/urllib.html#examples
Точно, как долго "слишком длинный"? Вы можете попробовать синхронизировать его по сравнению с доступом к сайту без прокси.
Кроме того, вам может понадобиться выполнить другое профилирование, чтобы увидеть, где находится узкое место. Это ваш python script, ваше подключение к Интернету, PHP скрипт или хост PHP? Является ли сайт PHP на общем хосте? Это может быть более эффектно, если у вас есть выделенный или VPS.
Еще одна мысль: вы можете попробовать добавить кеширование на стороне PHP. Если один и тот же пользователь продолжает использовать один и тот же сайт (-ы) снова и снова, нет никакого смысла в запросе базы данных каждый раз.
Как вы вставляете его, похоже, что вызов ProxyRequest.process(self) не выполняется внутри вашего метода процесса.