openswoole-server-mysql.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. require_once __DIR__.'/vendor/autoload.php';
  3. use OpenSwoole\Http\Request;
  4. use OpenSwoole\Http\Response;
  5. use OpenSwoole\Http\Server;
  6. use OpenSwoole\Util;
  7. use OpenSwoole\Core\Coroutine\Client\PDOClientFactory;
  8. use OpenSwoole\Core\Coroutine\Client\PDOConfig;
  9. use OpenSwoole\Core\Coroutine\Pool\ClientPool;
  10. $server = new Server('0.0.0.0', 8080, OpenSwoole\Server::SIMPLE_MODE);
  11. $server->set([
  12. 'worker_num' => Util::getCPUNum() * 2,
  13. 'log_file' => '/dev/null',
  14. 'log_level' => 5,
  15. 'open_tcp_nodelay' => true,
  16. ]);
  17. $pool = null;
  18. /**
  19. * On start of the PHP worker. One worker per server process is started.
  20. */
  21. $server->on('workerStart', function () use(&$pool) {
  22. $config = (new PDOConfig())
  23. ->withHost('tfb-database')
  24. ->withDbname('hello_world')
  25. ->withUsername('benchmarkdbuser')
  26. ->withPassword('benchmarkdbpass')
  27. ->withOptions([
  28. PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  29. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  30. PDO::ATTR_EMULATE_PREPARES => false
  31. ]);
  32. $pool = new ClientPool(PDOClientFactory::class, $config, \intdiv(512, Util::getCPUNum() * 2));
  33. });
  34. /**
  35. * The DB test
  36. *
  37. * @param string $database_type
  38. * @param int $queries
  39. *
  40. * @return string
  41. */
  42. $db_mysql = function (int $queries, $pool): string {
  43. $db = $pool->get();
  44. $query_count = 1;
  45. if ($queries > 1) {
  46. $query_count = $queries > 500 ? 500 : $queries;
  47. }
  48. // Create an array with the response string.
  49. $arr = [];
  50. $db_test = $db->prepare('SELECT id, randomNumber FROM World WHERE id = ?');
  51. // For each query, store the result set values in the response array
  52. while ($query_count--) {
  53. $db_test->execute([\mt_rand(1, 10000)]);
  54. $arr[] = $db_test->fetch();
  55. }
  56. $pool->put($db);
  57. if($queries < 0) {
  58. return \json_encode($arr[0], JSON_NUMERIC_CHECK);
  59. }
  60. return \json_encode($arr, JSON_NUMERIC_CHECK);
  61. };
  62. /**
  63. * The Fortunes test
  64. *
  65. * @param string $database_type
  66. *
  67. * @return string
  68. */
  69. $fortunes_mysql = function ($pool): string {
  70. $db = $pool->get();
  71. $fortune = [];
  72. $fortune_test = $db->prepare('SELECT id, message FROM Fortune');
  73. $fortune_test->execute();
  74. $fortune = $fortune_test->fetchAll(PDO::FETCH_KEY_PAIR);
  75. $fortune[0] = 'Additional fortune added at request time.';
  76. asort($fortune);
  77. $html = '';
  78. foreach ($fortune as $id => $message) {
  79. $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
  80. $html .= "<tr><td>$id</td><td>$message</td></tr>";
  81. }
  82. $pool->put($db);
  83. return "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>$html</table></body></html>";
  84. };
  85. /**
  86. * The Updates test
  87. *
  88. * @param string $database_type
  89. * @param int $queries
  90. *
  91. * @return string
  92. */
  93. $updates_mysql = function (int $queries = 0, $pool): string {
  94. $db = $pool->get();
  95. $query_count = 1;
  96. if ($queries > 1) {
  97. $query_count = $queries > 500 ? 500 : $queries;
  98. }
  99. $arr = [];
  100. $updates_test_select = $db->prepare('SELECT id,randomNumber FROM World WHERE id = ?');
  101. $updates_test_update = $db->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');
  102. while ($query_count--) {
  103. $id = \mt_rand(1, 10000);
  104. $updates_test_select->execute([$id]);
  105. $world = ["id" => $id, "randomNumber" => $updates_test_select->fetchColumn()];
  106. $world['randomNumber'] = mt_rand(1, 10000);
  107. $updates_test_update->execute([$world['randomNumber'], $world['id']]);
  108. $arr[] = $world;
  109. }
  110. $pool->put($db);
  111. return \json_encode($arr, JSON_NUMERIC_CHECK);
  112. };
  113. /**
  114. * On every request to the (web)server, execute the following code
  115. */
  116. $server->on('request', static function (Request $req, Response $res) use ($db_mysql, $db_query, $fortunes_mysql, $updates_mysql, &$pool) {
  117. try {
  118. switch ($req->server['request_uri']) {
  119. case '/json':
  120. $res->header('Content-Type', 'application/json');
  121. $res->header('Server', 'os');
  122. $res->end(json_encode(['message' => 'Hello, World!']));
  123. break;
  124. case '/plaintext':
  125. $res->header('Content-Type', 'text/plain; charset=utf-8');
  126. $res->header('Server', 'os');
  127. $res->end('Hello, World!');
  128. break;
  129. case '/db':
  130. $res->header('Content-Type', 'application/json');
  131. $res->header('Server', 'os');
  132. if (isset($req->get['queries'])) {
  133. $res->end($db_mysql((int)$req->get['queries'], $pool));
  134. } else {
  135. $res->end($db_mysql(-1, $pool));
  136. }
  137. break;
  138. case '/fortunes':
  139. $res->header('Content-Type', 'text/html; charset=utf-8');
  140. $res->header('Server', 'os');
  141. $res->end($fortunes_mysql($pool));
  142. break;
  143. case '/updates':
  144. $res->header('Content-Type', 'application/json');
  145. $res->header('Server', 'os');
  146. if (isset($req->get['queries'])) {
  147. $res->end($updates_mysql((int)$req->get['queries'], $pool));
  148. } else {
  149. $res->end($updates_mysql(-1, $pool));
  150. }
  151. break;
  152. default:
  153. $res->status(404);
  154. $res->end('Error 404');
  155. }
  156. } catch (\Throwable $e) {
  157. $res->status(500);
  158. $res->end('Error 500');
  159. }
  160. });
  161. $server->start();