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:
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:
Lưu ý : hướng dẫn này sử dụng DigitalOcean Managed MySQL và Spaces để 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 1 và 3 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 1 và 2 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:
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:
Outputmysql 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-xml
và php-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:
OutputLoading 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 Y
và ENTER
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.
Cài đặt liên kết lưu trữ
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
OutputThe [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:
Outputtotal 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:
OutputMigration 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:
OutputSeeding: 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:
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 storage
và bootstrap/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:
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
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:
OutputUsing 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:
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
:
'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:
'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
… 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:
<?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:
@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:
Outputupload: './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
Output2019-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:
Đế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:
- Đi tới Database và chọn cụm MySQL của bạn.
- Nhấp vào
Actions
và chọnAdd a read-only node
từ trình đơn thả xuống. - 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.
- Lặp lại các bước 1-4 để bạn có 2 nút chỉ đọc.
- 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ư INSERT
và UPDATE
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
:
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
, write
và sticky
. Các read
và write
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.
... '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:
... 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:
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.
Các tin liên quan