从单体服务到微服务:多模式 Web 应用开发记录<一>背景全局变量优化

news2024/11/14 13:23:32

背景

最近在做一个事:下线一个超级大单体服务。单一统计代码行数其实不够全面,反正项目 git clone 下来文件就有这么大:

在这里插入图片描述

这是一个已经存在了十年以上的服务,随着业务的发展,这个服务已经无法满足我们的需求。

我们统计了一下,有近 400 个页面菜单需要迁移到已经划分好领域的各个微服务之中。

其实最麻烦的还是前端页面,因为页面重写是比较麻烦的,涉及到大量的细节梳理,可能还需要前端、设计和产品同学的介入,想在 1 年甚至几个月全部重写完成在有限的资源情况下是不可能完成的任务。所以我提出了一个方案,低改动迁移 + 按需重写

  • 低改动迁移
    1. 设计一套机制,能够快速、便捷地将单体服务的页面迁移至微服务 Web 工程。
    2. 保持页面几乎无改动,无需前端介入,以确保迁移过程的高效性。
    3. 不可避免的,后端代码需要进行改造,以适应新的 MVC 框架。
  • 按需重写
    1. 结合实际业务需求和质量优化的工作,采用重写的方式。例如,对于一些核心的业务页面,我们可能会选择重写,以提供更好的用户体验和更高的性能。

接下来最关键的问题就是如何设计一套迁移机制:

  • 技术栈迁移
    • 从Spring + FreeMarker + Struts2 + Resin 迁移到 Spring Boot + Spring Web MVC + Embedded Tomcat + FreeMarker
  • 架构转变
    • 从纯动态数据交互最终演变为一个结合了静态页面渲染和动态数据交互的多模式 Web 应用(名词是我自己发明的)。这个新的架构可以更好地满足我们的业务需求,同时也提供了更好的用户体验。
  • 理论分析
    • Spring Web MVC 本身是一个基于 Java 的 MVC 设计模式的 Web 框架,且支持多种视图技术,包括但不限于 JSP、Freemarker、Thymeleaf 等

本文会记录在迁移的过程中碰到的一些有意思的点。在后续的文章中,我会详细介绍迁移经验,以及对其他面临类似问题的开发者的建议。

全局变量优化

工程结构设计

前面也提到了,后续我们的 Web 应用将最终演变为一个结合了静态页面渲染和动态数据交互的多模式 Web 应用,它融合了两种交互模式:一种是传统的服务器端渲染方式,利用FreeMarker模板引擎进行页面渲染;另一种是现在比较流行的前后端分离方式,通过 RESTful API 提供数据服务。

问题: 在之前的 Web 服务中,负责动态 JSON 数据交互的 Controller 通常使用 @RestController@ResponseBody 注解。而负责 FreeMarker 静态页面渲染的 Controller 则标注为@Controller,并且其方法(大部分)需要返回 String 类型。此外,FreeMarker 还需要使用全局变量和特定的响应参数等。

建议: 将原来的 Controller 和负责 FreeMarker 静态页面渲染的 Controller 进行区分。例如,可以将后者命名为XXFreeMarkerController,以便于识别。同时应该将所有与 FreeMarker 相关的代码放在一个单独的 package 中,以实现更好的管理。

全局变量优化

前面也提到了,FreeMarker 还需要使用全局变量,在 Spring MVC 中可以使用 @ControllerAdvice,比如:

@ControllerAdvice
public class GlobalFreeMarkerControllerAdvice extends BaseController {

    @Autowired
    private BasicService basicService;

    @ModelAttribute("basicService")
    public BasicService basicService() {
        return basicService;
    }

    /**
     * 获取当前登陆用户
     */
    @ModelAttribute("admin")
    public User admin() {
        return tryGetCurrentUser();
    }
}

在这个例子中,我定义了一个GlobalFreeMarkerControllerAdvice 类,并使用@ControllerAdvice注解标记它。我们在这个类中定义了两个方法:basicService()admin(),并使用@ModelAttribute注解标记它们。这样,每次处理请求时,Spring MVC都会先调用这两个方法,并将它们的返回值添加到模型中。

