当前位置: 首页 > news >正文

Spring 应用合并之路(一):摸石头过河 | 京东云技术团队

公司在推进降本增效,在尝试多种手段之后,发现应用太多,每个应用都做跨机房容灾部署,则最少需要 4 台机器(称为容器更合适)。那么,将相近应用做一个合并,减少维护项目,提高机器利用率就是一个可选方案。

经过前后三次不同的折腾,最后探索出来一个可行方案。记录一下,分享出来,希望对有相关需求的研发童鞋有所帮助。下面按照四种可能的方案,分别做介绍。另外,为了方便做演示,专门整了两个演示项目:

•diguage/merge-demo-boot — 合并项目,下面简称为 boot。

•diguage/merge-demo-web — 被合并项目,下面简称为 web。

一、Jar 包引用

这个方式,可能是给人印象最容易的方式。仔细思考一下,从维护性的角度来看,这个方式反而是最麻烦的方式,理由如下:

1.web 项目每次更新,都需要重新打包发布新版; boot 项目也需要跟着更新发布。拉一次屎,脱两次裤子。属实麻烦。

2.还需要考虑 web 项目的加载问题,类似下面要描述的,是否共用容器:共用容器 — 这是最容器想到的方式。但是这种方式,需要解决 Bean 冲突的问题。不共用容器 — 这种方式需要处理 web 容器如何加载的问题。默认应该是无法识别。

基于这些考虑,这种方式直接被抛弃了。

二、仓库合并,公用一套容器

这是第一次尝试使用的方案。也是遇到问题最多的方案。

1.将两个仓库做合并。

1.将 web 仓库的地址配置到 boot 项目里: git remote add web git@github.com:diguage/merge-demo-web.git;

2.在 boot 项目里,切出来一个分支: git switch -c web;

3.将 web 分支的提交清空: git update-ref -d HEAD,然后做一次提交;

4.将 web 项目的代码克隆到 web 分支上: git pull --rebase --allow-unrelated-histories web master;注意,这里需要加 --allow-unrelated-histories 参数,以允许不相干的仓库进行合并。

5.从 boot 项目的 master 分支上,切出来一个合并分支: git switch -c merge;

6.将 web 项目向 boot 项目合并: git merge --allow-unrelated-histories web;注意,这里需要加 --allow-unrelated-histories 参数,以允许不相干的仓库进行合并。

7.处理代码冲突,完成合并即可。

2.配置文件的合并于归整。为了防止同名配置文件冲突,需要把 web 项目的配置文件调整到一个文件夹下,这里设定为 web 目录。然后,需要把 web 项目的配置文件,让 boot 可以加载到。这个调整相对简单,只需要一个注解即可 @ImportResource({“classpath:web/spring-cfg.xml”})。

3.调整完配置文件,接着遇到的问题就是上面提到的 Bean 冲突的问题。由于两个项目都访问相同的数据库, Dao 及 Service 层很多很多类都是同名的。另外,在 web 项目里,Dao 是基于 iBATIS 开发的,而在 boot 项目里,DAO 是基于 MyBATIS 开发的。所以,只能给 web 项目的相关代码做重命名(严谨一点是给 Spring Bean 的 beanName 做重命名操作)。这又带来了新问题:原来的项目里,注入方式是根据名称注入的,就需要改动大量的代码,给相关的 Bean 变量做重命名操作。这无形中增加了很多的复杂度和不确定性。

经过不断折腾,这种方式被迫放弃。

三、仓库合并,Spring Boot 父子容器

在经过上述方式折腾后,就想到了另外一个方案:可以考虑使用父子容器的方式来搞。接着就查到了这篇文章: Context Hierarchy with the Spring Boot Fluent Builder API。感觉这种方式挺不错,就尝试了一下。

1.代码合并及文件调整,跟上述步骤类似,这个后面就不再赘述。

2.按照文章中的介绍,使用父子容器的方式来加载两个项目。代码如下:

