背景:最近在学习docker,没有看到比较好的实践案例,所以决定自己搭建个项目实践一下。
实践内容:
1.构建nginx镜像,nginx+php一体镜像,拉取mysql镜像(由于mysql安装比较慢,所以这个镜像直接拉取官方的)
2.构建私有镜像仓库保存自己构建的镜像。
3.用nginx容器做负载均衡连接3个nginx+php,
4.启动两台mysql,一台主一台从,实现主从复制
5.用一台nginx做负载均衡对读mysql做负载(虽然这里只有一台,为什么只有一台,因为虚拟机只有1G内存,不够用啊)
6.用php代码实现读写分离
架构图:
这个架构很不严谨,没有高可用(之后再补充)等,但是实践一下还是很不错的。
构建nginx镜像,nginx+php一体镜像,拉取mysql镜像
1.首先拉取基础镜像alpine,我们在这个镜像的基础上构建镜像
pull alpine
nginx.conf文件内容:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 10240;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
nginx.vh.defalut.conf的内容
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
最终要的Dockerfile文件的内容:
FROM alpine:latest
MAINTAINER NGINX Docker Maintainers "[email protected]"
#修改源
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories && \
echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories
# 安装需要的软件
RUN apk update && \
apk add --no-cache ca-certificates && \
apk add --no-cache curl bash tree tzdata && \
cp -rf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 设置变量
ENV NGINX_VERSION 1.14.0
RUN GPG_KEYS=B0F4253373F8F6F510D42178520A9993A1C052F8 \
&& CONFIG=" \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-compat \
--with-file-aio \
--with-http_v2_module \
" \
&& addgroup -S nginx \
&& adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx \
&& apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre-dev \
zlib-dev \
linux-headers \
curl \
gnupg \
libxslt-dev \
gd-dev \
geoip-dev \
&& curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \
&& curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz.asc -o nginx.tar.gz.asc \
&& export GNUPGHOME="$(mktemp -d)" \
&& found=''; \
for server in \
ha.pool.sks-keyservers.net \
hkp://keyserver.ubuntu.com:80 \
hkp://p80.pool.sks-keyservers.net:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $GPG_KEYS from $server"; \
gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \
gpg --batch --verify nginx.tar.gz.asc nginx.tar.gz \
&& rm -r "$GNUPGHOME" nginx.tar.gz.asc \
&& mkdir -p /usr/src \
&& tar -zxC /usr/src -f nginx.tar.gz \
&& rm nginx.tar.gz \
&& cd /usr/src/nginx-$NGINX_VERSION \
&& ./configure $CONFIG --with-debug \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& mv objs/nginx objs/nginx-debug \
&& mv objs/ngx_http_xslt_filter_module.so objs/ngx_http_xslt_filter_module-debug.so \
&& mv objs/ngx_http_image_filter_module.so objs/ngx_http_image_filter_module-debug.so \
&& mv objs/ngx_http_geoip_module.so objs/ngx_http_geoip_module-debug.so \
&& mv objs/ngx_stream_geoip_module.so objs/ngx_stream_geoip_module-debug.so \
&& ./configure $CONFIG \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& make install \
&& rm -rf /etc/nginx/html/ \
&& mkdir /etc/nginx/conf.d/ \
&& mkdir -p /usr/share/nginx/html/ \
&& install -m644 html/index.html /usr/share/nginx/html/ \
&& install -m644 html/50x.html /usr/share/nginx/html/ \
&& install -m755 objs/nginx-debug /usr/sbin/nginx-debug \
&& install -m755 objs/ngx_http_xslt_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_xslt_filter_module-debug.so \
&& install -m755 objs/ngx_http_image_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_image_filter_module-debug.so \
&& install -m755 objs/ngx_http_geoip_module-debug.so /usr/lib/nginx/modules/ngx_http_geoip_module-debug.so \
&& install -m755 objs/ngx_stream_geoip_module-debug.so /usr/lib/nginx/modules/ngx_stream_geoip_module-debug.so \
&& ln -s ../../usr/lib/nginx/modules /etc/nginx/modules \
&& strip /usr/sbin/nginx* \
&& strip /usr/lib/nginx/modules/*.so \
&& rm -rf /usr/src/nginx-$NGINX_VERSION \
\
# Bring in gettext so we can get `envsubst`, then throw
# the rest away. To do this, we need to install `gettext`
# then move `envsubst` out of the way so `gettext` can
# be deleted completely, then move `envsubst` back.
&& apk add --no-cache --virtual .gettext gettext \
&& mv /usr/bin/envsubst /tmp/ \
\
&& runDeps="$( \
scanelf --needed --nobanner /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --no-cache --virtual .nginx-rundeps $runDeps \
&& apk del .build-deps \
&& apk del .gettext \
&& mv /tmp/envsubst /usr/local/bin/ \
\
# forward request and error logs to docker log collector
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# 将目录下的文件copy到镜像中
COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf
# 开放80端口
EXPOSE 80
STOPSIGNAL SIGTERM
# 启动nginx命令
CMD ["nginx", "-g", "daemon off;"]
运行docker build -t mynginx:latest . 命令构建nginx镜像
构建php+nginx镜像
创建目录MyNginxAndPHP,格式如下:
nginx.conf 与nginx.vh.default.conf与上面一致
php-fpm.conf内容:
[global]
pid = run/php-fpm.pid
error_log = log/php-fpm.log
[www]
user = www
group = www
listen = 127.0.0.1:9000
pm = static
pm.max_children = 32
;pm.start_servers = 2
;pm.min_spare_servers = 1
;pm.max_spare_servers = 3
pm.max_requests = 8192
pm.status_path = /php-fpm_status
ping.path = /ping
request_terminate_timeout = 10
run.sh的内容:
#!/bin/bash
/usr/local/php/sbin/php-fpm &
/usr/sbin/sshd -D &
nginx
Dockerfile的内容:
FROM alpine:latest
MAINTAINER NGINX Docker Maintainers "[email protected]"
#修改源
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories && \
echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories
# 安装需要的软件
RUN apk update && \
apk add --no-cache ca-certificates && \
apk add --no-cache curl bash tree tzdata && \
apk add build-base shadow openssh bash libxml2-dev openssl-dev libjpeg-turbo-dev libpng-dev libxpm-dev freetype-dev gd-dev gettext-dev libmcrypt-dev binutils && \
cp -rf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 设置变量
ENV NGINX_VERSION 1.14.0
#安装NGINX
RUN GPG_KEYS=B0F4253373F8F6F510D42178520A9993A1C052F8 \
&& CONFIG=" \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-compat \
--with-file-aio \
--with-http_v2_module \
" \
&& addgroup -S nginx \
&& adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx \
&& apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
make \
openssl-dev \
pcre-dev \
zlib-dev \
linux-headers \
curl \
gnupg \
libxslt-dev \
gd-dev \
geoip-dev \
&& curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \
&& curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz.asc -o nginx.tar.gz.asc \
&& export GNUPGHOME="$(mktemp -d)" \
&& found=''; \
for server in \
ha.pool.sks-keyservers.net \
hkp://keyserver.ubuntu.com:80 \
hkp://p80.pool.sks-keyservers.net:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $GPG_KEYS from $server"; \
gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \
gpg --batch --verify nginx.tar.gz.asc nginx.tar.gz \
&& rm -r "$GNUPGHOME" nginx.tar.gz.asc \
&& mkdir -p /usr/src \
&& tar -zxC /usr/src -f nginx.tar.gz \
&& rm nginx.tar.gz \
&& cd /usr/src/nginx-$NGINX_VERSION \
&& ./configure $CONFIG --with-debug \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& mv objs/nginx objs/nginx-debug \
&& mv objs/ngx_http_xslt_filter_module.so objs/ngx_http_xslt_filter_module-debug.so \
&& mv objs/ngx_http_image_filter_module.so objs/ngx_http_image_filter_module-debug.so \
&& mv objs/ngx_http_geoip_module.so objs/ngx_http_geoip_module-debug.so \
&& mv objs/ngx_stream_geoip_module.so objs/ngx_stream_geoip_module-debug.so \
&& ./configure $CONFIG \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& make install \
&& rm -rf /etc/nginx/html/ \
&& mkdir /etc/nginx/conf.d/ \
&& mkdir -p /usr/share/nginx/html/ \
&& install -m644 html/index.html /usr/share/nginx/html/ \
&& install -m644 html/50x.html /usr/share/nginx/html/ \
&& install -m755 objs/nginx-debug /usr/sbin/nginx-debug \
&& install -m755 objs/ngx_http_xslt_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_xslt_filter_module-debug.so \
&& install -m755 objs/ngx_http_image_filter_module-debug.so /usr/lib/nginx/modules/ngx_http_image_filter_module-debug.so \
&& install -m755 objs/ngx_http_geoip_module-debug.so /usr/lib/nginx/modules/ngx_http_geoip_module-debug.so \
&& install -m755 objs/ngx_stream_geoip_module-debug.so /usr/lib/nginx/modules/ngx_stream_geoip_module-debug.so \
&& ln -s ../../usr/lib/nginx/modules /etc/nginx/modules \
&& strip /usr/sbin/nginx* \
&& strip /usr/lib/nginx/modules/*.so \
&& rm -rf /usr/src/nginx-$NGINX_VERSION \
&& apk add --no-cache --virtual .gettext gettext \
&& mv /usr/bin/envsubst /tmp/ \
\
&& runDeps="$( \
scanelf --needed --nobanner /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --no-cache --virtual .nginx-rundeps $runDeps \
&& apk del .build-deps \
&& apk del .gettext \
&& mv /tmp/envsubst /usr/local/bin/ \
\
# forward request and error logs to docker log collector
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
#安装php
RUN cd / && \
wget http://101.96.10.63/cn2.php.net/distributions/php-7.0.27.tar.gz && \
wget https://curl.haxx.se/download/curl-7.20.0.tar.gz && \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \
addgroup www && \
adduser -G www -D -s /sbin/nologin www && \
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" && \
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && \
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && \
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && \
usermod -s /bin/bash root && \
sed -i 's@#PermitRootLogin prohibit-password@PermitRootLogin yes@' /etc/ssh/sshd_config && \
echo -e "huanqiu.com\nhuanqiu.com" | passwd root && \
cd / && tar -zxf curl-7.20.0.tar.gz && cd curl-7.20.0 && ./configure --prefix=/usr/local/curl --disable-ipv6 && \
make && make install && \
cd / && tar -zxf php-7.0.27.tar.gz && cd php-7.0.27 && ./configure \
--prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-config-file-scan-dir=/usr/local/php/etc/php.d \
--disable-ipv6 \
--enable-bcmath \
--enable-calendar \
--enable-exif \
--enable-fpm \
--with-fpm-user=www \
--with-fpm-group=www \
--enable-ftp \
--enable-gd-jis-conv \
--enable-gd-native-ttf \
--enable-inline-optimization \
--enable-mbregex \
--enable-mbstring \
--enable-mysqlnd \
--enable-opcache \
--enable-pcntl \
--enable-shmop \
--enable-soap \
--enable-sockets \
--enable-static \
--enable-sysvsem \
--enable-wddx \
--enable-xml \
--with-curl=/usr/local/curl \
--with-gd=/usr \
--with-jpeg-dir \
--with-freetype-dir \
--with-xpm-dir \
--with-png-dir \
--with-gettext \
--with-iconv \
--with-libxml-dir=/usr \
--with-mcrypt \
--with-mhash \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-openssl \
--with-xmlrpc \
--with-zlib \
--without-pear \
--disable-debug \
--disable-phpdbg && \
make && make install && \
echo "PATH=\$PATH:/usr/local/php/bin" >> /root/.bashrc && \
echo "PATH=\$PATH:/usr/local/php/sbin" >> /root/.bashrc && \
echo "export rm='rm -i'" >> /root/.bashrc && \
echo "export cp='cp -i'" >> /root/.bashrc && \
strip /usr/local/php/bin/php && \
strip /usr/local/php/bin/php-cgi && \
strip /usr/local/php/sbin/php-fpm && \
apk del build-base shadow binutils && \
rm -rf /curl-7.20.0.tar.gz /curl-7.20.0 /php-7.0.27.tar.gz /php-7.0.27 /var/cache/apk/*
# 将目录下的文件copy到镜像中
COPY run.sh /
COPY php-fpm.conf /usr/local/php/etc/
COPY test.php /usr/share/nginx/html/test.php
COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx.vh.default.conf /etc/nginx/conf.d/default.conf
# 开放80端口
EXPOSE 80
STOPSIGNAL SIGTERM
# 启动nginx命令
CMD ["./run.sh"]
test.php是测试用的,内容随意。
运行命令 docker build -t phpandnginx:latest . 构建镜像
构建私有镜像仓库保存自己构建的镜像
pull registry 拉取官方registry镜像
docker run -d -p 5000:5000 --name registry -v /myregistry:/var/lib/registry registry
该命令运行私有仓库,
将nginx和php+nginx镜像打标签,例如docker tag mynginx:latest 127.0.0.1:5000/mynginx:latest
然后push,就可以将镜像推送到自己的私有仓库了
接下来就是配置架构了,先看docker-compose.yml内容:
version: "3"
services:
nginx1:
image: 127.0.0.1:5000/mynginx:latest
container_name: loadbalance01
ports:
- "80:80"
volumes:
- "/docker/dockerStudy/dockerCompose/nginx/nginx.conf:/etc/nginx/nginx.conf"
networks:
web:
aliases:
- loadbalance1
web1:
image: 127.0.0.1:5000/phpandnginx:latest
container_name: web1
volumes:
- "/myshare/ybc/:/usr/share/nginx/html/"
networks:
web:
aliases:
- web1
web2:
image: 127.0.0.1:5000/phpandnginx:latest
container_name: web2
volumes:
- "/myshare/ybc/:/usr/share/nginx/html/"
networks:
web:
aliases:
- web2
web3:
image: 127.0.0.1:5000/phpandnginx:latest
container_name: web3
volumes:
- "/myshare/ybc/:/usr/share/nginx/html/"
networks:
web:
aliases:
- web3
networks:
web:
用nginx容器做负载均衡连接3个nginx+php
这里都用文件挂在了配置文件,
首先看负载均衡的nginx的配置文件内容:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 10240;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
upstream load_balance_server
{
#server tomcat地址:端口号 weight表示权值,权值越大,被分配的几率越大;
server web1:80 weight=4 max_fails=2 fail_timeout=30s;
server web2:80 weight=4 max_fails=2 fail_timeout=30s;
server web3:80 weight=4 max_fails=2 fail_timeout=30s;
}
#HTTP服务器
server {
listen 80;
server_name www.helloworld.com;
location / {
root /root; #定义服务器的默认网站根目录位置
index index.html index.htm; #定义首页索引文件的名称
proxy_pass http://load_balance_server ;#请求转向load_balance_server 定义的服务器列表
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
}
}
}
运行docker-compose up命令就可以测试一下负载均衡了。
启动两台mysql,一台主一台从,实现主从复制
mysql镜像直接拉取官方的便可,这里是mysql:5.6
在docker-compose.yml中加入一下代码
mysql_master:
image: mysql:5.6
container_name: mysql_master
environment:
MYSQL_ROOT_PASSWORD: 123
volumes:
- “/docker/dockerStudy/dockerCompose/mysql/my_master.cnf:/etc/mysql/my.cnf”
networks:
web:
aliases:
- mysql_master
mysql_slave1:
image: mysql:5.6
container_name: mysql_slave1
environment:
MYSQL_ROOT_PASSWORD: 123
volumes:
- “/docker/dockerStudy/dockerCompose/mysql/my_slave.cnf:/etc/mysql/my.cnf”
networks:
web:
aliases:
- mysql_slave1
my_master.cnf文件的配置内容:
[mysql]
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
skip-host-cache
skip-name-resolve
#log-error = /var/log/mysql/error.log
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
server_id = 1
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-storage-engine=INNODB
#Optimize omit
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
log-bin = /var/lib/mysql/binlog
log_bin_trust_function_creators=1
binlog_format = ROW
expire_logs_days = 99
sync_binlog = 0
slow-query-log=1
slow-query-log-file=/var/log/mysql/slow-queries.log
long_query_time = 3
log-queries-not-using-indexes
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
my_slave.cnf配置文件内容:
[mysql]
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
skip-host-cache
skip-name-resolve
#log-error = /var/log/mysql/error.log
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
server_id = 2
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-storage-engine=INNODB
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
log-bin = /var/lib/mysql/binlog
log_bin_trust_function_creators=1
binlog_format = ROW
expire_logs_days = 99
sync_binlog = 0
relay_log=slave-relay-bin
log-slave-updates=1
slave-skip-errors=all
slow-query-log=1
slow-query-log-file=/var/log/mysql/slow-queries.log
long_query_time = 3
[mysqldump]
quick
quote-names
max_allowed_packet = 16M
启动容器后进入容器内部配置主从复制命令:docker exec -it 容器名 命令
进入mysql_master:
docker exec -it mysql-master mysql -p
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
查看Master结点的binlog状态:
show master status\G
*************************** 1. row ***************************
File: binlog.000004
Position: 505
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
进入mysql_slave1结点:
docker exec -it mysql-slave mysql -p
CHANGE MASTER TO \
MASTER_HOST='mysql_master',\
MASTER_PORT=3306,\
MASTER_USER='repl',\
MASTER_PASSWORD='repl',\
MASTER_LOG_FILE='binlog.000004;,\
MASTER_LOG_POS=505;
show slave status\G
然后就可以测试是否成功了。
注意:只有主数据库的写入才能同步。
用一台nginx做负载均衡对读mysql做负载
在docker-compose.yml加入一下代码
nginx2:
image: 127.0.0.1:5000/mynginx:latest
container_name: loadbalance02
volumes:
- “/docker/dockerStudy/dockerCompose/nginx/nginx2.conf:/etc/nginx/nginx.conf”
networks:
web:
aliases:
- loadbalance2
nginx2.conf配置文件的内容:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 10240;
}
stream {
upstream mysql {
hash $remote_addr consistent;
server mysql_slave1:3306 weight=5 max_fails=3 fail_timeout=30s;
}
server {
listen 3306;
#建立连接超时时间
proxy_connect_timeout 5s;
#proxy_timoute指定Nginx与客户端,以及Nginx与被代理的主机之间在两个相邻的读或写数据的操作之间的最大时间间隔。超过此时间间隔而没有数据读或写操作发生,则断开连接。
proxy_timeout 5m;
proxy_pass mysql;
}
}
用php代码实现读写分离
配置文件:
[
'read' => [
'dns' => 'mysql:host=loadbalance2;port=3306;dbname=test',
'dbname' => 'test',
'username' => 'root',
'password' =>'123',
'charset' => 'utf8'
],
'write' => [
'dns' => 'mysql:host=mysql_master;port=3306;dbname=test',
'dbname' => 'test',
'username' => 'root',
'password' =>'123',
'charset' => 'utf8'
]
],
];
PDOModel.php的内容
db_read = $conn;
$conn = new \PDO($config['write']['dns'],$config['write']['username'],
$config['write']['password']);
$this->db_write = $conn;
}
private function __clone(){}
public function getAll($sql,$params = []){
$stmt = $this->db_read->prepare($sql);
foreach($params as $key => $value){
$stmt->bindValue($key,$value,\PDO::PARAM_INT);
}
$stmt->execute();
return $stmt->FetchAll(\PDO::FETCH_ASSOC);
}
public function execute($sql,$params = []){
$querystr = trim($sql);
$querystr = substr($sql,0,6);
if ($querystr == 'select') {
$stmt = $this->db_read->prepare($sql);
foreach($params as $key => $value){
$stmt->bindValue($key,$value);
}
} else {
$stmt = $this->db_write->prepare($sql);
foreach($params as $key => $value){
$stmt->bindValue($key,$value);
}
}
return $stmt->execute();
}
}
到这里就配置结束了。