单体应用模拟微服务 - Maven

方案关键词:maven -> scope -> runtime

一、标准微服务化实现

微服务概念、特性啥的网上很多,这里略过,有兴趣的可以Google。 微服务架构的优势与不足 什么是微服务架构? 但是其中最基本的一个特性就是 服务接口API对服务调用方Consumer可见,但是服务实现Provider对Consumer不可见 这样服务双方解耦后,方便快速迭代。

dubbo为例:

服务调用方配置如下: pom.xml

<dependency>
    <groupId>com.goobai.aics</groupId>
    <artifactId>aics-data-api</artifactId>
    <version>1.0.0</version>
</dependency>

applicationContext.xml

<dubbo:reference version="1.0" id="productService" interface="com.goobai.aics.data.api.service.ProductService"/>

可以看出调用方是只能引用aics-data-api中的服务接口ProductService,该服务的实现是不可见的。

HTTP协议的RPC

如果接口是HTTP协议的话,服务调用方和提供方的耦合甚至更低,provider连api的jar包都不需要提供,只需要提供api接口说明文档即可。当然,provider的实现也对Consumer不可见。

二、使用Maven模拟微服务化

新项目在开始阶段的时候,开发人员少、代码量也不多,标准微服务带来的好处并不明显,反而容易增加代码管理成本,比如调试、排错等(打开的IDE也多)。但是使用单体应用模式,又担心项目增长后,迁移到微服务的代价太大。 面对这种情况,我们团队在开发过程中逐步摸索了一个简单的办法,在单体应用中使用maven实现对微服务的模拟,既可以在前期实现快速开发,又大大降低了微服务化的成本。

下面实例中以aics-data-api为服务接口,aics-data-provider为服务实现者,aics-server为服务调用方

  • 效果:只有服务API对Consumer可见,其实现对Consumer不可见,但却能为单体应用中的调用方提供服务
  • 方法简述:Consumer以compile(maven默认)的方式引入api(如aics-data-api),但是以runtime的方式引入实现(如aics-data-provider)

Maven项目架构如下图所示: aics-data-api是服务api,aics-data-provider是服务实现,aics-server是服务调用方

具体实现如下:

2.1 服务api(如aics-data-api)

public class ProductSevice {
    Optional<Product> queryById(int id)
}

2.2 服务实现provider(如aics-data-provider)

Provider中的Spring配置文件,叫做data-applicationContext.xml(名字其实都可以,但是不能跟consumer一样,方便在consumer的spring引用)

@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductMapper productMapper;
    
    @Override
    Optional<Product> queryById(int id) {
        return Optional.ofNullable(productMapper.selectByPrimaryKey(id));
    }
}

2.3 服务调用方consumer

服务调用方(aics-server)的pom.xml

<dependency>
    <groupId>com.goobai.aics</groupId>
    <artifactId>aics-data-api</artifactId>
    <version>1.0.0</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.goobai.aics</groupId>
    <artifactId>aics-data-provider</artifactId>
    <version>1.0.0</version>
    <scope>runtime</scope>
</dependency>

重点!!!: 注意看上面两个jar的scope,其中api的是compile,provider的是runtime

applicationContext.xml

<import resource="classpath*:data-applicationContext.xml" />
@RequestMapping("api/products")
@RestController
public class ProductController {
    @Resource
    private ProductService productService;
    
    @RequestMapping(value = "{id:\\d+}", method = RequestMethod.GET)
    public WebResult getOne(@PathVariable(name = "id") int id) {
        final Optional<Product> productOpt = productService.queryById(id);
        return productOpt.map(WebResult::new)
                .orElseGet(() -> new WebResult(404, "product does not exists"));
    }
}

2.4 其他

  1. aics-data-provider不能配置PropertySourcesPlaceholderConfigurerPropertyPlaceholderConfigurer。因为一个Spring上下文中只能有一个。所以最好配置在服务调用方(如:aics-server)

结语

使用Maven模拟微服务后,降低了项目中各模块间的耦合度;而且一般不同的功能模块主要是由一人负责,这样在开发过程中虽然在同一个git仓库,但也极少有代码冲突,提供了并发开发的效率。

PS: 这个方案是团队逐步摸索出来的,肯定存在很多的问题,欢迎各位大神批评指正,不胜感激!

参考文献

  1. 微服务架构的优势与不足
  2. 什么是微服务架构?

如果对你有一点帮助,麻烦为我点一个赞,如果没有帮助,也非常期待你的反馈

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏玄魂工作室

Kali Linux Web渗透测试手册(第二版) - 6.7 - 利用XML外部实体注入

thr0cyte,Gr33k,花花,MrTools,R1ght0us,7089bAt

10420
来自专栏Kiba518

C#-Xamarin的Android项目开发(一)——创建项目

使用Xamarin开发安卓项目,首先需要安装VS2017以上版本。因为VS2017以上的版本,可以直接创建Xamarin项目。

12510
来自专栏享智同行

学会这个工具的使用,让你快速生成验证码

验证码是我们做人机验证最常用的方式,常用于敏感操作的验证,比如:登录、注册、修改等。

16530
来自专栏Spring相关

Android的Fragment中的互相通信-桥梁activity

9520
来自专栏dotNET匠人的技术自留地

史上最最靠谱,又双叒叒(ruò,zhuó)简单的基于MSXML的XML解析指南-C++

最近做C++相关的项目,遇到同时使用COM和MSXML来解析XML文件中信息的问题,这类问题如果做MFC开发也会经常用到。 在网上搜了一整圈,确实很难找到可用...

10120
来自专栏Spring相关

Android的Fragment的第一种声明方式

11530
来自专栏Spring相关

Android模拟微信主页面的Demo

22010
来自专栏码匠的流水账

聊聊flink的logback配置

flink-release-1.7.1/flink-dist/src/main/flink-bin/bin/flink-daemon.sh

13020
来自专栏Spring相关

Android动态添加Fragment

26710
来自专栏编程坑太多

『互联网架构』软件架构-spring源码之spring ioc(九)

PS:读源码确实很麻烦,但是spring的源码大概120多MB,相当于一个JAVA的JDK了,读了怼咱们日常开发真的很有用,设计到的模式:单例模式,工厂模式,建...

9430

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励