SpringCloud通过docker-compose部署服务器
文章目录
- SpringCloud通过docker-compose部署服务器
- 〇、阅读条件
- 一、概述
- 二、部署流程
- 1、环境(博主部署环境)
- 2、前置条件
- 3、详细过程
- 3.0、打包模块
- 3.1、dockerfile编写
- 3.2、编写docker-compose.yml(如已有镜像,请跳转到3.5)
- 3.3、构建镜像
- 3.4、将镜像上传值服务器(若无需上传镜像服务器,跳转至3.7,更多配置参考3.5)
- 3.5 、编写docker-compose.yml(通过拉取镜像方式)
- 3.6、构建容器并运行
- 3.7 编写更多模块
- 三、问题
- 1、应用注册到eureka地址错误
- 2、springboot读取不到配置文件
- 四、总结
- 五、参考资料
〇、阅读条件
- 阅读本文需要具备以下知识:
- springcloud
- linux基础
- docker
一、概述
- 随着用户数量的增长,一台服务器往往难以承受巨大的流量,同时,服务的日趋复杂也需要多台服务器分别运行来提高可用性。微服务技术的使用越来越成为当前的主流。
- 一个应用的部署往往需要和系统环境、硬件环境等匹配,而docker的使用则使这个过程更轻松、更安全、更简单。
- docker-compose则可以方便的创建、管理docker镜像和容器。
- 难点:
- 在部署过程中将遇到很多细节问题,如网络互通、配置等,均导致部署失败,后续将提及。
二、部署流程
1、环境(博主部署环境)
- 操作系统:centos7.6
- Docker 20.10.5
- Docker-compose 1.28.6
2、前置条件
- springCloud服务本地测试无误
- 服务器对应端口正常访问,服务器间可正常通讯(可内网,本文为公网案例)
3、详细过程
3.0、打包模块
- 将springboot模块打包为jar包,若需要读取jar包相对路径的配置文件,可在后续编写docker-compose注意(会提到)
- 编写springboot配置文件(非必须)
server:
port: ${SERVICE_PORT:8001}
spring:
application:
name: microUserService # 服务名称,feign访问的依据
cloud:
sentinel: # sentinel配置
transport:
dashboard: ${SENTINEL_URL:localhost}:${SENTINEL_PORT:8888}
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${DB_URL:localhost}:${DB_PORT:3306}/${DB_NAME:db}?serverTimeZone=UTC&allowMultiQueries=true
username: ${DB_USER:root}
password: ${DB_PASSWORD:root}
redis:
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD}
## mybatis 配置
mybatis:
mapper-locations: classpath:**/mapper/*.xml
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
## eureka 配置
eureka:
client:
service-url:
defaultZone: ${EUREKA_URL:localhost}:${EUREKA_PORT:7001}/eureka/
instance:
ip-address: ${HOSTNAME:localhost} # 很重要,配置了这个,使用eureka注册会使用改地址,否则会注册172.xxx.xxx.xxx(容器地址),外部无法访问(学习、测试可写死)
instance-id: ${HOSTNAME:localhost}:microUserService:${service.port} #自定义服务名称信息
hostname: ${HOSTNAME:localhost}
prefer-ip-address: true #显示访问路径的 ip 地址
3.1、dockerfile编写
为每个模块编写对应的Dockerfile
- 容器需要依赖对应版本的java容器
- 需要复制 xxx.jar 文件到容器内路径
- 暴露端口
- 设置启动指令
- 文件相对路径如下,其中config为外部配置的放置位置,也可以和user-service.jar同级。
具体样例如下
# [Dockerfile]
FROM java:8-alpine # java 1.8版本的容器,其他版本请自行搜索
COPY ./user-service.jar /tmp/app.jar # 将user-service.jar文件复制到容器内的/tmp目录下,并重命名为 app.jar
EXPOSE 8001 # 暴露端口(自行决定,需要和应用的运行端口一致)
ENTRYPOINT cd /tmp && java -jar /tmp/app.jar # 配置启动命令,其中 cd /tmp 是为了启动时能够读取jar包外的配置文件(配置文件路径自行百度),若使用配置中心,可后续直接使用配置中心管理配置
3.2、编写docker-compose.yml(如已有镜像,请跳转到3.5)
- 自定义名称
- 配置构建的相对路径
- 挂载文件映射
- 开放权限(较新的docker版本才需要)
- 配置环境变量(建议将springboot 的配置写为环境变量的形式)
- 相对路径如下,其中user-service内结构如3.1
具体如下
# [docker-compose.yml]
version: "3.2"
services:
user-service: # 名字随便取
build: ./user-service # 构造路径(Dockerfile在的路径)
volumes: # 挂载文件映射
- "./user/config:/tmp/config" # 配置文件映射,即3.1中的config,也可以直接挂载配置文件,./user/config/application-prod.yml:/tmp/config/application-prod.yml
- "./user/logs:/tmp/logs" # 日志路径自行定义,前者为服务器路径,后者为容器内路径
ports: # 服务器-容器端口映射
- "8001:8001"
privileged: true # 开放权限,在较新版本docker才需要
3.3、构建镜像
- 将文件上传至服务器
- 进入到 docker-compose.yml所在路径
- 执行指令
docker-compose up --build # 构建镜像 并运行该镜像的容器
- 测试镜像是否正常运行
3.4、将镜像上传值服务器(若无需上传镜像服务器,跳转至3.7,更多配置参考3.5)
将镜像上传值 容器镜像服务器 ,方便其他服务器获取镜像。
博主使用的是腾讯云,若每次都本地上传,速度很慢(大约1MB/s),但是如果从腾讯云的镜像服务器下载,则是飞一般的体验!!!(具体服务器搭建可去腾讯云搜索 容器镜像服务 ,申请个人版(免费))
- 输入
docker images
查看镜像信息 - 重命名该镜像为 服务器+命名空间+镜像仓库:版本 的格式
- 例如服务器名为 ccr.xxx.tencentyun.com
- 命名空间为 mmkj
- 镜像仓库为 app_user-service
- 版本为 latest
- 指令为:
docker tag app_user-service ccr.xxx.tencentyun.com/mmkj/app_user-service:latest
- 输入docker images查看,发现多了一个
- 将镜像推送置服务器
docker push app_user-service ccr.xxx.tencentyun.com/mmkj/app_user-service:latest
3.5 、编写docker-compose.yml(通过拉取镜像方式)
当镜像服务器上有了你的服务器,就可以编写docker-compose.yml直接拉取镜像构建容器了
# [docker-compose.yml]
version: "3.2"
services:
user-service: # 名字随便取
image: ccr.xxx.tencentyun.com/mmkj/app_user-service # 镜像服务器容器地址
volumes: # 挂载文件
- "./user-service/config:/tmp/config" # 配置文件
- "./user-service/logs:/tmp/logs" # 日志文件
ports: # 端口映射
- "8001:8001"
privileged: true # 给与权限
environment: # 环境变量(可以在application.yml中自行配置,非必须)
- SERVICE_PORT=8001 # 服务端口
- SENTINEL_URL=xxx.xxx.xxx.xxx # sentinel路由
- SENTINEL_PORT=8888 # sentinel 端口
- DB_URL=xxx.xxx.xxx.xxx # 数据库相关配置
- DB_PORT=3306
- DB_NAME=dbname
- DB_USER=root
- DB_PASSWORD=root
- HOSTNAME=xxx.xxx.xxx.xxx # 主机地址,强烈建议配置该部分,否则可能导致服务注册至eureka时,使用容器网路的地址(外部无法访问)
3.6、构建容器并运行
同3.3
3.7 编写更多模块
编写更多dockerfile和docker-compose 即可完成服务部署
可通过docker logs -f 容器id
或 docker-compose logs -f
运行查看日志
附mysql和redis的compose 部署文件
version: "3.2"
services:
redis:
image: redis
container_name: docker_redis
volumes:
- ./redis/datadir:/data
- ./redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
- ./redis/logs:/logs
command:
# 两个写入操作 只是为了解决启动后警告 可以去掉
/bin/bash -c "echo 511 > /proc/sys/net/core/somaxconn
&& echo never > /sys/kernel/mm/transparent_hugepage/enabled
&& redis-server /usr/local/etc/redis/redis.conf" # 如需自定义配置文件,请自行百度
ports:
- "6379:6379"
privileged: true
mysql:
image: mysql:5.7.37
environment:
MYSQL_ROOT_PASSWORD: 'root' # 数据库密码
ports:
- "3306:3306"
volumes:
- "./mysql/mysql-5.7.37/data:/var/lib/mysql"
- "./mysql/mysql-5.7.37/mysql/conf:/etc/mysql/conf.d"
privileged: true
三、问题
1、应用注册到eureka地址错误
- Q:浏览器能访问到服务,eureka上注册服务正常,但是其他微服务无法访问到该微服务
- A:考虑在配置文件中配置 ip-address 字段,详见上文3.0中的配置文件
## eureka 配置
eureka:
client:
service-url:
defaultZone: ${EUREKA_URL:localhost}:${EUREKA_PORT:7001}/eureka/
instance:
ip-address: ${HOSTNAME:localhost} # 很重要,配置了这个,使用eureka注册会使用改地址,否则会注册172.xxx.xxx.xxx(容器地址),外部无法访问(学习、测试可写死)
instance-id: ${HOSTNAME:localhost}:microUserService:${service.port} #自定义服务名称信息
hostname: ${HOSTNAME:localhost}
prefer-ip-address: true #显示访问路径的 ip 地址
2、springboot读取不到配置文件
- Q:配置文件与jar包 同级 或 同级的config 文件夹下,但是不生效
- A:有多种可能
- 需要在jar包同级执行shell指令才能读取到配置文件,故dockerfile编写时需加入
ENTRYPOINT cd /tmp && java -jar /tmp/app.jar
- 容器没有权限读写配置文件,创建容器时加入
privileged: true
即可(可用docker exec -it 容器名 /bin/sh
进入容器尝试启动进行测试)
四、总结
- 通过使用 docker 能够很容易的搭建 大量 服务,或许单个服务部署比较麻烦,但当服务有10个甚至100、1000个时,docker的使用将大大减少服务的部署、维护和移植成本。
- 通过环境变量的方式编写配置文件将大大降低镜像的耦合度,提高可用性,多个服务器部署只需要修改docker-compose即可,当然使用 配置中心 也是主流的方式,这里不做阐述。
- 通过docker-compose部署主要步骤为:
- 编写配置文件
- 创建镜像
- 测试运行
五、参考资料