Python微信订餐小程序课程视频
https://blog.csdn.net/m0_56069948/article/details/122285951
Python实战量化交易理财系统
https://blog.csdn.net/m0_56069948/article/details/122285941
概述
我们使用前面《SpringCloudAlibaba注册中心与配置中心之利器Nacos实战与源码分析(中)》的两个微服务示例,分别是库存微服务和订单微服务,基于Nacos注册中心和配置中心的使用,前面Nacos我们已基于dock-compose方式部署,我们增加配置数据,这里我们暂时也不把数据打包进去,各位可以直接将容器以dokcer export方式导入为镜像,微服务使用订单、库存MySQL数据库暂时也不单独做成镜像,各位可以做成SQL脚本执行导入方式。
整体工程结构
- docker目录docker compose编排脚本目录
- bin目录:包含初始化脚本、启动脚本、停止脚本、更新脚本
- env目录:存在为微服务环境变量
- yaml目录:存在全局环境脚本变量、微服务docker-compose脚本
- 库存微服务
- bin目录:存在微服务启动脚本
- conf目录:存在启动配置文件和日志配置文件
- Dockerfile文件
- 订单微服务
- bin目录:存在微服务启动脚本
- conf目录:存在启动配置文件和日志配置文件
- Dockerfile文件
库存微服务
编写配置文件
bootstrap.yml
spring:application:name: ecom-storage-serviceprofiles:active: ${SPRING\_PROFILES\_ACTIVE:"dev"}main:allow-circular-references: truecloud:nacos:# 注册中心信息放在配置中心上,每个程序一般只配置配置中心的信息server-addr: ${NACOS\_CONFIG\_SERVER:"192.168.50.95:8848"}config:server-addr: ${spring.cloud.nacos.server-addr}file-extension: yamlnamespace: ${NACOS\_CONFIG\_NAMESPACE:"a2b1a5b7-d0bc-48e8-ab65-04695e61db01"}group: ${NACOS\_CONFIG\_GROUP:"storage-group"}extension-configs:- dataId: extension-priority-dev.yamlgroup: extension-grouprefresh: true- dataId: commons-dev.yamlgroup: commons-grouprefresh: trueshared-configs:- dataId: shared-priority-dev.yamlgroup: shared-grouprefresh: trueusername: itsxpassword: itxs123enabled: true # 默认为true,设置false 来完全关闭 Spring Cloud Nacos Configrefresh-enabled: true # 默认为true,当变更配置时,应用程序中能够获取到最新的值,设置false来关闭动态刷新,我们使用注册中心场景大部分就是动态感知,因此基本使用默认的
logback.xml
xml version="1.0" encoding="UTF-8" ?
<configuration debug="false"><springProperty scope="context" name="APP\_HOME" source="spring.application.name"/><property name="LOG\_HOME" value="${LOG\_PATH:-.}" /><property name="CONSOLE\_LOG\_PATTERN" value="%boldMagenta([%d{yyyy-MM-dd HH:mm:ss.SSS}]) %cyan([%X{requestId}]) %boldMagenta(%-5level) %blue(%logger{15}) %red([%thread]) %magenta(·⊱══>) %cyan(%msg%n)"/><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}pattern><charset>utf8charset>encoder>appender><appender name="DAY\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}_${APP_HOME}.%i.logFileNamePattern><MaxHistory>7MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>50MBmaxFileSize>timeBasedFileNamingAndTriggeringPolicy>rollingPolicy><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFOlevel> <onMatch>ACCEPTonMatch> <onMismatch>DENYonMismatch> filter><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>encoder>appender><appender name="DAY\_WARN\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}_${APP_HOME}_warn.%i.logFileNamePattern><MaxHistory>7MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>50MBmaxFileSize>timeBasedFileNamingAndTriggeringPolicy>rollingPolicy><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARNlevel> <onMatch>ACCEPTonMatch> <onMismatch>DENYonMismatch> filter><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>encoder>appender><appender name="DAY\_ERROR\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}_${APP_HOME}_error.%i.logFileNamePattern><MaxHistory>7MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>50MBmaxFileSize>timeBasedFileNamingAndTriggeringPolicy>rollingPolicy><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERRORlevel> <onMatch>ACCEPTonMatch> <onMismatch>DENYonMismatch> filter><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>encoder>appender><logger name="com.sand" level="INFO"/><logger name="com.apache.ibatis" level="INFO"/><logger name="java.sql.Statement" level="INFO"/><logger name="java.sql.Connection" level="INFO"/><logger name="java.sql.PreparedStatement" level="INFO"/><logger name="org.springframework" level="WARN"/><logger name="com.baomidou.mybatisplus" level="WARN"/><springProfile name="dev"><root level="INFO"><appender-ref ref="CONSOLE"/><appender-ref ref="DAY\_FILE"/><appender-ref ref="DAY\_WARN\_FILE"/><appender-ref ref="DAY\_ERROR\_FILE"/>root>springProfile><springProfile name="pro"><root level="INFO"><appender-ref ref="CONSOLE"/><appender-ref ref="DAY\_FILE"/><appender-ref ref="DAY\_WARN\_FILE"/><appender-ref ref="DAY\_ERROR\_FILE"/>root>springProfile>
configuration>
制作Docker启动脚本
docker-startup.sh
#!/bin/bash
set -x
export CUSTOM_SEARCH_NAMES="application,custom"
export CUSTOM_SEARCH_LOCATIONS=${BASE_DIR}/init.d/,file:${BASE_DIR}/conf/JAVA_OPT="${JAVA_OPT} -Dsimple_ecommerce.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/ecom-storage-service.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} --spring.config.additional-location=${CUSTOM_SEARCH_LOCATIONS}"
JAVA_OPT="${JAVA_OPT} --spring.config.name=${CUSTOM_SEARCH_NAMES}"
JAVA_OPT="${JAVA_OPT} --logging.config=${BASE_DIR}/conf/logback.xml"
JAVA_OPT="${JAVA_OPT} --logging.file.path=${BASE_DIR}/logs/"
JAVA_OPT="${JAVA_OPT} --spring.config.location=${BASE_DIR}/conf/bootstrap.yml"
JAVA_OPT="${JAVA_OPT} --server.max-http-header-size=524288"echo "ecom-storage-service is starting, you can docker logs your container"
exec $JAVA ${JAVA_OPT}
制作Dockerfile文件
Dockerfile文件
FROM java:8
MAINTAINER itxs "107734588@qq.com"ARG ECOM_STORAGE_SERVICE_VERSION=1.0
ARG ECOM_STORAGE_SERVICE_DIR="ecom-storage-service"
ARG ECOM_STORAGE_SERVICE_PACKAGE="ecom-storage-service-$ECOM\_STORAGE\_SERVICE\_VERSION.jar"
ARG ECOM_STORAGE_SERVICE_PROGRAM="ecom-storage-service.jar"# set environment
ENV BASE_DIR="/home/simple\_ecommerce/${ECOM\_STORAGE\_SERVICE\_DIR}" \CLASSPATH=".:/home/simple\_ecommerce/${ECOM\_STORAGE\_SERVICE\_DIR}/conf:$CLASSPATH" \JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64" \JAVA="/usr/lib/jvm/java-8-openjdk-amd64/bin/java" \JAVA_OPT_EXT="${JAVA\_OPT\_EXT}" \TIME_ZONE="Asia/Shanghai"WORKDIR $BASE\_DIRADD ./target/$ECOM\_STORAGE\_SERVICE\_PACKAGE target/$ECOM\_STORAGE\_SERVICE\_PROGRAM
RUN ln -snf /usr/share/zoneinfo/$TIME\_ZONE /etc/localtime && echo $TIME\_ZONE > /etc/timezoneADD bin/docker-startup.sh bin/docker-startup.sh
ADD conf/bootstrap.yml conf/bootstrap.yml
ADD conf/logback.xml conf/logback.xml
RUN mkdir -p init.d# set startup log dir
RUN mkdir -p logs \&& cd logs \&& touch start.out \&& ln -sf /dev/stdout start.out \&& ln -sf /dev/stderr start.out
RUN chmod +x bin/docker-startup.shEXPOSE 4080
ENTRYPOINT ["bin/docker-startup.sh"]
打包配置
库存微服务pom文件添加docker-maven-plugin
xml version=<span class="hljs-string""1.0" encoding="UTF-8"?>
"http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">simple-ecommercecn.itxs1.04.0.0ecom-storage-servicejar1.0ecom-storage-servicea simple electronic commerce platform demo tutorial for storage servicecn.itxsecom-commonsorg.projectlomboklombokprovidedorg.springframework.bootspring-boot-maven-plugincn.itxs.ecom.storage.StorageServiceApplicationZIPrepackageio.fabric8docker-maven-plugin0.39.1adminadmin12345simple\_ecommerce/${project.name}:${project.version}registry.itxs.cnmaster${project.basedir}/Dockerfilehostdocker-execinstallbuildpush
可以看到库存微服务pom文件添加docker-maven-plugin,mvn install阶段,当执行mvn install时 就会执行docker build 和docker push,我们前面也介绍Docker Harbor私有仓库的部署,可以通过插件直接推送内网的Harbor私有仓库里。
订单微服务
编写配置文件
bootstrap.yml
spring:application:name: ecom-order-serviceprofiles:active: devmain:allow-circular-references: truecloud:# 负载均衡器缓存loadbalancer:cache:enabled: truecaffeine:spec: initialCapacity=500,expireAfterWrite=5snacos:# 注册中心信息放在配置中心上,每个程序一般只配置配置中心的信息server-addr: ${NACOS\_CONFIG\_SERVER:"192.168.50.95:8848"}config:server-addr: ${spring.cloud.nacos.server-addr}file-extension: yamlnamespace: ${NACOS\_CONFIG\_NAMESPACE:"a2b1a5b7-d0bc-48e8-ab65-04695e61db01"}group: ${NACOS\_CONFIG\_GROUP:"order-group"}username: itsxpassword: itxs123extension-configs:- dataId: commons-dev.yamlgroup: commons-grouprefresh: trueenabled: true # 默认为true,设置false 来完全关闭 Spring Cloud Nacos Configrefresh-enabled: true # 默认为true,当变更配置时,应用程序中能够获取到最新的值,设置false来关闭动态刷新,我们使用注册中心场景大部分就是动态感知,因此基本使用默认的
制作Docker启动脚本
docker-startup.sh
#!/bin/bash
set -x
export CUSTOM_SEARCH_NAMES="application,custom"
export CUSTOM_SEARCH_LOCATIONS=${BASE_DIR}/init.d/,file:${BASE_DIR}/conf/JAVA_OPT="${JAVA_OPT} -Dsimple_ecommerce.home=${BASE_DIR}"
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/ecom-order-service.jar"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} --spring.config.additional-location=${CUSTOM_SEARCH_LOCATIONS}"
JAVA_OPT="${JAVA_OPT} --spring.config.name=${CUSTOM_SEARCH_NAMES}"
JAVA_OPT="${JAVA_OPT} --logging.config=${BASE_DIR}/conf/logback.xml"
JAVA_OPT="${JAVA_OPT} --logging.file.path=${BASE_DIR}/logs/"
JAVA_OPT="${JAVA_OPT} --spring.config.location=${BASE_DIR}/conf/bootstrap.yml"
JAVA_OPT="${JAVA_OPT} --server.max-http-header-size=524288"echo "ecom-order-service is starting, you can docker logs your container"
exec $JAVA ${JAVA_OPT}
制作Dockerfile文件
Dockerfile文件
FROM java:8
MAINTAINER itxs "107734588@qq.com"ARG ECOM_ORDER_SERVICE_VERSION=1.0
ARG ECOM_ORDER_SERVICE_DIR="ecom-order-service"
ARG ECOM_ORDER_SERVICE_PACKAGE="ecom-order-service-$ECOM\_ORDER\_SERVICE\_VERSION.jar"
ARG ECOM_ORDER_SERVICE_PROGRAM="ecom-order-service.jar"# set environment
ENV BASE_DIR="/home/simple\_ecommerce/${ECOM\_ORDER\_SERVICE\_DIR}" \CLASSPATH=".:/home/simple\_ecommerce/${ECOM\_ORDER\_SERVICE\_DIR}/conf:$CLASSPATH" \JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64" \JAVA="/usr/lib/jvm/java-8-openjdk-amd64/bin/java" \JAVA_OPT_EXT="${JAVA\_OPT\_EXT}" \TIME_ZONE="Asia/Shanghai"WORKDIR $BASE\_DIRADD ./target/$ECOM\_ORDER\_SERVICE\_PACKAGE target/$ECOM\_ORDER\_SERVICE\_PROGRAM
RUN ln -snf /usr/share/zoneinfo/$TIME\_ZONE /etc/localtime && echo $TIME\_ZONE > /etc/timezoneADD bin/docker-startup.sh bin/docker-startup.sh
ADD conf/bootstrap.yml conf/bootstrap.yml
ADD conf/logback.xml conf/logback.xml
RUN mkdir -p init.d# set startup log dir
RUN mkdir -p logs \&& cd logs \&& touch start.out \&& ln -sf /dev/stdout start.out \&& ln -sf /dev/stderr start.out
RUN chmod +x bin/docker-startup.shEXPOSE 4070
ENTRYPOINT ["bin/docker-startup.sh"]
打包配置
订单微服务pom文件添加docker-maven-plugin
xml version=<span class="hljs-string""1.0" encoding="UTF-8"?>
"http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">simple-ecommercecn.itxs1.04.0.0ecom-order-servicejar1.0ecom-order-servicea simple electronic commerce platform demo tutorial for order servicecn.itxsecom-commonsorg.projectlomboklombokprovidedcom.github.ben-manes.caffeinecaffeine3.0.6org.springframework.bootspring-boot-maven-plugincn.itxs.ecom.order.OrderServiceApplicationZIPrepackageio.fabric8docker-maven-plugin0.39.1adminadmin12345simple\_ecommerce/${project.name}:${project.version}registry.itxs.cnmaster${project.basedir}/Dockerfilehostdocker-execinstallbuildpush
上面订单微服务pom文件添加docker-maven-plugin,mvn install阶段,当执行mvn install时 就会执行docker build 和docker push,我们前面也介绍Docker Harbor私有仓库的部署,可以通过插件直接推送内网的Harbor私有仓库里。
打包
# 由于需要进行docker build 和docker push,打包机器需要安装docker,直接执行mvn clean install 即可,如果需要单独mvn clean install# 如果是单独针对库存微服务只进行docker build,可以进入库存微服务目录mvn clean package docker:bulid
docker build两个微服务的镜像文件如下,这个是我单独docker build没有push.如果install的话上传内网Harbor仓库本地先生成镜像,然后再上传最后删除本地的镜像。
部署
env目录
订单微服务环境变量ecom-order-service.env,这里NACOS_CONFIG_SERVER简单先用地址,如果是在单个宿主机或者K8s环境下,并且在同个容器网络内可以直接使用容器名,可不需要Nacos地址配置,这里我们就先用暴露宿主机端口,先重点放在两个微服务容器上。
SPRING_PROFILES_ACTIVE=dev
NACOS_CONFIG_SERVER=192.168.50.95:8848
NACOS_CONFIG_NAMESPACE=a2b1a5b7-d0bc-48e8-ab65-04695e61db01
NACOS_CONFIG_GROUP=order-group
JAVA_OPT_EXT="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xms1024m -Xmx1024m -Xmn1024m -XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=4 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-CMSConcurrentMTEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m"
库存微服务环境变量ecom-storage-service.env
SPRING_PROFILES_ACTIVE=dev
NACOS_CONFIG_SERVER=192.168.50.95:8848
NACOS_CONFIG_NAMESPACE=a2b1a5b7-d0bc-48e8-ab65-04695e61db01
NACOS_CONFIG_GROUP=storage-group
JAVA_OPT_EXT="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xms1024m -Xmx1024m -Xmn1024m -XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=4 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-CMSConcurrentMTEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m"
制作Docker-Compose编排文件
我这里做法没有将多个微服务编排的一个Docker-Compose文件里,而已单独做一个Docker-Compose,通过shell脚本串联起来执行,各位也可以直接编写一个Docker-Compose
全局环境变量.env存放全局参数信息,例如各微服务的版本信息
ECOM_STORAGE_VERSION=1.0ECOM_ORDER_VERSION=1.0
库存微服务Docker-Compose文件ecom-storage-service.yml,如果是本地build则image去掉registry.itxs.cn/
version: "3"
services:ecom-storage-service:image: registry.itxs.cn/simple\_ecommerce/ecom-storage-service:${ECOM\_STORAGE\_VERSION}container\_name: ecom-storage-serviceenv\_file:- ../env/ecom-storage-service.envvolumes:- ../logs/ecom-storage-service/:/home/simple\_ecommerce/ecom-storage-service/logsports:- "4080:4080"networks:- simple\_ecommercerestart: always
networks:simple\_ecommerce:external: true
订单微服务Docker-Compose文件ecom-order-service.yml
version: "3"
services:ecom-order-service:image: registry.itxs.cn/simple\_ecommerce/ecom-order-service:${ECOM\_ORDER\_VERSION}container\_name: ecom-order-serviceenv\_file:- ../env/ecom-order-service.envvolumes:- ../logs/ecom-order-service/:/home/simple\_ecommerce/ecom-order-service/logsports:- "4070:4070"networks:- simple\_ecommercerestart: always
networks:simple\_ecommerce:external: true
部署脚本
bin目录下我们创建操作脚本,init.sh初始化检查环境、安装docker和docker-compose、
#!/usr/bin/env bashecho "############当前操作系统版本##############"
if ! type yum >/dev/null 2>&1; thenecho "【ERROR】目前脚本仅支持CentOS7.X系统"exit 8
elseosVersion=$(echo `cat /etc/redhat-release | sed -r 's/.* ([0-9]+)\..*/\1/'`)if [[ "$osVersion" != "7" ]]; thenecho "【ERROR】目前脚本仅支持CentOS7.X系统"exit 8elseecho '版本校验成功' fi
fiecho "############判断是否安装了docker##############"
if ! type docker >/dev/null 2>&1; thenecho 'docker 未安装';echo '开始安装Docker....';yum install -y yum-utilsyum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo#安装docker核心引擎、命令行客户端、容器yum install docker-ce docker-ce-cli containerd.ioecho 'docker 安装完毕';#启动dockerecho '配置Docker开启启动';systemctl enable dockersystemctl start dockercat >> /etc/docker/daemon.json << EOF
{"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOFsystemctl restart docker
elseecho 'docker 安装完毕';
fiecho "############判断是否安装了wget##############"
if ! type wget >/dev/null 2>&1; thenecho 'wget 未安装';echo '开始安装wget....';yum -y install wget
elseecho 'wget 已安装';
fiecho "############判断是否安装了dos2unix##############"
if ! type dos2unix >/dev/null 2>&1; thenecho 'dos2unix 未安装';echo '开始安装dos2unix....';yum -y install dos2unix*
elseecho 'dos2unix 已安装';
fiecho "############判断是否安装了docker-compose##############"
if ! type docker-compose >/dev/null 2>&1; thenecho 'docker-compose 未安装';echo '开始安装docker-compose....';wget http://www.itxiaoshen.com:3001/assets/docker-composechmod +x docker-composemv docker-compose /usr/local/bin/docker-compose -vecho 'docker-compose安装完毕....';
elseecho 'docker-compose 已安装';
fiecho '创建simple_ecommerce网络';
docker network create simple_ecommerce# 添加执行权限
chmod +x ../bin/startup-all.sh
chmod +x ../bin/shutdown-all.sh
chmod +x ../bin/update.sh
chmod +x ../bin/wait-for-it.sh# 修改编码
echo "修改编码...."
dos2unix startup-all.sh
dos2unix shutdown-all.sh
dos2unix update.sh
dos2unix wait-for-it.shsh startup-all.sh
wait-for-it.sh等待请求脚本
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are availableWAITFORIT_cmdname=${0##*/}echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }usage()
{cat << USAGE >&2
Usage:$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]-h HOST | --host=HOST Host or IP under test-p PORT | --port=PORT TCP port under testAlternatively, you specify the host and port as host:port-s | --strict Only execute subcommand if the test succeeds-q | --quiet Don't output any status messages-t TIMEOUT | --timeout=TIMEOUTTimeout in seconds, zero for no timeout-- COMMAND ARGS Execute command with args after the test finishes
USAGEexit 1
}wait_for()
{if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; thenechoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"elseechoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"fiWAITFORIT_start_ts=$(date +%s)while :doif [[ $WAITFORIT_ISBUSY -eq 1 ]]; thennc -z $WAITFORIT_HOST $WAITFORIT_PORTWAITFORIT_result=$?else(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1WAITFORIT_result=$?fiif [[ $WAITFORIT_result -eq 0 ]]; thenWAITFORIT_end_ts=$(date +%s)echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"breakfisleep 1donereturn $WAITFORIT_result
}wait_for_wrapper()
{# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692if [[ $WAITFORIT_QUIET -eq 1 ]]; thentimeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &elsetimeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &fiWAITFORIT_PID=$!trap "kill -INT -$WAITFORIT_PID" INTwait $WAITFORIT_PIDWAITFORIT_RESULT=$?if [[ $WAITFORIT_RESULT -ne 0 ]]; thenechoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"fireturn $WAITFORIT_RESULT
}# process arguments
while [[ $# -gt 0 ]]
docase "$1" in*:* )WAITFORIT_hostport=(${1//:/ })WAITFORIT_HOST=${WAITFORIT_hostport[0]}WAITFORIT_PORT=${WAITFORIT_hostport[1]}shift 1;;--child)WAITFORIT_CHILD=1shift 1;;-q | --quiet)WAITFORIT_QUIET=1shift 1;;-s | --strict)WAITFORIT_STRICT=1shift 1;;-h)WAITFORIT_HOST="$2"if [[ $WAITFORIT_HOST == "" ]]; then break; fishift 2;;--host=*)WAITFORIT_HOST="${1#*=}"shift 1;;-p)WAITFORIT_PORT="$2"if [[ $WAITFORIT_PORT == "" ]]; then break; fishift 2;;--port=*)WAITFORIT_PORT="${1#*=}"shift 1;;-t)WAITFORIT_TIMEOUT="$2"if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fishift 2;;--timeout=*)WAITFORIT_TIMEOUT="${1#*=}"shift 1;;--)shiftWAITFORIT_CLI=("$@")break;;--help)usage;;*)echoerr "Unknown argument: $1"usage;;esac
doneif [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; thenechoerr "Error: you need to provide a host and port to test."usage
fiWAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}# Check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)WAITFORIT_BUSYTIMEFLAG=""
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; thenWAITFORIT_ISBUSY=1# Check if busybox timeout uses -t flag# (recent Alpine versions don't support -t anymore)if timeout &>/dev/stdout | grep -q -e '-t '; thenWAITFORIT_BUSYTIMEFLAG="-t"fi
elseWAITFORIT_ISBUSY=0
fiif [[ $WAITFORIT_CHILD -gt 0 ]]; thenwait_forWAITFORIT_RESULT=$?exit $WAITFORIT_RESULT
elseif [[ $WAITFORIT_TIMEOUT -gt 0 ]]; thenwait_for_wrapperWAITFORIT_RESULT=$?elsewait_forWAITFORIT_RESULT=$?fi
fiif [[ $WAITFORIT_CLI != "" ]]; thenif [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; thenechoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"exit $WAITFORIT_RESULTfiexec "${WAITFORIT_CLI[@]}"
elseexit $WAITFORIT_RESULT
fi
容器启动脚本startup-all.sh,其他只是示例流程,可以一步步完善补充
#!/usr/bin/env bashecho '=====开始安装simple_ecommerce系统环境====='#echo '=====开始运行mysql====='
#docker-compose -f ../yaml/mysql.yml up -d#echo '=====开始运行nacos====='
#docker-compose -f ../yaml/nacos.yml up -d
#echo '=====nacos正在进行初始化,请等待...====='
#./wait-for-it.sh http://localhost:8848 --timeout=60 -- echo "=====nacos已经准备就绪====="#echo '=====开始运行rocketmq====='
#docker-compose -f ../yaml/rocketmq.yml up -d#echo '=====开始运行redis====='
#docker-compose -f ../yaml/redis.yml up -d#echo '=====开始运行TinyID分布式系统全局ID服务====='
#docker-compose -f ../yaml/tinyid.yml up -d#echo '=====开始运行ELK====='
#docker-compose -f ../yaml/elk.yml up -decho '======================'
echo '=====开始运行后台====='
echo '======================'#echo '=====开始运行ecom-gateway====='
#docker-compose -f ../yaml/ecom-gateway.yml up -decho '=====开始运行ecom-storage-service====='
docker-compose -f ../yaml/ecom-storage-service.yml up -decho '=====开始运行ecom-order-service====='
docker-compose -f ../yaml/ecom-order-service.yml up -decho '执行完成 日志目录: ./log'echo '======================'
echo '=====开始运行前台====='
echo '======================'#echo '=====开始运行ecom\_vue\_web====='
#docker-compose -f ../yaml/ecom\_vue\_web.yml up -decho '======================================================'
echo '=====所有服务已经启动【请检查是否存在错误启动的】====='
echo '======================================================'
容器关闭脚本shutdown-all.sh
#!/usr/bin/env bashecho '=====开始结束运行simple_ecommerce系统服务====='#echo '=====结束运行mysql====='
#docker-compose -f ../yaml/mysql.yml down#echo '=====结束运行nacos====='
#docker-compose -f ../yaml/nacos.yml down#echo '=====结束运行rocketmq====='
#docker-compose -f ../yaml/rocketmq.yml down#echo '=====结束运行redis====='
#docker-compose -f ../yaml/redis.yml down#echo '=====结束运行TinyID分布式系统全局ID服务====='
#docker-compose -f ../yaml/tinyid.yml down#echo '=====结束运行ELK====='
#docker-compose -f ../yaml/elk.yml downecho '=========================='
echo '=====结束后台服务运行====='
echo '=========================='#echo '=====结束运行ecom-gateway====='
#docker-compose -f ../yaml/ecom-gateway.yml downecho '=====结束运行ecom-storage-service====='
docker-compose -f ../yaml/ecom-storage-service.yml downecho '=====结束运行ecom-order-service====='
docker-compose -f ../yaml/ecom-order-service.yml downecho '=========================='
echo '=====结束前台服务运行====='
echo '=========================='#echo '=====结束运行ecom\_vue\_web====='
#docker-compose -f ../yaml/ecom\_vue\_web.yml downecho '=============================='
echo '=====所有服务已经结束运行====='
echo '=============================='
更新镜像脚本update.sh,包含关闭容器、下载新的镜像、启动容器
#!/usr/bin/env bashecho '=====开始更新simple_ecommerce系统镜像====='echo '=====开始关闭运行的容器====='
sh shutdown-all.sh#echo '=====开始更新ecom-gateway====='
#docker pull registry.itxs.cn/simple\_ecommerce/ecom-gatewayecho '=====开始更新ecom-storage-service====='
docker pull registry.itxs.cn/simple_ecommerce/ecom-storage-serviceecho '=====开始更新ecom-order-service====='
docker pull registry.itxs.cn/simple_ecommerce/ecom-order-service#echo '=====开始更新cu\_vue\_web====='
#docker pull registry.itxs.cn/simple\_ecommerce/ecom\_vue\_webecho '=====删除docker标签为none的镜像====='
docker images | grep none | awk '{print $3}' | xargs docker rmiecho '=====开始运行的一键部署脚本====='
sh startup-all.sh
执行测试
# 进入到bin目录下,由于我这里本地有镜像,少了pull流程
sh ./init.sh
查看容器运行情况,容器正常运行
查看nacos服务的注册信息
访问订单接口http://192.168.50.95:4070/create/1001/1001/3 ,返回成功结果
查看订单表和库存表的数据都已更新,至此部署完毕
**本人博客网站 **IT小神 www.itxiaoshen.com