运维就要无所不能,无所不会
大家好,我是史丹利「stanley」,今天來聊聊微服务做容器化时应该规避哪些坑。
在上上篇文章里,我们有提到容器化时成本控制。
运维职业的第一职业敏感是成本。这毫无异议。
曾经有架构师推荐老板容器化的一个理由也是容器化可以大范围节约公司资金成本,我也一度很认可,但后来发现凡事是有前提的。
微服务天生适合容器化,这也毫无异议,但也是有前提的,前提就是做了合理的微服务拆分!
太过粗糙的微服务拆分,顶多影响开发工作版本迭代,提升版控难度,但过于细分的微服务拆分,则会增大容器化后的成本。
安全起见,Java 进程启动时都分显示声明的内存分配
-javaagent:/usr/local/skywalking_agent/skywalking-agent.jar -Dskywalking_config=/usr/local/skywalking_agent/config/app.config --eureka.client.serviceUrl.defaultZone=http://eureka.example.com/eureka/ -XX:PermSize=128m -XX:MaxPermSize=128m
k8s 也一样,官方建议对所有的pod做限额配置。
resources:
requests:
cpu: 2
memory: 2048Mi
limits:
cpu: 2
memory: 2Gi
如上的方式为资源硬设置,即固定分配2c2G的资源,如果觉得这样的方式,太浪费资源,k8s 同样提供了如下比较人性人的设置,
limits:
- default:
cpu: 800m
defaultRequest:
cpu: 800m
max:
cpu: 800m
min:
cpu: 200m
type: Container
软资源限制对资源浪费有缓存,但并不能实质性解决资源浪费的情况,因为没人知道什么时间pod的资源占用会达到峰值,即使知道,这部分资源也需要一直为其预留,与其这样,反倒硬资源限制更安全。
所以,问题就回到了,如何微服务的切割原则。
单体应用运行一段时间后,随着业务的增长,对系统性能和并发性要求越来越高,这个时候就面临着微服务重构的选择,但在重构前,我们必须反复权衡并且做好必要的基础设施准备以应对新架构下面临的新问题,而不是觉得微服务现在火脑袋一热就开始着手微服务重构。
结合实际项目回顾下微服务可能存在的坑,主要包含以下几点:
我们分几方面介绍:
服务拆分后,同步带来的验证、测试、上线等工作量是有增无减,微服务的过程其实是人力换质量的过程 。如果配套工具不成熟,同步带来的复杂度会远胜便利性。
restful API
新一代开发开发框架,基本上已经有很好的前后端分离。这样的好处是,无论后端如何变化,对前端都是透明的。而且可以实现拆分过程中的灰度发布,路由分发,流量切分,从而保证拆分的平滑进行
各功能模块间没有大量的复杂联合查询,优秀的库表设计应该能达到绝大多数的功能查询只是 k/v 的O(n) 查询。否则,微服务的拆分会有很大难度,和代码重构无异
无状态服务
新一代的开发框架和开源流行工具都在强调的功能特性,去中心化,无状态化。无状态化同样是k8s
的核心思想之一。
新业务通常使用springcloud
全家桶,在某些程度或者完全实现微服务化。
旧业务的微服务化改造的拆分并非自上而下一步到位的重构改造,通常是由痛点驱动,是业务真正遇到了快速迭代和高并发的问题,如果不拆分,将对于业务的发展带来影响,只有这个时候,微服务的拆分是有确定收益的,增加的运维成本才是值得的。
比如如下的情况之一:
如上情况,可考虑服务拆分
Akf拆分原则
[AKF扩展立方体](参考《The Art of Scalability》),是一个叫AKF的公司的技术专家抽象总结的应用扩展的三个维度。理论上按照这三个扩展模式,可以将一个单体系统,进行无限扩展。
Y 轴 :就是我们所说的微服务的拆分模式,就是基于不同的业务拆分。
场景说明:比如京东商城,一个集群撑不住时,分了多个集群,后来用户激增还是不够用,经过分析发现是6.18访问量很大,就将商城页面流量大功能再做拆分,每个拆分出来的功能,独立维护,各自都可以再次按需扩展。
反面教材:
我们公司的内部应用系统,使用人数不超过100人,但系统却拆分成30多个模块,造成容器化时大量资源浪费。
服务拆分规范并不是运维强项,或者运维并没有太多的机会和话语权参与到开发的实际开发工作中。
在实际工作中,微服务对运维工作造成比较大的影响,比如工作量陡增,资源成本消耗更多,但服务质量并没有实际提升,那么优先考虑
如果均没有,再考虑微服务拆分问题,这里仅做入门,建议深入学习后再和开发同学一起改进优化。
微服务规范参考: http://dockone.io/article/8241