Symfony – make sessions persistent over a LoadBalancing with your DB
By default, PHP (on which Symfony relies on) stores all sessions information on the filesystem.
However, when you scale-up your website, it is more likely that you’ll have multiple webservers behind a LoadBalancer. Having the sessions saved on the FileSystem will then lead to various issues (like being disconnected over requests).
To fix this, we have multiple ways.
Use the Database
One of the way to address this issue is to store all sessions informations into the Database. This ensure the datas are stored in a shared place that all WebServers can access at all time. However, this will add some strain on the DB.
To do so, you’ll need to edit the config/services.yaml
file. In this, you shall add this portion of code:
# config/services.yaml
services:
# ...
Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
arguments:
- '%env(DATABASE_URL)%'
# you can also use PDO configuration, but requires passing two arguments
# - 'mysql:dbname=mydatabase; host=myhost; port=myport'
# - { db_username: myuser, db_password: mypassword }
Then, edit the config/packages/framework.yaml
file to set the SessionHandler to use PDO:
# config/packages/framework.yaml
framework:
session:
# ...
handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
You can alter the columns that are used, if you need more customization over it, in the config/services.yaml
:
# config/services.yaml
services:
# ...
Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
arguments:
- '%env(DATABASE_URL)%'
- { db_table: 'customer_session', db_id_col: 'guid' }
Here is the list of the value you can change:
db_table
(defaultsessions
): The name of the session table in your database;db_username
: (default:''
) The username used to connect when using the PDO configuration (when using the connection based on theDATABASE_URL
env var, it overrides the username defined in the env var).db_password
: (default:''
) The password used to connect when using the PDO configuration (when using the connection based on theDATABASE_URL
env var, it overrides the password defined in the env var).db_id_col
(defaultsess_id
): The name of the column where to store the session ID (column type:VARCHAR(128)
);db_data_col
(defaultsess_data
): The name of the column where to store the session data (column type:BLOB
);db_time_col
(defaultsess_time
): The name of the column where to store the session creation timestamp (column type:INTEGER
);db_lifetime_col
(defaultsess_lifetime
): The name of the column where to store the session lifetime (column type:INTEGER
);db_connection_options
(default:[]
) An array of driver-specific connection options;lock_mode
(default:LOCK_TRANSACTIONAL
) The strategy for locking the database to avoid race conditions. Possible values areLOCK_NONE
(no locking),LOCK_ADVISORY
(application-level locking) andLOCK_TRANSACTIONAL
(row-level locking).
Then, you’ll just have to run the migrations to create the Session DB 🙂