>>分享流行的Java框架以及开源软件,对孙卫琴的《精通Spring:Java Web开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 20349 个阅读者 刷新本主题
 * 贴子主题:  微服务拆分实践 回复文章 点赞(0)  收藏  
作者:Jacky    发表时间:2020-06-16 05:56:07     消息  查看  搜索  好友  邮件  复制  引用

      
      点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

     说到微服务就不得不说拆分了,服务拆分要有一些指导依据。

拆分依据

微服务的理论知识有大量的分享,这里是我对微服务理论基础认识的一些观点:
  • 小,且专注于做一件事情,即满足单一职责原则。
  • 运行在独立的进程中。
  • 轻量级的通信机制,RPC或者HTTP或者MQ。
  • 松耦合,独立部署。
  • 康威定律:设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构。
服务拆分依据结合上面的理论基础充分考虑了以下因素:
  • 业务和领域模型
  • 技术、业务量等其他因素
  • 团队
业务应该说是最实在的,也是最好理解而且最容易把握的。虽然领域的有界上下文从理论上能指导拆分,但是万万需要拆分的不是一个全新的系统,而是一个在线上稳定运行了很长时间的,很多人一砖一瓦堆砌起来的,并且仍然在持续添砖加瓦,不管是桥梁,还是高楼,我们的目的是让系统运行的更健壮,而不是拆成七零八碎,所对于这样的老系统,用领域拆分需要结合团队现状,理论结合实际,事半功倍。

     运行时隔离也是很重要的拆分依据,会根据一些具有特定功能的API单独拆分出来作为一个微服务,和其他微服务隔离,避免相互影响,避免一个老鼠害了一锅汤。比如一些文件上传一类的API,特征是响应时间长,对IO依赖比较多,其线程池需要特殊配置;比如多线程利用CPU来换取响应时间的等等。

     对于康威定理,究竟是团队影响拆分,还是拆分影响团队,那就需要均衡利弊了。如果是因为拆分微服务,而拆分了团队,那势必会影响到团队的稳定性和团队成员的归属感,尤其是一个组建很久的老团队。反之,团队负责多种业务,也没有明显的职责区分,就要考虑是否拆分团队,明确拆分后的团队职责。

     对于正在运行的系统,如何拆分和拆分为多大的粒度,事实上是不能有太过理论化理想化,更需要深入项目本身和该项目团队,了解业务,人和代码。不能是拆迁队,也不是修缮,应该是拆成各种形状的合理大小的积木。

     孰重孰轻很难说明白,团队不一样项目不一样,实践就不一样,找到适合自己团队的方法。

拆分粒度

拆分粒度不应该过分追求细粒度,要考虑适中不能过大或过小。按照单一职责原则和康威定律,在业务域、团队还有技术上平衡粒度。拆分后的代码应该是易控制,易维护的,业务职责也是明确单一的。

拆分过程实践

在拆分过程不得不考虑的是业务在跑,砖在砌,不能停,而且拆分工作也必须得进行,过程上不能一部到位,必须一步一步走,也由于此拆分后落地上线也要稳妥。所以,过程上,我也采用了比较稳妥的战术, 先拆分为maven module,然后在拆分为微服务可部署构件。这样的好处是,拆分过程不影响业务迭代,而且可以随意组合成单体应用和微服务app,并且还可以事先测试和验证拆分,最大限度的降低微服务化实施的风险。

     下面是拆分代码过程实践经验:

     1). 设计module骨架

     module骨架的设计是基础,影响最终拆分结果,拆分成功的向导。按照技术,业务,部署打包,测试这几个维度来规划设计,下面是一个参考。

     最终骨架模型:    

root web app
    webapp  //war module,打包为单体war,整体部署
    micro-services //微服务pom module
        user-service
        customer-service
        order-service
        other-service
        api-gateway
    biz //业务相关的module
        entitys             //所有实体类
        biz-base            //一些无法拆分的代码上有依赖的服务
        biz-user            //用户业务
        biz-customer        //客户业务
        biz-order           //订单业务
        ...                
    commons
        async-framework  //一部框架
        utils               //工具类

  2). 拆分技术commons

     作为第一步,先对整个工程按业务和功能进行了maven多module的拆分。拆分过程没有技巧可言,一步一步走,一步一个脚印。首先是分离出技术上的commons,感觉这应该是最好拆分的了,把相关的类重构到一个包里,在分离出一个module即可。实际过程并非如此,因为是老项目,这类commons也并没有想象的容易,经过很多人的添砖加瓦,并没有完全按照单一职责原则来砌,根本就是把业务特征的代码也放到了技术类代码中,不过review代码后感觉还好,微遵循的毕竟是少数,那就先重构代码,把业务特性的砖从类里移出去。

     3). 拆分entity

     很多在业务代码上都会共享entity类,通常没法也没法把entity类分门别类,最简单就是把所有的entity类放到一个module,谁需要谁依赖的原则。entity类也没有太多jar依赖和业务依赖,也不会形成污染源。

     4). 公共业务

     同commons和entity方法,不在复述,也被各个业务依赖,这种业务大部分是过渡性的,在未来迭代演进时可以通过其他方式抽象集成。

     5). 拆分业务代码

     拆分业务是最痛苦的事情了,这个要看原来的代码整洁度和互相依赖程度,一般采取2中方法:
  • 新建业务module,加入基础module的pom依赖,再从源module复制和该业务module相关的代码(包括单元测试代码)过来,解决编译错误和单元测试错误,完成本业务拆分。
  • 从源module复制一个新业务module,保持代码一致,先删除和本义务无关的代码(包括单元测试代码),再删除无关的pom依赖,解决编译错误和单元测试错误,完成本业务拆分。
选择哪种方法,可以根据代码整洁度和互相依赖程度,如果代码很整洁且相互依赖较弱,可以采取前者,否则就采取后者。

     6). 拆分微服务

     有了以上的拆分基础,可以在合适的业务迭代将各个微服务module迁移到不同的代码仓库,完成进一步隔离管理。


----------------------------
原文链接:https://www.jianshu.com/p/80832f2d7a35
作者: 铁汤
程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-06-18 19:33:08 重新编辑]
  Java面向对象编程-->对象的生命周期
  JavaWeb开发-->开发JavaMail Web应用
  JSP与Hibernate开发-->持久化层的映射类型
  Java网络编程-->通过JDBC API访问数据库
  精通Spring-->绑定CSS样式
  Vue3开发-->Vue组件开发高级技术
  Spring事务容易掉入的坑
  Spring 5 webflux响应式编程 - 但时间也偷换概念
  @Configuration注解的用法
  Spring MVC服务器端推送的两种方式
  Spring MVC实现国际化的几种方式
  @SessionAttributes的用法
  SpringMVC Model、ModelMap和ModelAndView的区别和用法
  什么是Redis?Redis的各项功能解决了哪些问题?
  Spring Cloud构建微服务架构的分布式配置中心
  如何实现Git服务间同步
  Zabbix后端存储ES的优化实践
  Spring Boot 整合 Ehcache
  使用idea和gradle编译spring5源码
  反向代理、负载均衡!优秀的 Nginx 是如何做到的?
  Spring MVC:切面的应用
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。