配置范例
- 'mysql' => [
- 'driver' => 'mysql',
- 'write' => [
- 'host' => '192.168.1.180',
- ],
- 'read' => [
- ['host' => '192.168.1.182'],
- ['host' => '192.168.1.179'],
- ],
- ...
- ]
或
- 'mysql' => [
- 'driver' => 'mysql',
- 'write' => [
- 'host' => '192.168.1.180',
- ],
- 'read' => [
- 'host' => [
- '192.168.1.182',
- '192.168.1.179'
- ],
- ],
- ...
- ]
扩展配置范例
- 'mysql' => [
- 'driver' => 'mysql',
- 'write' => [
- 'host' => '192.168.1.180',
- 'username' => 'write',
- 'password' => 'write',
- ],
- 'read' => [
- [
- 'host' => '192.168.1.182',
- 'username' => 'read1',
- 'password' => 'read1',
- ],
- [
- 'host' => '192.168.1.179',
- 'username' => 'read2',
- 'password' => 'read2',
- ],
- ],
- ...
- ]
或者
- 'mysql' => [
- 'driver' => 'mysql',
- 'write' => [
- 'host' => '192.168.1.180',
- 'username' => 'write',
- 'password' => 'write',
- ],
- 'read' => [
- 'host' => [
- '192.168.1.179',
- '192.168.1.182',
- ],
- 'username' => 'read',
- 'password' => 'read',
- ],
- ...
- ]
公司数据库架构为一主多从,从库访问地址为唯一地址,该处方便负载均衡及扩展从库。所以最终线上采用的配置
- 'mysql' => [
- 'driver' => 'mysql',
- 'write' => [
- 'host' => '192.168.1.180',
- 'username' => 'write',
- 'password' => 'write',
- ],
- 'read' => [
- 'host' => '192.168.1.179'
- 'username' => 'read',
- 'password' => 'read',
- ],
- ...
- ]
代码分析
授人以鱼不如授人以渔,之所以配置如此灵活的原因,以及如何查找到这些配置方式。主要通过查找代码,分析代码;相关代码都在下面粘出,这里就不做解释了,代码能说明一切;
路径:vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php
代码:
- class ConnectionFactory
- {
- ...
-
- /**
- * Get the read configuration for a read / write connection.
- *
- * @param array $config
- * @return array
- */
- protected function getReadConfig(array $config)
- {
- $readConfig = $this->getReadWriteConfig($config, 'read');
-
- if (isset($readConfig['host']) && is_array($readConfig['host'])) {
- $readConfig['host'] = count($readConfig['host']) > 1
- ? $readConfig['host'][array_rand($readConfig['host'])]
- : $readConfig['host'][0];
- }
-
- return $this->mergeReadWriteConfig($config, $readConfig);
- }
-
- ...
-
- /**
- * Get a read / write level configuration.
- *
- * @param array $config
- * @param string $type
- * @return array
- */
- protected function getReadWriteConfig(array $config, $type)
- {
- if (isset($config[$type][0])) {
- return $config[$type][array_rand($config[$type])];
- }
-
- return $config[$type];
- }
-
- ...
-
- /**
- * Merge a configuration for a read / write connection.
- *
- * @param array $config
- * @param array $merge
- * @return array
- */
- protected function mergeReadWriteConfig(array $config, array $merge)
- {
- return Arr::except(array_merge($config, $merge), ['read', 'write']);
- }
-
- ...
- }
-
-
- class Arr
- {
- ...
-
- /**
- * Get all of the given array except for a specified array of items.
- *
- * @param array $array
- * @param array|string $keys
- * @return array
- */
- public static function except($array, $keys)
- {
- static::forget($array, $keys);
-
- return $array;
- }
-
- ...
-
- /**
- * Remove one or many array items from a given array using "dot" notation.
- *
- * @param array $array
- * @param array|string $keys
- * @return void
- */
- public static function forget(&$array, $keys)
- {
- $original = &$array;
-
- $keys = (array) $keys;
-
- if (count($keys) === 0) {
- return;
- }
-
- foreach ($keys as $key) {
- $parts = explode('.', $key);
-
- while (count($parts) > 1) {
- $part = array_shift($parts);
-
- if (isset($array[$part]) && is_array($array[$part])) {
- $array = &$array[$part];
- } else {
- $parts = [];
- }
- }
-
- unset($array[array_shift($parts)]);
-
- // clean up after each pass
- $array = &$original;
- }
- }
-
- ...
- }
以上这篇Laravel数据库读写分离配置的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持w3xue。