写点什么

构建一套适合微服务的高可用架构

用户头像
环信
关注
发布于: 2021 年 03 月 01 日

随着近几年微服务与云计算的飞速发展,机器由物理机逐步变为了虚拟机,应用服务由庞大的单体应用逐渐变为了若干个微服务联合组成的应用集群,更新迭代的速度成倍上涨,传统的部署模式已无法满足开发日常更新需求,需要一套适合微服务的管理架构。


技术栈及文档


资源调度框架 MESOS


应用编排平台 Marathon


nginx 动态修改 upstream dyups


nginx 动态修改 upstream upsync


使用 Mesos 进行机器资源管理


首先,是机器资源的管理。在微服务的架构中,原有的单体服务被拆分成了一个个独立单元的应用程序,这些服务体量较小,可以独立运行在配置较小的机器上。为了故障隔离,我们会尽可能的把这些服务部署在不同的虚拟机上,这样机器的数量会成倍增加。对于运维来说,每个新服务部署时,需要先查看现有机器的剩余资源是否满足新服务的需求,有时可能因为评估不准确造成来回扩容、迁移,或者资源浪费。


开始时,我们的架构可能时这样的


1.png


为了解决上面的问题,可以使用 MESOS ( 布式资源管理框架),它可以 让我们像用一台电脑(一个资源池)一样使用整个数据中心。

mesos 部署时分为 master 和 agent 两个角色,当然,你可以在同一台机器启动它们。


安装 Mesos 前需要安装 zookeeper,mesos 使用 zk 实现高可用和选举,包括一个 master leader 和 几个备份 master 避免宕机。


Mesos master  负责管理各个 Framework 和 Slave,并将 Slave 上的资源非配给各个 Framework。

Mesos agent   负责管理本节点上的各个 Mesos Task,为各个 Executor 分配资源 (低版本为 mesos-slave)。


$ cat > /tmp/bintray-mesos-el.repo <<EOF#bintray-mesos-el - packages by mesos from Bintray[bintray-mesos-el]name=bintray-mesos-elbaseurl=https://dl.bintray.com/apache/mesos/el7/x86_64gpgcheck=0repo_gpgcheck=0enabled=1EOF $ sudo mv /tmp/bintray-mesos-el.repo /etc/yum.repos.d/bintray-mesos-el.repo $ sudo yum update $ sudo yum install mesos $ tree /etc/mesos-master/etc/mesos-master/|-- hostname|-- ip|-- log_dir|-- quorum   # quorum > (number of masters)/2`-- work_dir $ tree /etc/mesos-agent/etc/mesos-agent/|-- containerizers  # 容器类型,默认 mesos,可以添加 docker,如: mesos,docker|-- hostname|-- ip|-- log_dir|-- master           # master 地址,格式为 host:port 或 zk://host1:port1,host2:port2,.../path 或 file:///path/to/file|-- resources       # 设置总资源大小,可以设置小些来预留更多机器资源`-- work_dir $ cat /etc/mesos/zk  # 设置 mesos 在zk 中的存储目录zk://192.168.100.9:2181,192.168.100.110:2181,192.168.100.234:2181/mesos $ systemctl start mesos-master$ systemctl start mesos-slave
复制代码

当 mesos 服务启动后,agent 会向 master 节点汇报机器资源,包括 CPU、内存、磁盘等。 当我们要发布一个服务时,只需要设置这个服务的 CPU、内存、磁盘参数, mesos master 会自动帮我们选择有足够资源的机器去运行,如下图


2.png


我们将微服务的启动都交给 Mesos 管理,这样我们只需要关注整体资源即可。MESOS 提 供了 UI 界面,可以直接访问 mesos master 的 5050 端口,查看集群资源使用情况。 总体使用情况 及 Agent 节点使用情况


3.png


4.png


完成以上后,我们的架构变成了这样


5.png


使用 Marathon 进行微服务管理 


Marathon 是建立在 Mesos 上的私有 PaaS 平台。它能自动处理硬件或者软件故障,并确 保每个应用程序都"永远在线"。 我们使用 Marathon 管理微服务有以下优势 1. 支持容器和非容器,不受限于服务启动类型,操作系统版本等。 2. 漂亮而强大的用户界面,可以在 UI 上进行快捷方便的应用程序配置 3. 支持约束条件,例如允许一个 mesos agent 节点只运行一个应用程序。 4. 支持健康检查。可以配置 http、https、tcp、command 类型的监控检查。 5. 完整的 REST API,易于集成和编写脚本。这个对于后期集成来说至关重要。


