最近遇到一个比较尴尬的问题,我有一个服务比较占用内存,做一些分析可能会让内存暴涨至十几个 G
,但是服务器的内存又比较小,只有 4G
,导致服务崩溃。
最实在的做法就是服务器扩容,但是自己测试的服务,没必要这么奢侈,但又不想一直重启服务器,官网查找发现 docker
有个 limits
的属性可以使用,本篇以内存限制简述下其使用。
docker run 镜像 -m 限制大小
-m
支持的参数格式
services:
frontend:
image: awesome/webapp
deploy:
resources:
limits:
memory: 50m
limits
支持的其他参数(例如:cpus
, pids
),用法可以上 官网 查看
文件夹目录结构,三个文件在同一文件夹下,文件具体内容往下看
- docker-compose.yaml
- dockerfile
- main.go
go
代码这里给个简单的示例,一个切片,不断的增加切片大小,输出当前占用的内存大小,直到其内存大于 20M
,退出程序,如下:
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
ticker := time.NewTicker(time.Second)
var s []int = []int{1, 2, 3}
for {
select {
case <-ticker.C:
var m runtime.MemStats
runtime.ReadMemStats(&m)
if m.Alloc > 1024*1024*20 {
fmt.Println("程序占用内存大于20M,退出程序")
return
}
fmt.Println("当前程序占用内存大小:", m.Alloc)
s = append(s, s...)
}
}
}
FROM golang:1.18-alpine as gobuilder
WORKDIR /opt
COPY ./main.go ./main.go
RUN go build -o mmm main.go
FROM alpine:latest
COPY --from=gobuilder /opt/mmm ./
ENTRYPOINT ./mmm
docker-compose.yaml
docker-compose.yaml
这里设置当内存超过 6M
时直接停止服务
version: "3"
services:
tl:
build:
context: .
dockerfile: ./dockerfile
container_name: test_limits
deploy:
resources:
limits:
memory: 6m
restart: always
直接执行 docker-compose up
可查看程序输出如下:
可以看到这里已经做出了控制,并没有输出 程序占用内存大于20M,退出程序
就已经退出程序了。
当使用 docker
时,服务器有资源限制,可以考虑使用 docker
内置的 limits
属性来进行 docker
容器的资源限制,由于 docker
有重启机制,这样就不会导致服务器的宕机。
但是最好还是找到资源占用比较夸张的地方,能优化则优化,不能优化则进行服务器扩容。
本篇讲述的是比较特殊的情况,服务重启不影响正常使用。