2017年,微服务很火,到处都在讲微服务,好像不做微服务,就out了。我们团队也跟风,把一个跑了好几年的单体应用,拆成了微服务,本以为拆完就万事大吉了,系统会更稳定,更易扩展,开发效率更高。

没想到,微服务的拆分,只是开始,微服务的治理,才是真正的噩梦。从服务发现、配置中心、熔断降级、限流、链路追踪、日志收集、监控告警、分布式事务、灰度发布,每一个都是坑,我们踩了一个又一个,从入门到放弃,经历了很多,差点就放弃了,又回到单体应用。

今天就来分享一下,我们团队微服务治理从入门到放弃的真实经历,踩过的坑,以及最后的感悟,希望能给准备做微服务的团队一些参考,不要盲目跟风,微服务不是银弹。

一、为什么要做微服务

先说说我们为什么要做微服务。

我们的系统,是一个电商系统,一开始是单体应用,所有的功能都在一个项目里,用户、商品、订单、支付、库存、营销、物流,都在一个应用里,用的是Java + Spring + MyBatis,部署在Tomcat里。

一开始,系统不大,用户不多,单体应用用得挺好的,开发简单,部署简单,调试简单,没有什么问题。

但是,随着业务的发展,用户越来越多,功能越来越复杂,单体应用的问题,就慢慢暴露出来了:

  1. 代码越来越庞大: 一个项目,几十万行代码,十几个模块,改一个小功能,要理解整个项目的代码,很费劲,新人上手很慢。
  2. 编译部署越来越慢: 项目越来越大,编译一次要十几分钟,部署一次要几十分钟,而且每次部署,都要整个应用重启,影响所有的功能,发布风险很大。
  3. 团队协作越来越困难: 十几个开发,都在一个项目里改代码,经常冲突,合并代码很痛苦,而且一个人改的代码,可能影响其他人的功能,互相影响。
  4. 扩展性不好: 整个应用一起扩容,但是有的模块,比如商品查询,压力大,需要多扩容,有的模块,比如后台管理,压力小,不需要扩容,但是单体应用只能一起扩容,浪费资源。
  5. 技术栈固定: 整个应用用一个技术栈,想尝试新的技术,比如用Node.js做前端接口,用Go做高并发的服务,很难,因为都在一个应用里。
  6. 稳定性不好: 一个模块出问题,比如订单模块有个Bug,内存泄漏,可能会导致整个应用挂掉,所有的功能都不能用,影响面很大。

这些问题,越来越严重,我们团队也很头疼,正好这时候,微服务很火,到处都在讲微服务的好处,说微服务能解决这些问题,我们就心动了,决定把单体应用拆成微服务。

现在想想,当时还是太年轻了,只看到了微服务的好处,没看到微服务的复杂度和治理成本,以为拆完就好了,没想到,微服务的治理,才是真正的挑战。

二、微服务拆分的过程

决定做微服务之后,我们就开始拆分了。

首先,我们学习了微服务的相关知识,看了很多文章,听了很多分享,了解了微服务的拆分原则,比如按业务领域拆分、单一职责、独立部署、独立数据存储等,也了解了微服务的技术栈,比如Spring Cloud、Dubbo、Kubernetes等。

经过讨论,我们选择了Spring Cloud作为微服务的技术栈,因为当时Spring Cloud很火,生态很完善,文档也很多,而且我们团队本来就用Java和Spring,上手比较快。

然后,我们开始拆分,按照业务领域,把单体应用拆成了以下几个微服务:

  1. 用户服务: 负责用户的注册、登录、信息管理、权限等。
  2. 商品服务: 负责商品的管理、分类、搜索、库存等。
  3. 订单服务: 负责订单的创建、查询、状态管理等。
  4. 支付服务: 负责支付、退款、对账等。
  5. 库存服务: 负责库存的管理、扣减、回补等。
  6. 营销服务: 负责优惠券、活动、促销等。
  7. 物流服务: 负责物流的查询、发货、跟踪等。
  8. 网关服务: 负责请求的路由、鉴权、限流、熔断等。
  9. 配置中心: 负责所有服务的配置管理。
  10. 注册中心: 负责服务的注册和发现。

