非托管对象 和托管对象_如何使用托管数据库和对象存储设置可扩展的Laravel 6应用程序

news/2024/7/3 4:46:01

非托管对象 和托管对象

介绍 (Introduction)

When scaling web applications horizontally, the first difficulties you’ll typically face are dealing with file storage and data persistence. This is mainly due to the fact that it is hard to maintain consistency of variable data between multiple application nodes; appropriate strategies must be in place to make sure data created in one node is immediately available to other nodes in a cluster.

在水平扩展Web应用程序时,通常会遇到的第一个困难是处理文件存储和数据持久性。 这主要是由于难以维护多个应用程序节点之间的变量数据的一致性。 必须采取适当的策略,以确保在一个节点中创建的数据可立即用于集群中的其他节点。

A practical way of solving the consistency problem is by using managed databases and object storage systems. The first will outsource data persistence to a managed database, and the latter will provide a remote storage service where you can keep static files and variable content such as images uploaded by users. Each node can then connect to these services at the application level.

解决一致性问题的一种实用方法是使用托管数据库和对象存储系统。 前者将数据持久性外包给托管数据库,后者将提供远程存储服务,您可以在其中保留静态文件和可变内容,例如用户上传的图像。 然后,每个节点都可以在应用程序级别连接到这些服务。

The following diagram demonstrates how such a setup can be used for horizontal scalability in the context of PHP applications:

下图演示了如何在PHP应用程序的上下文中将这种设置用于水平可伸缩性:

In this guide, we will update an existing Laravel 6 application to prepare it for horizontal scalability by connecting it to a managed MySQL database and setting up an S3-compatible object store to save user-generated files. By the end, you will have a travel list application running on an Nginx + PHP-FPM web server:

在本指南中,我们将更新现有的Laravel 6应用程序,以通过将其连接到托管MySQL数据库并设置与S3兼容的对象存储来保存用户生成的文件,以使其具有水平可伸缩性。 到最后,您将在Nginx + PHP-FPM Web服务器上运行一个旅行清单应用程序:

Note: this guide uses DigitalOcean Managed MySQL and Spaces to demonstrate a scalable application setup using managed databases and object storage. The instructions contained here should work in a similar way for other service providers.

注意 :本指南使用DigitalOcean托管MySQL和Spaces演示使用托管数据库和对象存储的可伸缩应用程序设置。 对于其他服务提供商,此处包含的说明应以类似的方式工作。

先决条件 (Prerequisites)

To begin this tutorial, you will first need the following prerequisites:

要开始本教程,您首先需要满足以下先决条件:

  • Access to an Ubuntu 18.04 server as a non-root user with sudo privileges, and an active firewall installed on your server. To set these up, please refer to our Initial Server Setup Guide for Ubuntu 18.04.

    以具有sudo特权的非root用户身份访问Ubuntu 18.04服务器,并在服务器上安装了活动的防火墙。 要进行设置,请参阅我们的Ubuntu 18.04初始服务器设置指南 。

  • Nginx and PHP-FPM installed and configured on your server, as explained in steps 1 and 3 of How to Install LEMP on Ubuntu 18.04. You should skip the step where MySQL is installed.

    如如何在Ubuntu 18.04上安装LEMP的步骤13中所述,在服务器上安装并配置了Nginx和PHP-FPM。 您应该跳过安装MySQL的步骤。

  • Composer installed on your server, as explained in steps 1 and 2 of How to Install and Use Composer on Ubuntu 18.04.

    作曲家安装在服务器上,因为在步骤12解释如何在Ubuntu 18.04安装和使用的作曲家 。

  • Admin credentials to a managed MySQL 8 database. For this guide, we’ll be using a DigitalOcean Managed MySQL cluster, but the instructions here should work similarly for other managed database services.

    到管理MySQL 8数据库的管理员凭据。 在本指南中,我们将使用DigitalOcean托管MySQL集群,但是此处的说明应与其他托管数据库服务类似。

  • A set of API keys with read and write permissions to an S3-compatible object storage service. In this guide, we’ll use DigitalOcean Spaces, but you are free to use a provider of your choice.

    一组具有对S3兼容对象存储服务的读写权限的API密钥。 在本指南中,我们将使用DigitalOcean Spaces ,但您可以自由使用自己选择的提供程序。

  • The s3cmd tool installed and configured to connect to your object storage drive. For instructions on how to set this up for DigitalOcean Spaces, please refer to our product documentation.

    s3cmd工具已安装并配置为连接到对象存储驱动器。 有关如何为DigitalOcean Spaces进行设置的说明,请参阅我们的产品文档 。

第1步-安装MySQL 8客户端 (Step 1 — Installing the MySQL 8 Client)

The default Ubuntu apt repositories come with the MySQL 5 client, which is not compatible with the MySQL 8 server we’ll be using in this guide. To install the compatible MySQL client, we’ll need to use the MySQL APT Repository provided by Oracle.

默认的Ubuntu apt存储库与MySQL 5客户端一起提供,该客户端与本指南中将使用MySQL 8服务器不兼容。 要安装兼容MySQL客户端,我们需要使用Oracle提供MySQL APT存储库。

Begin by navigating to the MySQL APT Repository page in your web browser. Find the Download button in the lower-right corner and click through to the next page. This page will prompt you to log in or sign up for an Oracle web account. You can skip that and instead look for the link that says No thanks, just start my download. Copy the link address and go back to your terminal window.

首先,在Web浏览器中导航到“ MySQL APT存储库”页面 。 在右下角找到“ 下载”按钮,然后单击进入下一页。 该页面将提示您登录或注册Oracle Web帐户。 您可以跳过该链接,而是寻找显示“ 不,谢谢”的链接,只需开始下载即可 。 复制链接地址,然后返回到您的终端窗口。

