一、前言

    此前大家集团安插服务,就是豪门都懂的那一套(安装JDK、汤姆cat —>
编译好文件或者打war包上传 —>
启动汤姆cat),那种布局形式直接持续了很久,带来的标题也不在少数:

1、繁重的宣布职责。微服务一多,就要每个服务都要重启两遍,而且只要集群的话,那要开动的劳动就更多了。

2、环境迁移报错。常常发生的一件事,同样的一套代码,那台服务器上就是能跑起来,换个服务器就是报错了。

3、士气低落。小集团从未正当的运维,都是让开发兼并着做那上头的劳作,然后负责那块的同事怨言很多(因为那种揭橥计划实在太无趣了)。

    所以领导决定挑起 Docker
作为我们的布署格局,一来可以很好的解决近年来项目布局存在的题材,二来为品种注入新鲜血液。

    从上个月15号早先接触
Docker,到现在把大家系统的微服务架构开始搭建好,折腾了绵绵,踩了无数坑。回忆一下小成就,写了那篇博客。为了幸免提到走漏公司机密,就小而全的做一些简约介绍哈,以上面那张小小微服务架构图为例,布署一套
Dubbo 微服务。

澳门金沙国际 1

热部署

pom.xml文件中添加spring-boot-devtools看重即可兑现页面和代码的热布置。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

一、应用场景

在做项目标历程中,服务器端的安顿是一个可怜首要的景观,当客户的服务器是Linux/Unix系统时,用Docker容器来配置最有利于不过了,Windows场景下Docker的支撑也比较完善了,使用Docker计划可以给我们带来有利、急速的感受。


在上一篇小说《Docker下dubbo开发,三部曲之一:极速体验》中,我们飞快体验了dubbo服务的注册、发现、调用,后天大家一块在地面制作一套那样的环境,经过这一次实战,我们就足以按照实际供给对团结的环境量身定制了。

二、服务镜像打包

正常配置

二、应用项目综合

本文中项目标费用条件是基于spring+springMVC+mybatis的maven项目。开发的IDE是速龙liJ
IDEA 2017.1.4,服务器是行使汤姆cat 9.0.0.M21,数据库使用MySQL
5.7。最终安插测试环境是MacOS Sierra 10.12.3


基础架构

整整环境由五个容器组成,梳理后相互的涉及如下图:

澳门金沙国际 2

接下去大家根据下边的报表来设计和创建对应的镜像:

容器 作用 镜像 功能 link连接
zk_server 注册中心 zookeeper:3.3.6 官方镜像
dubbo_admin 管理平台 bolingcavalry/dubbo_admin_tomcat 定制镜像,用tomcat官方镜像加dubbo_admin.war生成 用别名zkhost连接zk_server
dubbo_provider 服务提供者 bolingcavalry/dubbo_provider_tomcat 定制镜像,用tomcat官方镜像加dubboserviceprovider.war文件生成 用别名zkhost连接zk_server
dubbo_consumer 服务消费者 bolingcavalry/online_deploy_tomcat 定制镜像,是个支持在线部署的tomcat

     1、Tomcat 基础环境搭建

    我们系统的每个微服务都安插运行在 汤姆cat
上(听说那种措施很糟糕,对于部分不是web工程的,没必要搭建成 web
服务,增加复杂性,也浪费系统资源),所以我的想法是:先搭建一套 汤姆cat
环境镜像,然后每个微服务都基于那一个环境镜像去打造。所以写了一个
tomcat-env 的镜像,思路如下:

    — 基于 JDK 的 汤姆cat
容器(首要参考官网 汤姆cat 镜像的 Dockerfile)。

    — 在上下文目录存放项目编译文件,一碗水端平命名为
ROOT(不放 war
包的因由是考虑调试的时候便于,不用改一个文本,就打个war包)。

    — 删除原本 汤姆cat 容器 webapps 目录下的 ROOT
文件,并将上下文目录中项目标 ROOT 文件夹上传到容器 webapps
目录下。

    — 启动服务。

澳门金沙国际 3澳门金沙国际 4

FROM openjdk:8-jre

ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME

# let "Tomcat Native" live somewhere isolated
ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib
ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR

# runtime dependencies for Tomcat Native Libraries
# Tomcat Native 1.2+ requires a newer version of OpenSSL than debian:jessie has available
# > checking OpenSSL library version >= 1.0.2...
# > configure: error: Your version of OpenSSL is not compatible with this version of tcnative
# see http://tomcat.10.x6.nabble.com/VOTE-Release-Apache-Tomcat-8-0-32-tp5046007p5046024.html (and following discussion)
# and https://github.com/docker-library/tomcat/pull/31
ENV OPENSSL_VERSION 1.1.0f-3+deb9u2
RUN set -ex; \
    currentVersion="$(dpkg-query --show --showformat '${Version}\n' openssl)"; \
    if dpkg --compare-versions "$currentVersion" '<<' "$OPENSSL_VERSION"; then \
        if ! grep -q stretch /etc/apt/sources.list; then \
