Centos上安装Docker如下:

sudo su
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce 
systemctl start docker
systemctl enable docker

安装完毕以后, 查看Docker版本:

sh docker version

server_name  ~^(?<subdomain>.+)\.yourdomain\.com$;

set $root_path '/var/www/yanue.net';
root $root_path;
root html/$subdomain;
server{
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    root /data/$subdomain/public;
    # Make site accessible from http://localhost/
    server_name ~^(?<subdomain>.+).zdb.im$;
    location / {
        index  index.php index.html index.htm;
         #如果请求既不是一个文件,也不是一个目录,则执行一下重写规则
         if (!-e $request_filename)
         {
            #地址作为将参数rewrite到index.php上。
            rewrite ^/(.*)$ /index.php/$1;
            #若是子目录则使用下面这句,将subdir改成目录名称即可。
            #rewrite ^/subdir/(.*)$ /subdir/index.php/$1;
         }
    }
    #proxy the php scripts to php-fpm
    location ~ \.php {
            include fastcgi_params;
            ##pathinfo支持start
            #定义变量 $path_info ,用于存放pathinfo信息
            set $path_info "";
            #定义变量 $real_script_name,用于存放真实地址
            set $real_script_name $fastcgi_script_name;
            #如果地址与引号内的正则表达式匹配
            if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
                    #将文件地址赋值给变量 $real_script_name
                    set $real_script_name $1;
                    #将文件地址后的参数赋值给变量 $path_info
                    set $path_info $2;
            }
            #配置fastcgi的一些参数
            fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
            fastcgi_param SCRIPT_NAME $real_script_name;
            fastcgi_param PATH_INFO $path_info;
            ###pathinfo支持end
        fastcgi_intercept_errors on;
        fastcgi_pass   127.0.0.1:9000;
    }

    location ^~ /data/runtime {
        return 404;
    }

    location ^~ /application {
        return 404;
    }

}

两种认证方式,
第一种: 临时链接;
第二种: 固定密码链接;

第一种: 临时链接

  1. 服务端生成md5值和expires过期时间, 代码如下:
$expire = time() + 20;/*链接的有效期*/
$uri = '/audio/979.mp3'; /*访问的资源*/
$remoteAddr = '183.45.175.200';/*访问者的公网IP地址*/
$secret = 'zhuangdebiao'; /*密钥*/

/*拼接字符串, 生成哈希值*/
$hash = base64_encode(md5($expire.' '.$uri .' '.$remoteAddr . ' ' .$secret, true));
$hash = strtr($hash, '+/', '-_'); /*可选*/
$hash = str_replace('=', '', $hash); /*可选*/
/*最终URL*/
echo 'https://yey.zdb.im'.$uri.'?hash='.$hash.'&expires='.$expire;

URL示例 :
https://yey.zdb.im/audio/979.mp3?hash=qdmp79trLCCKKVzKAvia4A==&expires=1610085706

  1. 修改nginx配置
location /audio/ {
    secure_link $arg_hash,$arg_expires;
    secure_link_md5 "$secure_link_expires $uri $remote_addr zhuangdebiao";

    # hash error
    if ($secure_link = "") {
        return 403;
    }
    # expire
    if ($secure_link = "0") {
        return 410;
    }
    try_files $uri $uri/ = 404;
}
  1. 从$args即queryString中获取md5值和过期时间

secure_link $arg_hash,$arg_expires;

  1. 计算md5值的字符串模板

secure_link_md5 "$secure_link_expires $uri $remote_addr zhuangdebiao";

$secure_link_expires 即过期时间 $arg_expires;

$uri 即访问的资源路径;

$remote_addr 即用户的IP地址;

最后一段是密钥 secret;

用空格分隔, 也可以不用空格, 随意字符串都行;

  1. 如果md5值不相等, 即密钥等参数错误, 返回http 403错误;
  2. 如果链接过期, 返回410错误;
  3. 最终, 允许访问资源, 可以proxy_pass或者try_files检测文件是否存在 并返回给客户端浏览器;

第二种: 固定密码链接

uri 格式是 /prefix/hash/link

md5值的 格式是 hex(md5(link.secret))

原链接 https://yey.zdb.im/zdb/979.mp3

固定密码链接, 举例: https://yey.zdb.im/p/1656e96df11cbbcab7186e9f5dd171f3/979.mp3

location /p/ {
    secure_link_secret zhuangdebiao; # 密钥

    if ($secure_link = "") { 
        return 403;
    }

    rewrite ^ /zdb/$secure_link;
}
location /zdb/ { 
    alias /home/wwwroot/yey/Public/audio/;
    internal; # 仅允许内部访问,直接访问会返回404
}