This link should point to a .deb package that will set up the MySQL APT Repository in your server. After installing it, you’ll be able to use apt to install the latest releases of MySQL. We’ll use curl to download this file into a temporary location.

该链接应该指向一个.deb软件包,该软件包将在您的服务器中设置MySQL APT存储库。 安装后,您将可以使用apt安装最新版本MySQL。 我们将使用curl将这个文件下载到一个临时位置。

Go to your server’s tmp folder:

转到服务器的tmp文件夹:

  • cd /tmp

    cd / tmp

Now download the package with curl and using the URL you copied from the MySQL APT Repository page:

现在使用curl并使用您从MySQL APT Repository页面复制的URL下载该软件包:

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

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

After the download is finished, you can use dpkg to install the package:

下载完成后,可以使用dpkg安装软件包:

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

    须藤dpkg -i mysql-apt-config_0.8.13-1_all.deb

You will be presented with a screen where you can choose which MySQL version you’d like to select as default, as well as which MySQL components you’re interested in:

将显示一个屏幕,您可以在其中选择要选择MySQL版本作为默认版本,以及感兴趣MySQL组件:

You don’t need to change anything here, because the default options will install the repositories we need. Select “Ok” and the configuration will be finished.

您无需在此处进行任何更改,因为默认选项将安装我们需要的存储库。 选择“确定”,配置完成。

Next, you’ll need to update your apt cache with:

接下来,您需要使用以下命令更新apt缓存:

  • sudo apt update

    sudo apt更新

Now we can finally install the MySQL 8 client with:

现在,我们终于可以使用以下命令安装MySQL 8客户端了:

  • sudo apt install mysql-client

    sudo apt安装mysql客户端

Once that command finishes, check the software version number to ensure that you have the latest release:

该命令完成后,请检查软件版本号以确保您具有最新版本:

  • mysql --version

    mysql --version

You’ll see output like this:

您将看到如下输出:


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

In the next step, we’ll use the MySQL client to connect to your managed MySQL server and prepare the database for the application.

在下一步中,我们将使用MySQL客户端连接到托管MySQL服务器,并为应用程序准备数据库。

第2步-创建新MySQL用户和数据库 (Step 2 — Creating a new MySQL User and Database)

At the time of this writing, the native MySQL PHP library mysqlnd doesn’t support caching_sha2_authentication, the default authentication method for MySQL 8. We’ll need to create a new user with the mysql_native_password authentication method in order to be able to connect our Laravel application to the MySQL 8 server. We’ll also create a dedicated database for our demo application.

在撰写本文时,本机MySQL PHP库mysqlnd 不支持 caching_sha2_authentication ,这是MySQL 8的默认身份验证方法。我们需要使用mysql_native_password身份验证方法创建一个新用户,以便能够连接Laravel应用程序到MySQL 8服务器。 我们还将为演示应用程序创建一个专用的数据库。

To get started, log into your server using an admin account. Replace the highlighted values with your own MySQL user, host, and port:

首先,请使用管理员帐户登录到服务器。 用您自己MySQL用户,主机和端口替换突出显示的值:

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

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

When prompted, provide the admin user’s password. After logging in, you will have access to the MySQL 8 server command line interface.

出现提示时,请提供管理员用户的密码。 登录后,您将可以访问MySQL 8服务器命令行界面。

First, we’ll create a new database for the application. Run the following command to create a new database named travellist:

首先,我们将为该应用程序创建一个新的数据库。 运行以下命令以创建一个名为travellist的新数据库:

  • CREATE DATABASE travellist;

    创建数据库旅行清单 ;

Next, we’ll create a new user and set a password, using mysql_native_password as default authentication method for this user. You are encouraged to replace the highlighted values with values of your own, and to use a strong password:

接下来,我们将使用mysql_native_password作为该用户的默认身份验证方法来创建一个新用户并设置一个密码。 建议您将突出显示的值替换为您自己的值,并使用强密码:

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

    使用mysql_native_password创建用户' travellist-user '@'%',并通过' MYSQL_PASSWORD '进行身份验证 ;

Now we need to give this user permission over our application database:

现在,我们需要授予该用户对应用程序数据库的权限:

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

    将所有内容都授予旅行清单 。* 致 ' 旅行清单用户 '@'%';

You can now exit the MySQL prompt with:

现在,您可以使用以下命令退出MySQL提示符:

  • exit;

    出口;

You now have a dedicated database and a compatible user to connect from your Laravel application. In the next step, we’ll get the application code and set up configuration details, so your app can connect to your managed MySQL database.

您现在拥有一个专用的数据库和一个兼容的用户,可以从您的Laravel应用程序进行连接。 在下一步中,我们将获取应用程序代码并设置配置详细信息,以便您的应用程序可以连接到托管MySQL数据库。

In this guide, we’ll use Laravel Migrations and database seeds to set up our application tables. If you need to migrate an existing local database to a DigitalOcean Managed MySQL database, please refer to our documentation on How to Import MySQL Databases into DigitalOcean Managed Databases.

在本指南中,我们将使用Laravel Migrations和数据库种子来设置应用程序表。 如果您需要将现有的本地数据库迁移到DigitalOcean托管MySQL数据库,请参阅我们的文档“ 如何将MySQL数据库导入DigitalOcean托管的数据库” 。

步骤3 —设置演示应用程序 (Step 3 — Setting Up the Demo Application)