3.原以为,这种方式属于父子两个容器,即使有同名的 Bean 应该也没有影响。但是,经过实践才发现,上面这个猜测是错误的。Spring Boot 在启动的时候,它背后做了检查,如果两个容器有同名的 Bean,它也会报错。也会带来像上述方式那样的大量重命名。折腾一两天,最后还是放弃了这种寄予厚望的方式。

package com.diguage.demo.boot;import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;/*** @author D瓜哥 · https://www.diguage.com*/
public class DemoBootApplication {public static void main(String[] args) {new SpringApplicationBuilder().parent(BootConfig.class).web(WebApplicationType.NONE).child(WebConfig.class)// 如果有第三个项目,可以作为子容器的兄弟容器加载。// .sibling(SiblingConfig.class).run(args);}@Configuration@ImportResource({"classpath:spring-cfg.xml"})@ComponentScan(basePackages = "com.diguage.demo.boot")public static class BootConfig {}@Configuration@ImportResource({"classpath:web/spring-cfg.xml"})public static class WebConfig {}
}

| | Spring Boot 背后是否做了检查,这个是根据报错信息的猜测,没有翻看代码,所以这个猜测有一定的不确定性。有机会翻一下代码,查看一下具体原因。 |

革命尚未成功,且听下回分解……

作者:京东科技 李君

来源:京东云开发者社区 转载请注明来源

相关文章:

Spring 应用合并之路(一):摸石头过河 | 京东云技术团队

公司在推进降本增效,在尝试多种手段之后,发现应用太多,每个应用都做跨机房容灾部署,则最少需要 4 台机器(称为容器更合适)。那么,将相近应用做一个合并,减少维护项目,提高…...

Android13配置selinux让system应用可读sys,proc,SN号

system权限应用读sys,proc目录及SN号 Android13预置的system应用,需要读/sys, /proc目录,读(SN)serial number号, 需要修改selinux配置,否则会报avc错. 其修改方法会比Android11复杂一些. 实现 system_app.te中添加…...

防勒索病毒攻击的关键措施

【作者】朱向东 中原银行 高级工程师 在当今数字化时代,勒索病毒成为了企业和个人面临的一项严峻威胁。勒索病毒攻击可以导致数据丢失、系统瘫痪以及经济损失。为了保护自己和组织的利益,采取一系列的防范措施是至关重要的。下面是一些关键的措施&#…...

代表团坐车 - 华为OD统一考试

OD统一考试(B卷) 分值: 100分 题解: Java / Python / C++ 题目描述 某组织举行会议,来了多个代表团同时到达,接待处只有一辆汽车可以同时接待多个代表团,为了提高车辆利用率,请帮接待员计算可以坐满车的接待方案输出方案数量。 约束: 一个团只能上一辆车,并且代表团…...

运用Jmeter进行登录测试

开始了解Jmeter,写篇关于Jmeter的博客做备忘,这里以苏宁易购网站的登录请求为例实战来说明测试计划元件,创建一个 Web 测试计划。 今天简单介绍Jemeter的入门,Jmeter 的安装这边就跳过,直接讲述如何使用JMETER,如何运用Jmeter进行测试。 a.下载jmeter软件 b.安装…...

Docker学习与应用(四)-容器数据卷

1、容器数据卷 1)什么是容器数据卷 docker的理念回顾 将应用和环境打包成一个镜像! 数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化 MySQL,容器删…...

CentOS 7.6下HTTP隧道代理的安全性考虑

在CentOS 7.6上配置HTTP隧道代理时,安全性是一个不可忽视的重要因素。以下是对HTTP隧道代理安全性的一些关键考虑因素: 1. 加密和数据安全 使用强加密算法:确保您使用的是经过广泛认可和强化的加密算法,如AES-256-GCM。数据完整…...

Mockito+junit5搞定单元测试

