先说想法
这个标题并非一时兴起,也并非哗众取宠,而是我这段时间以来的思考。为什么会出现这样的想法?这还得从一个事实说起。
众所周知,微服务并不能提升整个项目的吞吐量,它的作用仅仅只是把项目按照一定的规则拆分成各种模块,然后每个模块都可以交给不同小组去开发。他解决的仅仅是大项目的团队协作问题。而真正能提升吞吐量的,除了程序本身的质量那就是负载均衡了,而且事实上微服务的架构中,每个服务都是以负载均衡的形式部署的,所以这里就有一个问题了:
如果仅仅是为了解决 [大项目的团队协作问题] 那么常规的模块化设计是不是也能做到?
现在由于 maven 的出现,再加上企业内部可以搭建私服,我们完全可以让每一个服务都以 jar 包的形式来开发。举个很简单的一个例子,比如有一个用户服务,订单服务,现在一般的做法是写一个聚合服务去调用这两个服务的接口,来实现业务逻辑的整合。
那如果把用户服务换成用户模块 jar 包、订单服务换成订单模块 jar 包,以 jar 包的形似传到私服,然后同样的写一个聚合服务,聚合服务把这两个 jar 包引入进来,是不是也能达到这样的效果?
如果需要负载均衡,那我们把这个聚合服务部署多个就好了,完全不影响。我完全想不到跟微服务比起来有什么坏处,如果有,欢迎大家指正。
微服务有什么缺点

耦合性太高,虽然开发和部署不会影响别的服务,但是你如果动了接口的出入参,那么其他服务就得同步升级了,而且是调用了这个接口的服务都要升级,又或者你需要为此单拎一个接口出来,做版本区分。
需要注册中心,项目会多出一个中间件,提升复杂度。
会消耗内网带宽,甚至是公网带宽,因为服务之间的调用都是通过网络完成的。
会出现分布式事务的问题,因为一个事务的操作可能会分布在不同的服务上执行。

如果用常规的模块化方案

虽然耦合也高,但是如果你动了接口的出入参甚至是接口名,别的服务是不需要立刻升级的,除非你是在改 bug ,但这是被业务逼着升级,因为不升级是有 bug 的,但他不会被技术逼得升级,因为模块只是被打成了一个 jar 包引入了其他模块里,无论你怎么变,已经部署在线上的别的模块里依然是用的你的老代码。
不需要注册中心
不会消耗多余的带宽资源
不需要分布式事务了

还是压力问题
一定会有人说,你把这么多模块都塞进一个服务里,那这个服务得部署多少台机器啊。
说到这里,就不得不从全局来看待问题了。我们可以看两张图(不好意思,有错别字,但是已经截图了就懒得改了,能看懂就行)
图 1

图 2

根据上面的两个图,我们是不是可以这么说,微服务在面对相同的流量时根本没有节约服务器的数量?反而还多了?
假如左边的聚合服务,他的业务量需要 10 台服务器才能支撑,右边的需要 5 台才能支撑,那么一共是 15 台。而微服务会导致 A 部署 15 台,B 也部署 15 台,再加上两个聚合服务,一共需要 32 台以上。
当然了,这只是极端的情况,现实中可能 A 服务不需要处理这么多业务,他可以少部署一点,又或者 B 服务可以少部署一点。但无论怎么算,服务器都是多了。
如果采用 jar 包的形式,那么只需要 15 台就够了,10 台用来部署左边的聚合服务,5 台用来部署右边的聚合服务。
说到底
这其实就是以三方库的思想在设计模块化,如果有一个工具类叫用户管理,有一个工具类叫支付管理。当你需要开发登录功能的时候,只需要引入一个 jar 包,然后调用里面的某个方法就好了,当你需要开发支付功能的时候也一样,你不需要去学习 dubbo ,不需要去学习 springcloud ,甚至不需要去关注注册中心是否挂没挂,注册中心的 url 是多少,服务到底有没有正常发布,有没有正常被发现。你会不会觉得这样有什么不妥呢?
以上只是个人的一点浅薄见解,欢迎大家理性探讨。

槽点有点多。。。。有的观点挺有意思

但是一些其他观点,需要区分架构和技术实现

这些观点包括

  • “如果仅仅是为了解决 [大项目的团队协作问题] ”。。。。它不是为了解决大项目的团队协作问题,它是适应了康威定律
  • 耦合性太高,这个我理解是抨击提供的是服务。。。这个是微服务必然带来的
  • 还有分布式事务。。。这个如果你说是数据去中心化,那确实是问题,但是分布式事务这个是技术

我个人觉得你可以思考自己的观点的时候先尝试证伪自己的观点

推荐
看下 martinfowler.com/articles/microservices.html 这个里面的定义

增加了大量 kpi ,增加了大量人工,增加了大量服务资源。不是吗???

看这说的,别的不说大型项目中更新时单体项目的话需要整体重启的要命性都没体会到,说明你还需要学习,不要质疑别人的智商,别的都不说,大型高负载快速迭代的项目单纯就是为了减少重启范围都值得搞微服务。还不说其他的问题

