点击上方蓝字关注我们


困境

近期优到达GPS监控后台优化,需要百万并发的测试环境,为此我们开发了一套GPS模拟器,在单台linux系统上可以模拟60000台gps虚拟机,并在树莓派4B上通过了测试,由于操作系统TCP动态端口数限制,无法在一个操作系统下实现百万并发,初期我们想到了两种方案,增加物理机器和在物理机器里跑虚拟机系统,虽然可以实现百万并发的压测环境,但是这样做,会增加部署成本,长期以来,因为成本的问题,一直未完成这一测试环境的搭建,随着互联网技术的发展,一种轻量级的虚拟机docker容器技术进入我们的视线,我们希望借助docker容器技术搭建优到达百万并发压测环境。

最小测试单元

用docker容器运行gps模拟器成为整个压测环境中最小测试单元,实际测试中,我们会用shell脚本批量启动多个运行着gps模拟器的docker容器,以达到我们需要的并发数。

GPS模拟器

为测试优到达后台而独立开发的软件,采用golang开发,可以跨平台运行,它可以创建指定数量的gps虚拟机,每个虚拟机都是单独的维护与服务器的链路,定时上传由指定的协议处理器封装的数据,虚拟机内置gps虚拟模块,随机产生相邻的gps数据,虚拟机定时采集模块的数据,每次上传前会将数据传入协议处理器,由协议处理器打包特定格式,虚拟机接收到数据也会路由到指定的协议处理器分析,该架构支持多协议处理器。

Docker概述

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。

Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。

Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。Docker 的基础是 Linux 容器(LXC)等技术。

在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。

Docker安装

sudo apt-get install docker.iosudo apt-get install docker-compose

构建最小docker镜像

如果曾经做过 VM 管理员,则可以把 Docker 镜像理解为 VM 模板,VM 模板就像停止运行的 VM,而 Docker 镜像就像停止运行的容器,作为一名研发人员,则可以将镜像理解为类(Class),容器理解为类的实例,Docker容器是镜像的运行实例,可以使用命令行界面命令运行,启动,停止,删除容器。

 

镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包。

因为容器的设计初衷就是快速和小巧,所以镜像通常都比较小,我们需要构建一个能自启动gps模拟器的最小镜像,以此来生成我们压测环境中最小测试单元docker容器,Alpine Docker 镜像相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB)。

编译GPS模拟器

export GOPATH=~/Project/go/uddgpsServer/GpsSimulatorProg

cd ~/Project/go/uddgpsServer/GpsSimulatorProg/src/GpsSimulator

export CGO_ENABLED=0

export GOOS=linux

go build -a -installsuffix cgo -o GpsSimulator .

构建Docker镜像

在Dockerfile文件中,我们用Alpine Docker 镜像作为父镜像,并对系统做了些必要的设置,如修改动态端口数范围以及同一时间打开的文件数等,最后将GpsSimulator 文件加入镜像并设置开机自启动。

Dockerfile文件:

FROM alpine:3.6

 # 设置locale

 ENV LANG en_US.UTF-8

 ENV LANGUAGE en_US:en

 ENV LC_ALL en_US.UTF-8

 ENV TZ=Asia/Shanghai

 RUN echo 'net.ipv4.ip_local_port_range = 1024 65535' >> /etc/sysctl.conf

 RUN ulimit -n 65411

 ADD GpsSimulator /

 CMD ["/GpsSimulator"]

用以下命令生成目标镜像

chmod 777 GpsSimulator

docker build -t gps-simulator:new .

在终端输入docker images,查看到我们新建的镜像大小才7mb左右

批量启动容器

以下是批量启动50个容器的shell脚本,在for循环中启动容器指定了gps-simulator:new镜像、服务器地址、gps虚拟机初始设备号,以及设备数、天琴协议处理器等参数

#!/bin/bash

n=800000001

C=20000

time1=5s

for((i=1;i<=50;i++));

do

docker run -d --network=bridge0 gps-simulator:new /GpsSimulator -DeviceProtocolType tianqin -DevicesCount $c-DevicesStartNo $n -ip 192.168.1.76 -port 9000

let n+=$c

sleep $time1

done

在上面的启动容器参数中,有一个network参数,表示指定bridge0虚拟网卡,启动后的容器由该网卡分配ip地址。

Docker网络

Docker 容器默认使用Bridge模式的网络,原理是在宿主机上虚拟出一块网卡docker0,然后所有容器会桥接在这块网卡的网段上。默认情况下容器能访问外部网络,但外部网络无法访问容器,需要通过暴露容器端口的方式(docker run -p)让外部网络访问容器内的服务。

本次实验中,我们创建了一个自定义网络,也是Bridge模式

docker network create --subnet=192.168.5.1/24 bridge0

服务器的配置

本次实验,后台是一个简单的tcp服务器,只负责接受tcp链接并输出响应,与最小压测单元Docker容器运行在一台服务器上,服务器的配置如下:

品牌:DELL/戴尔

型号:R730XD

CPU:48核心 E5-2678V3*2个

内存:128G内存(单条16G)

存储:1T SAS硬盘 希捷品牌*8个

对于绝大部分 Linux 操作系统, 默认情况下确实不支持百万并发,所以我们要对系统进行设置才能满足百万并发的正常运行

/etc/sysctl.conf 添加

fs.file-max= 10485760  

net.ipv4.ip_local_port_range= 1024 65535  

以上表示系统可以打开的最大文件数10485760  ,动态端口数范围1024至65535

/etc/security/limits.conf 修改:

soft nofile 1048576  

hardnofile 1048576  

以上表示一个进程可以打开的文件数

开启百万并发测试

启动后台

启动批量创建docker容器的脚本

每启动一个容器会返回一个容器ID

用docker ps命令输出当前系统中运行的容器

进入docker容器内部

docker attach modest_albattani &

上图是名称为modest_albattani的docker容器内gps模拟器中各个gps虚拟机发送数据后,收到的服务器应答信号,gps虚拟机是每10秒上报一次位置。

我们在看看容器的虚拟网卡

下图是容器的网桥,可以看到所有容器数据收发都经过我们创建的自定义网桥

在一段时间内,我们随机进入不同的容器,观察gps模拟器输出信号,非常稳定,本次测试顺利完成。

停止测试需要先停止容器,在删除容器

停止所有容器:docker stop $(docker ps -aq)

删除所有容器:docker rm $(docker ps -aq)

测试报告


ZooKeeper典型应用场景


Linux终端美化工具(oh-my-zsh)


接入与身份认证技术概述


Spring Boot接口如何做限流


戳这儿

点个在看你最好看

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