拆分的过程,还是比较顺利的,因为我们的单体应用,本来就是按模块分的,代码的耦合度不算太高,所以拆分起来,难度不算太大,花了大概两个月的时间,就把主要的功能拆完了,然后测试、上线,一开始,感觉还不错,各个服务独立部署,独立扩容,开发效率也提高了,团队成员各自负责一个服务,冲突少了很多。

但是,好景不长,上线没多久,各种问题就开始出现了,微服务的治理,才是真正的挑战。

三、微服务治理的各个组件和踩过的坑

微服务拆分之后,需要治理的组件很多,我们一个一个来,一个一个踩坑。

1. 服务发现(注册中心)

微服务之间,需要互相调用,但是服务的地址是动态的,可能会扩容、缩容、重启,所以需要服务发现,也就是注册中心,服务启动的时候,把自己的地址注册到注册中心,调用方从注册中心获取服务的地址,然后调用。

我们用的是Spring Cloud的Eureka作为注册中心,一开始,用得挺好的,服务注册、发现都正常。

但是,踩了几个坑:

坑1:Eureka的自我保护机制: Eureka有个自我保护机制,当网络分区故障的时候,Eureka会保护注册的服务实例,不会过期删除,这个机制本来是为了提高可用性的,但是我们遇到了问题,有个服务实例挂了,但是Eureka因为自我保护,没有把它删掉,调用方还在调用这个挂掉的实例,导致请求失败,排查了很久才发现是这个问题。后来,我们把自我保护机制关了,或者调整了参数,才解决。

坑2:服务注册慢: 服务启动的时候,注册到Eureka,需要一点时间,而且Eureka的缓存,也有延迟,所以服务刚启动的时候,调用方可能还看不到这个服务,导致请求失败。我们一开始,服务启动完就马上发流量,结果有很多请求失败,后来才知道,要等服务注册完成,并且被调用方拉取到之后,再发流量,或者用重试机制,解决这个问题。

坑3:Eureka集群同步延迟: 我们部署了Eureka集群,但是Eureka的节点之间,同步有延迟,服务注册到一个节点,另一个节点可能还没同步到,调用方从另一个节点获取服务列表,就获取不到这个服务,导致请求失败。后来,我们调整了Eureka的同步参数,或者让调用方从多个节点获取服务列表,才缓解了这个问题。

后来,我们听说Consul、Nacos比Eureka更好,支持健康检查、配置中心等,又折腾了一段时间,把注册中心换成了Nacos,才稳定了一些。

2. 配置中心

微服务很多,每个服务都有自己的配置,如果配置都写在代码里,或者配置文件里,修改配置要重新打包部署,很麻烦,所以需要配置中心,统一管理所有服务的配置,修改配置后,服务能动态刷新,不需要重新部署。

我们用的是Spring Cloud Config作为配置中心,配置存在Git仓库里,服务从配置中心拉取配置。

踩的坑:

坑1:配置中心单点故障: 一开始,配置中心只部署了一个实例,结果配置中心挂了,所有的服务启动的时候,都拉不到配置,都启动不了,影响很大。后来,我们把配置中心部署成集群,并且本地缓存配置,即使配置中心挂了,服务也能用本地缓存的配置启动,才解决了这个问题。

坑2:配置动态刷新不生效: 配置中心修改了配置,但是服务的配置没有动态刷新,还是用的旧配置,排查了很久,才发现,是因为有些Bean没有加@RefreshScope注解,所以配置刷新了,但是Bean没有重新创建,还是用的旧值。后来,我们把需要动态刷新的Bean,都加上了@RefreshScope注解,才解决。

