Рассказ о том как я участвовал в highloadcup (чемпионат для backend-разработчиков) от Mail.Ru. Написал на php сервер обслуживающий 10000 RPS, но я всё равно не получил победную футболку.
$server = new Swoole\Http\Server('0.0.0.0', 1080);
$server->set(['worker_num' => 1,]);
$server->on('Request', function($req, $res) {$res->end('hello world');});
$server->start();
ab -c 10 -n 10000 http://127.0.0.1:1080/
require_once DIR . '/vendor/autoload.php';
use Workerman\Worker;
$http_worker = new Worker("http://0.0.0.0:1080");
$http_worker->count = 1;
$http_worker->onMessage = function($conn, $data) {$conn->send("hello world");};
Worker::runAll();
pecl install event
добавил в код:Worker::$eventLoopClass = '\Workerman\Events\Ev';
require_once DIR . '/vendor/autoload.php';
use Workerman\Worker;
Worker::$eventLoopClass = '\Workerman\Events\Ev';
$http_worker = new Worker("http://0.0.0.0:1080");
$http_worker->count = 1;
$http_worker->onMessage = function($conn, $data) {$conn->send("hello world");};
Worker::runAll();
$serv = new Swoole\Http\Server('0.0.0.0', 1080, SWOOLE_BASE);
$serv = new Swoole\Http\Server('0.0.0.0', 1080);
$serv = new Swoole\Http\Server('0.0.0.0', 1080, SWOOLE_BASE);
$serv->set(['worker_num' => 1,]);
$serv->on('Request', function($req, $res) {$res->end('hello world');});
$serv->start();
const http = require('http');
const server = http.createServer(function(req, res) {
res.writeHead(200);
res.end('hello world');
});
server.listen(1080);
package main
import (
"flag"
"fmt"
"log"
"github.com/valyala/fasthttp"
)
var (
addr = flag.String("addr", ":1080", "TCP address to listen to")
compress = flag.Bool("compress", false, "Whether to enable transparent response compression")
)
func main() {
flag.Parse()
h := requestHandler
if *compress {
h = fasthttp.CompressHandler(h)
}
if err := fasthttp.ListenAndServe(*addr, h); err != nil {
log.Fatalf("Error in ListenAndServe: %s", err)
}
}
func requestHandler(ctx *fasthttp.RequestCtx) {
fmt.Fprintf(ctx, "Hello, world!")
}
User (Профиль):
id — уникальный внешний идентификатор пользователя. Устанавливается тестирующей системой и используется для проверки ответов сервера. 32-разрядное целое беззнаковое число.
email — адрес электронной почты пользователя. Тип — unicode-строка длиной до 100 символов. Уникальное поле.
first_name и last_name — имя и фамилия соответственно. Тип — unicode-строки длиной до 50 символов.
gender — unicode-строка m означает мужской пол, а f — женский.
birth_date — дата рождения, записанная как число секунд от начала UNIX-эпохи по UTC (другими словами — это timestamp).
Location (Достопримечательность):
id — уникальный внешний id достопримечательности. Устанавливается тестирующей системой. 32-разрядное целое беззнаковоее число.
place — описание достопримечательности. Текстовое поле неограниченной длины.
country — название страны расположения. unicode-строка длиной до 50 символов.
city — название города расположения. unicode-строка длиной до 50 символов.
distance — расстояние от города по прямой в километрах. 32-разрядное целое беззнаковое число.
Visit (Посещение):
id — уникальный внешний id посещения. 32-разрядное целое беззнакое число.
location — id достопримечательности. 32-разрядное целое беззнаковое число.
user — id путешественника. 32-разрядное целое беззнаковое число.
visited_at — дата посещения, timestamp.
mark — оценка посещения от 0 до 5 включительно. Целое число.
$visits = new swoole_table(11000000);
$visits->column('id', swoole_table::TYPE_INT);
$visits->column('user', swoole_table::TYPE_INT);
$visits->column('location', swoole_table::TYPE_INT);
$visits->column('mark', swoole_table::TYPE_INT);
$visits->column('visited_at', swoole_table::TYPE_INT);
$visits->create();
$i = 1;
while ($visitsData = @file_get_contents("data/visits_$i.json")) {
$visitsData = json_decode($visitsData, true);
foreach ($visitsData['visits'] as $k => $row) {
$visits->set($row['id'], $row);
}
$i++;
}
unset($visitsData);
gc_collect_cycles();
echo 'memory: ' . intval(memory_get_usage() / 1000000) . "\n";
$visits = [];
$i = 1;
while ($visitsData = @file_get_contents("data/visits_$i.json")) {
$visitsData = json_decode($visitsData, true);
foreach ($visitsData['visits'] as $k => $row) {
$visits[$row['id']] = $row;
}
$i++;echo "$i\n";
}
unset($visitsData);
gc_collect_cycles();
echo 'memory: ' . intval(memory_get_usage() / 1000000) . "\n";
$visits = new SplFixedArray(11000000);
$i = 1;
while ($visitsData = @file_get_contents("data/visits_$i.json")) {
$visitsData = json_decode($visitsData, true);
foreach ($visitsData['visits'] as $k => $row) {
$visits[$row['id']] = $row;
}
$i++;echo "$i\n";
}
unset($visitsData);
gc_collect_cycles();
echo 'memory: ' . intval(memory_get_usage() / 1000000) . "\n";
$visits[1] = ['user' => 153, 'location' => 17, 'mark' => 5, 'visited_at' => 1503695452];
$visits_user[1] = 153;
$visits_location[1] = 17;
$visits_mark[1] = 5;
$visits_visited_at[1] => 1503695452;
$user = $location = $mark = $visited_at = [];
$i = 1;
while ($visitsData = @file_get_contents("data/visits_$i.json")) {
$visitsData = json_decode($visitsData, true);
foreach ($visitsData['visits'] as $k => $row) {
$user[$row['id']] = $row['user'];
$location[$row['id']] = $row['location'];
$mark[$row['id']] = $row['mark'];
$visited_at[$row['id']] = $row['visited_at'];
}
$i++;echo "$i\n";
}
unset($visitsData);
gc_collect_cycles();
echo 'memory: ' . intval(memory_get_usage() / 1000000) . "\n";
$user = new SplFixedArray(11000000);
$location = new SplFixedArray(11000000);
$mark = new SplFixedArray(11000000);
$visited_at = new SplFixedArray(11000000);
$user_visits = [];
$location_visits = [];
$i = 1;
while ($visitsData = @file_get_contents("data/visits_$i.json")) {
$visitsData = json_decode($visitsData, true);
foreach ($visitsData['visits'] as $k => $row) {
$user[$row['id']] = $row['user'];
$location[$row['id']] = $row['location'];
$mark[$row['id']] = $row['mark'];
$visited_at[$row['id']] = $row['visited_at'];
if (isset($user_visits[$row['user']])) {
$user_visits[$row['user']][] = $row['id'];
} else {
$user_visits[$row['user']] = [$row['id']];
}
if (isset($location_visits[$row['location']])) {
$location_visits[$row['location']][] = $row['id'];
} else {
$location_visits[$row['location']] = [$row['id']];
}
}
$i++;echo "$i\n";
}
unset($visitsData);
gc_collect_cycles();
echo 'memory: ' . intval(memory_get_usage() / 1000000) . "\n";
const fs = require('fs');
global.visits = []; global.users_visits = []; global.locations_visits = [];
let i = 1; let visitsData;
while (fs.existsSync(`data/visits_${i}.json`) && (visitsData = JSON.parse(fs.readFileSync(`data/visits_${i}.json`, 'utf8')))) {
for (y = 0; y < visitsData.visits.length; y++) {
//visits[visitsData.visits[y]['id']] = visitsData.visits[y];
visits[visitsData.visits[y]['id']] = {
user:visitsData.visits[y].user,
location:visitsData.visits[y].location,
mark:visitsData.visits[y].mark,
visited_at:visitsData.visits[y].visited_at,
//id:visitsData.visits[y].id,
};
}
i++;
}
global.gc();
console.log("memory usage: " + parseInt(process.memoryUsage().heapTotal/1000000));
К сожалению, не доступен сервер mySQL