Thứ năm, 07/11/2019 | 00:00 GMT+7

Cách thiết lập ứng dụng Laravel 6 có thể mở rộng bằng cách sử dụng dịch vụ database và Lưu trữ đối tượng

Khi mở rộng các ứng dụng web theo chiều ngang, những khó khăn đầu tiên bạn thường gặp phải là giải quyết vấn đề lưu trữ file và tính liên tục của dữ liệu. Điều này chủ yếu là do thực tế là khó duy trì tính nhất quán của dữ liệu biến đổi giữa nhiều nút ứng dụng; các chiến lược thích hợp phải được đưa ra đảm bảo dữ liệu được tạo trong một nút có sẵn ngay lập tức cho các node khác trong một cụm.

Một cách thực tế để giải quyết vấn đề nhất quán là sử dụng dịch vụdatabase và hệ thốnglưu trữ đối tượng . Đầu tiên sẽ thuê ngoài sự bền vững của dữ liệu cho database được quản lý và thứ sau sẽ cung cấp dịch vụ lưu trữ từ xa, nơi bạn có thể giữ các file tĩnh và nội dung biến đổi như hình ảnh do user tải lên. Mỗi nút sau đó có thể kết nối với các dịch vụ này ở cấp ứng dụng.

Sơ đồ sau minh họa cách cài đặt như vậy được dùng cho khả năng mở rộng theo chiều ngang trong ngữ cảnh của các ứng dụng PHP:

Biểu đồ tỷ lệ Laravel

Trong hướng dẫn này, ta sẽ cập nhật ứng dụng Laravel 6 hiện có để chuẩn bị cho nó khả năng mở rộng theo chiều ngang bằng cách kết nối nó với database MySQL được quản lý và cài đặt kho đối tượng tương thích S3 để lưu các file do user tạo. Cuối cùng, bạn sẽ có một ứng dụng danh sách du lịch chạy trên web server Nginx + PHP-FPM:

Danh sách du lịch v1.0

Lưu ý : hướng dẫn này sử dụng DigitalOcean Managed MySQLSpaces để chứng minh cài đặt ứng dụng có thể mở rộng bằng cách sử dụng database được quản lý và lưu trữ đối tượng. Các hướng dẫn ở đây sẽ hoạt động theo cách tương tự đối với các nhà cung cấp dịch vụ khác.

Yêu cầu

Để bắt đầu hướng dẫn này, trước tiên bạn cần các yêu cầu sau:

  • Truy cập vào server Ubuntu 18.04 với quyền là user không phải root có quyền sudo và firewall hoạt động được cài đặt trên server của bạn. Để cài đặt những điều này, vui lòng tham khảo Hướng dẫn Cài đặt Server Ban đầu cho Ubuntu 18.04 của ta .
  • Nginx và PHP-FPM được cài đặt và cấu hình trên server của bạn, như được giải thích trong bước 13 của Cách cài đặt LEMP trên Ubuntu 18.04 . Bạn nên bỏ qua bước cài đặt MySQL.
  • Composer được cài đặt trên server của bạn, như được giải thích trong bước 12 của Cách cài đặt và sử dụng Composer trên Ubuntu 18.04 .
  • Thông tin đăng nhập administrator đối với database MySQL 8 được quản lý. Đối với hướng dẫn này, ta sẽ sử dụng cụm DigitalOcean Managed MySQL , nhưng các hướng dẫn ở đây sẽ hoạt động tương tự đối với các dịch vụ database được quản lý khác.
  • Một tập hợp các khóa API có quyền đọc và ghi đối với dịch vụ lưu trữ đối tượng tương thích với S3. Trong hướng dẫn này, ta sẽ sử dụng DigitalOcean Spaces , nhưng bạn có thể tự do sử dụng nhà cung cấp mà bạn chọn.
  • Công cụ s3cmd đã được cài đặt và cấu hình để kết nối với ổ lưu trữ đối tượng của bạn. Để biết hướng dẫn về cách cài đặt điều này cho DigitalOcean Spaces, vui lòng tham khảo tài liệu sản phẩm của ta .

Bước 1 - Cài đặt Máy khách MySQL 8

Kho lưu trữ apt Ubuntu mặc định đi kèm với client MySQL 5, không tương thích với server MySQL 8 mà ta sẽ sử dụng trong hướng dẫn này. Để cài đặt ứng dụng client MySQL tương thích, ta cần sử dụng Kho lưu trữ APT của MySQL do Oracle cung cấp.

Bắt đầu bằng cách chuyển đến trang Kho lưu trữ APT MySQL trong trình duyệt web . Tìm nút Download ở góc dưới bên phải và nhấp qua trang tiếp theo. Trang này sẽ nhắc bạn đăng nhập hoặc đăng ký account web Oracle. Bạn có thể bỏ qua điều đó và thay vào đó hãy tìm liên kết có nội dung Không, cảm ơn, chỉ cần bắt đầu download của tôi . Sao chép địa chỉ liên kết và quay lại cửa sổ dòng lệnh của bạn.

Liên kết này sẽ trỏ đến một .deb sẽ cài đặt Kho lưu trữ APT MySQL trong server của bạn. Sau khi cài đặt nó, bạn có thể sử dụng apt để cài đặt các bản phát hành mới nhất của MySQL. Ta sẽ sử dụng curl để tải file này xuống một vị trí tạm thời.