坑3:配置版本管理混乱: 配置存在Git里,但是不同的环境(开发、测试、生产),不同的版本,配置不一样,分支管理混乱,经常改错配置,把测试的配置改到生产了,导致生产故障。后来,我们规范了配置的分支管理,每个环境一个分支,修改配置要走审批,生产环境的配置修改,要双人确认,才减少了这类问题。

后来,我们也把配置中心换成了Nacos,因为Nacos同时支持注册中心和配置中心,更方便,而且配置的动态刷新更稳定,界面也更好用。

3. 熔断降级

微服务之间互相调用,一个服务挂了,或者响应太慢,可能会导致调用方的线程被占满,进而导致调用方也挂掉,然后一层层往上,导致整个系统雪崩,所以需要熔断降级,当下游服务故障的时候,熔断,直接返回降级结果,避免故障扩散。

我们用的是Hystrix作为熔断降级的组件,一开始,配置了熔断和降级,感觉还不错。

踩的坑:

坑1:熔断阈值设置不合理: 一开始,我们的熔断阈值,是随便设置的,比如错误率50%就熔断,但是有的服务,本来错误率就比较高,比如调用第三方接口的服务,经常超时,导致经常被熔断,影响正常的请求。后来,我们根据每个服务的实际情况,单独设置熔断阈值,并且不断调整,才合理。

坑2:降级结果不合理: 熔断之后,返回的降级结果,是随便写的,比如返回空列表,或者默认值,但是有的业务,不能返回空列表,否则会导致业务异常,比如库存服务,熔断了返回库存充足,就会导致超卖。后来,我们根据每个接口的业务情况,设计合理的降级结果,并且在降级的时候,记录日志,告警,及时处理。

坑3:Hystrix的线程池隔离: Hystrix默认用线程池隔离,每个服务的调用,用独立的线程池,避免一个服务的调用占满所有线程。但是,线程池的大小,设置不合理,太小的话,并发的时候,线程不够用,请求被拒绝;太大的话,占用太多资源。我们一开始,线程池设置得太小,导致高并发的时候,很多请求被拒绝,后来调整了线程池的大小,并且根据每个服务的并发量,单独设置,才解决。

后来,Hystrix停止维护了,我们又换成了Resilience4j,更轻量,更灵活,才稳定了一些。

4. 限流

高并发的时候,需要限流,保护系统不被打垮,比如秒杀活动,流量突然增加,需要限流,只允许一部分请求通过,其他的请求排队或者拒绝。

我们用的是Spring Cloud Gateway的限流,还有Redis的令牌桶限流。

踩的坑:

坑1:限流粒度不合理: 一开始,我们是整个服务限流,但是有的接口,压力大,需要更严格的限流,有的接口,压力小,不需要限流,整个服务限流,不合理。后来,我们改成按接口限流,每个接口单独设置限流阈值,才合理。

坑2:分布式限流不一致: 我们用Redis做分布式限流,但是Redis的限流,有并发问题,多个实例同时请求,可能会超过限流阈值,因为Redis的操作不是原子的。后来,我们用Redis的Lua脚本,保证限流操作的原子性,才解决了这个问题。

坑3:限流之后的处理不合理: 限流之后,请求被拒绝,返回429错误,但是用户体验不好,用户不知道为什么被拒绝,以为系统坏了。后来,我们限流之后,返回友好的提示,比如"系统繁忙,请稍后再试",或者让用户排队,排队成功再处理,用户体验好了很多。

5. 链路追踪

微服务很多,一个请求,可能会经过好几个服务,出了问题,不知道是哪个服务的问题,也不知道请求在各个服务的耗时,所以需要链路追踪,把一个请求在各个服务的调用链路串起来,方便排查问题和性能分析。

我们用的是Spring Cloud Sleuth + Zipkin做链路追踪。

踩的坑:

坑1:链路追踪的性能影响: 一开始,我们把所有的请求,都采集链路数据,结果对性能影响很大,请求的响应时间增加了很多,而且Zipkin的存储压力也很大,数据量太大,查询很慢。后来,我们改成采样,只采集一部分请求的链路数据,比如10%,并且用消息队列异步发送链路数据,不影响请求的响应时间,才解决了性能问题。

坑2:链路ID传递丢失: 微服务之间调用,需要传递链路ID,但是有的调用,比如异步调用、消息队列,链路ID没有传递过去,导致链路断了,看不到完整的调用链路。后来,我们在异步调用和消息队列里,也手动传递链路ID,才保证了链路的完整性。

坑3:Zipkin存储不稳定: 一开始,Zipkin用的是内存存储,重启之后数据就丢了,后来换成了MySQL存储,但是数据量太大,查询很慢,再后来换成了Elasticsearch存储,才稳定一些,但是Elasticsearch的运维成本也很高。

后来,我们听说SkyWalking比Zipkin更好,功能更强大,无侵入,又折腾了一段时间,把链路追踪换成了SkyWalking,才稳定了一些。

6. 日志收集

微服务很多,每个服务都有自己的日志,日志分散在各个服务器上,出了问题,要一台一台服务器去查日志,很麻烦,所以需要日志收集,把所有服务的日志,统一收集到一个地方,方便查询和分析。

我们用的是ELK(Elasticsearch + Logstash + Kibana)做日志收集。

踩的坑:

坑1:日志格式不统一: 各个服务的日志格式不一样,有的用logback,有的用log4j,有的输出JSON,有的输出纯文本,导致Logstash解析很困难,查询也不方便。后来,我们统一了日志格式,都用JSON格式输出,包含服务名、环境、链路ID、时间、日志级别、线程、类、方法、消息等字段,才方便查询和分析。

坑2:日志量太大: 微服务很多,请求量也大,日志量非常大,每天几十GB,Elasticsearch的存储压力很大,查询也很慢,而且成本很高。后来,我们做了日志分级,只把INFO及以上级别的日志收集到ELK,DEBUG级别的日志只存在本地,并且设置日志的过期时间,比如只保留7天的日志,超过的自动删除,才缓解了存储压力。

坑3:日志丢失: Logstash收集日志的时候,有时候会丢失日志,比如Logstash重启、网络故障、Elasticsearch写入失败等,导致日志不完整,排查问题的时候,找不到关键的日志。后来,我们用Filebeat收集日志,先写到本地文件,再异步发送到Logstash,并且设置了重试机制,即使Logstash挂了,日志也不会丢失,等Logstash恢复了,再继续发送,才减少了日志丢失的问题。

7. 监控告警

微服务很多,需要监控各个服务的状态,比如CPU、内存、磁盘、网络、请求量、响应时间、错误率等,出了问题,及时告警,及时处理。

我们用的是Prometheus + Grafana做监控告警。

踩的坑:

坑1:监控指标不全面: 一开始,我们只监控了服务器的CPU、内存、磁盘,没有监控应用层的指标,比如请求量、响应时间、错误率、JVM的堆内存、GC等,导致应用出了问题,监控没告警,等用户反馈了才知道。后来,我们用Micrometer,把应用层的指标也暴露给Prometheus,全面监控,才及时发现应用的问题。

坑2:告警太多,麻木了: 一开始,我们设置了很多告警,CPU超过80%告警,内存超过80%告警,错误率超过1%告警,响应时间超过1秒告警,结果每天都有很多告警,大部分是误报,或者不重要的告警,时间长了,大家就麻木了,真正重要的告警,也被忽略了。后来,我们对告警进行了分级,P0、P1、P2,不同级别的告警,用不同的通知方式,并且优化了告警阈值,减少误报,只保留重要的告警,才提高了告警的有效性。