然而,这种做法有一个问题。@ControllerAdvice注解会对所有的Controller进行全局预处理,包括那些只提供RESTful API的Controller。这些Controller并不需要全局数据绑定。例如,"获取当前登录用户"的操作可能需要查询缓存或者Dubbo服务,这将会降低一部分请求的性能。

因此,当使用@ControllerAdvice注解时,我们需要注意其可能带来的性能影响,并根据实际情况做出合理的设计和优化。

为了解决这个问题,可以利用 @ControllerAdvice 注解的 basePackagesannotations 属性来限制其作用范围。这样,只有特定的 Controller 会受到全局预处理的影响。这种做法与上文提到的"将原来的 Controller 和负责 FreeMarker 静态页面渲染的 Controller 进行区分,放在不同的 package 中"的策略是一致的。这样就可以确保只有需要的 Controller 会受到全局预处理的影响,从而避免不必要的性能损失。

BaseController

当然也可以创建一个 BaseController

public abstract class BaseController {

    @ModelAttribute("attributeName")
    public String myModelAttribute() {
        return "attributeValue";
    }

    // ...
}

@Controller
public class MyController extends BaseController {

    // ...
}

在这个例子中,myModelAttribute() 方法只会对 MyController 的请求进行预处理,因为只有 MyController 继承了 BaseController。如果有其他的 Controller 不继承 BaseController,那么 myModelAttribute() 方法就不会对它们的请求进行预处理。

这种做法的优点是简单明了,易于理解和实现。但是,它也有一个缺点,那就是如果有很多 Controller 需要使用同一个 @ModelAttribute 方法,那么你就需要让它们都继承 BaseController,这可能会导致继承层次过深,代码结构复杂

欢迎关注公众号:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1465278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

胡夏爱意满满,浪漫尽显,心动不止。

♥ 为方便您进行讨论和分享,同时也为能带给您不一样的参与感。请您在阅读本文之前,点击一下“关注”,非常感谢您的支持! 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 全网热议的胡夏暗恋文学,浪漫指数爆表&#xff01…

力扣382.链表随机节点