Đi tới folder tmp của server của bạn:

  • cd /tmp

Bây giờ download gói với curl và sử dụng URL bạn đã sao chép từ trang Kho lưu trữ APT của MySQL:

  • curl -OL https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb

Sau khi download xong, bạn có thể sử dụng dpkg để cài đặt gói:

  • sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb

Bạn sẽ thấy một màn hình nơi bạn có thể chọn version MySQL nào bạn muốn chọn làm mặc định, cũng như các thành phần MySQL mà bạn quan tâm:

Cài đặt repository  MySQL APT

Bạn không cần phải thay đổi bất cứ điều gì ở đây, vì các tùy chọn mặc định sẽ cài đặt kho ta cần. Chọn “Ok” và cấu hình sẽ hoàn tất.

Tiếp theo, bạn cần cập nhật bộ nhớ cache apt của bạn bằng:

  • sudo apt update

Bây giờ cuối cùng ta có thể cài đặt client MySQL 8 với:

  • sudo apt install mysql-client

Sau khi lệnh đó kết thúc, hãy kiểm tra số version phần mềm đảm bảo rằng bạn có bản phát hành mới nhất:

  • mysql --version

Bạn sẽ thấy kết quả như thế này:

Output
mysql Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)

Trong bước tiếp theo, ta sẽ sử dụng client MySQL để kết nối với server MySQL được quản lý của bạn và chuẩn bị database cho ứng dụng.

Bước 2 - Tạo Database và User MySQL mới

Tại thời điểm viết bài này, thư viện MySQL PHP mysqlnd không hỗ trợ caching_sha2_authentication , phương thức xác thực mặc định cho MySQL 8. Ta cần tạo một user mới với phương thức xác thực mysql_native_password để có thể kết nối Laravel của ta ứng dụng cho server MySQL 8. Ta cũng sẽ tạo một database dành riêng cho ứng dụng demo của ta .

Để bắt đầu, hãy đăng nhập vào server của bạn bằng account quản trị. Thay thế các giá trị được đánh dấu bằng user , server lưu trữ và cổng MySQL của bạn :

  • mysql -u MYSQL_USER -p -h MYSQL_HOST -P MYSQL_PORT

Khi được yêu cầu , hãy cung cấp password của admin-user viên. Sau khi đăng nhập, bạn sẽ có quyền truy cập vào giao diện dòng lệnh của server MySQL 8.

Đầu tiên, ta sẽ tạo một database mới cho ứng dụng. Chạy lệnh sau để tạo một database mới có tên travellist :

  • CREATE DATABASE travellist;

Tiếp theo, ta sẽ tạo một user mới và đặt password , sử dụng mysql_native_password làm phương thức xác thực mặc định cho user này. Bạn được khuyến khích thay thế các giá trị được đánh dấu bằng các giá trị của bạn và sử dụng password mạnh:

  • CREATE USER 'travellist-user'@'%' IDENTIFIED WITH mysql_native_password BY 'MYSQL_PASSWORD';

Bây giờ ta cần cấp quyền cho user này đối với database ứng dụng của ta :

  • GRANT ALL ON travellist.* TO 'travellist-user'@'%';

Đến đây bạn có thể thoát khỏi dấu nhắc MySQL bằng:

  • exit;

Đến đây bạn có một database chuyên dụng và một user tương thích để kết nối từ ứng dụng Laravel của bạn. Trong bước tiếp theo, ta sẽ lấy mã ứng dụng và cài đặt chi tiết cấu hình để ứng dụng của bạn có thể kết nối với database MySQL được quản lý của bạn.

Trong hướng dẫn này, ta sẽ sử dụng Laravel Migrations và các hạt database để cài đặt các bảng ứng dụng của ta . Nếu bạn cần di chuyển database local hiện có sang database MySQL được quản lý DigitalOcean, vui lòng tham khảo tài liệu của ta về Cách nhập Database MySQL vào Dịch vụdatabase DigitalOcean .

Bước 3 - Cài đặt ứng dụng Demo

Để bắt đầu, ta sẽ tìm nạp ứng dụng Laravel demo từ kho Github của nó. Hãy kiểm tra nội dung của ứng dụng trước khi chạy các lệnh tiếp theo.

Ứng dụng demo là một ứng dụng danh sách group du lịch ban đầu được phát triển trong hướng dẫn của ta về Cách cài đặt và cấu hình Laravel với LEMP trên Ubuntu 18.04 . Ứng dụng được cập nhật hiện có các cải tiến về hình ảnh bao gồm ảnh du lịch mà khách có thể tải lên và bản đồ thế giới. Nó cũng giới thiệu một kịch bản di chuyển database và các hạt database để tạo các bảng ứng dụng và đưa chúng vào dữ liệu mẫu, sử dụng các lệnh artisan .

Để lấy mã ứng dụng tương thích với hướng dẫn này, ta sẽ download bản phát hành 1.1 từ repository của dự án trên Github. Ta sẽ lưu file zip đã download dưới dạng travellist.zip bên trong folder chính của ta :

  • cd ~
  • curl -L https://github.com/do-community/travellist-laravel-demo/archive/1.1.zip -o travellist.zip

Bây giờ, extract nội dung của ứng dụng và đổi tên folder của nó bằng:

  • unzip travellist.zip
  • mv travellist-laravel-demo-1.1 travellist