坑3:监控本身不稳定: Prometheus和Grafana,本身也需要运维,有时候Prometheus挂了,或者Grafana挂了,监控就用不了了,出了问题都不知道。后来,我们把监控也部署成集群,并且监控监控本身,用另一个监控系统监控这个监控系统,确保监控的稳定。

8. 分布式事务

微服务拆分之后,一个业务操作,可能会涉及多个服务,比如下单,需要调用订单服务创建订单,调用库存服务扣减库存,调用营销服务核销优惠券,调用支付服务创建支付,这些操作,要么都成功,要么都失败,但是微服务是独立部署的,每个服务有自己的数据库,不能用本地事务,所以需要分布式事务。

这是我们踩的最大的坑,分布式事务,太复杂了。

一开始,我们用的是2PC(两阶段提交),用XA协议,但是性能很差,并发上不去,而且锁的时间长,容易死锁,用了一段时间,实在受不了,就放弃了。

后来,我们用TCC(Try-Confirm-Cancel),每个服务提供Try、Confirm、Cancel三个接口,业务代码里,先调用所有服务的Try,都成功了,再调用所有服务的Confirm,有一个失败了,就调用所有服务的Cancel。但是TCC的代码复杂度很高,每个接口都要写三个方法,还要处理幂等、空回滚、悬挂等问题,开发量很大,而且很容易出Bug,我们写了很久,才把下单的TCC写完,测试的时候,还是出了很多问题,比如库存扣减了,但是订单没创建,或者优惠券核销了,但是订单没创建,各种不一致,排查了很久。

再后来,我们用了消息队列的最终一致性,也就是本地消息表,或者事务消息,下单的时候,订单服务创建订单,同时发送一条消息到消息队列,库存服务、营销服务、支付服务,消费这条消息,执行对应的操作,如果失败了,就重试,保证最终一致性。这个方案,性能比较好,代码复杂度也比TCC低,但是有延迟,不是强一致性的,而且需要处理消息的幂等、重复消费、消息丢失等问题,也踩了很多坑。

分布式事务,是微服务里最头疼的问题,我们折腾了很久,试了好几种方案,最后用了消息队列的最终一致性,加上定时任务对账,才基本解决,但是还是偶尔会有数据不一致的情况,需要人工处理。

9. 灰度发布

微服务很多,发布频繁,每次发布,都有风险,所以需要灰度发布,先让一部分流量用新版本,观察一段时间,没有问题,再全量发布,有问题,就回滚,减少故障的影响。

我们用的是Spring Cloud Gateway的灰度发布,根据请求头或者用户ID,把一部分流量路由到新版本的服务。

踩的坑:

坑1:灰度规则复杂: 一开始,我们想按用户ID灰度,但是用户ID是分布在各个服务的,网关层拿不到用户ID,需要先调用用户服务查询,增加了延迟,而且规则很复杂,维护困难。后来,我们简化了灰度规则,按请求头灰度,测试的时候,在请求头里加一个标记,就走新版本,简单方便,线上灰度的时候,按比例灰度,比如10%的流量走新版本,简单易维护。

坑2:灰度的时候,数据兼容性问题: 新版本的服务,可能会修改数据库表结构,或者修改数据格式,灰度的时候,新旧版本同时运行,都读写同一个数据库,可能会有数据兼容性问题,比如新版本加了一个字段,旧版本不认识,或者新版本修改了字段的含义,旧版本读写出错。后来,我们规定,数据库变更要兼容,先加字段,不删除字段,不修改字段含义,等全量发布,旧版本都不用了,再清理旧字段,才解决了数据兼容性问题。

坑3:灰度回滚不及时: 灰度的时候,新版本出了问题,需要回滚,但是回滚的流程很复杂,要修改网关的路由规则,还要把新版本的服务下线,有时候回滚不及时,导致故障影响扩大。后来,我们做了一键回滚的功能,出了问题,点一下按钮,就能把流量切回旧版本,并且下线新版本,回滚时间从几分钟缩短到几秒钟,才减少了故障的影响。

