微服务设计简单实践---从一个简单需求学习微服务思想

从一个案例来看,如何在做架构设计时利用微服务的思想来帮我们解决问题。

背景介绍

公司对产品服务的管理目前还停留在物理机的那种理念,虽然阿里云、AWS、腾讯云、OpenStack等云平台用的不亦乐乎,但仍然停留在针对hostname和ip的管理上。如果想发布一个新版本,需要将设计到的所有机器的ip整理到一起,然后借助Ansible将产品更新上去。

这种现状的形成,并不只是技术上的落后,还有成本上的限制,毕竟包年付费模式要比按需付费便宜一大半。但是给运维团队带来的困扰也很大,毕竟遇到高峰期还是需要多备一套扩容组来扛流量,运维工程师除了要维护“静态的”云实例,还要维护这部分“动态的”云实例,运维成本很大。产品迭代后,包年的实例通过Ansible更新好后,运维工程师还要登陆到云平台上,选中一个更新后的实例,导出镜像,再将这个镜像更新到伸缩组的伸缩规则,这样才能保证伸缩组扩容出来的新实例运行的是新版本的应用。

需求下发:

开发一个系统可以直接从Ansible那边传来IP和伸缩组ID后,我的系统要把阿里云中伸缩组的镜像更新为该IP对应实例的镜像。

设计阶段:

产品的定位和扩展性

如果单单只实现这一点功能,可以写个python或者SpringMCV项目,调用阿里云的SDK就可以搞定。当我分析公司现有的资源和软件产品时发现,目前并没有一款这种对接云平台的辅助系统,所以我们可以把项目的定位抬高一些,做成对接所有云平台,甚至是对接运维所有辅助系统的这么一个项目。

最终选定用SpringFramework微服务架构来开发,虽然前期投入比较大,但是会带来很多优点:

1, 每个逻辑节点可以配置多个物理节点达到高可用性。 

2, 自动的服务发现和注册机制 

3, 节点间松耦合,新增和修改扩展灵活 

4, 统一的API网关,提供转发和过滤功能 

5, 可以添加Spring Config(统一配置中心)、Spring Bus(配置热修改)、Spring Sleuth(日志追踪)等辅助节点满足大批量节点管理 

现阶段: 

开发了4个节点:服务注册中心(Register)、对外服务网关(Gateway)、云总控(CloudCenter)、云分控(AliyunClient),架构图如下:

其中注册中心是基础运维研发关心的节点,用来观察服务节点的健康状况;Gateway是对外提供服务的入口,采用Restful协议,可定制安全规则(目前采用IP白名单);其它节点为内部服务节点,不对外暴漏,不允许直接访问。

再阶段:

后续与云平台相关的新功能,与阿里云有关的可以继续修改阿里云分控节点的代码,如果涉及到其它平台,新添加节点。 

这样设计的优点:1 某个云平台API升级、SDK更新等不会影响到其它节点代码的可用性;2 每个云平台根据自己的压力单独扩展资源。

终极形态:

对接更多的系统,扩展更多的组件

除开与云平台相关的功能,后续如果有其它模块需要开发的部分,也可以放到该项目中来。随着项目复杂度的增加,物理节点达到一定规模后,靠基础运维人工管理整套系统将会变的非常困难,需要引入Spring Cloud辅助工具。

API核心步骤

1 DescribeInstances:通过基准实例的内网ip查询对应实例id

2 CreateImage:使用实例id创建一个新镜像,记录镜像id

3 DescribeImages:通过镜像id查询镜像状态及progress,直到available为止

4 DescribeScalingGroups:通过伸缩组id查询到生效中的伸缩配置,记录ID

5 ModifyScalingConfiguration:修改伸缩配置,指向新的镜像

提高用户体验体验

阿里云基于实例制作镜像的过程几分钟至几小时时间不等,用户通过RESTFul的POST请求通过Json体传入实例IP和伸缩组ID后,将会陷入漫长的等待过程,所以操作请求和状态返回需要设计成异步形式避免等待。

异步又有两种可选的实现方式:1,后端任务完成后通过Queue通知客户;2,提供状态和进度的查询接口供客户端调用。两种方式各有利弊,对于请求者来说前者是被动的等待,不知道中间状态,甚至不知道死活;后者需要请求者通过get不断来轮询,但是可以拿到任务的进度。

所以,最终的设计是当收到任务请求后,经过简单校验直接转交后台处理,同时将查询进度的url通过http的response返回给请求端。

客户对自己的镜像可以有自定义的命名规则,方便后期维护和在云平台的查询,所以添加一个可选参数,让客户可定制镜像名称的前缀。

细节考虑

1 异步任务线程池

因为任务是异步执行的,而且前面也说过,一次任务的执行从十几分钟到几小时不等,如果不做控制很有可能线程数爆掉,所以处于安全和效率的考虑,需要增加任务的线程池。如果线程池扛不住并发数,只能扩展物理节点。

2 任务状态缓存

因为无法控制客户端调用状态查询接口的频率,如果完全透传给阿里云会严重影响我自己系统的性能。所以在设计中增加一层缓存,客户端接口只查询缓存中的状态,缓存层每1min调用一次阿里云的镜像状态接口更新一次缓存中的状态。

3 阿里云API容错机制

这个是上线后遇到的问题,由于网络的问题从我的系统到阿里云的服务并不能保证100%的问题,所以当轮询制作镜像任务状态时有极小概率会失败,但其实在阿里云端制作镜像的任务仍在运行中,但是在我的系统里却认为以失败结束了。

所以对于特定的API需要增加容错机制,连续3次API调用失败后才认为真正失败。

部分源码分享:

https://github.com/yejingtao/ci-register.git

https://github.com/yejingtao/ci-gateway.git

https://github.com/yejingtao/ci-cloudcenter.git

https://github.com/yejingtao/ci-aliclient.git

注意:因为我使用的JVM本地缓存,所以当前的服务需要java -jar部署到一台机器上,后续我会把本地缓存改造为共享缓存。

总结:

微服务开发是一个循序渐进的过程,只要开始把架构搭建好,随着功能一点点的添加,跟搭积木一样可以慢慢构建出一个庞大的系统,而且添加新功能模块对现有功能冲击很小。

原文链接:https://blog.csdn.net/yejingtao703/article/details/84961510

猜你喜欢

转载自blog.csdn.net/ebzxw/article/details/85016052