拯救老旧工程,记桥接 SpringMVC 与 Stripes 框架

本贴最后更新于 2395 天前,其中的信息可能已经时移俗易

背景:

  公司基础设施部门推出了自己的微服务框架(以下简称 M),要求所有业务应用都要接入进去,但坑爹的是 M 只提供了 SpringMVC 工程的 support,对于采用 Stripes 作为 MVC 框架的应用并不支持,所以就必须重构这个 Stripes 应用。

  M 虽然代替 Tomcat 自己实现了 IO,工作线程池,服务注册发现等等,但还是提供了对 Servlet 规范的简单支持(移除了 web.xml,filter,listener, 打包方式也改成了 tar.gz,保留了 ServletContext,request,response 等等)。

思路与分析:

  由于现有应用的业务逻辑还是比较复杂(沉淀了 3,4 年),且涉及到多个 APP 端和其他第三方的交互,所以如果想对应用做完全的重构是一件非常头痛的事情,不仅要投入大量的后端,测试等人力成本,而且整个重构周期也会比较长,影响到对其他需求的响应。

  于是在想:既然 SpringMVC 和 Stripes 都遵循 Servlet 规范,而 M 又能支持 SpringMVC,是否可以通过 SpringMVC 拦截到所有请求后,把之前的老接口的请求转发给 Stripes 处理,以后新开发的接口就直接走 SpringMVC,这样既兼容了公司的 M 框架也对原有应用的改动较小,开发周期短,测试人员只需要验证一些系统边界和主要流程,不用再挨个挨个验证已有的业务逻辑,这样可以节省大量人力成本,缩短开发周期。

  SpringMVC 是目前最流行的 MVC 框架,是 Spring 庞大家族的一员,而 Stripes 也是一个非常轻量的 MVC 框架,但是 SpringMVC 的 Controller 跟 Stripes 的 ActionBean 有个很明显的区别就是前者是单例的,跟状态无关,所有的请求参数都是封装在 ServletRequest 中的,而后者是 prototype,每次请求都会重新生成一个 ActionBean 对象。

动手实现原型:

新建桥接工程XXX-bridge,所有新增代码均放在新工程,对老工程零侵入,仅新增了pom文件里的两个plugin,可以实现Stripes和SpringMVC两种框架模式下的并行开发,(原来的老工程持续有需求进来)。 /** * 拦截所有请求,如果能映射到Stripes则直接派发给Stripes并return false; * 如果不能映射则回退给SpringMVC */ @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { if (handlerMapping.isEmpty()) { return true; } String url = httpServletRequest.getRequestURI(); String contextPath = httpServletRequest.getContextPath(); url = url.replace(contextPath, "").replaceAll("/+", "/"); LOGGER.info("当前请求路径: {}", url); if (!StripesContextHandlerInterceptor.handlerMapping.containsKey(url)) { LOGGER.info("请求由SpringMVC处理: {}", url); return true; } try { LOGGER.info("请求由Stripes处理: {}", url); StripesContextHolder.doService(httpServletRequest.getServletContext(), getApplicationContext(), httpServletRequest, httpServletResponse); return false; } catch (Exception e) { LOGGER.error("处理请求异常:", e); return false; } } 关键点在于要解析到所有的老接口地址,然后通过拦截器来判断当前请求是否是老接口,是的话就转发给Stripes来处理。其他详细的代码托管在github(已排除掉公司相关信息) https://github.com/hiccup234/web-advance/blob/master/bridge.rar

问题与验证:

1、因为初始化Stripes需要 ServletContext,但是应用启动时却没办法获取到 ServletContext 对象,所以在 StripesContextHolder 里做了懒加载,只有当第一个请求进来后才初始化Stripes。

  2、Stripes 是支持 queryString 为空的查询的,类似:http://127.0.0.1/server/test?list 这种,而 M 会在解析请求参数的时候对这种情况直接抛异常,经过与基础设施同事协商,他们做出让步,对这种请求的情况直接放行给应用,从而避免了前端和第三方做改造。

今晚上线成功,目前跟 Tomcat 并行发布,5% 的流量灰度,观察日志一切正常。前期的技术验证加上近一月的开发测试到今天的上线,算是向着架构的方向迈出了小小一步。

未完待续...

  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖 • 2 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    42 引用 • 130 回帖 • 253 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 350 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 563 关注
  • danl
    181 关注
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    1 引用 • 31 回帖
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 564 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 664 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 109 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    209 引用 • 2040 回帖
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 236 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 441 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 801 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    4 引用 • 16 回帖 • 197 关注
  • Access
    1 引用 • 3 回帖 • 3 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • OnlyOffice
    4 引用 • 19 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 89 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1795 回帖 • 2 关注
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 1 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 51 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 1 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 561 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 726 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    46 引用 • 114 回帖 • 167 关注