目录 一、简介1.1 单元测试的特点1.2 Mock类框架的使用场景1.3 常见的Mock框架1.3.1 Mockito1.3.2 EasyMock1.3.3 PowerMock1.3.4 Testable1.3.5 比较 二、Mockito的使用2.1 导入pom文件2.2 mock对象和spy对象2.3 初始化mock/spy对象的方式2.4 参数匹配2.5 方法插桩2.6 InjectM…...

PostgreSQL获取当天、昨天、本月、上个月、本年、去年的数据

gps_time为timestamp类型日期字段 获取当天的数据 WHERE DATE_TRUNC(day, gps_time) CURRENT_DATE --或 WHERE DATE(gps_time) CURRENT_DATE获取昨天的数据 WHERE DATE_TRUNC(day, gps_time) CURRENT_DATE - INTERVAL 1 day获取本月的数据 WHERE DATE_TRUNC(month, gps_…...

XCTF:stage1[WriteUP]

从题目中下载到图片: 考虑图片是png,隐写方式有可能是高宽修改,也可能是色相隐藏,色彩通道位隐藏等等 使用stegsolve对图片进行一下伽马、颜色转换 在图片的左上角就显示出了一个二维码 使用QR_Rresearch工具对二维码扫描 获得一…...

STM32CubeMX教程13 ADC - 单通道转换

目录 1、准备材料 2、实验目标 3、ADC概述 4、实验流程 4.0、前提知识 4.1、CubeMX相关配置 4.1.1、时钟树配置 4.1.2、外设参数配置 4.1.3、外设中断配置 4.2、生成代码 4.2.1、外设初始化调用流程 4.2.2、外设中断调用流程 4.2.3、添加其他必要代码 5、常用函数…...

矩阵的乘法

首先矩阵的乘法定义如下&#xff1a; #include <stdio.h> int main() { int i 0; int j 0; int arr[20][20] { 0 }; int str[20][20] { 0 }; int s[20][20] { 0 }; int n1 0; int n2 0; int m2 0; int z 0; int m1 0;…...

python爬取招聘网站数据

这段代码是使用Selenium自动化测试模块进行网页爬取的示例代码。它通过模拟人的行为在浏览器中操作网页来实现爬取。具体的流程如下&#xff1a; 导入所需的模块&#xff0c;包括Selenium、时间、随机、csv等模块。打开浏览器&#xff0c;创建一个Chrome浏览器实例。设置要爬取…...

灌区信息化方案(什么是现代化灌区,如何一步到位)

一、系统概述 详情&#xff1a;https://www.key-iot.com.cn/ 本灌区信息化方案以星创易联公司的各类智能设备为基础,通过其产品完成水文、雨情、土壤等多源异构数据的采集,以无线自组网的方式实现数据传输,并在后台管理中心建立信息化软件平台,对数据进行融合处理。系统实现对…...

jmeter自动录制脚本功能

问题排查&#xff1a; 建议用 google浏览器&#xff1b; 重启一下jmeter&#xff1b; 过滤规则重新检查下&#xff1b; 看下代理设置是否正常&#xff1b; 注意&#xff1a;下面的的过滤设置中 用的都是正则表达式的规则。...

十一、工具盒类(MyQQ)(Qt5 GUI系列)

目录 ​编辑 一、设计需求 二、实现代码 三、代码解析 四、总结 一、设计需求 抽屉效果是软件界面设计中的一种常用形式&#xff0c;可以以一种动态直观的方式在有限大小的界面上扩展出更多的功能。本例要求实现类似 QQ 抽屉效果。 二、实现代码 #include "dialog.…...

postgresql 查询字段 信息

SELECT base.“column_name”, col_description ( t1.oid, t2.attnum ), base.udt_name, COALESCE(character_maximum_length, numeric_precision, datetime_precision), (CASE WHEN ( SELECT t2.attnum ANY ( conkey ) FROM pg_constraint WHERE conrelid t1.oid AND contyp…...

antv/x6_2.0学习使用(四、边)

一、添加边 节点和边都有共同的基类 Cell&#xff0c;除了从 Cell 继承属性外&#xff0c;还支持以下选项。 属性名类型默认值描述sourceTerminalData-源节点或起始点targetTerminalData-目标节点或目标点verticesPoint.PointLike[]-路径点routerRouterData-路由connectorCon…...

C++ stack用法总结

std::stack 是 C 标准模板库&#xff08;STL&#xff09;中的容器适配器&#xff0c;它提供了栈&#xff08;stack&#xff09;的功能&#xff0c;基于其他序列容器实现。以下是 std::stack 的用法总结&#xff1a; 包含头文件&#xff1a; #include <stack>创建 std::…...

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax概述

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax概述 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax快速入门 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax类图 【大数据进阶第三阶段之Datax学习笔记】使用…...

PHP 基础编程 2

文章目录 时间函数dategetdatetime 使用数组实现登录注册和修改密码简单数组增加元素方法修改元素方法删除元素方法 具体实现方法数组序列化数组写入文件判断元素是否在关联数组中&#xff08;登录功能实现&#xff09;实现注册功能实现修改admin用户密码功能 时间函数 时区&am…...

git merge origin master 和 git merge origin/master 的区别

git merge origin master和git merge origin/master的区别 1. git checkout dev 2. git fetch origin master 3. git merge origin release 把 origin/master&#xff0c;heads/release merge到 heads/dev1. git checkout dev 2. git fetch origin master 3. git me…...

数据挖掘 模糊聚类

格式化之前的代码&#xff1a; import matplotlib.pyplot as plt#绘图 import pandas as pd#读取数据集 from sklearn.preprocessing import scale from sklearn.cluster import DBSCAN#聚类 from sklearn import preprocessing#数据预处理的功能&#xff0c;包括缩放、标准化…...

Vue2和Vue3各自的优缺点以及区别对比

Vue2和Vue3各自的优缺点以及区别对比 Vue2的优点&#xff1a; 成熟稳定&#xff1a;Vue2是一个经过长时间发展和测试的成熟版本&#xff0c;广泛应用于各种项目中。 生态系统丰富&#xff1a;由于Vue2的流行程度&#xff0c;它的生态系统相对较为完善&#xff0c;有大量的插件…...

手写一个加盐加密算法(java实现)

目录 前言 什么是MD5&#xff1f;&#xff1f; 加盐算法 那别的人会不会跟你得到相同的UUID&#xff1f; 如何使用盐加密&#xff1f; 代码实现 前言 对于我们常见的登录的时候需要用到的组件&#xff0c;加密是一个必不可少的东西&#xff0c;如果我们往数据库存放用户…...

基于Springboot的在线考试系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88499371 mysql5、mysql8都可使用 内含配置教程文档&#xff0c;一步一步配置 Springboot所写 管理员页面 学生页面...

【React系列】JSX核心语法和原理

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. ES6 的 class 虽然目前React开发模式中更加流行hooks&#xff0c;但是依然有很多的项目依然是使用类组件&#x…...

【C++初阶(九)】C++模版(初阶)----函数模版与类模版

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…...

Permission denied

Permission denied&#xff1a;权限被拒绝&#xff0c;没有访问文件的权限。 查询对文件的权限&#xff1a; ls -l 文件名称 r为可读权限&#xff0c;w为可写权限&#xff0c;x为可执行权限。 授权文件rwx&#xff0c;可读可写可执行权限&#xff1a; chmod 777 文件名称 如…...

轻松学会电脑如何录制音频

随手录音&#xff0c;保留证据以便后续出现问题进行判定&#xff0c;或者保存会议音频记录方便后续根据录音内容整理自己会议记录不足之处等等&#xff1b;越来越多的地方需要用到录音&#xff0c;那么在电脑上该如何进行音频录制呢&#xff1f;特别是使用比较广泛的Windows电脑…...