Điều hướng đến travellist folder :

  • cd travellist

Trước khi tiếp tục, ta cần cài đặt một số module PHP được yêu cầu bởi khung công tác Laravel, đó là: php-xml , php-mbstring , php-xmlphp-bcmath . Để cài đặt các gói này, hãy chạy:

  • sudo apt install unzip php-xml php-mbstring php-xml php-bcmath

Để cài đặt các phụ thuộc ứng dụng, hãy chạy:

  • composer install

Bạn sẽ thấy kết quả tương tự như sau:

Output
Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Package operations: 80 installs, 0 updates, 0 removals - Installing doctrine/inflector (v1.3.0): Downloading (100%) - Installing doctrine/lexer (1.1.0): Downloading (100%) - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%) - Installing erusev/parsedown (1.7.3): Downloading (100%) ... Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: beyondcode/laravel-dump-server Discovered Package: fideloper/proxy Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully.

Các phụ thuộc ứng dụng hiện đã được cài đặt. Tiếp theo, ta sẽ cấu hình ứng dụng để kết nối với Database MySQL được quản lý.

Tạo file cấu hình .env và đặt Khóa ứng dụng

Bây giờ ta sẽ tạo một file .env chứa các biến sẽ được sử dụng để cấu hình ứng dụng Laravel trên cơ sở từng môi trường. Ứng dụng này bao gồm một file ví dụ mà ta có thể sao chép và sau đó sửa đổi các giá trị của nó để phản ánh cài đặt môi trường của ta .

Sao chép file .env.example file mới có tên .env :

  • cp .env.example .env

Bây giờ ta cần cài đặt khóa ứng dụng. Khóa này được sử dụng để mã hóa dữ liệu phiên và phải được đặt thành một chuỗi dài 32 ký tự duy nhất. Ta có thể tạo khóa này tự động bằng artisan cụ artisan công:

  • php artisan key:generate

Hãy chỉnh sửa file cấu hình môi trường để cài đặt chi tiết database . Mở file .env bằng editor dòng lệnh mà bạn chọn. Ở đây, ta sẽ sử dụng nano :

  • nano .env

Tìm phần thông tin database . Các biến sau đây cần bạn chú ý:

DB_HOST : server lưu trữ server MySQL được quản lý của bạn.
DB_PORT : cổng server MySQL được quản lý của bạn.
DB_DATABASE : tên của database ứng dụng mà ta đã tạo ở Bước 2 .
DB_USERNAME : user database mà ta đã tạo ở Bước 2 .
DB_PASSWORD : password cho user database mà ta đã xác định trong Bước 2 .

Cập nhật các giá trị được đánh dấu bằng thông tin MySQL được quản lý của bạn và bằng chứng xác thực:

... DB_CONNECTION=mysql DB_HOST=MANAGED_MYSQL_HOST DB_PORT=MANAGED_MYSQL_PORT DB_DATABASE=MANAGED_MYSQL_DB DB_USERNAME=MANAGED_MYSQL_USER DB_PASSWORD=MANAGED_MYSQL_PASSWORD ... 

Lưu file bằng lệnh CTRL+X rồi đến YENTER khi bạn chỉnh sửa xong.

Bây giờ mà các ứng dụng được cấu hình để kết nối với database MySQL, ta có thể sử dụng công cụ dòng lệnh Laravel của artisan để tạo ra các bảng database và cư chúng với dữ liệu mẫu.

Trước khi thực hiện các công cụ database được cung cấp bởi lệnh artisan , ta cần tạo một softlink đến folder lưu trữ công cộng sẽ lưu trữ các bức ảnh du lịch mà ta đang sử dụng trong ứng dụng. Điều này là cần thiết vì tập lệnh hạt giống database của ta dựa vào các ảnh mẫu này để chèn dữ liệu vào bảng places .

Lệnh sau sẽ tạo một softlink bên trong folder public , được hiển thị công khai thông qua web server , trỏ đến folder lưu trữ nội bộ của storage/app/public :

  • php artisan storage:link
Output
The [public/storage] directory has been linked.

Để kiểm tra xem liên kết đã được tạo chưa và liên kết trỏ đến, bạn có thể chạy:

  • ls -la public/

Bạn sẽ thấy kết quả như thế này:

Output
total 36 drwxrwxr-x 5 sammy sammy 4096 Oct 25 14:59 . drwxrwxr-x 12 sammy sammy 4096 Oct 25 14:58 .. -rw-rw-r-- 1 sammy sammy 593 Oct 25 06:29 .htaccess drwxrwxr-x 2 sammy sammy 4096 Oct 25 06:29 css -rw-rw-r-- 1 sammy sammy 0 Oct 25 06:29 favicon.ico drwxrwxr-x 2 sammy sammy 4096 Oct 25 06:29 img -rw-rw-r-- 1 sammy sammy 1823 Oct 25 06:29 index.php drwxrwxr-x 2 sammy sammy 4096 Oct 25 06:29 js -rw-rw-r-- 1 sammy sammy 24 Oct 25 06:29 robots.txt lrwxrwxrwx 1 sammy sammy 41 Oct 25 14:59 storage -> /home/sammy/travellist/storage/app/public -rw-rw-r-- 1 sammy sammy 1194 Oct 25 06:29 web.config

Di chuyển và đưa vào database

