Yêu cầu thg 5 22, 2022 2:58 CH 161 0 2
  • 161 0 2
0

Cấu hình sever khi chạy chương trình nặng trong laravel

Chia sẻ
  • 161 0 2

Mình mới đưa 1 website lên vps ( CentOs7 - Nginx - larave9 - php8) Mình cco một chương trình đệ quy chạy khá nặng nên khi vào truy cập vào thì luôn báo là 502 bad Gateway trong log của nginx thì báo

2022/05/22 15:02:49 [error] 28086#0: *23 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 210.245.104.244, server: domain.com, request: "GET /testTNT HTTP/2.0", upstream: "fastcgi://unix:/tmp/php-cgi-80.sock:", host: "domain.com"

Vấn đề là cùng code và db đó mình chạy trên localhost thì nó không sao cả. Hiện mình đang không biết cần chỉnh sửa gì trong cấu hình của PHP or Nginx. thanks

2 CÂU TRẢ LỜI


Đã trả lời thg 5 22, 2022 5:26 CH
0

cái này bạn chạy đệ quy truy xuất trực tiếp từ cơ sở dữ liệu sẽ khá nặng .Bạn thử cân nhắc xem cách mình xem sao .Truy vấn 1 lần cơ sở dữ liệu sau đó lưu trữ dưới dạng array .Các lần đệ quy bạn sẽ đệ quy trên array điều này sẽ giảm tải cho cơ sở dữ liệu sẽ xử lý được vấn đề

Chia sẻ
Avatar LongThanh @LongThanh.it
thg 5 23, 2022 10:36 SA

Mình cũng từng có ý tưởng đó nhưng vì số lượng bản ghi khá lớn tầm hơn 40.000 bản ghi và còn tăng nên làm thể cái arr sợ nó to quá dễ bị lỗi k nhỉ?

Avatar Dương Hải Ngọc @haingoc86vibo
thg 5 26, 2022 7:29 SA

@LongThanh.it thường thì đệ quy để hiểu được thuật toán thôi, còn code thực thế sẽ chuyển thành vòng lặp while hoặc for , chứ dùng đệ quy nó ngốn tài nguyên máy chủ lắm , vì khi hàm đệ quy chưa thực thi xong nó sẽ không giải phóng bộ nhỡ hay đóng kết nối DB

Avatar LongThanh @LongThanh.it
thg 5 26, 2022 8:25 SA

Hiện tại mình đang có 2 hướng đi.

  1. Truy vấn đệ quy trực tiếp với database thông qua model.
Model: 
 public function parent()
    {
        return $this->hasMany(Post::class, 'id', 'parent_id')->with('parent');
    }
Contronller 
 public function home($id
    {
        $AllPost = Post::select('id',  'parent_id', )->with('parent')->get()->toArray();
        $collapsed = collect($nhanh)->flatten();
//  Đã có dữ liệu .... 
}
  1. Lấy hết dữ liệu ra thành array sau đó với dùng đệ quy phân cấp.
Controller:

public function home($id)
    {
        $post= Post::where('id', $id)->first();
            $allpost= Post::select('id', 'parent_id') ->get()->toArray();
            $collapsed = $this->dequy_timcha($allpost, $post->id);
      //Đã có dữ liệu .... 
     }

public function dequy_timcha($data, $parent_id)
    {
        $result = [];
        foreach ($data as $key => $item) {
            if ($item['id'] == $parent_id) {
                $result[] = $item;
$child = $this->dequy_timcha($data, $item['parent_id']);
                $result = array_merge($result, $child);
            }
        }
        return $result;
    }  

Mình đã test cả hai cách này với dữ liệu tầm hơn 40.000 thì nó lag như nhau. ko thấy khác biệt luôn. xử lý rất lâu.

Avatar Nguyễn Anh Hiến @nguyenanhhien_90
thg 5 27, 2022 12:25 SA

@LongThanh.it Dữ liệu nhiều nên dùng chunkById https://laravel.com/docs/9.x/queries#chunking-results ban sử dụng $posts = Post::chunkById xem sao .Tham khảo thử xem nhé việc tạo sitemap bên mình .Dữ liệu mình query rồi lưu cache ở redis . $data = Cache::remember('sitemaps_index_art',env('CACHE_TIME',10000),function (){ DB::table('articlers')->chunkById(200,function($articlers) { foreach ($articlers as $article) { $this->array_return[] = $article; } }); return $this->array_return; });

Avatar Dương Hải Ngọc @haingoc86vibo
thg 6 3, 2022 8:12 SA

@LongThanh.it

public function timcha_ko_dequy($data, $parent_id)
    {
        $list_parent_id = []; 
        $list_parent_id[] =  $parent_id; 
        $result = [];
        foreach ($data as $key => $item) {
            if (in_array($item['id'] ,list_parent_id )) {
                $result[] = $item;
                $list_parent_id = array_merge($list_parent_id , $item['parent_id']) 
            }
        }
        return $result;
    }
Avatar LongThanh @LongThanh.it
thg 6 3, 2022 9:01 SA

@haingoc86vibo có nhầm gì không b?

$list_parent_id = array_merge($list_parent_id , $item['parent_id']) 

array_merge(): Argument #2 must be of type array, int given

Đã trả lời thg 5 24, 2022 10:44 SA
0

Đối với các hàm đệ quy, bạn không nên sử dụng các câu lệnh truy vấn dữ liệu.

Điều đó sẽ làm tăng số lần truy vấn đến database, dẫn đến tăng thời gian chờ và có thể gây quá tải cho database.

Ngoài ra, bạn cũng có thể cấu hình để tăng thời gian chờ của nginx trong tệp config như sau:

http { 
    ...
    fastcgi_buffers         8 16k;
    fastcgi_buffer_size     32k;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout    300;
    fastcgi_read_timeout    300;
}

Tuy nhiên việc tăng cấu hình nginx sẽ không triệt để, khi lượng data của bạn ngày càng nhiều lên thì việc tăng ở trên sẽ không còn tác dụng

Chia sẻ
Avatar LongThanh @LongThanh.it
thg 5 27, 2022 2:18 SA

thanks

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí