Docker下部署微服务实践踩坑总结

网友投稿 282 2022-10-19

Docker下部署微服务实践踩坑总结

【1】java.net.UnknownHostException

① 问题背景与表现

背景:docker启动应用服务注册到别处eureka(注意是别的服务器的eureka),启动命令格式类似如下:

sudo docker run -d --name mallprovider -p 9122:9122 -v /home/app/fs:/root/fs -v /home/app/provider/server:/usr/local/server/ --privileged=true mallprovide:centos

如何让docker启动的服务注册实例名称为{主机名称:服务名称:服务端口号}或{主机Ip:服务名称:服务端口号}?怎么让已经停掉的容器下线(如何找到正确的服务)?

② docker容器启动的服务注册实例名称正常化

正常我们起一个微服务注册到eureka他的实例id是默认这样的:​​主机名称:服务名称:服务端口号​​​,如果配置​​eureka.instance.prefer-ip-address=true​​​则实例id为:​​主机Ip:服务名称:服务端口号​​​。当然我们也可以通过​​eureka.instance.instance-id​​自定义实例ID格式。

通常配置实例如下:

eureka: client: #客户端注册进eureka服务列表内 service-url: defaultZone: instance: instance-id: ${spring.application.name}:${server.port} prefer-ip-address: true #访问路径可以显示IP地址

指定容器网络模式为host,如下增加​​--net host​​:

sudo docker run -d --name --net host mallprovider -p 9122:9122 -v /home/app/fs:/root/fs -v /home/app/provider/server:/usr/local/server/ --privileged=true mallprovide:centos

为什么要指定网络模式host(这样就不会使用docker的ip):

​​--net=bridge​​​:默认选项,用网桥的方式来连接docker容器。​​​--net=host​​​:docker跳过配置容器的独立网络栈。​​​--net=container:NAME_or_ID​​​:告诉docker让这个新建的容器使用已有容器的网络配置。​​​--net=none​​:告诉docker为新建的容器建立一个网络栈,但不对这个网络栈进行任何配置,所以只能访问本地网络,没有外网。

③ 服务强制下线

通过api强制下线,postman发送delete请求即可

格式如下:

stop 时服务不会从eureka注册中心down!

这里是容器启动的时候通过执行一个脚本来启动服务的,脚本如下:

#!/bin/bashcd /usr/local/server/if [ -f nohup.out ];then rm -rf nohup.outelse touch nohup.out chmod 755 nohup.outfinohup java -jar mallmng-client-1.0-SNAPSHOT.jar &>>nohup.out &tail -f nohup.out

【2】时间差8小时

背景:使用docker启动应用发现时间少了8小时,但是宿主机、docker容器时区时间都正常。

第一反应,很显然是典型的8小时时区问题啊。Linux中检测时间时区几个常用命令如下所示:

[app@beijing-csmf-4 client]$ date +"%Z %z"CST +0800[app@beijing-csmf-4 client]$ dateThu Aug 6 19:17:28 CST 2020[app@beijing-csmf-4 client]$ date -RThu, 06 Aug 2020 19:17:30 +0800[app@beijing-csmf-4 client]$ timedatectl Local time: Thu 2020-08-06 19:18:06 CST Universal time: Thu 2020-08-06 11:18:06 UTC RTC time: Thu 2020-08-06 19:18:06 Time zone: Asia/Shanghai (CST, +0800) NTP enabled: noNTP synchronized: no RTC in local TZ: yes DST active: n/a

检测发现宿主机、docker容器都正常,甚至启动命令时直接同步了宿主机的时区:

#同步时区 ro表示read only 即容器内的数据只允许读-v /etc/localtime:/etc/localtime:ro#同步时间 -v /etc/localtime:/etc/localtime:ro #容器启动命令格式类似如下docker run -d -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro mallprovide:centos

但是如上所示仍旧不可以,最后不得已在启动的时候硬指定了区域:

docker run -d -e TZ=Asia/Shanghai mallprovide:centos

如果自定义了Dockerfile,也可以在Dockerfile里面指定环境变量:

ENV TZ=Asia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

【3】中文乱码

在Dockerfile中添加一行环境配置即可:

ENV LANG C.UTF-8

​​C.utf8=POSIX​​​标准兼容的默认语言环境。只有严格的ASCII字符才是有效的,扩展后允许基本使用UTF-8​​​en_US.utf8​​=美式英语UTF-8语言环境。

一般来说,C指的是计算机,en_US指的是我们中说英语的人(以及其他想要同样行为的人)。

computer的意味着字符串有时更标准(但仍然是英语),因此程序的输出可以从其他程序读取。使用en_US,字符串可以得到改进,字母顺序可以得到改进(可能通过芝加哥风格规则的新规则等)。所以更方便用户,但可能不太稳定。注意:语言环境不仅用于字符串的转换,还用于排序(字母顺序、数字(例如千位分隔符)、货币(我认为可以安全地预测美元和小数点后两位)、月份、星期几等

​​C.utf8=POSIX​​​与​​en_US.utf8​​只是两个地区的UTF-8版本。通常这个不太重要,应该只更改日志和错误消息(如果您使用locale.setlocale())。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java超详细分析泛型与通配符
下一篇:#云原生征文#两种 Docker 镜像打包的常用方式
相关文章

 发表评论

暂时没有评论,来抢沙发吧~