To get started, we’ll fetch the demo Laravel application from its Github repository. Feel free to inspect the contents of the application before running the next commands.

首先,我们将从其Github存储库中获取演示Laravel应用程序。 在运行下一个命令之前,请随时检查应用程序的内容。

The demo application is a travel bucket list app that was initially developed in our guide on How to Install and Configure Laravel with LEMP on Ubuntu 18.04. The updated app now contains visual improvements including travel photos that can be uploaded by a visitor, and a world map. It also introduces a database migration script and database seeds to create the application tables and populate them with sample data, using artisan commands.

该演示应用程序是一个旅行清单应用程序,最初是在有关如何在Ubuntu 18.04上使用LEMP安装和配置Laravel的指南中开发的。 更新后的应用程序现在包含视觉上的改进,其中包括可以由访客上传的旅行照片以及世界地图。 它还引入了数据库迁移脚本和数据库种子,以使用artisan命令创建应用程序表并使用示例数据填充它们。

To obtain the application code that is compatible with this tutorial, we’ll download the 1.1 release from the project’s repository on Github. We’ll save the downloaded zip file as travellist.zip inside our home directory:

要获取与本教程兼容的应用程序代码,我们将从Github上的项目存储库中下载1.1版本 。 我们会将下载的zip文件保存为home目录中的travellist.zip

  • cd ~

    光盘〜
  • curl -L https://github.com/do-community/travellist-laravel-demo/archive/1.1.zip -o travellist.zip

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

Now, unzip the contents of the application and rename its directory with:

现在,解压缩应用程序的内容,并使用以下命令重命名其目录:

  • unzip travellist.zip

    解压缩travellist.zip
  • mv travellist-laravel-demo-1.1 travellist

    mv travellist-laravel-demo-1.1旅行清单

Navigate to the travellist directory:

导航到travellist目录:

  • cd travellist

    cd旅行清单

Before going ahead, we’ll need to install a few PHP modules that are required by the Laravel framework, namely: php-xml, php-mbstring, php-xml and php-bcmath. To install these packages, run:

在继续之前,我们需要安装Laravel框架所需的一些PHP模块,即: php-xmlphp-mbstringphp-xmlphp-bcmath 。 要安装这些软件包,请运行:

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

    sudo apt安装解压缩php-xml php-mbstring php-xml php-bcmath

To install the application dependencies, run:

要安装应用程序依赖项,请运行:

  • composer install

    作曲家安装

You will see output similar to this:

您将看到类似于以下的输出:


   
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.

The application dependencies are now installed. Next, we’ll configure the application to connect to the managed MySQL Database.

现在已安装了应用程序依赖项。 接下来,我们将配置应用程序以连接到托管MySQL数据库。

创建.env配置文件并设置应用程序密钥 (Creating the .env configuration file and setting the App Key)

We’ll now create a .env file containing variables that will be used to configure the Laravel application in a per-environment basis. The application includes an example file that we can copy and then modify its values to reflect our environment settings.

现在,我们将创建一个.env文件,其中包含将用于在每个环境中配置Laravel应用程序的变量。 该应用程序包含一个示例文件,我们可以复制该文件,然后修改其值以反映我们的环境设置。

Copy the .env.example file to a new file named .env:

.env.example文件复制到名为.env的新文件中:

  • cp .env.example .env

    cp .env.example .env

Now we need to set the application key. This key is used to encrypt session data, and should be set to a unique 32 characters-long string. We can generate this key automatically with the artisan tool:

现在我们需要设置应用程序密钥。 该密钥用于加密会话数据,应设置为唯一的32个字符长的字符串。 我们可以使用artisan工具自动生成此密钥:

  • php artisan key:generate

    PHP的工匠键:生成

Let’s edit the environment configuration file to set up the database details. Open the .env file using your command line editor of choice. Here, we will be using nano:

让我们编辑环境配置文件以设置数据库详细信息。 使用您选择的命令行编辑器打开.env文件。 在这里,我们将使用nano

  • nano .env

    纳米.env

Look for the database credentials section. The following variables need your attention:

查找数据库凭证部分。 以下变量需要引起您的注意:

DB_HOST: your managed MySQL server host. DB_PORT: your managed MySQL server port. DB_DATABASE: the name of the application database we created in Step 2. DB_USERNAME: the database user we created in Step 2. DB_PASSWORD: the password for the database user we defined in Step 2.

DB_HOST :您的托管MySQL服务器主机。 DB_PORT :您的托管MySQL服务器端口。 DB_DATABASE :我们在步骤2中创建的应用程序数据库的名称。 DB_USERNAME :我们在步骤2中创建的数据库用户。 DB_PASSWORD :我们在步骤2中定义的数据库用户的密码。

Update the highlighted values with your own managed MySQL info and credentials:

使用您自己的托管MySQL信息和凭据更新突出显示的值:

...
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
...

Save and close the file by typing CTRL+X then Y and ENTER when you’re done editing.

完成编辑后,请依次按CTRL+X YENTER保存并关闭文件。

Now that the application is configured to connect to the MySQL database, we can use Laravel’s command line tool artisan to create the database tables and populate them with sample data.

现在已经配置了应用程序以连接到MySQL数据库,我们可以使用Laravel的命令行工具artisan创建数据库表并用示例数据填充它们。

Before executing the database tools provided by the artisan command, we need to create a symbolic link to the public storage folder that will host the travel photos we’re using in the application. This is necessary because our database seed script relies on these sample photos to insert data in the places table.

在执行artisan命令提供的数据库工具之前,我们需要创建一个指向公共存储文件夹的符号链接,该文件夹将托管我们在应用程序中使用的旅行照片。 这是必需的,因为我们的数据库种子脚本依赖于这些样本照片将数据插入places表中。