Problem: 382. 链表随机节点 文章目录 题目描述思路复杂度Code 题目描述 思路 由水塘抽样易得,当遇到i个元素,有 1 / i 1/i 1/i的概率选择该元素;则在实际操作中我们定义一个下标i从1开始遍历每次判断rand() % i 0(该操作就是判断…

Verilog刷题笔记35

题目: Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel0 should select in[0], sel1 selects bits in[1], sel2 selects bits in[2], etc. 解法: module top_module( input [255:…

猜谜“龘”人速来!网安人元宵灯谜有礼了

​​灯笼高挂,星光璀璨,品味糯叽叽的元宵,以灯谜为媒,亚信安全邀你共赴元宵佳节。 热辣滚烫的班先别上了,文末有奖竞猜,快来参与! 喜闹元宵 谜面一:一路向上成大业; 谜…

HTML5新婚、年会、各种聚会的现场抽奖活动(附源码)

文章目录 1.抽奖平台设计来源1.1 主界面效果1.2 抽奖效果1.3 中奖效果 2.效果和源码配置2.1 动态效果2.2 人员信息配置2.3 奖品信息配置2.4 抽奖音效配置2.5 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/deta…

第一节-docker介绍

这里写自定义目录标题 一、什么是docker二、docker和virtual machine三、docker架构 一、什么是docker docker是一种容器引擎,用于构建、部署、运行应用程序和服务。 docker的每个容器通过沙箱机制相互隔离,互不干扰。 docker容器技术相比传统的虚拟机有…

六、回归与聚类算法 - 模型保存与加载

目录 1、API 2、案例 欠拟合与过拟合线性回归的改进 - 岭回归分类算法:逻辑回归模型保存与加载无监督学习:K-means算法 1、API 2、案例

费舍尔FISHER金属探测器探测仪维修F70

美国FISHER LABS费舍尔地下金属探测器,金属探测仪等维修(考古探金银铜探宝等仪器)。 费舍尔F70视听目标ID金属探测器,Fisher 金属探测器公司成立于1931年,在实验条件很艰苦的情况下,研发出了地下金属探测器…

昨天Google发布了最新的开源模型Gemma,今天我来体验一下

前言 看看以前写的文章,业余搞人工智能还是很早之前的事情了,之前为了高工资,一直想从事人工智能相关的工作都没有实现。现在终于可以安静地系统地学习一下了。也是一边学习一边写博客记录吧。 昨天Google发布了最新的开源模型Gemma&#xf…

常见锁策略,CAS,synchrodized原理讲解

🎥 个人主页:Dikz12📕格言:那些在暗处执拗生长的花,终有一日会馥郁传香欢迎大家👍点赞✍评论⭐收藏 目录 常见锁策略 乐观锁和悲观锁 轻量级锁和重量级锁 自旋锁和挂起等待锁 读写锁 公平锁和非公平锁…

【ctfshow—web】——信息搜集篇1(web1~20详解)

ctfshow—web题解 web1web2web3web4web5web6web7web8web9web10web11web12web13web14web15web16web17web18web19web20 web1 题目提示 开发注释未及时删除 那就找开发注释咯,可以用F12来查看,也可以CtrlU直接查看源代码呢 就拿到flag了 web2 题目提示 j…

【数据结构】顺序表实现的层层分析!!

关注小庄 顿顿解馋◍˃ ᗜ ˂◍ 引言:本篇博客我们来认识数据结构其中之一的顺序表,我们将认识到什么是顺序表以及顺序表的实现,请放心食用~ 文章目录 一.什么是顺序表🏠 线性表🏠 顺序表 二.顺序表的实现&#x1f3e0…

ShardingSphere 5.x 系列【14】广播表、单表

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1.广播表1.1 概述1.2 案例演示1.2.1 环境准备1.2.2 配置1.2.3 测试2. 单表2.…

2024年.NET框架发展趋势预测

.NET框架仍然是全球开发人员的编程基石,为构建广泛的应用程序提供了一个通用的、强大的环境。微软对创新的坚定承诺见证了.NET的发展,以满足技术领域不断变化的需求。今年,在更广泛的行业运动、技术进步和开发者社区反馈的推动下,…

记一次:Python的学习笔记五(Django集成swagger)

上一篇集成在了gatway上了,但给别人使用swagger的时候还是没有文档,如何集成swagger呢? python版本:Python 3.11.5 Django版本:4.2.7 0、Swagger 文档介绍 Swagger 是一种用于 RESTful API 的开源框架,…

2种方法,教你使用Python实现接口自动化中的参数关联

通常在接口自动化中,经常会参数关联的问题,那么什么是参数关联? 参数关联就是上一个接口的返回值会被下一个接口当做参数运用,其中Python中可以实现参数关联的方法有很多种,今天小编给大家介绍下,如何通过…

SQL Server ID 自增不连续、删除数据后再次插入ID不连续

背景 当我们使用SQL Server 进行数据库操作时,经常会把 Table 的 ID 设置成主键自增 PRIMARY KEY IDENTITY,但是这样做存在一个问题就是 当我们删除一行数据后,再次添加后会看到ID的顺序不连续,如下所示。 查询一下:…

冲突管理最佳实践

任何团队都无法避免冲突,如何有效管理冲突,将冲突转化为团队成长和凝聚的动力,是任何一个团队管理者的必修课。原文: Best Practices for Managing Conflict in Engineering Management Obie Fernandez Unsplash 冲突在任何组织中都不可避免&…

排序第三篇 直接插入排序

插入排序的基本思想是: 每次将一个待排序的记录按其关键字的大小插入到前面已排好序的文件中的适当位置, 直到全部记录插入完为止。 一 简介 插入排序可分为2类 本文介绍 直接插入排序 它的基本操作是: 假设待排充序的记录存储在数组 R[1……

【鸿蒙 HarmonyOS 4.0】状态管理

一、介绍 资料来自官网:文档中心 在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状…