四、为什么差点放弃

微服务治理的这些组件,每一个都踩了很多坑,我们团队,花了大半年的时间,才把这些组件基本搭起来,但是,还是经常出问题,不是注册中心挂了,就是配置中心有问题,不是链路追踪丢数据了,就是分布式事务数据不一致,不是监控告警误报了,就是灰度发布出问题了。

团队成员,大部分时间都在处理这些微服务治理的问题,没有时间做业务功能,业务方很不满意,说我们效率低,一个简单的功能,要做好久。

而且,微服务的复杂度,远远超出了我们的预期,原来的单体应用,只有一个,运维起来很简单,现在,有十几个微服务,每个服务都要部署、监控、告警、扩容、缩容,运维的工作量,增加了好几倍,我们团队,没有专门的运维,都是开发自己运维,根本忙不过来。

还有,微服务之间的调用,网络开销很大,原来的单体应用,方法调用,是内存级别的,现在,微服务之间调用,是网络级别的,延迟增加了很多,而且,网络不稳定的时候,调用经常失败,用户体验反而不如以前的单体应用。

最头疼的是分布式事务,数据不一致的问题,经常出现,比如订单创建了,但是库存没扣减,或者优惠券核销了,但是订单没创建,需要人工处理,客服天天找我们,说数据不对,我们天天修数据,修得怀疑人生。

那段时间,团队成员都很沮丧,觉得微服务就是个坑,还不如以前的单体应用,简单、稳定、好维护,甚至有人提议,把微服务合并回去,重新做单体应用。

我们真的差点就放弃了,把微服务合并回单体应用。

五、最后的坚持和感悟

后来,我们冷静下来,认真分析了一下,微服务确实带来了很多问题,但是,也确实解决了单体应用的一些问题,比如,团队协作更顺畅了,各个服务独立部署,发布风险小了,扩展性也好了,各个服务可以独立扩容。

微服务的问题,主要是因为我们的治理能力跟不上,技术能力和运维能力,都不足以支撑微服务的复杂度,而不是微服务本身的问题。

所以,我们决定,不放弃,继续坚持,但是,要调整策略,不要追求大而全,不要什么组件都用,根据我们的实际情况,精简微服务的治理,只保留必要的组件,把必要的组件做稳定,其他的,能简化就简化,能不用就不用。

我们做了以下调整:

  1. 精简微服务的数量: 把一些太小的、关系太密切的服务,合并起来,比如把库存服务合并到商品服务,把物流服务合并到订单服务,减少微服务的数量,从十几个,减少到七八个,降低治理的复杂度。
  1. 精简治理组件: 注册中心和配置中心,用Nacos,一个组件搞定,不用Eureka + Spring Cloud Config了;熔断降级,用Resilience4j,轻量简单,不用Hystrix了;链路追踪,用SkyWalking,无侵入,功能强大,不用Zipkin了;日志收集,用ELK,但是简化配置,统一格式;监控告警,用Prometheus + Grafana,精简告警,只保留重要的。
  1. 分布式事务,尽量避免: 能不用分布式事务的,就不用,比如,下单的时候,先创建订单,库存扣减、优惠券核销,用消息队列异步处理,最终一致性,不用强一致性,接受短暂的不一致,用定时任务对账,保证最终一致。实在需要强一致性的,用TCC,但是只在核心流程用,其他的,都用最终一致性。
  1. 完善运维体系: 引入了Kubernetes,用容器化部署,自动扩缩容,自动恢复,减少运维的工作量;完善了CI/CD流水线,自动化测试、自动化构建、自动化部署、自动化灰度发布,提高发布效率,减少人为错误。
  1. 加强团队培训: 组织微服务相关的培训,让团队成员都了解微服务的原理和最佳实践,提高团队的技术能力;建立微服务的规范,比如服务拆分的规范、接口设计的规范、日志的规范、监控的规范,让大家有章可循。

