<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                項目背景 該項目為基于微信公眾號的投票項目,每人每天可以投 10 票。項目為周期性項目,上線 15 天后自然下線,日平均 pv 20W(甲方在溝通需求過程中說的用戶量要遠比這個數字高)。因為項目用戶情況特殊,24 小時均有用戶操作。高峰為晚 4 點到晚 8 點,最高峰每分鐘 200 次投票,阿里云性能測試(PTS)壓測,最高并發400,TPS 400+。 因為項目要求上線15天中零故障,同時因為不自信。采用了四臺百度云主機,其中兩臺程序主機(使用負載均衡),一臺獨立 MySQL,一臺獨立 Redis。項目下線后總結,其實只用一臺程序主機完全足夠了。 因為項目下線后經我總結,對項目代碼有一些調整,本章節提供的代碼是調整后的代碼。調整后的代碼性能和并發要比上述調整前的性能并發數至少高于30% 項目設計 項目同時運行四個投票活動,每個活動投票數,選項數,每個用戶每日投票數獨立。使用微信公眾號網頁授權來開發,除了便于傳播外,還可以用 open_id 來識別用戶,某種情況下解決了刷票和灌水等惡意攻擊。所有投票均有投票記錄,每個投票記錄由活動 id,open_id,投票時間組成。 投票操作由 ajax 提交給 swoole_http_server,所有投票數和投票記錄均先寫入 Redis,然后由 Swoole 毫秒定時器每分鐘寫入一次數據庫做持久化存儲;實時排行榜使用 Redis 的有序集合數據結構完成;每個投票活動和投票選項詳情內容使用 Redis 存儲。避免過大訪問量帶給 MySQL 壓力。 基礎環境建設 除了標準的 lnmp 環境配置外,通過 pecl 安裝 swoole,redis pecl 拓展 $ > `pecl install swoole` $ > `pecl install redis` 安裝成功后通過php --ri redis和php --ri swoole來檢查是否安裝成功 本章節不提供 LNMP 環境配置和 Redis 服務器端安裝教程 投票流程 1.創建命令行類 - 創建application/console/Vote.php文件 ~~~ <?php namespace app\Console; use think\console\Command; use think\console\Input; use think\console\Output; use think\Db; use think\Exception; class Vote extends Command { protected $server; // 命令行配置函數 protected function configure() { // setName 設置命令行名稱 && setDescription 設置命令行描述 $this->setName('vote:server')->setDescription('Start Vote Server!'); } // 設置命令返回信息 protected function execute(Input $input, Output $output) { $this->server = new \swoole_http_server("0.0.0.0", 9502); $this->server->on('WorkerStart', [$this, 'onWorkerStart']); $this->server->on('Request', [$this, 'onRequest']); $this->server->on('Task', [$this, 'onTask']); $this->server->on('Finish', [$this, 'onFinish']); $this->server->start(); } // Worker/Task進程啟動時回調函數 public function onWorkerStart(\swoole_server $serv, $worker_id) { if (0 == $worker_id) { // 啟動 Timer 定時器,每5分鐘回調一次 asyncWriteDatabase 函數 swoole_timer_tick(1000 * 60 * 5, [$this, 'asyncWriteDatabase']); } } // 響應函數 public function onRequest(\swoole_http_server $server, \swoole_http_request $request, \swoole_http_response $response) { try { $data = isset($request->get) ? $request->get : ''; if (empty($data)) { throw new Exception('沒有傳遞參數', 422); } $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); if (0 == $redis->hGet('vote_user_number:' . $data['vote_id'], $data['open_id'])) { throw new Exception('今日投票數已用完', 503); } if ($redis->exists('option_today_proof:' . $data['option_id'] . ':' . $data['open_id'])) { throw new Exception('今日已投過該選項', 405); } // 減少用戶今日投票數 $redis->hIncrBy('vote_user_number:' . $data['vote_id'], $data['open_id'], -1); // 創建用戶和選項今日的已投票憑證 $exp = Time::today()[1] - time(); $redis->set('option_today_proof:' . $data['option_id'] . ':' . $data['open_id'], 1, $exp); // 增加所有投票的總票數 $redis->incrBy('totalVoteCount', 1); // 增加指定投票的所有選項總票數 $redis->incrBy($data['vote_id'] . 'OfVoteCount', 1); // 增加選項的投票數 $redis->zIncrBy('vote: '. $data['vote_id'] . ':option', 1, $data['option_id']); // 投遞異步任務,使用異步完成投票記錄寫入 Redis 隊列 $data['create_time'] = time(); $server->task(json_encode($data)); } catch (Exception $exception) { $response->end(json_encode(['code' => $exception->getCode(), 'message' => $exception->getMessage()])); } $response->end(json_encode(['code' => 200, 'message' => '操作成功'])); } // 異步任務處理函數 public function onTask(\swoole_server $serv, $task_id, $src_worker_id, $data) { // 把每個用戶的投票記錄寫入 Redis 隊列 $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); $redis->lPush('voteLogQueue', $data); return true; } // 異步任務完成通知 public function onFinish(\swoole_server $server, $task_id, $data) { } // 定時器任務函數 public function asyncWriteDatabase($timer_id, $params = null) { $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); // 把 Redis 隊列中的投票記錄取出,寫入到 MySQL 數據庫 $length = $redis->lLen('voteLogQueue'); for ($i = 1; $i <= $length; $i++) { $log = json_decode($redis->rPop('voteLogQueue'), true); Db::name('vote_log')->insert($log); } } } ~~~ 2.修改配置文件 - 文件所在 application/command.php ~~~ <?php return [ 'app\console\Vote', ]; ~~~ 接下來就可以通過命令行來啟動投票服務 $ >` php think vote:server`
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看