03 | 微服务反模式与缺陷:代码共享反模式
译者简介:ASCE1885, 《Android 高级进阶》作者。 本文首发于Source Code Chain开发者社区,欢迎使用我的专属邀请链接加入一起交流。
微服务被称为“无共享”架构,实际上,我更倾向于把它看作是一种“尽可能少共享”的架构,因为微服务之间不可避免的总会存在某种程度的代码共享。例如,与其使用一个负责身份验证和授权的安全服务,你可能会更倾向于将安全功能相关的代码封装为一个 JAR 文件,例如 security.jar
,并提供给所有服务使用。如果安全性的保证是在服务内处理的,那么这种方式通常是一个很好的做法,因为它避免了每个请求都需要对安全服务发起远程调用,从而提高了系统的性能和可靠性。
然而,如果这种方式被滥用,那最终你将会碰到依赖的噩梦,如图 3-1 所示,其中每个服务都依赖于多个自定义的共享库。
这种级别的共享不仅打破了服务间的边界上下文,同时也引入了其他一些问题,包括总体可靠性,变更控制,可测试性和可部署性。
依赖过多
让我们回顾一下大多数面向对象软件应用的开发过程,不难发现共享带来的问题,特别是从单体应用架构迁移到微服务架构的时候。在大多数单体应用中,最重要的事情之一就是代码复用和共享。图 3-2 展示了在大多数单体应用架构中都会共享的两种构件(抽象类和公共的工具类)。
虽然创建抽象类和接口是大多数面向对象编程语言的常见实践,但当我们将单体应用中某个模块拆分为微服务时,这种实践会存在问题。自定义的共享类和工具类也存在类似的问题,例如共用的日期,字符串,计算等工具类。对于可能被潜在的数百个服务共享的代码你将作何处理呢?
微服务架构模式的主要目标之一就是尽可能的减少共享,这有助于保证每个服务的边界上下文,从而换来快速的测试和部署能力。使用微服务,所有这些都可以归结为变更控制和依赖关系。服务间依赖越多,想要隔离服务的变化就越困难,从而很难单独对一个服务进行测试和部署。服务间共享越多,依赖也就越多,从而导致了脆弱的系统,它难以测试和部署。
代码共享的技巧
避免这种反模式最好的方法就是服务间不共享代码,但这说起来容易,做起来难。正如我在本文开头实事求是的讲,总会有一些代码需要共享。那么这些代码要怎么放置呢?
图 3-3 展示了解决代码共享问题的四个基本技巧:共享工程,共享函数库,代码复制和服务合并。
共享工程的使用将会在共享工程中的公共源代码和每个服务工程之间形成编译期的绑定。虽然这使得软件开发和改动变得简单,但它是我最不喜欢的共享技巧,因为它在运行时会引入潜在的问题,使得应用程序变得不那么健壮。共享工程技巧的主要问题是沟通和控制,我们很难知道共享模块的变动及其原因,也很难控制我们服务是否需要特定的更改。想象一下,当你正准备发布你的微服务时,却发现有人对共享模块作了重大修改,从而迫使你不得不对服务代码作改动和重新测试,然后才能进行部署。
如果你想要共享代码,更好的方式是使用共享函数库(例如 .NET assembly 或者 JAR 文件)。但这种方式使得开发更加困难,因为任何对共享库中模块的改动,开发人员都必须首先打包函数库,然后重启服务,最后重新测试。然而共享库的优点是我们可以对库进行版本控制,从而更好的控制服务的部署和运行时的行为。如果共享库作了修改和版本化,那么服务的所有者可以决定何时合并该修改到服务中。
微服务架构中常见的第三种技巧是违反 DRY(Don't Repeat Yourself)原则,它在需要特定功能的所有服务中复制共享模块。虽然这种复制技术有风险,但它避免了依赖共享,并保留了服务的边界上下文。当复制的共享模块需要改动时,尤其是修复某个缺陷时,这种技巧就会出现问题。这种情况下,所有服务都要进行修改。因此这种技巧只对非常稳定的,几乎不会再改动的共享模块有用。
有时可能使用的第四种技巧是服务合并。假设两个或三个服务共享一部分相同的代码,而这些公共模块需要经常改动。由于这几个服务在公共模块改动时也都要跟着测试和部署,所以你可以把这些服务和公共模块整合到一个服务中,从而移除依赖的库。
关于共享库的一个建议是避免把所有共享的代码合并成单一的共享库,例如 common.jar
。使用 common.jar
你很难知道你的服务是否需要集成共享代码以及何时使用。更好的方法是把共享库拆分成具有独立上下文的多个库。例如创建基于上下文的 security.jar
, persistence.jar
和 dateutils.jar
等。这能够把不经常改变的代码和频繁改动的代码分离开,从而更容易认清每次更改的上下文,以及决定是否要立即把更改的内容集成到我们的服务中。
03 | 微服务反模式与缺陷:代码共享反模式相关推荐
- 【Springboot+vue项目开发】:网盘系统项目开发流程(03 微服务项目的划分及构建)
03 微服务项目的划分及构建 项目链接 问题1:IDEA如何将git下来的是工程转为maven工程 IDEA如何将git下来的是工程转为maven工程 问题2:jdk1.8的选用 问题3:Maven工 ...
- 03 | 微服务反模式与陷阱:代码共享反模式
译者简介:ASCE1885, <Android 高级进阶>作者. 本文首发于Source Code Chain开发者社区,欢迎使用我的专属邀请链接加入一起交流. 微服务被称为"无 ...
- 微服务中的面向切面编程和更多模式
目录 介绍 如何建立这篇文章? 在Java中使用代码(11 +,Spring boot 2.2 +,Spring Boot AOP,AspectJ) 在C#中使用代码(7,.NET MVC Core ...
- 《Spring Cloud与Docker微服务架构实战》配套代码
不才写了本使用Spring Cloud玩转微服务架构的书,书名是<Spring Cloud与Docker微服务架构实战> - 周立,已于2017-01-12交稿.不少朋友想先看看源码,现将 ...
- 微服务发展的历史_Spring Cloud Alibaba#03. 微服务的发展史
本文介绍微服务的发展历史以及架构演变过程 笔记对应视频学习地址: https://www.itlaoqi.com/chapter/2645.html 单体架构 单点架构面临的挑战 用户量越来越大,导致 ...
- 骚年快答 | 为何微服务项目都使用单体代码仓库?
[答疑解惑]| 作者 / Edison Zhou 这是恰童鞋骚年的第265篇原创内容 之前在学习微软的示例eShopOnContainers时发现它使用的是单体代码仓库库,之后又发现大家在进行微服务项 ...
- 微服务seata 1.4.2 分布式事务TCC模式示例
seata TCC模式和AT模式的基础环境是一样的,只是在实现方式上有所区别,而且TCC模式还可以和AT模式混合使用. 关于AT模式示例,可以参考seata 1.4.2 分布式事务AT模式示例. TC ...
- java b2b 开源_springcloud微服务多用户商城系统java_代码开源_B2B电商系统_B2C电商系统...
Spring Cloud是一系列框架的有序集合.利用Spring Boot的开发模式简化了分布式系统基础设施的开发,如服务发现.注册.配置中心.消息总线.负载均衡.断路器.数据监控等(这里只简单的列了 ...
- 亿级流量电商详情页系统实战(完整版):缓存架构+高可用服务架构+微服务架构(包含落地代码实操)
链接:百度网盘 请输入提取码 提取码:l472 更多儒猿专栏~ 欢迎关注儒猿技术窝
最新文章
- 彻底弄懂flex布局
- python中一共有多少个关键字-python – 搜索多个关键字的字符串列表
- 获取mysql可行方法_Mysql学习Java实现获得MySQL数据库中所有表的记录总数可行方法...
- Python 【快手】短视频的自动上传与发布实例演示,同时支持抖音、哔哩哔哩、小红书、微视、西瓜视频、微信视频号等平台的视频自动化同步发布
- Key_handle的学习
- Python-21-socket编程
- js数组如何按照固定的下标去重_js数组去重方法总结
- “年薪25万只是白菜价”已成过去式,AI 岗位年薪下降8.9%!
- java怎么查问题,java线上问题排查(日志、资源、代码定位)
- 二叉树 知道度 求节点数
- 1. java程序的编译命令_Java中javac、java、javap使用详解(java编译命令)
- Silverlight中使用Timer的方法
- python turtle绘图
- 红米note5linux刷机包_红米Note5刷机包 MIUI11
- 2020 数学建模 A题
- 挖金子修订版开发进行中
- python——设置渐变色
- 使用arduino控制多个PCA968516路舵机控制板从而达到最多可以控制992个伺服舵机
- Word 2016 大括号多行公式左对齐详解
- ios android 跨平台工具,15个很优秀的跨平台的移动开发工具