而且都不需要多高的 qps ,估计超过 100qps ,三天两头动不动全体重启所产生的不可预测异常,所产生的损失就足够老板重视了,否则你需要多复杂的重启更新流程来弄,每次重启手都得抖吧

重启一个单体项目 跟 重启一个服务,区别没那么大吧?单体项目跟一个服务从技术层面来说不都一个单体项目?只不过从架构上来说一个是服务,一个是单体项目。

假如淘宝的订单服务需要重启,重启期间如果不采取一些措施,那么这段时间所有用户一样下不了单,只不过是能登录能浏览。话又说回来,既然重启一个服务时可以采取措施,让流量暂时往其他节点跑,那么单体项目也可以这么干啊,不需要整体停服。

如果一些遗留服务只要维护不需要再投入成本和升级依赖,另一个核心服务需要不断维护并跟上最新框架,你搞成单体的不太方便吧

你打工的话,微服务提供更多就业岗位

你外包接业务的话,微服务比单体可以让甲方掏更多钱

你解决问题的话,微服务本身带来更多问题

你指挥好几个组的话,微服务如果拆分恰当,可以提高协作效率。

主要看你屁股在哪里。

确实是个问题

究其根本原因:你没有遇到足够大规模的业务而已,见了太多为了微服务而微服务的做法感觉有些“不过如此”的体验。

你可以猜测一下字节跳动的容器数量

主要矛盾是随着系统越来越大,有了业务解耦的需求,把大系统抽象成模块(服务),提升开发体验的,方便找到出系统瓶颈。

至于微服务的实现是 HTTP 、grpc,甚至是 jar 包 都没问题,取决于你怎么去划分业务,没有绝对正确,跟业务需求匹配就好了。

以前还有一个老东西——SOA ,也是面向服务架构,只是以过去系统规模,把单一的支付系统归为一个大的服务,现在有了微服务,再细化,把支付拆分成微信支付服务,支付宝服务,银联支付服务等。

至于分成支付系统服务,还是多个渠道支付服务拆分,都是没错的。业务的发展进度不同,都是合理的。

组织架构决定系统架构,并不完全是项目大不大来决定的

本来我维护一个没什么流量的小业务,重新部署 10 台机器就够了。现在你这么搞,我改一行代码就得重新部署一万台服务器。
本来这个服务 4c8g 的容器就够了,现在你这么搞,我直接上物理机也不够啊,天知道几千万行代码里哪些天杀的业务吃完了内存。
本来这个服务只有我们两三个人改,想什么时候发布就什么时候发布。现在你这么搞,每次发布前面排着几百个发布单,一个月才能发布成功一次。万一再出个故障要回滚代码,那真是画面太美我不敢看。。

啥,整个业务总用才用了不到 100 核?那你上什么微服务嘛……

脱离 Java ,在异构世界中会有更广大的视野。例如规模较大的团队把 Java 、Python 、Golang 不同的系统串起来…
而且,重点是为了解决康威定律带来的组织效率问题(大部分企业的沟通成本和协作效率的成本远大于设备的开支),如 1 楼所述。而为了微服务而实施微服务,这是一种本末倒置了。

我工作一两年经验的时候也思考过类似问题,也是接触到更大的项目、流量才有了实际的改观
1 、微服务本身就是模块化方案:相比单体,协作(功能设计、代码开发)、运维(版本、发布、监控)都更敏捷
2 、服务健壮性:单体一旦引入了内存溢出、死循环等问题,直接影响整个服务
3 、压力:(图挂了看文字描述不太理解)单体项目一旦过于庞大,如何做压力评估?哪些模块需要支持多少 qps ?出现某个模块压力,单体只能扩充一台实例
4 、。。。

简单说,idea 不是错误的方向. 因为最后是个大的分布式系统,每个服务独立出来开发调优挺好的.
但是用 k8s, docker, Java 这些 bloat 垃圾来做,就是实现上太差劲了而已

OP 你说的 4 个缺点,只有 2 是微服务的问题。但多个注册中心算什么问题?你还需要多个网关、多个链路追踪组件呢。多出这些就增加系统复杂度了?不,对于开发来说,一点复杂度都没增加。因为这些基础设施不需要你去维护,你只管用一行代码调用就行了。

至于其他 3 个问题,都是人的问题而非微服务的问题。算了,我还是老观点:不会封装和不会自动化运维的,老老实实玩单体就好。微服务肯定要比单体先进,自己没这个本事玩微服务就别玩,不要把锅甩给微服务。

看具体应用场景

DHH 16 年就发表过类似观点,好像是叫 Majestic Monolitch 吧。可以搜搜看。

适合你当前需要的,就是最好的。

说个题外话:社会环境和人情文化->企业文化->技术文化,理论要结合实际,现在 JAVA 八股文和技术栈基本都是微服务那套东西,这样的技术环境下 IT 从业者也会围绕这套东西来,但我相信大多数人了解实际,也知道如何做才能结合实际,但是在这样的企业文化下,这么做对己对团队没有太大好处,所以既然是为了自己和团队,以围绕 KPI 建设企业文化下,当然是盘子越大越好,至于装不装下那么多饭,那是另外一回事了。

微服务架构下有负载均衡,可以按先后顺序重启。

经验太少