Bây giờ ta sẽ sử dụng Laravel Migrations và các hạt database để cài đặt các bảng ứng dụng. Điều này sẽ giúp ta xác định xem cấu hình database của ta có hoạt động như mong đợi hay không.

Để thực thi tập lệnh di chuyển sẽ tạo các bảng được ứng dụng sử dụng, hãy chạy:

  • php artisan migrate

Bạn sẽ thấy kết quả tương tự như sau:

Output
Migration table created successfully. Migrating: 2019_09_19_123737_create_places_table Migrated: 2019_09_19_123737_create_places_table (0.26 seconds) Migrating: 2019_10_14_124700_create_photos_table Migrated: 2019_10_14_124700_create_photos_table (0.42 seconds)

Để điền dữ liệu mẫu vào database , hãy chạy:

  • php artisan db:seed

Bạn sẽ thấy kết quả như thế này:

Output
Seeding: PlacesTableSeeder Seeded: PlacesTableSeeder (0.86 seconds) Database seeding completed successfully.

Các bảng ứng dụng hiện đã được tạo và điền dữ liệu mẫu.

Chạy server thử nghiệm (tùy chọn)

Bạn có thể sử dụng lệnh artisan serve để nhanh chóng xác minh mọi thứ được cài đặt chính xác trong ứng dụng, trước khi phải cấu hình web server đầy đủ tính năng như Nginx để phục vụ ứng dụng trong thời gian dài.

Ta sẽ sử dụng cổng 8000 để tạm thời cung cấp ứng dụng để thử nghiệm. Nếu bạn đã bật firewall UFW trên server của bạn , trước tiên bạn nên cho phép truy cập vào cổng này với:

  • sudo ufw allow 8000

Bây giờ, để chạy server PHP tích hợp sẵn mà Laravel hiển thị thông qua artisan cụ artisan công, hãy chạy:

  • php artisan serve --host=0.0.0.0 --port=8000

Lệnh này sẽ chặn terminal của bạn cho đến khi bị ngắt bằng CTRL+C Nó sẽ sử dụng web server PHP tích hợp sẵn để phục vụ ứng dụng cho mục đích thử nghiệm trên tất cả các network interface , sử dụng cổng 8000 .

Bây giờ, hãy truy cập trình duyệt của bạn và truy cập ứng dụng bằng domain hoặc địa chỉ IP của server trên cổng 8000 :

http://server_domain_or_IP:8000 

Bạn sẽ thấy trang sau:

Danh sách du lịch v1.0

Nếu bạn thấy trang này, điều đó nghĩa là ứng dụng đang lấy thành công dữ liệu về vị trí và ảnh từ database được quản lý đã cấu hình . Các file hình ảnh vẫn được lưu trữ trong đĩa local , nhưng ta sẽ thay đổi điều này trong bước sau của hướng dẫn này.

Khi hoàn tất quá trình kiểm tra ứng dụng, bạn có thể dừng lệnh serve bằng cách nhấn CTRL+C

Đừng quên đóng cổng 8000 nếu bạn đang chạy UFW trên server của bạn :

  • sudo ufw deny 8000

Bước 4 - Cấu hình Nginx để cung cấp ứng dụng

Mặc dù web server PHP tích hợp sẵn rất hữu ích cho mục đích phát triển và thử nghiệm, nó không được sử dụng như một giải pháp lâu dài để phục vụ các ứng dụng PHP. Sử dụng một web server đầy đủ tính năng như Nginx là cách được khuyến khích để làm điều đó.

Để bắt đầu, ta sẽ di chuyển folder ứng dụng đến /var/www , đây là vị trí thông thường cho các ứng dụng web chạy trên Nginx. Đầu tiên, sử dụng lệnh mv để di chuyển folder ứng dụng với tất cả nội dung của nó vào /var/www/travellist :

  • sudo mv ~/travellist /var/www/travellist

Bây giờ ta cần cấp cho user web server quyền ghi vào các folder storagebootstrap/cache , nơi Laravel lưu trữ các file do ứng dụng tạo. Ta sẽ đặt các quyền này bằng setfacl , một tiện ích dòng lệnh cho phép cài đặt quyền chi tiết và mạnh mẽ hơn trong các file và folder .

Để bao gồm quyền đọc, ghi và thực thi (rwx) cho user web server trên các folder bắt buộc, hãy chạy:

  • sudo setfacl -R -m g:www-data:rwx /var/www/travellist/storage
  • sudo setfacl -R -m g:www-data:rwx /var/www/travellist/bootstrap/cache

Các file ứng dụng hiện đã được sắp xếp theo thứ tự, nhưng ta vẫn cần cấu hình Nginx để phân phát nội dung. Để thực hiện việc này, ta sẽ tạo một file cấu hình server ảo mới tại /etc/nginx/sites-available :

  • sudo nano /etc/nginx/sites-available/travellist

Tệp cấu hình sau chứa các cài đặt được đề xuất cho các ứng dụng Laravel trên Nginx:

/ etc / nginx / sites-available / travellist
server {     listen 80;     server_name server_domain_or_IP;     root /var/www/travellist/public;      add_header X-Frame-Options "SAMEORIGIN";     add_header X-XSS-Protection "1; mode=block";     add_header X-Content-Type-Options "nosniff";      index index.html index.htm index.php;      charset utf-8;      location / {         try_files $uri $uri/ /index.php?$query_string;     }      location = /favicon.ico { access_log off; log_not_found off; }     location = /robots.txt  { access_log off; log_not_found off; }      error_page 404 /index.php;      location ~ \.php$ {         fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;         fastcgi_index index.php;         fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;         include fastcgi_params;     }      location ~ /\.(?!well-known).* {         deny all;     } } 

