背景
由于历史的原因我们的机器目前还是单机或单集群对应一个业务模块的形式,优势应对爆发式增长扩容方便,成本结算简单。但是随着网民的饱和,相同业务模块下移动流量上涨,PC流量直线下降,很多业务出现了低负载情况,海量服务器运维中只要有1%的低负载(既机器利用率不饱和)规模也是惊人的,在实际运营中低负载+长尾模块机器数量可能达到了25%-30%之间,当然这里也包含业务对流量做了冗余与灾备,但是多个业务模块的灾备就会出现浪费资源的情况。我们从运营中发现了这问题的存在,而运维的核心价值也是通过技术优化,能在(成本、质量、效率与安全)四块做优化达到一个很好的收益,所以从2014年中我们开始做离线业务部署项目。项目的思路是通过高负载业务(离线计算)与低负载业务进行混合部署,提升低负载机器利用率同时逐步下线高负载业务的机器为部门节约机器成本。不过经过半年多的运营中我们也发现了很多问题,离线业务的负载均衡权重统一,但是混合部署后的机器负载不均有高有低,混部的结果经常会导致部分机器高负载影响业务,可以看出这里缺少监控负载的和业务合理的手段,经常导致高负载业务影响低负载业务,接口超时影响用户的情况,这是我们不希望看到的,所以总结经验教训,在2015年上半年我们重新打磨项目开发了离线业务混合部署(琥珀自动调度系统)项目,新项目与老项目相比通过docker技术将混部业务控制在容器中,消除争抢资源对业务影响,同时对容器流量进行根据负载调度,在此基础上实现了分时调度等功能。
负载调度演示(图1)
希望通过技术架构优化与升级来充分扎干硬件资源,为公司节约服务器成本。在开发过程中,相关业务也向我们提出了以下需求(已经实现功能见图2):
- 机器主动与被动下线不影响在线业务;
- 可以方便的查看到系统运行状态;
- 可以连接到容器内部查询日志以及debug程序;
- 沉淀各系统日常数据,并根据沉淀的数据进行戳峰调度。 Web功能展示(图2)
系统访问逻辑及接入方式
根据系统需求,最终访问逻辑分为三部分(用户接入、程序逻辑、和容器生成),每层之前交互通过接口,尽量把复杂的逻辑对上一层透明,见图3。
琥珀访问逻辑图(图3)
琥珀系统提供两种接入方式:
方式1:
通过vip方式接入(推荐),用户不必关心底层系统。首次接入将业务环境打为docker,并测试。后续业务流量通过vip引入计算集群(注:计算集群与首次docker业务环境一致),用户不必关系集群内部机器数量与机器状态,系统保证相应的计算量已经容灾调度。见图4
接入访问逻辑1,图4
方式2:
业务流量通过接口获取动态IP列表,并将流量下发到列表IP中。当机器下线接口主动通知业务流量踢IP。与方式1同样首次接入需要打docker镜像源。见图5
接入访问逻辑2,图5
系统架构
我们通过介绍开源软件(docker + haproxy + confd + etcd+ clip)来完整整个琥珀系统的架构,见图6
琥珀架构图(图6)
其中开源软件(docker + haproxy + confd + etcd+ clip)介绍如下:如下:
Docker (官方网站:https://www.docker.com/)是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化;
HAproxy (官方网站:http://www.haproxy.org/ )为负载均衡软件可以根据IP权重自动分发流量,支持8种负载均衡算法;
Confd(官方网站:https://github.com/kelseyhightower/confd)是一个轻量级配置管理工具,它可以从 etcd, consul, dynamodb, redis,zookeeper 或 env获取最新的数据更新本地模板文件;
Etcd (官方网站:https://github.com/coreos/etcd) 是一款高可用的键/储存储系统,主要用于服务发现与共享配置,同时聚焦;
简单:支持 curl 方式的API (HTTP+JSON); 安全:可选 SSL 客户端证书认证; 快速:单实例可达每秒 1000 次写操作; 可靠:使用 Raft 实现分布式。
etcd是由CoreOS开发并维护使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性。目前很多大项目都使用了etcd,如:Google的Kubernetes、Pivotal的Cloud Foundry、Mailgun、Apache Mesos与Mesosphere的DCOS。除开这些大型项目,在GitHub上还有超过500个项目使用了etcd;
Clip是(cmdb + tools)( http://blog.puppeter.com/read.php?7 )的结合,它将传统的对IP管理维度替换为String维度,其中String格式为(机房-产品-模块-组-端口),通过Clip可以对IP进行打标签,并根据便签对应属性形式区分服务来源。
程序安装
1)HAproxy安装
1 | # wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.14.tar.gz |
HAproxy源码编译安装,启动和关闭建议采用以下方式。
1 | # 启动 |
HAproxy 二进制命令参数
1 | -d 前台,debug模式 |
HAproxy优化(HA为负载均衡,通常会产生大量的time_wait,通过对系统优化尽量降低time_wait对系统影响)
1 | net.ipv4.tcp_syncookies = 1 |
- confd安装
Confd的用途是监听etcd中键值变化,并根据变化更新模块中的数据。(注:这里confd 需要安装在HAproxy相同机器)1
2
3
4
5
6wget https://github.com/kelseyhightower/confd/releases/download/v0.6.3/confd-0.6.3-linux-amd64
# mv confd /usr/local/bin/confd
# chmod +x /usr/local/bin/confd
# /usr/local/bin/confd -version
# mkdir /etc/confd/{conf.d templates}
在conf.d目录中创建haproxy.toml文件。haproxy.toml是confd的配置文件,其作用是当etcd中的数据发生变化,根据haproxy.toml中的(src)模板信息重新生成目标(dest) 模板,最后重新加目标程序配置文件。它支持所有带配置文件的软件,譬如(nginx,apache,haproxy,lighttpd)等。以下为haproxy.toml文件内容。
1 | haproxy.toml |
3) etcd安装
1 | # wget https://github.com/coreos/etcd/releases/download/v0.4.6/etcd-v0.4.6-linux-amd64.tar.gz |
启动
1 | # etcd -name ip_data -addr IP:4001 -data-dir 数据文件地址 -bind-addr IP:4001 |
其中etcd常用参数如下:
1 | -name:节点名称; |
例子:
其中RESET-API例子
增
1 | $ curl -L -X PUT http://127.0.0.1:4001/v2/keys/message -d value="Hello" |
查
1 | curl -L http://127.0.0.1:4001/v2/keys/message |
删
1 | $ curl -L -X DELETE http://127.0.0.1:4001/v2/keys/message |
关于etcd更多信息见:https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/