赞
踩
注:
1)docker 好在容器编排和部署于机器无关(简化部署),并不是性能;因其虚拟网络和容器化环境,其性能能砍到1/4~1/2;
例如:不建议在 Docker 中跑 MySQL(其中关于性能损耗部分是有参考性,其他部署描述有错误)
https://www.zhihu.com/question/627105598/answer/3261151560
2)目前(2023-12-22)redis+消息队列+jar可能5000/qps,放在docker 闭眼盲猜1000/qps
3)docker企业版本是支持大型机;以前在大型机操作系统上虚拟操作系统,现在在其上虚拟容器;
,所有真实并发在专业机器上性能有待考证(专业资料不好找):
https://developer.aliyun.com/article/193973
4)所以docker适用于中大型企业负载均衡管理应用(或者一定的降低部署难度),不适合小企业;且应用负载均衡节点数大于5;
5)由于docker与操作系统的隔离性,所以程序要读取部署机器上的相关硬件设备信息,实现困难;
即使折中处理,基本上不符合docker安全使用规范;
教程: https://doracoin.cc/504
注:dnf替代yum是早晚的事,所以就不找低版本教程了
注:镜像:存放在本地或远程仓库的docker打包文件叫镜像,仓库:集中存放和管理镜像的地方;
容器:镜像启动后生成的虚拟容器(含成功和失败的)
列出本地镜像:docker image ls 查找mysql镜像:docker search mysql 拉取镜像 mysql镜像:docker pull mysql:8.2.0 删除镜像:docker rmi -f mysql:8.2.0 查找镜像版本:1、命令查找:命令特别长,2、官网查找(推荐):hub.docker.com;3)或者百度镜像版本号 查看本机存在的容器:docker ps (运行的)或docker ps -a (全部的,含停止运行的) 查看镜像日志(正在运行的,含状态异常) docker logs -f 镜像名 启动容器:docker run --name 容器别名 -d 镜像:版本号 重启容器:docker restart 容器别名 停止容器:docker stop 容器别名 删除容器:docker rm -f 容器别名 进入镜像内 docker exec -it 容器别名 /bin/bash 退出:exit;
$ docker stop $(docker ps -a -q) : 停止所有容器 $ docker start $(docker ps -a -q) : 启动所有容器 $ docker rm -f $(docker ps -a -q) : 删除所有容器 $ docker ps :列出当前所有正在运行的container $ docker ps -a :列出所有的container(包含历史,即运行过的container) $ docker kill id : 杀死容器 $ docker stop id : 停止容器 $ docker start id : 启动容器 $ docker restart id : 重启容器 $ docker rmi -f <image ID>: 删除一个或多个镜像 image $ docker rm -f id : 删除指定 镜像 image $ docker rm -f <container...> : 删除一个或多个container $ docker rm -f `docker ps -a -q` : 删除所有的container $ docker rm `docker ps -f "status=exited" -q` : 删除停止的容器 $ docker kill`docker ps -a -q` :停止所有container $ docker exec -it ng /bin/bash :进入容器 $ docker cp ng:/etc/nginx/nginx.conf /data/nginx.conf :拷贝容器内文件到外部 $ docker logs -f 容器名称 :查看容器日志
全命令补充,菜鸟:https://www.runoob.com/docker/docker-command-manual.html
(2019年后未更新,学的快):http://www.zhaowenyu.com/docker/dockerbackground/docker-history.html
# 1、mysql(最新镜像 2023-12-15):8.2.0 ,下载镜像:
docker pull mysql:8.2.0
# 2、redis(最新镜像 2023-12-15):7.2.3 ,下载镜像:
docker pull redis:7.2.3
# 3、rabbitmq(最新镜像 2023-12-15:3.13.0-rc),下载镜像:
# 不带控制台的镜像
docker pull rabbitmq:3.12.10
# management带控制台的镜像
docker pull rabbitmq:3.12.10-management
# 4、jdk(最新镜像 2023-12-15:openjdk:21),下载镜像(项目使用):
docker pull openjdk:17
# 5、nginx(最新镜像 2023-12-15:1.25.3),下载镜像:
docker pull nginx:1.25.3
注:1)若镜像拉去速度慢,可注册阿里云账号,用自己的阿里云镜像仓库拉去镜像(目前:2023-12-22 阿里镜像仓库免费-镜像空间)
2)mysql、redis、消息队列等高io应用,对应实体机一般要配置优化(例如:打开文件句柄数);高并发下,其实不建议容器部署(非专业硬件,例如:专门虚拟化机器,也有适配容器的 jvm: 9j);且mysql、redis、消息队列等高io应用,这些也属于分布式应用中的有主服务;
3)目前(2023-12-22) jvm: 9j 配置麻烦(ibm掺和了),且未做并发压测(jmeter压测),所以本教程采用常规方案-openjdk;
4)若拉取镜像报禁止,设置DNS为8.8.8.8(谷歌免费提供的DNS服务);拉取超时,则设置国内镜像源:https://developer.aliyun.com/article/1044251
mkdir -p /data/mysql8
chmod 777 /data/mysql8
touch /data/mysql8/my.conf
my.conf文件内容
注:该配置未优化,优化见(含:内存:32g linux和64 g windows mysql的配置):
https://blog.csdn.net/qq_26408545/article/details/124114793
[mysql] #设置mysql客户端默认字符集 default-character-set=UTF8MB4 [mysqld] #linux 需配置,忽略表名大小写 lower_case_table_names=1 #设置3306端口 port=3306 #允许最大连接数 max_connections=200 #允许连接失败的次数 max_connect_errors=10 #使用“caching_sha2_password”插件认证 default_authentication_plugin=caching_sha2_password #服务端使用的字符集默认为8比特编码的latin1字符集 character-set-server=UTF8MB4 #开启查询缓存 explicit_defaults_for_timestamp=true #创建新表时将使用的默认存储引擎 default-storage-engine=INNODB #等待超时时间秒 wait_timeout=60 #交互式连接超时时间秒 interactive-timeout=600 #binlog日志保留10天的 binlog_expire_logs_seconds=864000
注:mysql镜像日志未挂在出来:日志默认输出到docker镜像的控制台,查看日志用 docker logs -f mysql8
踩坑:运行镜像:可添加参数运行远程访问
# 研究镜像日志默认输出为终端log_error = stderr
# 即 -v /data/mysql8/mysqld.log:/var/log/mysqld.log 无意义,所以就未独立日志
docker run --name mysql8\
-p 3308:3306 \
-v /data/mysql8/my.cnf:/etc/my.cnf \
-v /data/mysql8/data:/var/lib/mysql \
-e TZ=Asia/Shanghai \
-e MYSQL_DATABASE=hy_cost_grain \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_ROOT_HOST='%' \
--restart=always \
--privileged=true \
-d mysql:8.2.0
补充启动参数:-e 参数=值
# 数据库时区 TZ: Asia/Shanghai # 开启远程访问 MYSQL_ROOT_HOST: '%' # 等同于 -e MYSQL_ROOT_PASSWORD指定root的登录密码 MYSQL_ROOT_PASSWORD: 123456 #- MYSQL_ROOT_PASSWORD=123456a? #- MYSQL_ALLOW_EMPTY_PASSWORD='no' # 这里这个指令compose启动成功后会自动创建名为docker的数据库 MYSQL_DATABASE: hy_cost_grain #- MYSQL_DATABASE='ecdb02' # 此处就是相当于 mysql create user,创建了数据库的登录用户 #- MYSQL_USER='ecuser' #- MYSQL_PASSWORD='123456a?'
docker logs -f mysql8
注:若有问题:
#查看容器运行情况
docker ps
# 停止
docker stop mysql8
# 删除
docker rm -f mysql8
# 重启
docker restart mysql8
# 产看端口占用
nestat -ntlp | grep 占用端口号
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
# 注:如果用的是阿里云的话,也需要配置 阿里云控制台防火墙
工具链接数据库,操作:略
操作:略
dbeaver导入数据:数据库右击->选择恢复数据->弹窗中 额外的命令参数添加:–default-character-set=utf8
例如:假设需要开启mysql远程访问
注:启动mysql镜像时,已开启允许远程访问,本操作仅是知识补充
docker exec -it mysql8 /bin/bash
进入镜像:像正常linux操作即可
注:很多镜像只含基础命令,例如vim,ll等不存在,可自己安装:一般采用rpm源码包安装(保证容器体积不至于太大)
# 本机访问mysql:mysql -u账户 -p密码
mysql -uroot -p123456
#切换数据库
use mysql;
#开启远程访问
alter user 'root'@'%' identified with caching_sha2_password by '123456';
#刷新权限
flush privileges;
#退出mysql命令窗口
quit; 或者 exit;
#退出容器
exit;
注:
1)redis号称单机20w/qps,固一般保证并发,实体机器+本机和机器配置优化+(条件可以:再建个哨兵保证高可用)
2)性能评估按照10w/qps用;redis6 有多线程参数-启用相关参数是真的能到
3)硬件:多核4~16核 8~16g内存 或者 低配3台 4核8g内存的哨兵(低配:rdb文件-不建议超过4g,高配rdb建议超过:7g,高配更好-事少(16核16g也是其顶配了);
4)应用链接池lettuce,其他的连接池各种崩溃,例如:jedis-操作接口简单、redission-分布式限流等解决方案;
mkdir -p /data/redis/data
mkdir -p /data/redis/logs
touch /data/redis/redis.conf
redis.conf 文件内容如下
注:redis 具体的优化看此篇文章中的优化部分:https://blog.csdn.net/qq_26408545/article/details/132696788
#暂不设置密码,启动容器也可设置密码 #requirepass 123 maxclients 10000 #如果要外网访问,请注释掉下面,或者修改为0.0.0.0,保险起见,也可以把protected-mode设置为no bind 0.0.0.0 protected-mode no #注意修改这里端口,根据你实际暴露端口情况配置 port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 #注意这里要把后台运行设置为no,避免docker后台运行冲突 daemonize no supervised no pidfile /docker/redis/redis.pid loglevel notice databases 16 always-show-logo yes save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb #注意修改这里的目录为容器内目录,默认reids进来是在/data/目录 dir /data/redis/data #日志输入指定路径 #logfile "" replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no replica-priority 100 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no #注意修改这里的配置,yes开启持久化,no关闭持久化 appendonly yes appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes
注:redis 和数据库一样吃内存,他多的时候甚至占12G,redisDb文件在
配置了日志未映射出来,所以放弃了
# 日志配置放弃: -v /data/redis/logs:/data/redis/logs \
docker run \
--restart=always \
--log-opt max-size=100m \
--log-opt max-file=2 \
-p 6379:6379 \
--name redis7 \
-v /data/redis/conf/redis.conf:/etc/redis/redis.conf \
-v /data/redis/data:/data/redis/data \
-d redis:7.2.3 redis-server /etc/redis/redis.conf \
--appendonly yes \
--requirepass ''
略 Another-Redis-Desktop-Manager 链接看一下
注:1)rabbitmq-金融领域消息队列:(2023-12-22)单机优化配置的 性能 1w/qps;其它号称10w/qps的消息队列,一般给数据中心传递数据用,不用做应用领域;当时集群怕问题,就1个应用对应1个队列;(并发大)
2)消息队列堆积100w后各种问题,磁盘占用100G,所以部署应用+队列:50G+200G挂载盘+独立文件服务:8核+16G;有台单独处理任务的windows server(部署含队列中间件) 16核+32G(定时处理各种数据的 + 一些手工处理数据的 + 一些处理特殊任务的)
3)应用的rabbitmq链接池配置,要压测通过,加参数保证高并发,连接池不崩溃;
4)没系统研究过,配置优化不知道。网传(opp、vivo、小米:其中的2家)-迁移它的环境很麻烦,只能停机等消费完,且迁移步骤麻烦;
mkdir -p /data/rabbitmq/{data,conf,log}
chmod -R 777 /data/rabbitmq
注:启动命令,未挂在配置目录 -v /data/rabbitmq/conf:/etc/rabbitmq
网上未找到专业的关于rabbitmq配置优化(且配置空,无法启动控制台)
docker run -d --privileged=true --name rabbitmq3.12.10 \ --hostname localhost \ -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=12345678 \ -v /rabbitmq/data:/var/lib/rabbitmq \ -v /data/rabbitmq/log:/var/log/rabbitmq \ -v /docker-work/rabbitmq/conf:/etc/rabbitmq \ -p 5672:5672 -p 15672:15672 \ -d rabbitmq:3.12.10-management 参数说明: –restart=always :表示随着Docker容器重启(~~可加可不加~~ ) --hostname :主机名 (~~可加可不加~~ ) rabbitmq节点名称 -e :指定环境变量 RABBITMQ_DEFAULT_VHOST:默认虚拟机名; -e :RABBITMQ_DEFAULT_USER:默认的用户名; -e :RABBITMQ_DEFAULT_PASS:默认用户名的密码,rabbitmq默认账号和密码是guest -p :端口映射 -v :文件挂载 -d :表示后台运行 –name rabbitmq :表示启动后的容器实例名称为rabbitmq
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --reload
# 注:如果用的是阿里云的话,顺便开放下这两个端口,不然没法访问
netstat -ntlp|grep 5672
浏览器访问:http://IP:15672/
注:(2023-12-22)我们当时压测1w/qps就各种问题,理论2w/qps;号称10w/qps这货;尴尬的是(jdk15+,16核32g,优化参数的tomcat)单个jar可达到5000~7000/qps;不过nginx是占用内存小,但cpu耗用高,优化其多线程参数;因没能力优化-就外采的一个负载均衡中间件(基于nginx的);
仅参考教程前半部分生成配置文件,文档也付相关配置和目录
教程:https://blog.csdn.net/longzaizai_/article/details/130675135
#nginx配置文件2个,日志目录2个文件,html容器路径映射出来
docker cp nginx01:/etc/nginx/nginx.conf /data/nginx/
docker cp nginx01:/etc/nginx/conf.d /data/nginx/conf/
docker cp nginx01:/usr/share/nginx/html /data/nginx/html
docker cp nginx01:/var/log/nginx/ /data/nginx/logs/
注:html的路径实在容器下:所以开头:/usr/share/nginx/html/
** 网络要用主机ip,因为localhost 是指向容器 **
# 省去不必要的配置代码 server { listen 80; # 本服务监听的端口号 server_name localhost; # 主机名称 client_max_body_size 600m; client_body_buffer_size 128k; proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; proxy_buffer_size 64k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; location / { # root 规定了通过监听的端口号访问的文件目录 root /usr/share/nginx/html/grain/dist; # 配置资源重新跳转,防止刷新后页面丢失 try_files $uri $uri/ /index.html; # index 规定了该目录下指定哪个文件 index index.html index.htm; } # 配置后端接口的跨域代理 # 对于路径为 "prod-api 的接口,帮助他跳转到指定的地址 location /prod-api/ { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 本机上运行的后端接口 proxy_pass http://localhost:8080/; } location /status{ stub_status on; } }
docker run --name nginx \
-p 80:80 -p 443:443 \
-v /data/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /data/nginx/logs:/var/log/nginx \
-v /data/nginx/html:/usr/share/nginx/html \
-v /data/nginx/conf:/etc/nginx/conf.d \
--privileged=true \
-e TZ=Asia/Shanghai \
-d nginx:1.25.3
注:jar包尽量无主服务方便扩容(token+redis 认证变无主,独立文件、数据库让其于应用无关),负载均衡不行买现成的;消息队列目前这玩意高并发坑多;rocketmq 并发高,吃资源太厉害了;
分布式部署jar,得将jar打成镜像,方便一键部署;
注:因为容器部署问题
或者将DockerFile也上传linux相应路径
#基础镜像使用jdk17 FROM openjdk:17 #作者 MAINTAINER kly # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp VOLUME /tmp # 将jar包添加到容器中并更名 ADD hy-admin.jar /app.jar # 运行jar包 RUN bash -c 'touch /app.jar' # 为了缩短 Tomcat 启动时间,添加一个系统属性指向 “/dev/./urandom” 作为 Entropy Source ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] #ENTRYPOINT ["nohup","java","-jar","/data/app/hy-admin.jar","&"] #暴露9000端口 EXPOSE 9000
注:命令最后面有 空格 和 点符号
# 命令后面有个 空格 .
docker build -f DockerFile -t app:1.0 .
docker run -d --name app -p 9000:9000 app:1.0
docker logs -f app:1.0
先了解:1)docker网络命令:https://www.phpsdk.cn/plug/news/show.html?id=12824
Docker 网络之前,我们有必要先来了解一下这几种网络模式都是什么意思。
Docker中容器间的通信方式
1.通过容器ip访问
容器重启后,ip会发生变化。通过容器ip访问不是一个好的方案。
2.通过宿主机的ip:port访问
通过宿主机的ip:port访问,只能依靠监听在暴露出的端口的进程来进行有限的通信。
3.通过link建立连接(官方不推荐使用)
4.通过 User-defined networks(推荐)
例子:
# 1、创建 docker 虚拟网络 docker network create my-network # 查看网络情况: docker network ls # 2、所有容器通信添加2个参数(建议启动时添加):--network 虚拟网络网卡 --network-alias 容器在虚拟网路别名 # 之后 springboot应用 可通过 容器的虚拟网路别名, 直接访问mysql docker run -itd --name mysql --network my-network --network-alias mysql \ -e MYSQL_ROOT_PASSWORD=root mysql:5.7.24 # 3、对于已经创建好的容器: 如果容器已创建好但是之前没有指定自己的网络,则使用下面命令修改: docker network connect --alias mysql my-network mysql # 第一个mysql是网络别名 第二个mysql是容器名 # 4、通过网络别名测试访问 # 进入web容器,使用ping命令测试 docker exec -it mysql /bin/bash 容器> ping mysql
参考教程:https://blog.csdn.net/cjbfzxz/article/details/106652867
创建 docker 虚拟网络
docker network create my-network
#查看网络情况:
docker network ls
docker network connect --alias mysql8 my-network mysql8
docker network connect --alias redis7 my-network redis7
docker network connect --alias rabbitmq3.12.10 my-network rabbitmq3.12.10
注:修改nginx配置为后台应用地址:假设springboot 应用的虚拟网路别名为:jar-grain-9000 – 类型-项目-端口号
# 重启
docker restart nginx
# 俩接网络
docker network connect --alias nginx my-network nginx
例如mysql的链接
url: jdbc:mysql://${DB_HOST:mysql8}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。