1. 选择 Repo

nameserver: rocketmqinc/rocketmq-namesrv

broker: rocketmqinc/rocketmq-broker

查找过程中发现 rocketmqinc 官方还有一个单独的 rocketmq 仓库,但是已经很久没更新了,所以选择比较新的

2. 目录挂载映射

默认 rocketmq 日志和存储放在 home 目录,用户是 root,配置如下:

namesrv:

本机容器
/d/docker/mq/logs/root/logs
/d/docker/mq/store/root/store

broker:

本机容器
/d/docker/mq/logs/root/logs
/d/docker/mq/store/root/store
/d/docker/mq/conf/root/conf

这里一开始犯了个错误,把自定义的 broker.conf 所在 conf 目录映射到了 rocketmq 的 workspace 里,造成 conf 目录被替换,而我的配置文件只有一个 broker.conf,造成缺少其他配置文件无法启动 broker 的问题。

3. 配置 broker

本机的 conf 目录下建立自定义的 broker.conf 配置:

brokerClusterName = DefaultCluster
brokerName = broker-syf
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
brokerIP1=10.208.203.69

这里需要注意的是 brokerIP,需要指定为你的内/外网 ip。比如我连接的网络本机内网 ip 是 10.208.203.69,后面才可以用 localhost 访问,否则默认的 172.x.x.x 是容器内网 ip,离开容器在外面是访问不到的。

同时在 docker-compose.yml 文件中手动指定我们刚刚创建的 broker.conf,根据映射关系在容器中的路径是 /root/conf/broker.conf,启动命令配置如下:

sh mqbroker -n namesrv:9876 -c /root/conf/broker.conf

完整的 docker-compose.yml 文件如下:

- 阅读剩余部分 -

首先生成一个 height*weight*3 的全零 numpy 矩阵,dtype 为 uint8。

将其 RGB 中的绿色(G)通道设置为 255(纯绿色)。

然后使用 Pillow 将其保存到本地图片,最后调用 ffmpeg 命令生成对应视频。

ffmpeg 命令行参数:

ffmpeg -framerate 24 -loop 1 -i .\cache.png -pix_fmt yuv420p -t 39.540 -vcodec libx264 green_1080p24.mp4 -y

完整代码:

- 阅读剩余部分 -

图像分割任务中,input 和 target 都是图片,此时做数据增广时如果用到随机变换,例如随机翻转和旋转,则需要保证两者随机值相同,否则分割 label 就不准确。

例如变换:

self.transform = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(90),
    transforms.CenterCrop(480),
    transforms.ToTensor(),
    transforms.ToPILImage()
])

在使用时如果直接

image = self.transform(image)
bulb = self.transform(bulb)

则输入图片和 label 会产生不同的翻转/旋转角,造成数据不对应的问题。

- 阅读剩余部分 -

在阿里云 vgn5i 实例上部署深度学习环境,服务器系统为 Ubuntu 16.04

1. 安装 GRID 驱动

https://help.aliyun.com/document_detail/118852.html

按照此文档安装 GRID 驱动,注意 vGPU 需要使用专用的 GRID 驱动,安装普通驱动是无法识别虚拟卡的,且安装完驱动之后需要按照文档获得许可才可以实际使用 CUDA。在没有获得许可之前,虽然torch.cuda.is_available()返回的是True,但实际上到了代码中model.to(cuda)这一步还是会报RuntimeError: CUDA error: all CUDA-capable devices are busy or unavailable错误。

2. 使用 systemd + gunicorn 部署项目

这一步创建了个没有 sudo 权限的用户ob来跑项目,保证生产环境上服务器安全。代码放在/home/ob/ob_cuda_server目录下。坑点在于 systemd 中 anaconda 环境的切换,解决办法就是在 service 配置里指定环境变量 PATH 就直接是对应的 conda 下的 env/bin 目录,就不会用冲突了。

2.1 安装项目依赖

按照此文档下载 anaconda 并配置国内源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/

创建虚拟环境:

conda create -n ob_prod python=3.6

切换到此环境:

conda activate ob_prod

通过 conda 安装 torch:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

通过 pip 安装其他依赖:

pip install flask opencv-python numpy

其中 opencv-python 可能会缺少一些系统 so 库,稍后运行程序时如果提示缺少某 lib 文件则需要使用 apt 安装对应的库。

2.2 配置生产环境

安装 gunicorn 进行生产环境部署以提供更好的性能:

pip install gunicorn

安装好之后可以使用gunicorn -w 8 -b 0.0.0.0:9001 main:app来部署项目看看效果

另开一个会话使用 curl 测试服务是否在线:

(base) syf@obulb:~$ curl localhost:9001
ob cuda server online!

可以看到已经返回了自定义的首页信息

确认可以运行后按Ctrl+C停止,后面用 systemd 来启动管理守护进程。

为了守护项目进程,让其后台自启运行,需要写一个 service 配置将 gunicorn 写入 systemd 服务。

新建/etc/systemd/system/ob_cuda并编辑:

[Unit]
Description=ob cuda server
After=network.target

[Service]
User=ob
WorkingDirectory=/home/ob/ob_cuda_server
Environment="PATH=/home/ob/anaconda3/envs/ob_prod/bin"
ExecStart=/home/ob/anaconda3/envs/ob_prod/bin/gunicorn -w 8 -b 0.0.0.0:9001 main:app
# gunicorn 多线程加载模型可能会造成显存不足或其他问题,如果用此部署后有问题则直接跑 flask,就可以解决:
# ExecStart=/home/ob/anaconda3/envs/ob_prod/bin/python main.py

[Install]
WantedBy=multi-user.target

保存后重新加载 systemd:

sudo systemctl daemon-reload

写成 systemd 服务后就可以直接用 systemctl 来管理服务了:

设置开机启动:

systemctl enable ob_cuda

查看服务状态:

systemctl status ob_cuda

重启服务:

systemctl restart ob_cuda

对 python 的 Flask、FastAPI 和 Spring Boot 集成的简单接口做速度对比,返回 json 格式的当前时间戳:

{
    "timestamp":1584416801569
}

同时把某个11位时间戳 json string 写死在 index.html 里,测试 Nginx 的并发量。虽然一个静态资源一个动态计算没有可比性,但是为了体现性能差距,还是把 Nginx 的并发拿来做对比。

- 阅读剩余部分 -