Sao chép nội dung này vào file /etc/nginx/sites-available/ travellist và điều chỉnh các giá trị được đánh dấu để phù hợp với cấu hình của bạn . Lưu file khi bạn chỉnh sửa xong.

Để kích hoạt các file cấu hình server ảo mới, tạo ra một softlink đến travellist trong sites-enabled :

  • sudo ln -s /etc/nginx/sites-available/travellist /etc/nginx/sites-enabled/

Lưu ý: Nếu bạn có một file server ảo mà trước đây đã được cấu hình cho cùng server_name sử dụng trong travellist server ảo, bạn có thể cần phải tắt cấu hình cũ bằng cách loại bỏ tương ứng bên trong softlink /etc/nginx/sites-enabled/ .

Để xác nhận cấu hình không có bất kỳ lỗi cú pháp nào, bạn có thể sử dụng:

  • sudo nginx -t

Bạn sẽ thấy kết quả như thế này:

Output
  • nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
  • nginx: configuration file /etc/nginx/nginx.conf test is successful

Để áp dụng các thay đổi, hãy reload Nginx bằng:

  • sudo systemctl reload nginx

Nếu bạn reload trình duyệt của bạn ngay bây giờ, các hình ảnh ứng dụng sẽ bị hỏng. Điều đó xảy ra bởi vì ta đã di chuyển folder ứng dụng đến một vị trí mới bên trong server và vì lý do đó ta cần tạo lại softlink đến folder lưu trữ ứng dụng.

Xóa liên kết cũ với:

  • cd /var/www/travellist
  • rm -f public/storage

Bây giờ hãy chạy lại lệnh artisan để tạo liên kết lưu trữ:

  • php artisan storage:link

Bây giờ, hãy truy cập trình duyệt của bạn và truy cập ứng dụng bằng domain hoặc địa chỉ IP của server , như được xác định bởi chỉ thị server_name trong file cấu hình của bạn:

http://server_domain_or_IP 

Danh sách du lịch v1.0

Trong bước tiếp theo, ta sẽ tích hợp một dịch vụ lưu trữ đối tượng vào ứng dụng. Điều này sẽ thay thế bộ nhớ đĩa local hiện tại được sử dụng cho ảnh du lịch.

Bước 5 - Tích hợp Bộ nhớ Đối tượng Tương thích S3 vào Ứng dụng

Bây giờ ta sẽ cài đặt ứng dụng để sử dụng dịch vụ lưu trữ đối tượng tương thích với S3 để lưu trữ các bức ảnh du lịch được trưng bày trên trang index . Vì ứng dụng đã có một vài ảnh mẫu được lưu trữ trong đĩa local , ta cũng sẽ sử dụng công cụ s3cmd để tải các file ảnh local hiện có lên bộ lưu trữ đối tượng từ xa.

Cài đặt trình điều khiển S3 cho Laravel

Laravel sử dụng league/flysystem , một thư viện trừu tượng hệ thống file cho phép ứng dụng Laravel sử dụng và kết hợp nhiều giải pháp lưu trữ, bao gồm đĩa local và các dịch vụ cloud . Cần có một gói bổ sung để sử dụng trình điều khiển s3 . Ta có thể cài đặt gói này bằng cách sử dụng lệnh composer require request.

Truy cập folder ứng dụng:

  • cd /var/www/travellist
  • composer require league/flysystem-aws-s3-v3

Bạn sẽ thấy kết quả tương tự như sau:

Output
Using version ^1.0 for league/flysystem-aws-s3-v3 ./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 8 installs, 0 updates, 0 removals - Installing mtdowling/jmespath.php (2.4.0): Loading from cache - Installing ralouphie/getallheaders (3.0.3): Loading from cache - Installing psr/http-message (1.0.1): Loading from cache - Installing guzzlehttp/psr7 (1.6.1): Loading from cache - Installing guzzlehttp/promises (v1.3.1): Loading from cache - Installing guzzlehttp/guzzle (6.4.1): Downloading (100%) - Installing aws/aws-sdk-php (3.112.28): Downloading (100%) - Installing league/flysystem-aws-s3-v3 (1.0.23): Loading from cache ...

Bây giờ các gói bắt buộc đã được cài đặt, ta có thể cập nhật ứng dụng để kết nối với bộ lưu trữ đối tượng. Đầu tiên, ta sẽ mở lại file .env để cài đặt chi tiết cấu hình như khóa, tên group và khu vực cho dịch vụ lưu trữ đối tượng của bạn.

Mở file .env :

  • nano .env

Bao gồm các biến môi trường sau, thay thế các giá trị được đánh dấu bằng chi tiết cấu hình object stores của bạn:

/var/www/travellist/.env
DO_SPACES_KEY=EXAMPLE7UQOTHDTF3GK4 DO_SPACES_SECRET=exampleb8e1ec97b97bff326955375c5 DO_SPACES_ENDPOINT=https://ams3.digitaloceanspaces.com DO_SPACES_REGION=ams3 DO_SPACES_BUCKET=sammy-travellist 