经过这些调整,我们的微服务,终于稳定了一些,出问题的频率,大大降低了,团队成员,也不用天天救火了,有时间做业务功能了,业务方也满意了。

现在回头看,微服务治理从入门到放弃,我们经历了很多,踩了很多坑,也学到了很多,有一些感悟,分享给大家:

1. 微服务不是银弹,不要盲目跟风: 微服务能解决单体应用的一些问题,但是也带来了很多新的问题,复杂度大大增加,需要团队有足够的技术能力和运维能力,才能驾驭。如果团队的技术能力和运维能力不足,微服务带来的问题,可能比解决的问题还多,还不如用单体应用。所以,不要盲目跟风,要根据自己团队的实际情况,决定要不要做微服务。

2. 微服务的拆分,要循序渐进: 不要一开始,就把单体应用拆得很细,拆成几十个微服务,这样治理的复杂度太高,团队根本驾驭不了。要循序渐进,先拆成几个大的服务,稳定之后,再根据需要,拆成更细的服务,而且,能不拆的,就不拆,不要为了微服务而微服务。

3. 微服务的治理,要精简,不要大而全: 微服务治理的组件很多,注册中心、配置中心、熔断降级、限流、链路追踪、日志收集、监控告警、分布式事务、灰度发布等等,不要一开始,就把所有的组件都用上,这样复杂度太高,维护成本太高。要根据实际需要,只保留必要的组件,把必要的组件做稳定,其他的,能简化就简化,能不用就不用。

4. 分布式事务,能不用就不用: 分布式事务,是微服务里最复杂、最头疼的问题,能不用就不用,尽量用最终一致性,接受短暂的不一致,用消息队列、定时任务对账,保证最终一致。实在需要强一致性的,再用TCC或者2PC,但是只在核心流程用,不要到处用。

5. 运维能力,是微服务的基础: 微服务的运维复杂度,比单体应用高很多,没有足够的运维能力,不要做微服务。要完善运维体系,用容器化、自动化部署、自动化监控、自动化告警,减少运维的工作量,提高运维的效率。如果团队没有专门的运维,开发的运维能力也不足,要慎重考虑要不要做微服务。

6. 团队的技术能力,很重要: 微服务,对团队的技术能力要求很高,需要团队成员,都了解微服务的原理和最佳实践,能独立开发、测试、部署、运维一个服务。如果团队的技术能力不足,要先培训,提高团队的技术能力,再做微服务,否则,会踩很多坑,甚至失败。

7. 微服务,是手段,不是目的: 做微服务,是为了解决单体应用的问题,提高开发效率,提高系统的稳定性和扩展性,不是为了微服务而微服务,不要把微服务当成目的。如果微服务没有解决问题,反而带来了更多的问题,那就要反思,是不是不应该做微服务,或者是不是做得不对,及时调整,不要一条路走到黑。

写在最后

微服务治理从入门到放弃,我经历了什么。

我们团队,从跟风做微服务,到拆分微服务,到微服务治理踩坑,到差点放弃,到最后调整策略,坚持下来,稳定运行,经历了很多,踩了很多坑,也学到了很多。

微服务不是银弹,它能解决单体应用的一些问题,但是也带来了很多新的问题,复杂度大大增加,需要团队有足够的技术能力和运维能力,才能驾驭。如果团队的能力不足,微服务带来的问题,可能比解决的问题还多。

所以,不要盲目跟风做微服务,要根据自己团队的实际情况,决定要不要做,怎么做,循序渐进,精简治理,完善运维,提高团队能力,才能真正发挥微服务的优势。

最后,用一句话结尾:

"微服务不是银弹,而是一把双刃剑,用好了,能解决很多问题,用不好,会带来更多的问题。不要盲目跟风,要根据自己的实际情况,理性选择,循序渐进,才能真正发挥微服务的价值。"

祝大家都能根据自己的实际情况,选择合适的架构,少踩坑,系统稳定运行!