# only add stretch if we're not already building from within stretch
            { \
                echo 'deb http://deb.debian.org/debian stretch main'; \
                echo 'deb http://security.debian.org stretch/updates main'; \
                echo 'deb http://deb.debian.org/debian stretch-updates main'; \
            } > /etc/apt/sources.list.d/stretch.list; \
            { \
# add a negative "Pin-Priority" so that we never ever get packages from stretch unless we explicitly request them
                echo 'Package: *'; \
                echo 'Pin: release n=stretch*'; \
                echo 'Pin-Priority: -10'; \
                echo; \
# ... except OpenSSL, which is the reason we're here
                echo 'Package: openssl libssl*'; \
                echo "Pin: version $OPENSSL_VERSION"; \
                echo 'Pin-Priority: 990'; \
            } > /etc/apt/preferences.d/stretch-openssl; \
        fi; \
        apt-get update; \
        apt-get install -y --no-install-recommends openssl="$OPENSSL_VERSION"; \
        rm -rf /var/lib/apt/lists/*; \
    fi

RUN apt-get update && apt-get install -y --no-install-recommends \
        libapr1 \
    && rm -rf /var/lib/apt/lists/*

# see https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/KEYS
# see also "update.sh" (https://github.com/docker-library/tomcat/blob/master/update.sh)
ENV GPG_KEYS 05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 713DA88BE50911535FE716F5208B0AB1D63011C7 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23

ENV TOMCAT_MAJOR 8
ENV TOMCAT_VERSION 8.0.53
ENV TOMCAT_SHA512 cd8a4e48a629a2f2bb4ce6b101ebcce41da52b506064396ec1b2915c0b0d8d82123091242f2929a649bcd8b65ecf6cd1ab9c7d90ac0e261821097ab6fbe22df9

ENV TOMCAT_TGZ_URLS \
# https://issues.apache.org/jira/browse/INFRA-8753?focusedCommentId=14735394#comment-14735394
    https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz \
# if the version is outdated, we might have to pull from the dist/archive :/
    https://www-us.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz \
    https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz \
    https://archive.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz

ENV TOMCAT_ASC_URLS \
    https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc \
# not all the mirrors actually carry the .asc files :'(
    https://www-us.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc \
    https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc \
    https://archive.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz.asc

RUN set -eux; \
    \
    savedAptMark="$(apt-mark showmanual)"; \
    apt-get update; \
    \
    apt-get install -y --no-install-recommends gnupg dirmngr; \
    \
    export GNUPGHOME="$(mktemp -d)"; \
    for key in $GPG_KEYS; do \
        gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
    done; \
    \
    apt-get install -y --no-install-recommends wget ca-certificates; \
    \
    success=; \
    for url in $TOMCAT_TGZ_URLS; do \
        if wget -O tomcat.tar.gz "$url"; then \
            success=1; \
            break; \
        fi; \
    done; \
    [ -n "$success" ]; \
    \
    echo "$TOMCAT_SHA512 *tomcat.tar.gz" | sha512sum -c -; \
    \
    success=; \
    for url in $TOMCAT_ASC_URLS; do \
        if wget -O tomcat.tar.gz.asc "$url"; then \
            success=1; \
            break; \
        fi; \
    done; \
    [ -n "$success" ]; \
    \
    gpg --batch --verify tomcat.tar.gz.asc tomcat.tar.gz; \
    tar -xvf tomcat.tar.gz --strip-components=1; \
    rm bin/*.bat; \
    rm tomcat.tar.gz*; \
    command -v gpgconf && gpgconf --kill all || :; \
    rm -rf "$GNUPGHOME"; \
    \
    nativeBuildDir="$(mktemp -d)"; \
    tar -xvf bin/tomcat-native.tar.gz -C "$nativeBuildDir" --strip-components=1; \
    apt-get install -y --no-install-recommends \
        dpkg-dev \
        gcc \
        libapr1-dev \
        libssl-dev \
        make \
        "openjdk-${JAVA_VERSION%%[.~bu-]*}-jdk=$JAVA_DEBIAN_VERSION" \
    ; \
    ( \
        export CATALINA_HOME="$PWD"; \
        cd "$nativeBuildDir/native"; \
        gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
        ./configure \
            --build="$gnuArch" \
            --libdir="$TOMCAT_NATIVE_LIBDIR" \
            --prefix="$CATALINA_HOME" \
            --with-apr="$(which apr-1-config)" \
            --with-java-home="$(docker-java-home)" \
            --with-ssl=yes; \
        make -j "$(nproc)"; \
        make install; \
    ); \
    rm -rf "$nativeBuildDir"; \
    rm bin/tomcat-native.tar.gz; \
    \
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
    apt-mark auto '.*' > /dev/null; \
    [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
    apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
    rm -rf /var/lib/apt/lists/*; \
    \
# sh removes env vars it doesn't support (ones with periods)
# https://github.com/docker-library/tomcat/issues/77
    find ./bin/ -name '*.sh' -exec sed -ri 's|^#!/bin/sh$|#!/usr/bin/env bash|' '{}' +

# verify Tomcat Native is working properly
RUN set -e \
    && nativeLines="$(catalina.sh configtest 2>&1)" \
    && nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')" \
    && nativeLines="$(echo "$nativeLines" | sort -u)" \
    && if ! echo "$nativeLines" | grep 'INFO: Loaded APR based Apache Tomcat Native library' >&2; then \
        echo >&2 "$nativeLines"; \
        exit 1; \
    fi

EXPOSE 8080
RUN rm -rf /usr/local/tomcat/webapps/ROOT/
ONBUILD COPY ROOT /usr/local/tomcat/webapps/ROOT/
ONBUILD ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]

tomcat-env

看起来很复杂,不要被吓到,其实都是抄的官网 汤姆cat
镜像的Dockerfile,然后改成了几许,重即使前边三句:删除容器 ROOT
文件夹,拷贝上下文目录的 ROOT 文件夹到 wenapps 目录下,重启服务。

RUN rm -rf /usr/local/tomcat/webapps/ROOT/
ONBUILD COPY ROOT /usr/local/tomcat/webapps/ROOT/
ONBUILD ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]

tips:1、ONBUILD
命令本次镜像不会被实施,唯有以这么些镜像为根基镜像的时候才会被实践。

          2、上下文目录指的是 Dockerfile 文件所在的目录。

          3、该镜像已上传到 DockerHub 上:https://hub.docker.com/r/jmcui/tomcat-env/

jar

  • 打包

mvn package
  • 运行

java -jar xxx.jar
  • war 转 jar

    • pom.xml文件上将<packaging>war</packaging>改为<packaging>jar</packaging>
    • 去掉ServletInitializer类
    • 去掉如下着重,复苏默许内嵌汤姆cat信赖

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
          <scope>provided</scope>
      </dependency>
      
  • 注册Linux服务

    • 修改spring-boot-maven-plugin配置

      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <configuration>
                      <executable>true</executable>
                  </configuration>
              <plugin>
          </plugins>
      </build>
      
    • 使用mvn package打包

    • 拔取init.d或systemd注册服务

      • init.d部署
        挂号服务

        sudo ln -s /var/apps/xxx.jar /etc/init.d/xxx
        

        开行服务

        service xxx start
        

        悬停服务

        service xxx stop
        

        劳动情形

        service xxx status
        

        开机启动

        chkconfig xxx on
        

        日志存放在/var/log/xxx.log。

      • systemd部署
        注册服务
        MySQL容器陈设,本地环境搭建。在/etc/systemd/system/目录下新建文件xxx.service,xxx.service内容如下:

        [Unit]
        Description=xxx
        After=syslog.target
        
        [Service]
        ExecStart= /usr/bin/java -jar /var/apps/xxx.jar
        
        [Install]
        WantedBy=multi-user.target
        

        起首服务

        systemctl start xxx
        
        systemctl start xxx.service
        

        悬停服务

        systemctl stop xxx
        
        systemctl stop xxx.service
        

        劳务场地

        systemctl status xxx
        
        systemctl status xxx.service
        

        开机启动

        systemctl enable xxx
        
        systemctl enable xxx.service
        

        花色日志

        journalctl -u xxx
        
        journalctl -u xxx.service
        

三、安装Docker

工欲善其事,必先利其器。首先大家应该在支付机器上设置Docker。关于Docker的装置,那里就不详细讲述了,官网的步调都很详细,给大家搬运一下网址:

1、Docker官网:

2、Mac安装格局:

3、Linux安装方式:

4、Windows安装格局:


专门关爱

dubbo_provider和dubbo_consumer是个别用来提供劳动和消费服务的,其实是三个web应用被布署在差距的器皿中,一般的话把web应用在docker的tomcat容器中运作起来有二种艺术:
1.
写Dockerfile文件做一个定制镜像,用tomcat官方镜像做基础镜像,在Dockerfile元帅war包复制到tomcat的webapps目录下,dubbo_admin和dubbo_provider都是用那种艺术;
2.
运行一个支撑在线安插的tomcat容器,然后在线布署war包,具体细节请看《实战docker,编写Dockerfile定制tomcat镜像,完结web应用在线陈设》,dubbo_consumer用的就是那种措施;

很明朗,第一种艺术用起来更简约,在docker-compose.yml中把镜像指定了就行,而第两种方法略为劳动,要协调出手去布置war包;

读者们或许会有难题:既然第一种办法大致,为何dubbo_consumer不用那种办法布署呢?其实我事先是用过的,只是在开行应用的时候会破产才改成了第二种,详细原因请看《Docker下安插dubbo,消费者使用不可以使用link参数的标题》

上边咱们伊始本地搭建dubbo体验条件的历程,首先把具备手续列出来,然后逐个已毕:

  1. 镜像zk_server不用制作,pull即可;
  2. 制作镜像dubbo_admin;
  3. 制作镜像dubbo_provider;
  4. 镜像dubbo_consumer不用制作,pull即可;
  5. 制作docker-compose.yml文件;
  6. 启动所有容器;
    7.
    下载、编译dubbo_consumer对应的源码,在线陈设到dubbo_consumer容器;
  7. 开班感受;

开始啦:

     2、微服务镜像打包

    有了基础环境镜像
tomcat-env,那么打包一个服务镜像就是一件再容易然而的事务了:

澳门金沙国际 5

FROM tomcat-env:1.0

澳门金沙国际,    没错,就是这么不难,因为我们把所有的工作都放在 tomcat-env
中了,其实就是可怜 ONBUILD 命令的功效啊~~ 

war

  • 打包

mvn package
  • 运行
    将war包丢到接济war文件的Servlet容器执行。
  • jar 转 war

    • pom.xml文件上校<packaging>jar</packaging>改为<packaging>war</packaging>
    • 增加ServletInitializer类

      import org.springframework.boot.builder.SpringApplicationBuilder;
      import org.springframework.boot.context.web.SpringBootServletInitializer;
      public class ServletInitializer extends SpringBootServletInitializer {
          @Override
          protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
              return application.source(XxxApplication.class)
          }
      }
      
    • 追加如下依赖,覆盖默许内嵌汤姆cat爱护

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
          <scope>provided</scope>
      </dependency>
      

四、布置专业启幕

好了,做好了前三步准备工作,我们借使项目已经支付已毕,Docker也合情合理安装在了您的测试机器上,你也学习了部分Docker的操作命令,不是一个完全的小白了,大家就能够开头布局应用了。

镜像:zk_server

zk_server的职能是注册中央,其余多少个容器都会用到,自身是个普通的zookeeper,那里大家用官方镜像,启动一个单机实例即可;

三、编排文件 docker-compose.yml

    微服务项目要配备起来,紧要是靠 docker-compose.yml
文件进行编辑,规定服务时期的关系以及先后启动顺序,然后把几十个伤痕累累的微服务当成一个完好来归并保管。

    首先,干扰自己的是网络难点。做过支付的都知情,要在品种中指定(Spring
在 applicationContext.xml)数据库地址和 Zookeeper
地址,那么自己怎么了然容器的 ip 地址是稍微呢?先来打探下 Docker
的互联网方式?

    Docker 的默许网络布置是 “bridge”,当 Docker
启动时,会活动在主机上创制一个 docker0 虚拟网桥,实际上是 Linux 的一个
bridge,可以知晓为一个软件沟通机。Docker
会随机分配一个地点未占用的私有网段(在 RFC1918 中定义)中的一个地方给
docker0 接口,它会在挂载到它的网口之间开展中转。当制造一个 Docker
容器的时候,同时会创设了一对 veth pair 接口。那对接口一端在容器内,即
eth0;另一端在地面并被挂载到 docker0 网桥,名称以 veth 开端(例如
vethAQI2QT)。通过那种方法,主机可以跟容器通讯,容器之间也可以互相通讯。

     也就是说,每回容器启动之后的 ip
地址是不稳定的,那该如何是好吧?当然可以写死 IP
地址,规定局域网网段,给种种服务编排 IP
地址;当然也得以把network_mode=”host”,统一用宿主机的网络地址。当然!那一个都不是最好的法子:

version: '3.7'
#服务列表
services:
  #基础组件 zookeeper  
  zookeeper:
    image: zookeeper
    restart: always
    ports:
      - 4181:2181
  #基础组件 MySQL
  db:
    image: mysql:5.7.17
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --init-connect='SET NAMES utf8mb4;'
    ports:
     - "3636:3306"
    volumes:
     - /var/mysqldb:/var/lib/mysql
     - /docker/mysql/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
  #消费者服务1 admin
  admin:
    image: "admin:2.3.1"
    ports:
     - "7575:8080"
    depends_on:
     - zookeeper
    restart: always
    environment:
      zookeeper.host: zookeeper://zookeeper:2181
  #提供者服务1 system
  system:
    image: "system:2.3.1"
    depends_on:
     - db
     - zookeeper
    restart: always
    environment:
      zookeeper.host: zookeeper://zookeeper:2181
      mysql.address: db:3306

    看到了呢?IP 地址直接由 服务名 指定就足以了。别的, Docker
中安装的环境变量,竟然能被 applicationContext.xml
中读取,我也是蛮诧异的!(在代码和 Docker 中都配备了mysql.address 的话,以 Docker
中设置的生效)。

    然后 docker-compose up -d 启动微服务项目就足以了~~

   
容器安顿的一个规则:尽量不要在容器内部做文件的改动,要修改的情节用数据卷的措施映射到宿主机上,比如上面的MySQL配置文件和数据仓库。

澳门金沙国际 6

    在 Docker 上安排 MySQL 遇到了多少个难题,不难罗列下:

1、Navicat 连接的时候:
Client does not support authentication protocol requested by server

解决:进入 MySQL 容器,运行

ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

2、Expression #1 of
SELECT list is not in GROUP BY clause and contains nonaggre
的问题?

缘由:MySQL 5.7.5及以上功用器重检测功能。如若启用了ONLY_FULL_GROUP_BY
SQL格局(默许意况下),MySQL将拒绝采用列表,HAVING条件或ORDER
BY列表的询问引用在GROUP
BY子句中既未命名的非集合列,也不在功效上注重于它们。

缓解:在MySQL的布置文件中拉长:

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

3、MySQL
连接参数useSSL=true 和
useSSL=false 的分别?

   
提出并非在平素不服务器身份验证的情事下创设SSL连接(同一个 Docker-compose
中是内网环境)。依据 MySQL 5.5.45 +,5.6.26 +和5.7.6+
需求假若未安装显式选项,则必须默许建立SSL连接。为了顺应不选拔SSL的共处应用程序。您要求通过安装useSSL = false显式禁用SSL,或者设置useSSL =
true并为服务器证书验证提供信任库。

云部署

1、创建MySQL容器

镜像:dubbo_admin

那是dubbbo的军事管制平台,是个web应用,安插在tomcat下,要求大家手工定制;
率先我们要准备war包,有二种办法获取war包:
1.
自己曾经编译好了,在自己的github下载,地址是:,里面有四个文件夹,dubbo_tomcat目录下的dubbo-admin.war文件就是我们需求的war包;
2.
去dubbo的github仓库下载官方源码,然后自己出手编译,一共要求四步成功,如下:
2.1 执行git clone git@github.com:alibaba/dubbo.git,下载dubbo源码;
2.2
下载后,打开dubbo/dubbo-admin/src/main/webapp/WEB-INF/dubbo.properties那一个文件,修改dubbo.registry.address那些参数的值,修改后dubbo.registry.address=zookeeper://zkhost:2181
2.3 进入dubbo-admin子目录,执行命令mvn clean package -U
-Dmaven.test.skip=true
2.4
mvn执行到位后,在dubbo/dubbo-admin/target目录下找到dubbo-admin-2.5.4-SNAPSHOT.war文件,重命名为dubbo-admin.war;

取得war包后,我们开端成立Dockerfile文件,内容很简短,就是以tomcat官方镜像为根基,复制dubbo-admin.war文件到镜像中,别的为了让走访url更短,我们把tomcat镜像的server.xml替换掉,新的server.xml中把webapps/dubbo-admin目录配制成了url的根目录,那样只要输入localhost:8080就能访问dubbo-admin的目录了;

先看server.xml,内容如下:

<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
        <Context path="" docBase="/usr/local/tomcat/webapps/dubbo-admin" debug="0" reloadable="true" crossContext="true"/>        
      </Host>
    </Engine>
  </Service>
</Server>

Dockerfile内容如下:

# Docker image of dubbo-admin webapp tomcat
# VERSION 0.0.1
# Author: bolingcavalry

#基础镜像使用tomcat:7.0.77-jre8
FROM tomcat:7.0.77-jre8

#作者
MAINTAINER BolingCavalry <zq2599@gmail.com>

#定义工作目录
ENV TOMCAT_BASE /usr/local/tomcat

#复制配置文件
COPY ./server.xml $TOMCAT_BASE/conf/

#复制war包
COPY ./dubbo-admin.war $TOMCAT_BASE/webapps/

#给配置文件增加读权限
RUN chmod a+xr $TOMCAT_BASE/conf/server.xml

#删除默认的ROOT文件件
RUN rm -rf $TOMCAT_BASE/webapps/ROOT

把Dockerfile,server.xml,dubbo-admin.war三个文本放在同一个目录下,然后打开控制台进入那个目录,执行以下命令营造镜像:

docker build -t bolingcavalry/dubbo_admin_tomcat:0.0.1 .

实施完结后营造dubbo_admin镜像成功,通过docker images命令可以见到;

四、结语

    总算是把一个微服务项目配置运行起来了,大概是用了起码的
Docker-compose 模板文件,所以照旧有很多地点可以周密的,比如说 MySQL
密码没有加密处理、服务没有做健康检查、集群方面还没怎么考虑(用 Docker
Swarm 完成)等等……路短时间其修远兮,吾将上下而求索。共勉!

Docker

使用Dockerfile编译Docker镜像。

下载MySQL镜像

启动Docker的情景下,在极限中输入 docker search
mysql命令可以寻找到各样各类的MySQL镜像,大家选用star最多的MySQL官方镜像。

下一场输入:docker pull
mysql命令,将以此镜像拉到本地(有可能会相比慢,可以使用阿里云加快或者fanqiang)。 

拉取落成后,在地点输入:docker images
查看镜像可以看来如下图中所示,表明您的镜像已经拉取成功。

澳门金沙国际 7

镜像:dubbo_provider

其一镜像是个tomcat容器,里面运行了一个war包,功效是提供劳务并登记到dubbo注册中央,具体的代码大家会在下一章详细介绍;

下载地址是:,里面有多个文本夹,provider_tomcat目录下的dubboserviceprovider.war文件就是咱们需求的war包;

和dubbo_admin一样,大家也部署了server.xml:

<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
        <Context path="" docBase="/usr/local/tomcat/webapps/dubboserviceprovider" debug="0" reloadable="true" crossContext="true"/>        
      </Host>
    </Engine>
  </Service>
</Server>

接下去是Dockerfile文件,内容也很简单,复制war,替换server.xml,删除原有的root目录:

# Docker image of dubbo-admin webapp tomcat
# VERSION 0.0.1
# Author: bolingcavalry

#基础镜像使用tomcat:7.0.77-jre8
FROM tomcat:7.0.77-jre8

#作者
MAINTAINER BolingCavalry <zq2599@gmail.com>

#定义工作目录
ENV TOMCAT_BASE /usr/local/tomcat


#复制配置文件
COPY ./server.xml $TOMCAT_BASE/conf/

#复制war包
COPY ./dubboserviceprovider.war $TOMCAT_BASE/webapps/

#给配置文件增加读权限
RUN chmod a+xr $TOMCAT_BASE/conf/server.xml

#删除默认的ROOT文件件
RUN rm -rf $TOMCAT_BASE/webapps/ROOT

把Dockerfile,server.xml,dubboserviceprovider.war七个文本放在同一个目录下,然后打开控制台进入这些目录,执行以下命令营造镜像:

docker build -t bolingcavalry/dubbo_provider_tomcat:0.0.1 .

执行落成后打造dubbo_provider镜像成功,通过docker images命令可以见见;

Dockerfile指令

  • FROM
    指明当前镜像继承的基镜像,编译当前镜像时会自动下载基镜像。

    FROM java:8
    
  • MAINTAINER
    指明当前镜像的撰稿人。

    MAINTAINER linliangsheng
    
  • RUN
    时下镜像上推行Linux命令并形成一个新的层,编译时(build)动作。

    RUN /bin/bash -c "echo hello"
    
    RUN ["/bin/bash", "-c", "echo hello"]
    
  • CMD
    开行镜像容器时的默许行为,一个Dockerfile只可以有一个CMD指令,可在运转镜像时采取参数覆盖,运行时(run)动作。

    CMD echo "hello"
    

    参数覆盖写法:

    docker run -d image_name echo "docker-hello"
    
  • EXPOSE
    指明镜像运行时的器皿必需监听指定的端口。

    EXPOSE 8080
    
  • ENV
    设置环境变量。

    ENV name=linliangsheng
    
    ENV name linliangsheng
    
  • ADD
    从当前工作目录复制文件到镜像目录。

    ADD xxx.jar app.jar
    
  • ENTRYPOINT
    让容器像可执行程序一样运行,镜像运行时可选择参数,运行时(run)动作。

    ENTRYPOINT ["java"]
    

    参数接收写法:

    docker run -d image_name "-jar app.jar"
    

创建MySQL容器

开行容器:MySQL可以一向把端口地址映射到宿主机上,不过在生产环境中映射宿主主机有可能会造成端口争论等一种种题材,所以大家用容器互联的艺术,让MySQL的端口只揭破给汤姆cat服务器,命令如下:

docker run –name health-tomcat  -v /home/mysql_data:/var/lib/mysql
–restart=always -e MYSQL_ROOT_PASSWORD=123456 -d <IMAGE-ID>

    -v:容器的/var/lib/mysql目录挂载在主机的/home/mysql_data目录

    -e 设置默许参数,协助参数:

    • MYSQL_ROOT_PASSWORD

    • MYSQL_DATABASE

    • MYSQL_USER, MYSQL_PASSWORD

    • MYSQL_ALLOW_EMPTY_PASSWORD

    • MYSQL_RANDOM_ROOT_PASSWORD

    • MYSQL_ONETIME_PASSWORD

我们用MYSQL_ROOT_PASSWORD=123456是给默许的root用户设置密码为123456.

<IMAGE-ID>为您的镜像的名字,那里为mysql。

进去容器:

动用命令 docker exec -it health-mysql mysql -uroot
-p进入MySQL容器,在Enter
password:输入你刚好安装的密码。进入之后的操作跟你在祥和电脑上设置MySQL后的操作一样。

导入宿主机.sql文件到MySQL容器的数据库中:

先查看MySQL运行名称:docker ps, NAMES栏底下为名称

跻身刚刚创立的器皿:docker exec -it health-mysql mysql -uroot -p

开创一个数据库:create database health_data

退出MySQL环境

将宿主机文件导入:MySQL容器名称为:health-mysql, 
容器中数据库名称为:health_data

执行:docker exec -i health-mysql mysql -u root -p123456 health_data
< /Users/jacob/Desktop/health_data.sql

镜像:dubbo_consumer

dubbo_consumer也是web应用,前面已说过此选拔的安顿格局和dubbo_provider分歧,是在线陈设,所以镜像文件用bolingcavalry/online_deploy_tomcat:0.0.1,此镜像已宣布到hub.docker.com,可以一直运用,它里面有个tomcat,援救提过maven插件在线计划,有关此镜像的详情请看《实战docker,编写Dockerfile定制tomcat镜像,落成web应用在线安插》,请记得修改maven的安插文件,否则在线陈设的鉴权不能透过;

dubbo_consumer对应的war包要求下载对应的源码,然后编译安顿,这么些大家前面会讲到;

Docker安装

  • 安装Docker

    yum install docker
    
  • 启动Docker

    systemctl start docker
    
  • 开机自启动

    systemctl enable docker
    

2、创建汤姆cat容器并且用–link连接到MySQL容器

1、下载镜像:docker pull tomcat

2、创立一个地点目录:/Users/jacob/Desktop/tomcat_data,把项目标war包放到这几个本机文件夹。要求留意的是,在容器互联的时候须求为MySQL容器创造一个别名,在档次的jdbc.properties中jdbc.url=jdbc:mysql://tomysql:3306/guotai?useUnicode=true&characterEncoding=utf-8,3306端口前的tomysql就是通过数据库别名,那样才能访问项目,他一定于localhost/你的IP地址。所以在导出war包以前,先想好您的数据库别名,然后把3306面前的名号和你的数据库别名设置成一致然后导出(很关键!!!)

3、创设汤姆cat容器并一而再到MySQL

直接线上命令,然后解释

docker run -d -p 8888:8080 -v
/Users/jacob/Desktop/tomcat_data:/usr/Downloads –name health-tomcat
–link health-mysql:tomysql tomcat

1、-p前边是把汤姆cat的8080端口映射到8888端口,安顿后用8888来走访。

2、-v /Users/jacob/Desktop/tomcat_data:/usr/Downloads
把/usr/Downloads目录挂载到你的房war包的地方目录,为一会拷贝war包到汤姆cat容器做准备。

3、–name health-tomcat 为你的汤姆cat容器起一个名字

4、–link health-mysql:tomysql
这步就是促成强强联合,health-mysql就是你一先河首先步创制的MySQL容器的名目,冒号前面就是MySQL容器在汤姆cat容器中的别名,那分别名要和你项目标jdbcurl
3306端口前的称号一致,那样才足以建立数据库连接(谨记)

5、tomcat 这几个就是你的镜像名称

实施完容器创制后,大家需求把war包从本机拷贝到汤姆cat服务器中。

先是:执行以下命令进入容器:docker exec -it health-tomcat /bin/bash

进入容器后再实施以下命令将war包复制到tomcat容器目录下:cp
/usr/Downloads/Demo.war /usr/local/tomcat/webapps/

/usr/Downloads/Demo.war是您刚好挂在的本土存放war报的目录

/usr/local/tomcat/webapps/是汤姆cat容器中你要把war包拷贝到这里

那时,准备工作早就全体扫尾,享受成果吧!

在浏览器输入URL:

澳门金沙国际 8

8888是您碰巧在成立容器时给8080端口映射的端口值,Demo是您的war包的名字,在拜访你的API的时候要加上war包名字这么些途径。


好了,那是本人安插的一对经历。每个品种具体的不相同会造成操作步骤和指令上的出入,才疏学浅,错误在所难免,希望咱们批评指正!

制作docker-compose.yml

docker-compose.yml内容如下:

version: '2'
services:
  zk_server: 
    image: daocloud.io/library/zookeeper:3.3.6
    restart: always
  dubbo_admin: 
    image: bolingcavalry/dubbo_admin_tomcat:0.0.1
    links: 
      - zk_server:zkhost
    depends_on:
          - "zk_server"
    ports: 
      - "8080:8080"
    restart: always
  dubbo_provider: 
    image: bolingcavalry/dubbo_provider_tomcat:0.0.1
    links: 
      - zk_server:zkhost
    depends_on:
          - "dubbo_admin"
    environment:
      TOMCAT_SERVER_ID: dubbo_provider_tomcat
    restart: always
  dubbo_consumer: 
    image: bolingcavalry/online_deploy_tomcat:0.0.1
    ports: 
      - "8082:8080"
    environment:
      TOMCAT_SERVER_ID: dubbo_consumer_tomcat
    restart: always

那其中使用了depends_on参数,是为着确保启动顺序;

Docker实践

起步所有容器

执行命令:

docker-compose up -d

三个容器启动成功,如下图:

澳门金沙国际 9

Spring Boot实践

在xxx.jar包同级目录建立Dockerfile文件,Dockerfile文件内容如下:

FROM java:8
MAINTAINER linliangsheng
ADD xxx.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

编译镜像:

docker build -t wisely/xxx .

运转镜像:

docker run -d --name xxx -p 8080:8080 wisely/xxx

dubbo_consumer对应的源码编译和在线安排

编译代码前,要先确定zookeeper的ip,前边执行docker-compose up
-d的时候,控制台提醒zookeeper容器的名目是16_zk_server_1,由此举办以下命令可看zookeeper容器ip:

docker exec -it 16_zk_server_1 ip a

正如图红框,ip是172.28.0.3

澳门金沙国际 10

近日开始下载和编译源码了,dubbo消费者的webapp源码地址是:git@github.com:zq2599/blog_demos.git,里面有多个工程,这次实战用到的工程是dubbo_service_consumer,如下图红框所示:

澳门金沙国际 11

代码下载后,在dubbo_service_consumer/src/main/resources目录下,打开spring-extends.xml文件,修改下图红框中的ip,改成zookeeper的ip:172.28.0.3:

澳门金沙国际 12

执行命令mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy

mvn执行到位后,web应用已经部署到dubbo_consumer的tomcat上;

Spring Cloud实践

  1. 编写runboot.sh脚本
    位于src/main/docker下:

    sleep 10
    java -Djava.security.egd=file:/dev/./urandom -jar /app/app.jar
    

    据悉启动顺序调整sleep时间

  2. 编写Dockerfile
    位于src/main/docker下:

    FROM java:8
    VOLUME /tmp
    RUN mkdir /app
    ADD xxx.jar /app/app.jar
    ADD runboot.sh /app/
    RUN bash -c 'touch /app/app.jar'
    WORKDIR /app
    RUN chmod a+x runboot.sh
    EXPOSE 8888
    CMD /app/runboot.sh
    

    今非昔比的微服务只需修改

    ADD xxx.jar /app/app.jar
    EXPOSE 8888
    
  3. Docker插件
    在pom.xml中增加docker-maven-plugin插件

    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <configuration>
                    <imageName>${project.name}:${project.version}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <skipDockerBuild>false</skipDockerBuild>
                    <resources>
                        <resource>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
  4. 编译镜像
    docker-maven-plugin默许将Docker编译到localhost,如若是远程Linux服务器,须要配备环境变量DOCKER_HOST,变量值tcp://IP地址:端口号
    执行mvn命令进行镜像编译:

    mvn clean package docker:build -DskipTests
    
  5. Docker Compose
    Docker
    Compose是用来定义和运作多容器应用的工具,使用一个docker-compose.yml来讲述多容器定义,使用docker-compose up -d运转总体应用,-d代表后台运行。
    docker-compose.yml参考情节:

    postgresdb:
      image: busybox
      volumes:
        - /var/lib/postgresql/data
    postgres:
      name: postgres
      image: postgres
      hostname: postgres
      volumes_from:
        - postgresdb
      environment:
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    discovery:
      name: discovery
      image: "discovery:1.0.0-SNAPSHOT"
      hostname: discovery
      ports:
        - "8761:8761"
    config:
      name: config
      image: "config:1.0.0-SNAPSHOT"
      hostname: config
      links:
        - discovery
      environment:
        - EUREKA_HOST: discovery
        - EUREKA_PORT: 8761
      ports:
        - "8888:8888"
    person:
      name: person
      image: "person:1.0.0-SNAPSHOT"
      hostname: person
      links:
        - discovery
        - config
        - postgres
      environment:
        - EUREKA_HOST: discovery
        - EUREKA_PORT: 8761
        - SPRING_PROFILES_ACTIVE: docker
      ports:
        - "8082:8082"
    some:
      name: some
      image: "some:1.0.0-SNAPSHOT"
      hostname: some
      links:
        - discovery
        - config
      environment:
        - EUREKA_HOST: discovery
        - EUREKA_PORT: 8761
        - SPRING_PROFILES_ACTIVE: docker
      ports:
        - "8083:8083"
    ui:
      name: ui
      image: "ui:1.0.0-SNAPSHOT"
      hostname: ui
      links:
        - discovery
        - config
        - person
        - some
      environment:
        - EUREKA_HOST: discovery
        - EUREKA_PORT: 8761
        - SPRING_PROFILES_ACTIVE: docker
      ports:
        - "80:80"
    monitor:
      name: monitor
      image: "monitor:1.0.0-SNAPSHOT"
      hostname: monitor
      links:
        - discovery
        - config
        - person
        - some
        - ui
      environment:
        - EUREKA_HOST: discovery
        - EUREKA_PORT: 8761
        - SPRING_PROFILES_ACTIVE: docker
      ports:
        - "8989:8989"
    

起来体验

今天本地环境搭建已经形成,可以起来体验了,体验步骤和《Docker下dubbo开发,三部曲之一:极速体验》中的体验环节同样,就不在此赘述了,简单的讲分为以下两步:
1.
在dubbo-admin的web页面上查看服务提供者、消费者的挂号意况,地址是;
2.
在dubbo_consumer的web页面上印证远程调用,地址是

以上就是docker下dubbo本地搭建的万事进程,经过本章的实战,大家早就可以基于自己的急需订制dubbo环境了,下一章是dubbo学习的终章,大家一同实战编码,学会开发dubbo环境下的劳务提供者和消费者;

FAQ

  1. 编译打包报错I/O exception (java.io.IOException) caught when processing request to {}->unix://localhost:80: Permission denied
    亟需配置DOCKER_HOST环境变量,Ubuntu16.04LTS中环境变量配置是修改~/.bashrc文件,增加export DOCKER_HOST=tcp://127.0.0.1:5555,使配置的环境变量马上生效source ~/.bashrc。同时,须要修改Docker后台进度监听5555端口,编辑/etc/default/docker,增加DOCKER_OPTS="-H 0.0.0.0:5555",然后service docker restart重启Docker。
  2. 编译打包报错Exception caught: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
    一再编译打包就可以化解。
    Tip:
    翻开本地镜像命令:docker images
    翻看当前容器状态:docker ps

参考资料

Java EE开发的颠覆者-Spring Boot实战.汪云飞.407-424,478-484

相关文章