# Add the repository$ sudo rpm -Uvh http://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-2.noarch.rpm # Install packages$ sudo yum -y install mesos marathon # marathon  and mesos zk path$ cat /etc/default/marathon MARATHON_MESOS_USER="root"MARATHON_MASTER="zk://192.168.100.9:2181,192.168.100.110:2181,192.168.100.234:2181/mesos"MARATHON_ZK="zk://192.168.200.9:1181,192.168.100.110:2181,192.168.100.234:2181/marathon" systemctl start marathon
复制代码

启动后,直接访问 marathon 的 8080 端口,就能看到一个漂亮强大的 UI 界面。


6.png


我们以 springboot 应用为例,在 marathon 上创建一个应用程序


7.png


8.png


9.png


10.png


当我们更新应用程序时, marathon 会新建相同实例数量的应用程序,待 health check 通过之后替换老节点,所以不需要担心新的服务没有启动期间老的服务停掉造成线上事 故。 到这里为止,我们已经可以在 marathon 上方便快捷的进行日常应用的创建、升级、扩 容、缩容。当服务健康检查失败或者机器宕机后,marathon 会自动在其它节点上启动挂掉的应用程序,大大提升了高可用性。


11.png


使用 nginx upsync/dyups 模块进行平滑变更 


当我们的微服务可以随机分配在不同机器上时,便产生了一个新的令人头疼的问题。 nginx 并不知道后端节点的变更, 也不可能每次都去手动修改 upstream 节点, reload nginx,这样成本就太高了。 我们的解决思路是和微服务的注册中心打通,当服务注册、注销时,都会对注册中心进行 更新,利用 nginx upsync/dyups 模块 可以动态修改 upstream 节点的能力进行同步,做 到平滑变更。 如果使用的注册中心为 consul,建议使用 upsync 模块,这样无需开发,只需要简单的 nginx 配置,就可以实现我们想要的效果, 支持 consul kv, consul_services, consul_health, 同时 upsync 也支持 etcd。建议使用 consul_health 接口。 upsync 模块不是 nginx 内置模块,使用时需要重新编译添加此模块。


wget 'http://nginx.org/download/nginx-1.8.0.tar.gz'tar -xzvf nginx-1.8.0.tar.gzcd nginx-1.8.0/  ./configure --add-module=/path/to/nginx-upsync-modulemakemake install
复制代码

配置文件示例


http {    upstream test {        upsync 127.0.0.1:8500/v1/health/service/test upsync_timeout=6m upsync_interval=500ms upsync_type=consul_health strong_dependency=off;        upsync_dump_path /usr/local/nginx/conf/servers/servers_test.conf;         include /usr/local/nginx/conf/servers/servers_test.conf;    }     upstream bar {        server 127.0.0.1:8090 weight=1 fail_timeout=10 max_fails=3;    }     server {        listen 8080;         location = /proxy_test {            proxy_pass http://test;        }         location = /bar {            proxy_pass http://bar;        }         location = /upstream_show {            upstream_show;        }     }}
复制代码

当 upsync 无法满足我们的需求或者注册中心不是 consul、etcd 时,我们可以考虑使用 nginx dyups 模块。dyups 仅对外提供 upstream 的增删查改接口,和注册中心对比、修 改的工作需要我们通过脚本的方式完成。虽然这种方式麻烦一些,但是可定制化程度高, 支持 http, C,lua API,基本上可以满足大部分的场景需求。 


dyups 模块也需要 nginx 编译时添加


$ git clone git://github.com/yzprofile/ngx_http_dyups_module.git # to compile as a static module$ ./configure --add-module=./ngx_http_dyups_module # to compile as a dynamic module$ ./configure --add-dynamic-module=./ngx_http_dyups_module
复制代码

示例配置


http {     include conf/upstream.conf;     server {        listen   8080;         location / {            # The upstream here must be a nginx variable            proxy_pass http://$dyups_host;        }    }     server {        listen 8088;        location / {            return 200 "8088";        }    }     server {        listen 8089;        location / {            return 200 "8089";        }    }     server {        listen 8081;        location / {            dyups_interface;        }    }}
复制代码

特别注意,使用 dyups 时, proxy_pass 时的 upstream 必须是 nginx 变量,否则不生 效,切记。


14.png


整体回顾


经过以上调整,我们得到了以下优化

1. 服务器资源自动分配,合理利用


2. 提升微服务的高可用性


3. 减低 OPS 人工成本,更加便于管理和维护


发布于: 2021 年 03 月 01 日阅读数: 17
用户头像

环信

关注

即时通讯领行者 2020.03.17 加入

环信成立于2013年4月,是国内领行的企业级软件服务提供商,于2016年荣膺“Gartner 2016 Cool Vendor”。是国内较早覆盖云通讯、云客服、智能机器人的一体化产品技术储备企服公司。

评论

发布
暂无评论
构建一套适合微服务的高可用架构