微服务如何设计公共组件库

learn_more 发布于 2017/11/02 14:30
阅读 1K+
收藏 0

@黄勇 老师你好,请教您一个问题,希望能够得到您的解答。

微服务提倡各个服务独立,互不依赖,甚至提倡各个微服务之间的数据库、抽象接口、utility 都不共享,对此我的问题是我们公司积累了这么久的公共组件库(比如一些常用逻辑参数校验组件、报表导出公共类、返回值枚举等)难道都不能在微服务中共享使用了吗?是不是说每个微服务互相独立就要把这些公共组件都复制到各自的项目中各自维护?

我本来的设计是这样的,把这些公共组件单独建立一个项目封装成一个jar,然后通过maven的方式依赖引入到各自项目中,但是他们懂微服务的说,这样子虽然做到了代码重用,遵循了DRY原则,但是带来了一个很大的问题就是:微服务项目这么多,如果公共组件库的代码发生变化,那么是不是要对每个微服务项目测试呢?因此,他们觉得各个微服务都应该拷贝一份这个代码,要改也是改自己那份不会影响到其他的微服务!

对此,其实大家看法不一,希望 @黄勇 老师帮我梳理一下这个公共组件库应该如何在系统中搭建。谢谢

加载中
1
learn_more
learn_more

引用来自“黄勇”的评论

问题非常好!

微服务架构也有一个不断演化的过程,优雅的架构不是一天形成的,牛逼的架构也未必适合现在的应用场景,架构是随着业务不断变化和升级的。

对于你说到的代码重用问题而言,如果我们将这些代码做成公共包(jar 包),再让其他服务依赖它,这样重用问题似乎解决了,但却引发了其他新的问题,当我们升级这个 jar 包,需要发布所有依赖它的服务。那么反过来说,代码不重用,真的就是目前遇到最大的问题吗?如果不是,为什么要考虑代码重用问题,而不是其他更加重要的问题?比如:让服务合理切分并分工,从而提高团队工作效率。

我的建议是:公共组件可以有,但绝不要做到服务内部依赖(jar 包依赖),而要做到服务间通信(rpc 调用),将公共组件做成公共服务,当我们发布一个公共服务时,无需发布其他服务。

补充:对于和业务不相关,并且变化较少的公共代码,不妨可以考虑做成公共 jar 包,毕竟它不会经常发布。

谢谢黄老师的解答,对您的这段回复我是这样理解的,和业务相关的代码,应该单独抽离出一个服务,而且服务与服务之间通过RPC解耦依赖;对于非业务相关(比如框架、util)的代码,应该打成jar包给各项目复用;

对于复用jar包的代码是否稳定(以后会变化),我觉得可以通过版本标记来解决,

比如 A服务和 B服务都依赖 C-0.1.jar,

假如 A服务使用 C-0.1.jar 发现一个bug,那么这个bug必须修复,这个时候升级为 C-0.2.jar ,同时也要通知 B服务更新且重新发布;

假如 A服务使用 C-0.1.jar 发现功能不够,此时同样升级 C-1.0.jar,但是不要通知 B服务更新,B服务依然使用旧的jar。

最后,再次谢谢 @黄勇 老师!

0
高山流水情
高山流水情

他们懂微服务的说...”,楼主,想问下他们工作几年了,真的懂微服务吗?

learn_more
learn_more
谢谢您的回复。主要是网上很多这样的评论,可以参考如下文章 https://www.qcloud.com/community/article/348977 http://geek.csdn.net/news/detail/79014
0
黄勇
黄勇

问题非常好!

微服务架构也有一个不断演化的过程,优雅的架构不是一天形成的,牛逼的架构也未必适合现在的应用场景,架构是随着业务不断变化和升级的。

对于你说到的代码重用问题而言,如果我们将这些代码做成公共包(jar 包),再让其他服务依赖它,这样重用问题似乎解决了,但却引发了其他新的问题,当我们升级这个 jar 包,需要发布所有依赖它的服务。那么反过来说,代码不重用,真的就是目前遇到最大的问题吗?如果不是,为什么要考虑代码重用问题,而不是其他更加重要的问题?比如:让服务合理切分并分工,从而提高团队工作效率。

我的建议是:公共组件可以有,但绝不要做到服务内部依赖(jar 包依赖),而要做到服务间通信(rpc 调用),将公共组件做成公共服务,当我们发布一个公共服务时,无需发布其他服务。

补充:对于和业务不相关,并且变化较少的公共代码,不妨可以考虑做成公共 jar 包,毕竟它不会经常发布。

黄勇
黄勇
回复 @公孙二狗 : 这些就不是服务,这样的代码应该在数据框架层面或者公共组件库中。
公孙二狗
公孙二狗
比如一些常用逻辑参数校验组件、返回值枚举等:这个明显是不服务,是一些底层代码,让人家怎么怎么发布成服务呢。
0
苏蚊子

我们就是这么做的,框架和通用工具类做成公共jar包,本来就很少改。

公孙二狗
公孙二狗
关键是功能的输入输出和说明写的一样,这样修改实现没关系,如果输入输出都变化了,那可以重写新的接口,并不会影响已有的实现。
learn_more
learn_more
嗯,谢谢,同感同感
返回顶部
顶部