docker学习实践---docker-compose搭建php负载均衡集群

背景:最近在学习docker,没有看到比较好的实践案例,所以决定自己搭建个项目实践一下。
实践内容:
1.构建nginx镜像,nginx+php一体镜像,拉取mysql镜像(由于mysql安装比较慢,所以这个镜像直接拉取官方的)
2.构建私有镜像仓库保存自己构建的镜像。
3.用nginx容器做负载均衡连接3个nginx+php,
4.启动两台mysql,一台主一台从,实现主从复制
5.用一台nginx做负载均衡对读mysql做负载(虽然这里只有一台,为什么只有一台,因为虚拟机只有1G内存,不够用啊)
6.用php代码实现读写分离

架构图:
docker学习实践---docker-compose搭建php负载均衡集群_第1张图片
这个架构很不严谨,没有高可用(之后再补充)等,但是实践一下还是很不错的。

构建nginx镜像,nginx+php一体镜像,拉取mysql镜像
1.首先拉取基础镜像alpine,我们在这个镜像的基础上构建镜像
pull alpine

2.创建MyNginx目录,格式如下图:
docker学习实践---docker-compose搭建php负载均衡集群_第2张图片

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,格式如下:
docker学习实践---docker-compose搭建php负载均衡集群_第3张图片
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();
    
        } 
    }

到这里就配置结束了。

你可能感兴趣的:(docker开发之旅)