计算md5值的算法:

$prefix = 'p'; /*入口前缀*/
$secret = 'zhuangdebiao'; /*固定的密钥*/
$link = '979.mp3'; /*访问的资源*/

$hash = md5($link .$secret, false); /*十六进制*/
echo 'https://yey.zdb.im'.'/'.$prefix.'/'.$hash.'/' .$link;

注意:配置过程中个人使用的指令所需要的权限比较高,主要是因为个人习惯了用root账户操作,如果使用自己创建的账户(输入指令时是‘$’ 而非‘#’,‘#’表示系统账户)可能会说权限不足,请自行切换到root用户或使用可执行的其他等效指令

1.在阿里云数据库1的my.cnf的mysqld节点添加以下配置:

port=3305

server-id=1

log-bin=mysql-bin

auto_increment_increment=2

auto_increment_offset=1

binlog-ignore=mysql

binlog-ignore=information_schema

binlog-ignore=performance_schema

character_set_server=utf8

log-bin-trust-function-creators=1

2.在阿里云数据库2的my.cnf的mysqld节点添加以下配置

port=3305

server-id=2

log-bin=mysql-bin

auto_increment_increment=2

auto_increment_offset=2

binlog-ignore=mysql

binlog-ignore=information_schema

binlog-ignore=performance_schema

character_set_server=utf8

log-bin-trust-function-creators=1
这里对上述添加的配置做详细说明:

port=3305 将mysql启动端口设置成3305(默认为3306)

log_bin 启动mysql二进制日志,如果没有配置这个将无法远程链接

binlog-ignore 指定不同步的数据库,如果有多个数据库不需要同步可以多个分别声明

character_set_server=utf8 指定utf8为默认字符集

server-id 可以为任意自然数,必须保证两台mysql主机不重复

auto_increment_increment=2 步进值auto_imcrement。一般有n台主MySQL就填n

auto_increment_offset 设定数据库中自动增长的起点,两台mysql的起点必须不同,这样才能避免两台服务器同步时出现主键冲突

replicate-do-db 要同步的数据库,如果需要就填,指定数据库的名称即可,默认为所有库,声明了不同步就默认除了不同步数据库意外的所有库。这里我没写。

log-bin-trust-function-creators=1 在默认情况下mysql会阻止主从同步的数据库function的创建,这会导致我们在导入sql文件时如果有创建function或者使用function的语句将会报错。

在主主同步所需要的主要为以上所介绍到的配置,当然还有其他的配置可以添加,具体的根据实际要求可百度查询。

3.重启mysql

执行指令:service mysqld restart

4.进入mysql:

mysql -uroot -p

5.相互授权:

192.168.18.129数据库1:

grant replication slave, replication client on . to 'iot123'@'192.168.18.130' identified by 'iot123'

flush privileges; //刷新MySQL的系统权限相关表,否则会无法用账号链接

192.168.18.130数据库2:

grant replication slave, replication client on . to 'iot123'@'192.168.18.129' identified by 'iot123';

flush privileges; //刷新MySQL的系统权限相关表,否则会无法用账号链接

注意:推荐两个主机相互授权的账号密码相同,否则在接下来的操作中可能会比较乱(我就是之前用了俩个不同的账号搞了好久也没搞定,后来改成相同的账号瞬间成功)

6.分别查看两台主机的日志节点:

show master status;

7.相互设置同步的日志节点

192.168.18.129:

mysql> change master to

->master_host='192.168.18.130', 
->master_port=3305, 
->master_user='iot123',
->master_password='iot123',
->master_log_file='mysql-bin.000010',
->master_log_pos=120;

192.168.18.130:

mysql> change master to

->master_host='192.168.18.129', 
->master_port=3305, 
->master_user='iot123',
->master_password='iot123',
->master_log_file='mysql-bin.000012',
->master_log_pos=120;

分段写如果写错了c退出,第二段开始最后是逗号,最有一段是分号,表结束,端口号和pos不用加引号,其他的配置需要加引号

说明:

所有的内容都是另一台主机的内容,log_file和log_pos对于另一台主机的日志节点。还有,必须要说明的是,每次“flush privileges”和“stop slave”后日志节点的内容会改变,所以如果不确定,每次执行此操作前必须要查看日志节点——show master status。另外,执行此操作时slave必须没有启动,如果之前执行了,那就先停止,指令:stop slave;

9.在两台主机上启动slave服务

start slave;

查看状态:

show slave statusG

结果如下:

上图表示成功

10.异常及解决方法

如果状态如下图所示:

往下看有错误提示,错误原因大致如下:

网络不通

账号密码错误

pos错误

3305端口未开放

解决方法如下:

1.网络不通——你相互ping一下各自的ip地址,ping的通就说明不是这个问题,我是开的两台虚拟机,在同一局域网内,所以肯定通,如果你用的是阿里云啊之类的外网服务器,ping不通就检查网络接口之类的。

2.账号密码错误——把两台主机的账号密码设置成相同的好处就是不会出现这种情况,我之前账号密码搞混弄了好久

3.pos错误——看看当前日志节点内容与你之前打的一样不,反正重新来一遍准没错

4.3305端口未开放:

找到iptables文件(etc/sysconfig/iptables)

再里面添加如下内容:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3305 -j ACCEPT

个人开放端口如下

重启防火墙:

service iptables restart

尝试一下能不能navecat远程链接数据库,不行的话就直接把防火墙关了。

在数据库相互授权的过程中可能会报错

原因,设置的密码太简单,不符合MySQL5.7的默认要求

如果想要密码设置简单点,方法如下:

mysql > set global validate_password_policy=0;
mysql > set global validate_password_length=4;

上述是把密码程度设置成最低级,密码长度设置成4(最小是4,不能再少了)

在MySQL数据库中,在进行数据迁移和从库只读状态设置时,都会涉及到只读状态和Master-slave的设置和关系。

经过实际测试,对于MySQL单实例数据库和master库,如果需要设置为只读状态,需要进行如下操作和设置:
将MySQL设置为只读状态的命令:
mysql -uroot -p
mysql> show global variables like "%read_only%";
mysql> flush tables with read lock;
mysql> set global read_only=1;
mysql> show global variables like "%read_only%";

将MySQL从只读设置为读写状态的命令:
mysql> unlock tables;
mysql> set global read_only=0;

对于需要保证master-slave主从同步的salve库,如果要设置为只读状态,需要执行的命令为:
mysql> set global read_only=1;

将salve库从只读状态变为读写状态,需要执行的命令是:
mysql> set global read_only=0;

 对于数据库读写状态,主要靠 “read_only”全局参数来设定;默认情况下,数据库是用于读写操作的,所以read_only参数也是0或faluse状态,这时候不论是本地用户还是远程访问数据库的用户,都可以进行读写操作;如需设置为只读状态,将该read_only参数设置为1或TRUE状态,但设置 read_only=1 状态有两个需要注意的地方:
  1.read_only=1只读模式,不会影响slave同步复制的功能,所以在MySQL slave库中设定了read_only=1后,通过 show slave status\G 命令查看salve状态,可以看到salve仍然会读取master上的日志,并且在slave库中应用日志,保证主从数据库同步一致;
  2.read_only=1只读模式,可以限定普通用户进行数据修改的操作,但不会限定具有super权限的用户的数据修改操作;在MySQL中设置read_only=1后,普通的应用用户进行insert、update、delete等会产生数据变化的DML操作时,都会报出数据库处于只读模式不能发生数据变化的错误,但具有super权限的用户,例如在本地或远程通过root用户登录到数据库,还是可以进行数据变化的DML操作;

-------锁表---

  为了确保所有用户,包括具有super权限的用户也不能进行读写操作,就需要执行给所有的表加读锁的命令 “flush tables with read lock;”,这样使用具有super权限的用户登录数据库,想要发生数据变化的操作时,也会提示表被锁定不能修改的报错。

    这样通过 设置“read_only=1”和“flush tables with read lock;”两条命令,就可以确保数据库处于只读模式,不会发生任何数据改变,在MySQL进行数据库迁移时,限定master主库不能有任何数据变化,就可以通过这种方式来设定。

   但同时由于加表锁的命令对数据库表限定非常严格,如果再slave从库上执行这个命令后,slave库可以从master读取binlog日志,但不能够应用日志,slave库不能发生数据改变,当然也不能够实现主从同步了,这时如果使用 “unlock tables;”解除全局的表读锁,slave就会应用从master读取到的binlog日志,继续保证主从库数据库一致同步。

   为了保证主从同步可以一直进行,在slave库上要保证具有super权限的root等用户只能在本地登录,不会发生数据变化,其他远程连接的应用用户只按需分配为select,insert,update,delete等权限,保证没有super权限,则只需要将salve设定“read_only=1”模式,即可保证主从同步,又可以实现从库只读。
   相对的,设定“read_only=1”只读模式开启的解锁命令为设定“read_only=0”;设定全局锁“flush tables with read lock;”,对应的解锁模式命令为:“unlock tables;”.

  当然设定了read_only=1后,所有的select查询操作都是可以正常进行的。