Lưu file khi bạn hoàn tất. Bây giờ hãy mở file config/filesystems.php :

  • nano config/filesystems.php

Trong file này, ta sẽ tạo một mục đĩa mới trong mảng disks . Ta sẽ đặt tên cho spaces đĩa này và ta sẽ sử dụng các biến môi trường mà ta đã đặt trong file .env để cấu hình đĩa mới. Bao gồm mục nhập sau trong mảng disks :

config / filesystems.php
 'spaces' => [    'driver' => 's3',    'key' => env('DO_SPACES_KEY'),    'secret' => env('DO_SPACES_SECRET'),    'endpoint' => env('DO_SPACES_ENDPOINT'),    'region' => env('DO_SPACES_REGION'),    'bucket' => env('DO_SPACES_BUCKET'), ],  

Vẫn trong cùng một file , hãy tìm mục nhập cloud và thay đổi nó để đặt đĩa spaces mới làm đĩa hệ thống file cloud mặc định:

config / filesystems.php
'cloud' => env('FILESYSTEM_CLOUD', 'spaces'), 

Lưu file khi bạn chỉnh sửa xong. Từ bộ điều khiển của bạn, bây giờ bạn có thể sử dụng phương thức Storage::cloud() làm lối tắt để truy cập đĩa cloud mặc định. Bằng cách này, ứng dụng vẫn linh hoạt để sử dụng nhiều giải pháp lưu trữ và bạn có thể chuyển đổi giữa các nhà cung cấp trên cơ sở từng môi trường.

Ứng dụng hiện đã được cấu hình để sử dụng lưu trữ đối tượng, nhưng ta vẫn cần cập nhật mã tải ảnh mới lên ứng dụng.

Đầu tiên ta hãy kiểm tra tuyến uploadPhoto hiện tại, nằm trong lớp PhotoController . Mở file bằng editor của bạn:

  • nano app/Http/Controllers/PhotoController.php
