Azure中使用Laravel的单个请求的多个重复HTTP请求/查询

Ben*_*son 5 php postgresql ajax laravel

我在Azure上提供了一个Laravel应用程序.我正在使用AJAX请求来轮询javascript图表的数据.

AJAX请求在我的路由(web.php)中定义的URL,因此:

Route::get('/rfp_chart_data', 'DataController@chart_data')->name('chart_data');
Run Code Online (Sandbox Code Playgroud)

该控制器方法运行postgresql查询并返回JSON文件.一切正常.

但是,在遇到一些性能问题后,我决定监视postgres查询,并发现对于此URL的每个请求,同一查询运行了3次.

无论我是否:

  • 通过AJAX请求访问URL

  • 直接转到浏览器中的URL

  • 通过cURL访问URL

这个(AFAIK)消除了这种某种缺少img src问题的可能性(例如什么可能导致双页请求?)

非常感谢任何帮助......

编辑:

postgres pg_stat_activity中重复查询的图像 - 来自1个Web请求:

重复请求的图像

编辑:

完整控制器代码:

<?php

namespace App\Http\Controllers;

use App\AllRfpEntry;
use DB;
use Illuminate\Http\Request;
use Yajra\Datatables\Facades\Datatables;

class DataController extends Controller {
    /**
     * Displays datatables front end view
     *
     * @return \Illuminate\View\View
     */

    //|| result_url || '\">' || result_title || '</a>'

    public function chart_data(Request $request) {

        $binding_array = array();

        $chart_data_sql = "SELECT relevant_dates.date::date,
            CASE WHEN award_totals.sum IS NULL
            THEN 0
            ELSE award_totals.sum
            END
            as sum

            ,


            CASE WHEN award_totals.transaction_count IS NULL
            THEN 0
            ELSE award_totals.transaction_count
            END
            as transaction_count FROM

            (
            SELECT * FROM generate_series('" . date('Y-m-01', strtotime('-15 month')) . "'::date, '" . date('Y-m-01') . "'::date, '1 month') AS date
            )  relevant_dates

            LEFT JOIN

            (
            SELECT extract(year from awarded_date)::text || '-' || RIGHT('0' || extract(month from awarded_date)::text, 2) || '-01'  as date, sum(award_amount)::numeric as sum, COUNT(award_amount) as transaction_count FROM all_rfp_entries

            WHERE awarded_date >= '" . date('Y-m-01', strtotime('-15 month')) . "'

            AND awarded_date <= '" . date("Y-m-d") . "' AND award_status = 'AWARDED'
            AND award_amount::numeric < 10000000000";

        if ($request->get('rfp_company_filter')) {

            $binding_array['rfp_company_filter'] = $request->get('rfp_company_filter');

            $chart_data_sql .= " AND company = :rfp_company_filter";

        };

        if ($request->get('rfp_source_filter')) {

            $binding_array['rfp_source_filter'] = $request->get('rfp_source_filter');

            $chart_data_sql .= " AND rfp_source = :rfp_source_filter";

        }

        if ($request->get('exclude_fed_rev')) {

            $chart_data_sql .= " AND rfp_source != 'US FED REV' ";

        }

        if ($request->get('rfp_year_filter')) {

            $binding_array['rfp_year_filter'] = $request->get('rfp_year_filter');

            $chart_data_sql .= " AND year = :rfp_year_filter";

        }

        if ($request->get('rfp_priority_level_filter')) {

            $binding_array['rfp_priority_level_filter'] = $request->get('rfp_priority_level_filter');

            $chart_data_sql .= " AND priority_level = :rfp_priority_level_filter";

        }

        if ($request->get('rfp_search_input_chart')) {

            $binding_array['rfp_search_input_chart'] = $request->get('rfp_search_input_chart');

            $chart_data_sql .= " AND search_document::tsvector @@ plainto_tsquery('simple', :rfp_search_input_chart)";

        }

        $chart_data_sql .= " GROUP BY extract(year from awarded_date), extract(month from awarded_date)
        ) award_totals
        on award_totals.date::date = relevant_dates.date::date

        ORDER BY extract(year from relevant_dates.date::date), extract(month from relevant_dates.date::date)
        ";

        return json_encode(DB::select($chart_data_sql, $binding_array));


    }

    public function data(Request $request) {

        $query = AllRfpEntry::select('id', 'year', 'company', 'result_title', 'award_amount', 'edit_column', 'doc_type', 'rfp_source', 'posted_date', 'awarded_date', 'award_status', 'priority_level', 'word_score', 'summary', 'contract_age', 'search_document', 'link');

        if ($request->get('exclude_na')) {

            $query->where('all_rfp_entries.company', '!=', 'NA');

        }

        if ($request->get('clicked_date')) {

            $query->where('all_rfp_entries.awarded_date', '>', $request->get('clicked_date'));

            $query->where('all_rfp_entries.awarded_date', '<=', $request->get('clicked_date_plus_one_month'));

        }

        if ($request->get('filter_input')) {

            $query->whereRaw("search_document::tsvector @@ plainto_tsquery('simple', '" . $request->get('filter_input') . "')");

        }

        $datatables_json = datatables()->of($query)

            ->rawColumns(['result_title', 'edit_column', 'link'])

            ->orderColumn('award_amount', 'award_amount $1 NULLS LAST')
            ->orderColumn('priority_level', 'priority_level $1 NULLS LAST');

        if (!$request->get('filter_input')) {

            $datatables_json = $datatables_json->orderByNullsLast();

        }

        if (!$request->get('filter_input') and !$request->get('clicked_date')) {

            $count_table = 'all_rfp_entries';

            $count = DB::select(DB::raw("SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = :count_table "), array('count_table' => $count_table))[0]->n_live_tup;

            $datatables_json = $datatables_json->setTotalRecords($count);

        }

            $datatables_json = $datatables_json->make(true);

        return $datatables_json;

    }


}
Run Code Online (Sandbox Code Playgroud)

编辑:

更疯狂的皱纹......

我在这台服务器上的Laravel中有一个方法指向另一台服务器上的postgres数据库来摄取新数据.我刚刚发现即使是THAT方法(指向外部服务器的方法)也会在外部postsgres服务器上生成多个查询!

在此输入图像描述

除非我遗漏了某些内容,否则这会消除nginx问题或我的提供商(Azure)的问题,或者任何一种特定方法的问题.即使是通过端口5432的直接数据库连接(我假设Laravel如何访问外部数据库)也会产生乘数效应,所以它必须是我的Laravel安装的一些东西......但是没有更接近找出什么.

sg3*_*g3s 4

调试此问题的最佳方法是使用 xdebug 启动调试会话并逐步执行代码,同时在单独的窗口中关注 stdout/logging 输出。

在控制器的第一行设置一个断点,当它中断时应该完成 0 个查询。如果不是,您就知道路由/请求中发生了奇怪的事情。然后逐步执行构建查询时使用的函数调用。

可能是您使用的函数之一触发了执行查询(如 Aaron Saray 所建议的)或方法缺失(如 Diogo Gomes 所建议的),但是如果不知道代码或单步执行执行上下文步骤,则很难判断这一点 -一步一步。

如果您没有调试器,您始终可以dd($data);在任何行使用来停止处理并转储给定的数据。这只需要更长的时间,因为您将为代码中的每个步骤发出一个新请求。