The following command will create a symbolic link inside the public directory, which is publicly exposed through the web server, pointing to the application’s internal storage directory storage/app/public:

以下命令将在public目录内创建一个符号链接,该链接通过Web服务器公开显示,指向应用程序的内部存储目录storage/app/public

  • php artisan storage:link

    PHP的工匠存储:链接

   
Output
The [public/storage] directory has been linked.

To check that the link was created and where it points to, you can run:

要检查链接是否已创建及其指向的位置,可以运行:

  • ls -la public/

    ls -la public /

You’ll see output like this:

您将看到如下输出:


   
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

迁移和填充数据库 (Migrating and populating the database)

We’ll now use Laravel Migrations and database seeds to set up the application tables. This will help us determine if our database configuration works as expected.

现在,我们将使用Laravel Migrations和数据库种子来设置应用程序表。 这将帮助我们确定数据库配置是否按预期工作。

To execute the migration script that will create the tables used by the application, run:

要执行将创建应用程序使用的表的迁移脚本,请运行:

  • php artisan migrate

    PHP的工匠迁移

You will see output similar to this:

您将看到类似于以下的输出:


   
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)

To populate the database with sample data, run:

要用示例数据填充数据库,请运行:

  • php artisan db:seed

    PHP的工匠db:seed

You will see output like this:

您将看到如下输出:


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

The application tables are now created and populated with sample data.

现在创建了应用程序表,并使用示例数据填充了该表。

运行测试服务器(可选) (Running the test server (optional))

You can use the artisan serve command to quickly verify that everything is set up correctly within the application, before having to configure a full-featured web server like Nginx to serve the application for the long term.

在必须配置诸如Nginx之类的功能齐全的Web服务器来长期服务该应用程序之前,您可以使用artisan serve命令快速验证该应用程序内的所有设置是否正确。

We’ll use port 8000 to temporarily serve the application for testing. If you have the UFW firewall enabled on your server, you should first allow access to this port with:

我们将使用端口8000暂时为应用程序提供服务以进行测试。 如果在服务器上启用了UFW防火墙,则应首先使用以下命令允许访问此端口:

  • sudo ufw allow 8000

    sudo ufw允许8000

Now, to run the built in PHP server that Laravel exposes through the artisan tool, run:

现在,要运行Laravel通过artisan工具公开的内置PHP服务器,请运行:

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

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

This command will block your terminal until interrupted with a CTRL+C. It will use the built-in PHP web server to serve the application for test purposes on all network interfaces, using port 8000.

此命令将阻止您的终端,直到被CTRL+C中断为止。 它将使用内置PHP Web服务器使用端口8000在所有网络接口上为测试目的提供应用程序服务。

Now go to your browser and access the application using the server’s domain name or IP address on port 8000:

现在转到浏览器,使用服务器的域名或端口8000上的IP地址访问应用程序:

http://server_domain_or_IP:8000

You will see the following page:

您将看到以下页面:

If you see this page, it means the application is successfully pulling data about locations and photos from the configured managed database. The image files are still stored in the local disk, but we’ll change this in a following step of this guide.

如果看到此页面,则表示该应用程序已成功从配置的托管数据库中提取有关位置和照片的数据。 映像文件仍存储在本地磁盘中,但是我们将在本指南的后续步骤中对此进行更改。

When you are finished testing the application, you can stop the serve command by hitting CTRL+C.

测试完应用程序后,可以通过按CTRL+C来停止serve命令。

Don’t forget to close port 8000 again if you are running UFW on your server:

如果您在服务器上运行UFW,请不要忘记再次关闭端口8000

  • sudo ufw deny 8000

    sudo ufw拒绝8000

步骤4 —配置Nginx服务应用程序 (Step 4 — Configuring Nginx to Serve the Application)

Although the built-in PHP web server is very useful for development and testing purposes, it is not intended to be used as a long term solution to serve PHP applications. Using a full featured web server like Nginx is the recommended way of doing that.

尽管内置PHP Web服务器对于开发和测试目的非常有用,但并不打算用作服务PHP应用程序的长期解决方案。 建议使用像Nginx这样的功能齐全的Web服务器。

To get started, we’ll move the application folder to /var/www, which is the usual location for web applications running on Nginx. First, use the mv command to move the application folder with all its contents to /var/www/travellist:

首先,我们将应用程序文件夹移动到/var/www ,这是在Nginx上运行的Web应用程序的常用位置。 首先,使用mv命令将应用程序文件夹及其所有内容移动到/var/www/travellist

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

    须藤MV〜/ travellist / var / www / travellist

Now we need to give the web server user write access to the storage and bootstrap/cache folders, where Laravel stores application-generated files. We’ll set these permissions using setfacl, a command line utility that allows for more robust and fine-grained permission settings in files and folders.

现在,我们需要为Web服务器用户提供对storagebootstrap/cache文件夹的写访问权,Laravel在其中存储应用程序生成的文件。 我们将使用setfacl (命令行实用程序)设置这些权限,该实用程序允许在文件和文件夹中进行更强大且更细粒度的权限设置。

To include read, write and execution (rwx) permissions to the web server user over the required directories, run:

要在所需目录上包括对Web服务器用户的读,写和执行(rwx)权限,请运行:

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

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

    须藤setfacl -R -mg:www-data:rwx / var / www / travellist / bootstrap / cache

The application files are now in order, but we still need to configure Nginx to serve the content. To do this, we’ll create a new virtual host configuration file at /etc/nginx/sites-available:

现在,应用程序文件已经整理好了,但是我们仍然需要配置Nginx来提供内容。 为此,我们将在/etc/nginx/sites-available创建一个新的虚拟主机配置文件:

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

    须藤纳米/ etc / nginx / sites-available / travellist

The following configuration file contains the recommended settings for Laravel applications on Nginx:

以下配置文件包含Nginx上Laravel应用程序的建议设置:

/etc/nginx/sites-available/travellist
/ 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;
    }
}

Copy this content to your /etc/nginx/sites-available/travellist file and adjust the highlighted values to align with your own configuration. Save and close the file when you’re done editing.

将此内容复制到您的/etc/nginx/sites-available/ travellist文件中,并调整突出显示的值以符合您自己的配置。 完成编辑后,保存并关闭文件。

To activate the new virtual host configuration file, create a symbolic link to travellist in sites-enabled:

要激活新的虚拟主机配置文件,请在sites-enabled创建指向travellist的符号链接:

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

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

Note: If you have another virtual host file that was previously configured for the same server_name used in the travellist virtual host, you might need to deactivate the old configuration by removing the corresponding symbolic link inside /etc/nginx/sites-enabled/.

注意 :如果您有另一个虚拟主机文件,该文件先前已配置为与travellist虚拟主机中使用的相同的server_name ,则可能需要通过删除/etc/nginx/sites-enabled/的相应符号链接来停用旧配置。

To confirm that the configuration doesn’t contain any syntax errors, you can use:

要确认配置不包含任何语法错误,可以使用:

  • sudo nginx -t

    须藤Nginx -t

You should see output like this:

您应该看到如下输出:

Output
输出量
  • nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

    nginx:配置文件/etc/nginx/nginx.conf语法正常
  • nginx: configuration file /etc/nginx/nginx.conf test is successful

    nginx:配置文件/etc/nginx/nginx.conf测试成功

To apply the changes, reload Nginx with:

要应用更改,请使用以下命令重新加载Nginx:

  • sudo systemctl reload nginx

    须藤systemctl重新加载nginx

If you reload your browser now, the application images will be broken. That happens because we moved the application directory to a new location inside the server, and for that reason we need to re-create the symbolic link to the application storage folder.

如果现在重新加载浏览器,则应用程序映像将损坏。 发生这种情况是因为我们将应用程序目录移动到了服务器内部的新位置,因此我们需要重新创建指向应用程序存储文件夹的符号链接。

Remove the old link with:

使用以下方法删除旧链接:

  • cd /var/www/travellist

    cd / var / www / travellist

  • rm -f public/storage

    rm -f公共/存储

Now run once again the artisan command to generate the storage link:

现在再次运行artisan命令以生成存储链接:

  • php artisan storage:link

    PHP的工匠存储:链接

Now go to your browser and access the application using the server’s domain name or IP address, as defined by the server_name directive in your configuration file:

现在转到浏览器,使用服务器的域名或IP地址访问应用程序,该域名或IP地址由配置文件中的server_name指令定义:

http://server_domain_or_IP

In the next step, we’ll integrate an object storage service into the application. This will replace the current local disk storage used for the travel photos.

在下一步中,我们将对象存储服务集成到应用程序中。 这将替换用于旅行照片的当前本地磁盘存储。

步骤5 —将兼容S3的对象存储集成到应用程序中 (Step 5 — Integrating an S3-Compatible Object Storage into the Application)

We’ll now set up the application to use an S3-compatible object storage service for storing the travel photos exhibited on the index page. Because the application already has a few sample photos stored in the local disk, we’ll also use the s3cmd tool to upload the existing local image files to the remote object storage.

现在,我们将应用程序设置为使用与S3兼容的对象存储服务,以存储索引页面上显示的旅行照片。 由于应用程序已经在本地磁盘中存储了一些示例照片,因此我们还将使用s3cmd工具将现有的本地图像文件上载到远程对象存储中。

为Laravel设置S3驱动程序 (Setting Up the S3 Driver for Laravel)

Laravel uses league/flysystem, a filesystem abstraction library that enables a Laravel application to use and combine multiple storage solutions, including local disk and cloud services. An additional package is required to use the s3 driver. We can install this package using the composer require command.

Laravel使用League league/flysystem这个文件系统抽象库,使Laravel应用程序可以使用和组合多个存储解决方案,包括本地磁盘和云服务。 要使用s3驱动程序,需要附加软件包。 我们可以使用composer require命令安装此软件包。

Access the application directory:

访问应用程序目录:

  • cd /var/www/travellist

    cd / var / www / travellist

  • composer require league/flysystem-aws-s3-v3

    作曲家需要League / flysystem-aws-s3-v3

You will see output similar to this:

您将看到类似于以下的输出:


   
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 ...

Now that the required packages are installed, we can update the application to connect to the object storage. First, we’ll open the .env file again to set up configuration details such as keys, bucket name, and region for your object storage service.

现在已经安装了必需的软件包,我们可以更新应用程序以连接到对象存储。 首先,我们将再次打开.env文件以设置配置详细信息,例如对象存储服务的键,存储区名称和区域。

Open the .env file:

打开.env文件:

  • nano .env

    纳米.env

Include the following environment variables, replacing the highlighted values with your object store configuration details:

包括以下环境变量,用对象库配置详细信息替换突出显示的值:

/var/www/travellist/.env
/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

Save and close the file when you’re done. Now open the config/filesystems.php file:

完成后,保存并关闭文件。 现在打开config/filesystems.php文件:

  • nano config/filesystems.php

    纳米config / filesystems.php