app / Http / Controllers / PhotoController.php
…  public function uploadPhoto(Request $request) {    $photo = new Photo();    $place = Place::find($request->input('place'));     if (!$place) {        //add new place        $place = new Place();        $place->name = $request->input('place_name');        $place->lat = $request->input('place_lat');        $place->lng = $request->input('place_lng');    }     $place->visited = 1;    $place->save();     $photo->place()->associate($place);    $photo->image = $request->image->store('/', 'public');    $photo->save();     return redirect()->route('Main'); }  

Phương thức này chấp nhận yêu cầu POST và tạo mục nhập ảnh mới trong bảng ảnh. Quá trình này bắt đầu bằng cách kiểm tra xem một địa điểm hiện có đã được chọn trong biểu mẫu tải ảnh lên hay chưa và nếu không đúng như vậy, nó sẽ tạo một địa điểm mới bằng cách sử dụng thông tin được cung cấp. Địa điểm sau đó được đặt thành visited và lưu vào database . Sau đó, một liên kết được tạo để ảnh mới được liên kết với địa điểm được chỉ định. Các file ảnh sau đó được lưu trữ trong folder root của public đĩa. Cuối cùng, bức ảnh được lưu vào database . Sau đó user được chuyển hướng đến tuyến đường chính, là trang index của ứng dụng.

Dòng được đánh dấu trong mã này là những gì ta quan tâm. Trong dòng đó, file hình ảnh được lưu vào đĩa bằng phương thức store . Phương thức store được sử dụng để lưu file vào bất kỳ đĩa nào được xác định trong filesystem.php cấu hình filesystem.php . Trong trường hợp này, nó đang sử dụng đĩa mặc định để lưu trữ các hình ảnh đã tải lên.

Ta sẽ thay đổi hành vi này để hình ảnh được lưu vào repository đối tượng thay vì đĩa local . Để làm được điều đó, ta cần phải thay thế các public đĩa bằng các spaces đĩa trong store gọi phương thức. Ta cũng cần đảm bảo mức độ hiển thị của file đã tải lên được đặt thành công khai thay vì riêng tư .

Đoạn mã sau chứa đầy đủ lớp PhotoController , bao gồm cả phương thức uploadPhoto được cập nhật:

app / Http / Controllers / PhotoController.php
<?php  namespace App\Http\Controllers;  use Illuminate\Http\Request; use App\Photo; use App\Place; use Illuminate\Support\Facades\Storage;  class PhotoController extends Controller {    public function uploadForm()    {        $places = Place::all();         return view('upload_photo', [            'places' => $places        ]);    }     public function uploadPhoto(Request $request)    {        $photo = new Photo();        $place = Place::find($request->input('place'));         if (!$place) {            //add new place            $place = new Place();            $place->name = $request->input('place_name');            $place->lat = $request->input('place_lat');            $place->lng = $request->input('place_lng');        }         $place->visited = 1;        $place->save();         $photo->place()->associate($place);        $photo->image = $request->image->store('/', 'spaces');        Storage::setVisibility($photo->image, 'public');        $photo->save();         return redirect()->route('Main');    } }   

Sao chép mã đã cập nhật vào PhotoController của bạn để nó phản ánh những thay đổi được đánh dấu. Lưu file khi bạn chỉnh sửa xong.

Ta vẫn cần sửa đổi chế độ xem chính của ứng dụng để nó sử dụng URL file lưu trữ đối tượng để hiển thị hình ảnh. Mở mẫu travel_list.blade.php :

  • nano resources/views/travel_list.blade.php

Bây giờ xác định vị trí phần footer của trang, hiện có dạng như sau:

resource / views / travel_list.blade.php
@section('footer')    <h2>Travel Photos <small>[ <a href="{{ route('Upload.form') }}">Upload Photo</a> ]</small></h2>    @foreach ($photos as $photo)        <div class="photo">           <img src="{{ asset('storage') . '/' . $photo->image }}" />            <p>{{ $photo->place->name }}</p>        </div>    @endforeach  @endsection 

Thay thế thuộc tính src hình ảnh hiện tại để sử dụng URL file từ đĩa lưu trữ spaces :

<img src="{{ Storage::disk('spaces')->url($photo->image) }}" /> 

Nếu bạn truy cập trình duyệt của bạn ngay bây giờ và reload trang ứng dụng, nó sẽ chỉ hiển thị những hình ảnh bị hỏng. Điều đó xảy ra bởi vì các file hình ảnh cho những bức ảnh du lịch đó vẫn chỉ nằm trong đĩa local . Ta cần tải các file ảnh hiện có lên bộ lưu trữ đối tượng, để ảnh đã được lưu trữ trong database có thể được trưng bày thành công trong trang ứng dụng.

Đồng bộ hóa hình ảnh local với s3cmd

Công cụ s3cmd được dùng để đồng bộ hóa các file local với dịch vụ lưu trữ đối tượng tương thích với S3. Ta sẽ chạy lệnh sync để tải tất cả các file bên trong storage/app/public/photos lên dịch vụ lưu trữ đối tượng.

Truy cập folder lưu trữ ứng dụng public :

  • cd /var/www/travellist/storage/app/public

Để xem các file đã được lưu trữ trong đĩa từ xa của bạn, bạn có thể sử dụng s3cmd ls :

  • s3cmd ls s3://your_bucket_name

Bây giờ hãy chạy lệnh sync để tải các file hiện có trong folder lưu trữ công cộng lên bộ lưu trữ đối tượng:

  • s3cmd sync ./ s3://your_bucket_name --acl-public --exclude=.gitignore

Thao tác này sẽ đồng bộ hóa folder hiện tại ( storage/app/public ) với dir root của bộ lưu trữ đối tượng từ xa. Bạn sẽ nhận được kết quả tương tự như sau:

Output
upload: './bermudas.jpg' -> 's3://sammy-travellist/bermudas.jpg' [1 of 3] 2538230 of 2538230 100% in 7s 329.12 kB/s done upload: './grindavik.jpg' -> 's3://sammy-travellist/grindavik.jpg' [2 of 3] 1295260 of 1295260 100% in 5s 230.45 kB/s done upload: './japan.jpg' -> 's3://sammy-travellist/japan.jpg' [3 of 3] 8940470 of 8940470 100% in 24s 363.61 kB/s done Done. Uploaded 12773960 bytes in 37.1 seconds, 336.68 kB/s.

Bây giờ, nếu bạn chạy lại s3cmd ls , bạn sẽ thấy rằng ba file mới đã được thêm vào folder root của group lưu trữ đối tượng của bạn:

  • s3cmd ls s3://your_bucket_name
Output
2019-10-25 11:49 2538230 s3://sammy-travellist/bermudas.jpg 2019-10-25 11:49 1295260 s3://sammy-travellist/grindavik.jpg 2019-10-25 11:49 8940470 s3://sammy-travellist/japan.jpg

Truy cập trình duyệt của bạn và reload trang ứng dụng. Tất cả các hình ảnh sẽ hiển thị ngay bây giờ và nếu bạn kiểm tra chúng bằng công cụ gỡ lỗi của trình duyệt, bạn sẽ nhận thấy rằng tất cả chúng đều sử dụng URL từ bộ nhớ đối tượng của bạn.

Kiểm tra sự tích hợp

Ứng dụng demo hiện có đầy đủ chức năng, lưu trữ file trong dịch vụ lưu trữ đối tượng từ xa và lưu dữ liệu vào database MySQL được quản lý. Bây giờ ta có thể tải lên một vài ảnh để kiểm tra cài đặt của bạn .

Truy cập tuyến /upload ứng dụng từ trình duyệt của bạn:

http://server_domain_or_IP/upload 

Bạn sẽ thấy biểu mẫu sau:

Biểu mẫu tải ảnh lên danh sách du lịch

Đến đây bạn có thể tải lên một vài ảnh để kiểm tra việc tích hợp bộ nhớ đối tượng. Sau khi chọn hình ảnh từ máy tính, bạn có thể chọn một địa điểm hiện có từ menu thả xuống hoặc bạn có thể thêm một địa điểm mới bằng cách cung cấp tên và tọa độ địa lý của nó để có thể tải nó vào bản đồ ứng dụng.

Bước 6 - Mở rộng quy mô database MySQL được quản lý DigitalOcean với các node chỉ đọc (Tùy chọn)

Bởi vì các hoạt động chỉ đọc thường thường xuyên hơn các hoạt động ghi trên server database , một thực tế phổ biến là mở rộng một cụm database bằng cách cài đặt nhiều nút chỉ đọc. Điều này sẽ phân phối tải được tạo ra bởi các hoạt động SELECT .

Để chứng minh cài đặt này, trước tiên ta sẽ thêm 2 nút chỉ đọc vào cụm DigitalOcean Managed MySQL của ta . Sau đó, ta sẽ cấu hình ứng dụng Laravel để sử dụng các node này.

Truy cập Control panel cloud DigitalOcean và làm theo các hướng dẫn sau:

  1. Đi tới Database và chọn cụm MySQL của bạn.
  2. Nhấp vào Actions và chọn Add a read-only node từ trình đơn thả xuống.
  3. Cấu hình các tùy chọn nút và nhấn nút Tạo . Lưu ý có thể mất vài phút để nút mới sẵn sàng.
  4. Lặp lại các bước 1-4 để bạn có 2 nút chỉ đọc.
  5. Ghi lại các server của hai nút vì ta cần chúng cho cấu hình Laravel của bạn .

Khi bạn đã chuẩn bị xong các node chỉ đọc, hãy quay lại terminal của bạn.

Bây giờ ta sẽ cấu hình ứng dụng Laravel của bạn để hoạt động với nhiều nút database . Khi ta hoàn tất, các truy vấn như INSERTUPDATE sẽ được chuyển tiếp đến nút cụm chính của bạn, trong khi tất cả các truy vấn SELECT sẽ được chuyển hướng đến các node chỉ đọc của bạn.

Trước tiên, hãy chuyển đến folder của ứng dụng trên server và mở file .env của bạn bằng editor mà bạn chọn:

  • cd /var/www/travellist
  • nano .env

Tìm cấu hình database MySQL và comment dòng DB_HOST :

/var/www/travellist/.env
DB_CONNECTION=mysql #DB_HOST=MANAGED_MYSQL_HOST DB_PORT=MANAGED_MYSQL_PORT DB_DATABASE=MANAGED_MYSQL_DB DB_USERNAME=MANAGED_MYSQL_USER DB_PASSWORD=MANAGED_MYSQL_PASSWORD 

Lưu file khi bạn hoàn tất. Bây giờ mở config/database.php trong editor của bạn:

  • nano config/database.php

Tìm mục nhập mysql bên trong mảng connections . Bạn nên bao gồm ba mục mới trong mảng cấu hình này: read , writesticky . Các readwrite các mục sẽ cài đặt các node cluster, và sticky tùy chọn cài đặt để true sẽ tái sử dụng write các kết nối để các dữ liệu ghi vào database có sẵn ngay trong chu kỳ yêu cầu tương tự. Bạn có thể đặt nó thành false nếu bạn không muốn hành vi này.

/var/www/travel_list/config/database.php
...       'mysql' => [          'read' => [            'host' => [               'READONLY_NODE1_HOST',               'READONLY_NODE2_HOST',            ],          ],          'write' => [            'host' => [              'MANAGED_MYSQL_HOST',            ],          ],        'sticky' => true, ... 

Lưu file khi bạn chỉnh sửa xong. Để kiểm tra xem mọi thứ có hoạt động như mong đợi hay không, ta có thể tạo một đường dẫn tạm thời bên trong routes/web.php để lấy một số dữ liệu từ database và hiển thị chi tiết về kết nối đang được sử dụng. Bằng cách này, ta sẽ có thể xem các yêu cầu đang được cân bằng tải như thế nào giữa các node chỉ đọc.

Mở file tin routes/web.php :

  • nano routes/web.php

Bao gồm các tuyến đường sau:

/var/www/travel_list/routes/web.php
...  Route::get('/mysql-test', function () {   $places = App\Place::all();   $results = DB::select( DB::raw("SHOW VARIABLES LIKE 'server_id'") );    return "Server ID: " . $results[0]->Value; }); 

Bây giờ, hãy truy cập trình duyệt của bạn và truy cập vào tuyến ứng dụng /mysql-test :

http://server_domain_or_IP/mysql-test 

Bạn sẽ thấy một trang như thế này:

trang kiểm tra nút mysql

Reload trang một vài lần và bạn sẽ nhận thấy rằng giá trị Server ID thay đổi, cho biết rằng các yêu cầu đang được phân phối ngẫu nhiên giữa hai nút chỉ đọc.

Kết luận

Trong hướng dẫn này, ta đã chuẩn bị một ứng dụng Laravel 6 cho một môi trường có khả năng mở rộng và khả dụng cao. Ta đã thuê ngoài hệ thống database cho một dịch vụ MySQL được quản lý bên ngoài và ta đã tích hợp dịch vụ lưu trữ đối tượng tương thích với S3 vào ứng dụng để lưu trữ các file do user tải lên. Cuối cùng, ta đã thấy cách mở rộng database của ứng dụng bằng cách bao gồm các node cụm chỉ đọc bổ sung trong file cấu hình của ứng dụng.

Bạn có thể tìm thấy mã ứng dụng demo được cập nhật chứa tất cả các sửa đổi được thực hiện trong hướng dẫn này trong thẻ 2.1 trong repository ứng dụng trên Github.

Từ đây, bạn có thể cài đặt Load Balancer để phân phối tải và chia tỷ lệ ứng dụng của bạn giữa nhiều nút. Bạn cũng có thể tận dụng cài đặt này để tạo một môi trường chứa để chạy ứng dụng của bạn trên Docker.


Tags:

Các tin liên quan