【日常总结】docker容器相互调用,占用服务器带宽解决方案
目录
一、场景:
docker容器相互调用,占用慢服务器带宽,导致netty连接的物联网设备集体掉线
1. 环境
- 阿里云服务器
- 8核64G
- 带宽:10M
- docker:iot平台(微服务)
- docker:mysql
- docker:redis
- docker:mongodb
- 物联网设备使用 netty 连接 iot平台
- 5000+ 台物联网设备在线,每分钟上报数据状态
2. 项目背景:
最近物联网平台需要添加全球时区显示功能,服务器保存的创建/更新时间等相关19个接口,上线后发生网络带宽占满问题
3. 全球时区解决方案
- 方案一:前端修改 -- 浏览器获取当地时区,通过时区编写函数计算19个接口返回的时间
- 方案二:后端修改 -- 用户绑定时区,接口返回时根据时区计算(存在异地登录漏洞问题)
无奈,公司没有前端,只能后端处理
4. 方案二步骤
- 根据请求header中token获取用户名username
- 查询redis,key 为username的user对象(user包含时区)
- 如果没有则根据username查询数据库获取user,并保存到redis中
二、问题
世界时区显示上线后,发现物联网设备掉线80%以上,初步判定是网络问题。查看Grafana 发现网络带宽被占满
阿里云管理后台查看服务器上网络监控带宽也异常
三、产生原因
- 第一:方案二步骤中频繁查询数据库导致占用带宽
- 第二:user对象中包含(设备列表等信息)数据量大,读写redis也占大量带宽
- 第三:最主要原因,docker内部容器间访问,为什么占用外网带宽呢?
- 原因是iot平台连接redis、mysql、mongodb均使用的是云服务外网ip+3个数据库映射的外网端口
四、解决方案
解决问题一:使用redis缓存user对象,降低mysql读写压力
解决问题二:重写查询方法尽量缩小user对象大小
解决问题三:
1. 将iot微服务、redis、mysql、mongodb放入同一个network中
2. 在iot配置文件中连接数据库的ip更换成容器名即可
五、解决步骤
- Step 1:创建 network ,输入命令
docker network create xph-network
- Step 2:docker-compose.yaml文件添加xph-network(iot、mysql、mongodb同样处理)
networks:
default:
external:
name: xph-network
如
- Step 3:重新构建 redis容器,输入命令 (iot、mysql、mongodb同样处理)
#进入redis的docker-compose.yaml根目录
cd /mnt/docker/redis
#重新构建redis
docker-compose up -d --build
- Step 4:查看network详情
docker network inspect xph-network
结果如下
- Step 5:修改 iot 连接数据库配置
将ip修改成容器名(见Step 4中的Name)
- Step 6:重新构建iot即可
#进入iot的docker-compose.yaml根目录
cd /mnt/docker/iot
#重新构建redis
docker-compose up -d --build
六、整改效果
几乎不占服务器带宽
七、延伸:
1. 如果 redis、mysql、mongodb 在云服务器中,不在docker中,iot在docker中,会不会引发带宽占满问题?
2. 如何使用docker-compose安装redis、mysql、mongodb ?
3.安装mysql出现错误 libpthread.so.0- cannot stat shared object- Permission denied,如何处理?