Within this file, we’ll create a new disk entry in the disks array. We’ll name this disk spaces, and we’ll use the environment variables we’ve set in the .env file to configure the new disk. Include the following entry in the disks array:

在此文件中,我们将在disks数组中创建一个新的磁盘条目。 我们将命名该磁盘spaces ,并使用在.env文件中设置的环境变量来配置新磁盘。 在disks阵列中包括以下条目:

config/filesystems.php
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'),
],

Still in the same file, locate the cloud entry and change it to set the new spaces disk as default cloud filesystem disk:

仍在同一文件中,找到cloud条目并将其更改以将新的spaces磁盘设置为默认云文件系统磁盘:

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

Save and close the file when you’re done editing. From your controllers, you can now use the Storage::cloud() method as a shortcut to access the default cloud disk. This way, the application stays flexible to use multiple storage solutions, and you can switch between providers on a per-environment basis.

完成编辑后,保存并关闭文件。 现在,您可以从控制器中使用Storage::cloud()方法作为访问默认cloud磁盘的快捷方式。 这样,应用程序可以灵活使用多个存储解决方案,并且您可以基于每个环境在提供程序之间进行切换。

The application is now configured to use object storage, but we still need to update the code that uploads new photos to the application.

现在将应用程序配置为使用对象存储,但是我们仍然需要更新将新照片上传到应用程序的代码。

Let’s first examine the current uploadPhoto route, located in the PhotoController class. Open the file using your text editor:

首先让我们检查位于PhotoController类中的当前uploadPhoto路由。 使用文本编辑器打开文件:

  • nano app/Http/Controllers/PhotoController.php

    纳米app / Http / Controllers / PhotoController.php
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');
}

This method accepts a POST request and creates a new photo entry in the photos table. It begins by checking if an existing place was selected in the photo upload form, and if that’s not the case, it will create a new place using the provided information. The place is then set to visited and saved to the database. Following that, an association is created so that the new photo is linked to the designated place. The image file is then stored in the root folder of the public disk. Finally, the photo is saved to the database. The user is then redirected to the main route, which is the index page of the application.

此方法接受POST请求,并在photos表中创建一个新的photo条目。 首先检查在照片上传表单中是否选择了现有地点,如果不是这样,它将使用所提供的信息创建一个新地点。 然后将该地点设置为已visited并保存到数据库。 之后,创建关联,以便将新照片链接到指定的位置。 然后将映像文件存储在public磁盘的根文件夹中。 最后,照片被保存到数据库中。 然后,用户将被重定向到主路由,即应用程序的索引页面。

The highlighted line in this code is what we’re interested in. In that line, the image file is saved to the disk using the store method. The store method is used to save files to any of the disks defined in the filesystem.php configuration file. In this case, it is using the default disk to store uploaded images.

这段代码中突出显示的行是我们感兴趣的行。在该行中,使用store方法将映像文件保存到磁盘。 store方法用于将文件保存到filesystem.php配置文件中定义的任何磁盘上。 在这种情况下,它将使用默认磁盘来存储上载的图像。

We will change this behavior so that the image is saved to the object store instead of the local disk. In order to do that, we need to replace the public disk by the spaces disk in the store method call. We also need to make sure the uploaded file’s visibility is set to public instead of private.

我们将更改此行为,以便将映像保存到对象存储而不是本地磁盘。 为此,我们需要在store方法调用中将public磁盘替换为spaces磁盘。 我们还需要确保上传文件的可见性设置为public而不是private

The following code contains the full PhotoController class, including the updated uploadPhoto method:

以下代码包含完整的PhotoController类,其中包括更新的uploadPhoto方法:

app/Http/Controllers/PhotoController.php
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');
   }
}

Copy the updated code to your own PhotoController so that it reflects the highlighted changes. Save and close the file when you’re done editing.

将更新的代码复制到您自己的PhotoController ,以使其反映突出显示的更改。 完成编辑后,保存并关闭文件。

We still need to modify the application’s main view so that it uses the object storage file URL to render the image. Open the travel_list.blade.php template:

我们仍然需要修改应用程序的主视图,以便它使用对象存储文件URL呈现图像。 打开travel_list.blade.php模板:

  • nano resources/views/travel_list.blade.php

    纳米资源/视图/travel_list.blade.php

Now locate the footer section of the page, which currently looks like this:

现在找到页面的footer部分,当前如下所示:

resources/views/travel_list.blade.php
资源/视图/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

Replace the current image src attribute to use the file URL from the spaces storage disk:

替换当前图像src属性以使用来自spaces存储磁盘的文件URL:

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

If you go to your browser now and reload the application page, it will show only broken images. That happens because the image files for those travel photos are still only in the local disk. We need to upload the existing image files to the object storage, so that the photos already stored in the database can be successfully exhibited in the application page.

如果您现在进入浏览器并重新加载应用程序页面,它将仅显示损坏的图像。 发生这种情况是因为这些旅行照片的图像文件仍仅位于本地磁盘中。 我们需要将现有的图像文件上传到对象存储,以便可以将已存储在数据库中的照片成功显示在应用程序页面中。

s3cmd同步本地图像 (Syncing local images with s3cmd)

The s3cmd tool can be used to sync local files with an S3-compatible object storage service. We’ll run a sync command to upload all files inside storage/app/public/photos to the object storage service.

s3cmd工具可用于将本地文件与兼容S3的对象存储服务同步。 我们将运行sync命令,将storage/app/public/photos中的所有文件上传到对象存储服务。

Access the public app storage directory:

访问public应用程序存储目录:

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

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

To have a look at the files already stored in your remote disk, you can use the s3cmd ls command:

要查看已经存储在远程磁盘中的文件,可以使用s3cmd ls命令:

  • s3cmd ls s3://your_bucket_name

    s3cmd ls s3:// your_bucket_name

Now run the sync command to upload existing files in the public storage folder to the object storage:

现在运行sync命令,将公共存储文件夹中的现有文件上传到对象存储:

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

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

This will synchronize the current folder (storage/app/public) with the remote object storage’s root dir. You will get output similar to this:

这会将当前文件夹( storage/app/public )与远程对象存储的根目录同步。 您将获得类似于以下的输出:


   
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.

Now, if you run s3cmd ls again, you will see that three new files were added to the root folder of your object storage bucket:

现在,如果再次运行s3cmd ls ,您将看到三个新文件已添加到对象存储桶的根文件夹中:

  • s3cmd ls s3://your_bucket_name

    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

Go to your browser and reload the application page. All images should be visible now, and if you inspect them using your browser debug tools, you’ll notice that they’re all using URLs from your object storage.

转到浏览器并重新加载应用程序页面。 现在所有图像都应该可见,并且如果使用浏览器调试工具检查它们,您会注意到它们都使用了对象存储中的URL。

测试集成 (Testing the Integration)

The demo application is now fully functional, storing files in a remote object storage service, and saving data to a managed MySQL database. We can now upload a few photos to test our setup.

演示应用程序现已完全正常运行,将文件存储在远程对象存储服务中,并将数据保存到托管MySQL数据库中。 现在,我们可以上传几张照片来测试设置。

Access the /upload application route from your browser:

从浏览器访问/upload应用程序路由:

http://server_domain_or_IP/upload

You will see the following form:

您将看到以下形式:

You can now upload a few photos to test the object storage integration. After choosing an image from your computer, you can select an existing place from the dropdown menu, or you can add a new place by providing its name and geographic coordinates so it can be loaded in the application map.

现在,您可以上传一些照片以测试对象存储集成。 从计算机中选择图像后,可以从下拉菜单中选择一个现有位置,也可以通过提供其名称和地理坐标来添加新位置,以便可以将其加载到应用程序地图中。

第6步-扩大具有只读节点的DigitalOcean托管MySQL数据库(可选) (Step 6 — Scaling Up a DigitalOcean Managed MySQL Database with Read-Only Nodes (Optional))

Because read-only operations are typically more frequent than writing operations on database servers, its is a common practice to scale up a database cluster by setting up multiple read-only nodes. This will distribute the load generated by SELECT operations.

因为只读操作通常比在数据库服务器上进行写操作更为频繁,所以通过设置多个只读节点来扩展数据库集群是一种常见的做法。 这将分配由SELECT操作生成的负载。

To demonstrate this setup, we’ll first add 2 read-only nodes to our DigitalOcean Managed MySQL cluster. Then, we’ll configure the Laravel application to use these nodes.

为了演示此设置,我们首先将2个只读节点添加到我们的DigitalOcean托管MySQL集群中。 然后,我们将配置Laravel应用程序以使用这些节点。

Access the DigitalOcean Cloud Panel and follow these instructions:

访问DigitalOcean Cloud Panel并按照以下说明进行操作:

  1. Go to Databases and select your MySQL cluster.

    转到数据库,然后选择您MySQL群集。

  2. Click Actions and choose Add a read-only node from the drop-down menu.

    单击“ Actions然后从下拉菜单中选择“ Add a read-only node ”。

  3. Configure the node options and hit the Create button. Notice that it might take several minutes for the new node to be ready.

    配置节点选项,然后单击“ 创建”按钮。 请注意,准备好新节点可能要花费几分钟。

  4. Repeat steps 1-4 one more time so that you have 2 read-only nodes.

    再重复一次1-4,以便您有2个只读节点。
  5. Note down the hosts of the two nodes as we will need them for our Laravel configuration.

    记下两个节点的主机,因为我们的Laravel配置将需要它们。

Once you have your read-only nodes ready, head back to your terminal.

准备好只读节点后,请回到终端。

We’ll now configure our Laravel application to work with multiple database nodes. When we’re finished, queries such as INSERT and UPDATE will be forwarded to your primary cluster node, while all SELECT queries will be redirected to your read-only nodes.

现在,我们将配置Laravel应用程序以与多个数据库节点一起使用。 完成后,诸如INSERTUPDATE查询将被转发到您的主群集节点,而所有SELECT查询将被重定向到您的只读节点。

First, go to the application’s directory on the server and open your .env file using your text editor of choice:

首先,转到服务器上应用程序的目录,然后使用所选的文本编辑器打开.env文件:

  • cd /var/www/travellist

    cd / var / www / travellist
  • nano .env

    纳米.env

Locate the MySQL database configuration and comment out the DB_HOST line:

找到MySQL数据库配置并注释掉DB_HOST行:

/var/www/travellist/.env
/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

Save and close the file when you’re done. Now open the config/database.php in your text editor:

完成后,保存并关闭文件。 现在,在文本编辑器中打开config/database.php

  • nano config/database.php

    纳米config / database.php

Look for the mysql entry inside the connections array. You should include three new items in this configuration array: read, write, and sticky. The read and write entries will set up the cluster nodes, and the sticky option set to true will reuse write connections so that data written to the database is immediately available in the same request cycle. You can set it to false if you don’t want this behavior.

connections数组中查找mysql条目。 您应该在此配置数组中包括三个新项目: readwritesticky 。 在readwrite条目将设置群集节点和sticky选项设置为true将重用write连接,以便写入到数据库中的数据在同一个请求周期立即可用。 如果您不希望出现这种情况,可以将其设置为false

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

Save and close the file when you are done editing. To test that everything works as expected, we can create a temporary route inside routes/web.php to pull some data from the database and show details about the connection being used. This way we will be able to see how the requests are being load balanced between the read-only nodes.

完成编辑后,保存并关闭文件。 为了测试一切正常,我们可以在routes/web.php创建一条临时路由,以从数据库中提取一些数据并显示有关所使用连接的详细信息。 这样,我们将能够看到请求如何在只读节点之间进行负载平衡。

Open the routes/web.php file:

打开routes/web.php文件:

  • nano routes/web.php

    纳米路线/ web.php

Include the following route:

包括以下路线:

/var/www/travel_list/routes/web.php
/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;
});

Now go to your browser and access the /mysql-test application route:

现在转到浏览器并访问/mysql-test应用程序路由:

http://server_domain_or_IP/mysql-test

You’ll see a page like this:

您会看到这样的页面:

Reload the page a few times and you will notice that the Server ID value changes, indicating that the requests are being randomly distributed between the two read-only nodes.

重新加载页面几次,您会注意到Server ID值更改,表明请求在两个只读节点之间随机分配。

结论 (Conclusion)

In this guide, we’ve prepared a Laravel 6 application for a highly available and scalable environment. We’ve outsourced the database system to an external managed MySQL service, and we’ve integrated an S3-compatible object storage service into the application to store files uploaded by users. Finally, we’ve seen how to scale up the application’s database by including additional read-only cluster nodes in the app’s configuration file.

在本指南中,我们为高可用性和可伸缩环境准备了Laravel 6应用程序。 我们已经将数据库系统外包给了外部托管MySQL服务,并且已经将兼容S3的对象存储服务集成到应用程序中,以存储用户上传的文件。 最后,我们已经了解了如何通过在应用程序的配置文件中包括其他只读群集节点来扩展应用程序的数据库。

The updated demo application code containing all modifications made in this guide can be found within the 2.1 tag in the application’s repository on Github.

可以在Github上的应用程序存储库的2.1标签中找到包含本指南中所有修改的更新的演示应用程序代码。

From here, you can set up a Load Balancer to distribute load and scale your application among multiple nodes. You can also leverage this setup to create a containerized environment to run your application on Docker.

从这里,您可以设置负载均衡器以在多个节点之间分配负载并扩展您的应用程序。 您还可以利用此设置来创建一个容器化环境,以在Docker上运行您的应用程序。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-scalable-laravel-6-application-using-managed-databases-and-object-storage

非托管对象 和托管对象


http://www.niftyadmin.cn/n/3649507.html

相关文章

微笑涛声博客正式关联第三方博客平台

第三方博客平台简介 第三方博客指的是不要求自己有域名&#xff0c;空间&#xff0c;服务器&#xff0c;仅在大型门户网址注册就可运行的博客平台。 这类博客有新浪&#xff0c;搜狐&#xff0c;和讯&#xff0c;网易等。第三方博客现在已经成为更多网络爱好者发布自己心情&…

[Domino]Java访问Domino邮件代码片断[1]

[Domino]Java访问Domino邮件代码片断编写者日期关键词郑昀ultrapower2005-6-20Java Domino得到用户收件箱中的邮件三个知识点&#xff1a;1&#xff1a;如果是打开mailfile数据库后直接Database dbMail sNotes.getDatabase(sNotes.getServerName(), mailfile, false);Document…

sidekiq redis_如何将Sidekiq和Redis添加到Ruby on Rails应用程序

sidekiq redis介绍 (Introduction) When developing a Ruby on Rails application, you may find you have application tasks that should be performed asynchronously. Processing data, sending batch emails, or interacting with external APIs are all examples of work…

使用Axure RP进行博客系统的原型设计

原型设计 我使用Axure RP软件对个人博客系统进行原型设计&#xff0c;其实就是仿照我的博客进行简单的设计&#xff0c;然后做一些改变。以下是博客首页的原型设计图。虽然很丑&#xff0c;但是是第一次接触原型设计。再接再厉。

Eclipse特色主题推荐——Marketplace

eclipse皮肤 由于最近Android开发使用Eclipse&#xff0c;所以推荐一款Eclipse的主题。前面习惯了Android studio的代码风格&#xff0c;虽然eclipse自带有几款不错的主题&#xff0c;不过优化的不是很好。在网上发现了一款主题&#xff0c;非常不错&#xff0c;安装也比较简单…

人工智能(pytorch)搭建模型17-pytorch搭建ReitnNet模型,加载数据进行模型训练与预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型17-pytorch搭建ReitnNet模型&#xff0c;加载数据进行模型训练与预测&#xff0c;RetinaNet 是一种用于目标检测任务的深度学习模型&#xff0c;旨在解决目标检测中存在的困难样本和不平衡…

mysql桌面应用程序_如何使用AdonisJs和MySQL构建鼓舞人心的报价应用程序

mysql桌面应用程序The author selected the Tech Education Fund to receive a donation as part of the Write for DOnations program. 作者选择了Tech Education Fund作为“ Write for DOnations”计划的一部分来接受捐赠。 介绍 (Introduction) AdonisJs is a Node.js web …

推荐一款截图神器——FSCapture

FSCapture FSCapture是一款抓屏工具&#xff0c;体积小巧、功能强大&#xff0c;不但具有常规截图等功能&#xff0c;更有从扫描器获取图像&#xff0c;和将图像转换为 PDF文档等功能。还有图片编辑&#xff0c;屏幕录像&#xff0c;编辑视频等强大的功能。以前博客的图片和视频…