Giter VIP home page Giter VIP logo

sofa-jarslink's Introduction

简介

Build Status Coverage Status license maven

This project is no longer in active development, and is currently in maintenance mode. All the existing features have been merged into SOFAArk as part of modular development framework Koupleless, and we highly recommend that you use Koupleless instead.

本项目已不再继续添加新功能,处于维护模式;本项目已有功能已被合并进 Koupleless,并作为模块化研发框架和平台 Koupleless 的能力之一, 我们推荐您直接使用 Koupleless


Jarslink 2.0 是 SOFABoot 官方基于 SOFAArk 开发的功能插件,负责管理多应用在 SOFAArk 容器之上的合并部署,具备如下特性:

  • 支持运行时动态安装和卸载应用。

  • 支持运行时应用热替换能力,保证服务的连续性。

  • 跨应用内部通信,支持应用发布引用 JVM 服务,跨应用既可以使用 RPC 框架,也可以走内部 JVM 服务进行通信。

  • 支持应用健康检查。

背景

在蚂蚁金服内部,在同一个 JVM 之上部署多个应用,是一件常见的事情。这样带来的主要优势如下:

  • 无关应用合并部署:有些应用在独立部署时,相互之间没有服务依赖,而且这些应用承担业务体量都偏小,单独启动 Java 虚拟机比较浪费资源, 将这些应用合并部署,能够节省资源。

  • 相关应用合并部署:有些应用之间存在服务依赖,独立部署时,各应用之间使用 RPC 调用,虽然使用了分布式架构,稳定性高,但依然存在网络抖动导致的延时性问题。这些应用合并部署,RPC 调用优先转为 JVM 内部调用,缩减调用开销。

不仅应用间存在合并部署,近端包也有同样的诉求。

近端包是提供一系列公共服务的三方组件,一般由应用作为依赖引入,这种开发模式容易导致两个问题:

  • 近端包引入的三方依赖和应用本身的依赖产生冲突,期望能做到隔离部署。

  • 近端包由应用作为依赖引入,因此近端包的任何升级改造都需要应用配合升级。但是作为一个公共的功能组件,近端包通常会被很多业务方应用依赖,此时推动业务方改造工作量巨大,因此期望能做到近端包的动态升级。

除了合并部署,蚂蚁金服很多业务场景需要模块的热部署,即在应用运行时,需要动态替换某特定模块而不影响其他模块的正常运行。

Jarslink2.0 正是为了解决诸如此类的问题,它是基于 SOFAArk 开发的 Ark Plugin,用于管理多应用合并部署。在了解 Jarslink2.0 之前,你需要提前了解 SOFAArk 框架。关于 SOFAArk 可以访问链接获取更多详细信息。

原理

Jarslink2.0 是一款基于 SOFAArk 开发的 Ark Plugin 。假设你已经对 SOFAArk 有一定的了解,很容易知道,应用被打包成 Ark Biz 的形式运行在 SOFAArk 容器之上。SOFABoot 或者 Spring Boot 应用,甚至普通的模块都可以借助 SOFAArk 插件打包成一个标准的 Ark Biz 包。

Jarslink2.0 支持多个 Ark Biz 运行在 SOFAArk 容器之上,从而做到多应用的合并部署。应用可以通过注解的形式快速发布服务或者引用其他应用发布的服务,达到相互通信的目的。下图是运行时多应用合并部署结构图:

undefined

从图中可以看到,使用 Jarslink2.0 通常需要引入两个 Ark Plugin, 下面介绍这两个 Ark Plugin 的作用。

  • Jarslink: Jarslink2.0 核心代码,支持动态接收命令,如安装、卸载、切换等等,用于管理 Ark Biz 的生命周期。如果需要运行时动态部署应用,需要添加如下依赖:
<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>sofa-jarslink-ark-starter</artifactId>
    <classifier>ark-plugin</classifier>
</dependency>
  • SOFARuntime: SOFARuntime 是 SOFABoot 提供的功能模块,用于实现跨应用的服务调用。如果需要使用跨应用调用功能,需要添加如下依赖:
<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>runtime-sofa-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.alipay.sofa</groupId>
    <artifactId>runtime-sofa-boot-starter</artifactId>
    <classifier>ark-plugin</classifier>
</dependency>

快速开始

贡献

文档

sofa-jarslink's People

Contributors

duan-0916 avatar kiral avatar lvjing2 avatar qilongzhang avatar seeflood avatar straybirdzls avatar ujjboy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sofa-jarslink's Issues

一些想法

  1. 模块跟框架的代码太紧耦合了,一个简单的类加载封装,感觉不像是模块化,更像是业务组件容器(Component)。
  2. 太轻量级了,模块缺乏生命周期管理,缺乏组件的运维性管理。需要对模块的状态和生命周期进行定义。
  3. 缺乏依赖管理机制和模块相互调用机制。

支持gbk编码

现在模块(xxx)加载失败:Line 1 in XML document from URL [jar:file:/home/admin/xxxSNAPSHOT-jar-with-dependencies.jar!/META-INF/spring/xxxx.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 37; Invalid encoding name "GBK".

没有bean.xml文件会加载失败

临时解决方案是放一个空文件进去,或者在新版本里用注解的方式加载BEAN。

错误信息是:
resources length is 0

如何实现调用模块action返回自定义对象

模块action返回的是内部定义的对象,调用时又没有依赖,如何实现呢?还是模块化本就不能直接依赖模块jar包?而是将模块jar包放在classpath下,action入参出参都只能是jdk自带的

建议

现在实际上调用方,看不到模块提供者的api 定义的
而且使用起来有点不方便

建议是封装一层, 提供 Builder 代理类的方法。
代理类的工作 : 把class,method,参数等信息传到模块中去执行。

A 服务引用 模块B提供的api jar包,然后 生成代理类,在A服务中直接api调用

关于数据源的问题

模块中如果要进行数据库操作,需要配置数据源么?
如果模块中配置了数据源,模块加载之后,主系统中会有多个数据源么?

模块最终还是要加载到主系统中的,能复用主系统中配置好的数据源么?

建议增加扩展点

1、建议增加扩展点,供模块的间的功能扩展实现
2、模块的配置,可以直接读jar 里固定的元数据信息的,可以不需要再进行API声明

设置默认版本code bug

        //设置默认版本
        if (!defaultVersions.contains(getModuleName(name))) {
            activeVersion(name, module.getVersion());
        }

Map.contains()方法是不是应该改成containsKey()?

file: com.alipay.jarslink.api.impl.ModuleManagerImpl#register(com.alipay.jarslink.api.Module)

能不能发个dubbo应用场景集成的demo

如题,看使用指南多少有些混乱,代码与test里也不一样,或者有些过时?

能否提供dubbo微服务应用场景集成的案例,目前的资料都太抽象了,我一个微服务里有N多接口,然后是实现,怎么接入呢?微服务发布、远程调用怎么办?

image

求大神指导!

maven 编译不通过

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.672 s
[INFO] Finished at: 2018-02-03T09:05:52+08:00
[INFO] Final Memory: 10M/128M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project titan-api: Could not resolve dependencies for project com.alipay.titan:titan-api:jar:1.5.0.20171107-SNAPSHOT: Could not find artifact org.springframework:org.springframework.test:jar:3.0.5.RELEASE in central (https://repo.maven.apache.org/maven2) -> [Help 1]

模块配置 升级成类似 spring boot 自动配置,外化配置

    // TODO 模块配置 升级成类似 spring boot 自动配置,外化配置
    /**
     * 构建模块配置信息
     */
    public static ModuleConfig buildModuleConfig() {
        return buildModuleConfig(true);
    }

    public static ModuleConfig buildModuleConfig(boolean enabled) {
        URL demoModule = Thread.currentThread().getContextClassLoader().getResource("titan-demo-1.0.0.jar");
        ModuleConfig moduleConfig = new ModuleConfig();
        moduleConfig.setName("demo");
        moduleConfig.setEnabled(enabled);
        moduleConfig.setOverridePackages(ImmutableList.of("com.alipay.titan.demo"));
        moduleConfig.setVersion("1.0.0.20170621");
        Map<String, Object> properties = new HashMap();
        properties.put("fcfluxnet_url", "127.0.0.1:12200");
        moduleConfig.setProperties(properties);
        moduleConfig.setModuleUrl(ImmutableList.of(demoModule));
        return moduleConfig;
    }

多个不同的模块并存时,下一个模块加载会覆盖上一个

我有两个模块实现相同的方法,但是两个方法处理的逻辑不一样,用于处理不同的业务特性,例如我有一个模块是提供给车贷用的,另一个模块提供给现金贷用的,想通过模块化管理,多个模块并存,通过请求的产品类型不同,自动路由到对应的模块,当时我发现jarslink只能同时存在一个模块,当存在了车贷模块时,再加载一个现金贷模块就会移除其他模块,这就做不到多个不同模块共存时根据不同的产品路由到不同的模块去处理,想问下有对应的处理方法吗

注册两个不同的模块会被后一个移除

我想用jarsLink尝试实现不同的模块,相当的方法名,但是对应的方法处理逻辑会有些不同来实现业务特性通过插拔式去开发,但是发现当我加载了一个kn-module-demo的模块,再加载wps-module-demo模块时候,jarslink会认为这两个不同的模块是属于多于,会移除上一个kn-module-demo模块,实际上我想这两个模块并存,例如我一个请求是process,模块名是kn-module-demo的时候会自动去找kn-module-demo下的action里的process,当我请求是process,模块名是wps-module-demo时,会自动去找wps-module-demo下的action,这样可以根据不同的业务场景,实现业务特性处理。当时jaslink会移除上一个module

在SpringMVC中无法进行热替换更新???

本人试了一下,可以在SpringMVC中动态新增更新可以实现,但是实现类替换更新就不能实现?

具体步骤:

1.我创建了两个JAR包,相同的包名和类名称,就是里面的实现方法中返回的名称getActionName名称不一样
2.在SpringMVC中创建两个Controller方法和两个ModuleManager、ModuleLoader
3.可以实现动态的增加更新,却无法实现替换更新

动态修改模块不会有问题吗?

动态修改模块的version,新旧模块切换时,会不会有负作用,不会影响正在执行的代码吗?

比如,旧容器里面的方法还没有执行完,此时去卸载旧模块会怎么样?

在spring MVC单元测中存在的问题

我做了测试,当脱离SpringMVC运行环境时,测试可以通过。但是当我结合SpringMVC环境进行单元测试时发现以下问题:
1.在context.refresh时,会将SpringMVC所有的上下文环境进行刷新,这样会不会导致事务依赖问题。
2.当新增模块后,刷新时,会重新加载resourceHandlerMapping,并且抛出异常
`@Bean
public HandlerMapping resourceHandlerMapping() {
Assert.state(this.applicationContext != null, "No ApplicationContext set");
Assert.state(this.servletContext != null, "No ServletContext set");

	ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext,
			this.servletContext, mvcContentNegotiationManager(), mvcUrlPathHelper());`

创建这个bean时,Assert.state(this.servletContext != null, "No ServletContext set"); 这句抛出异常`
请问是我的配置出现问题,还是jarlink本身存在的问题?
对于以上的问题,还望指教?
另外,我现在使用的是hibernate + springMVC,当新增模块后,Hibernate会不会加载实体注解

Action包重新package之后为什么没有更新

文档中要修改版本号才能更新,但是ModuleConfig的url指定了jar包的名字,我在Action的pom里升级的他的version,会生成一个新的名字的jar包,此时应该如何更新原来的jar,达到更新逻辑的能力呢?这里看文档做demo完全搞不懂。

按照文档“启动 SOFABoot 应用”出现“Failed to execute goal com.mycila:license-maven-plugin:3.0:remove” 错误

按照官方文档介绍的sofaboot-sample-with-isle 运行 SOFABoot出现Failed to execute goal com.mycila:license-maven-plugin:3.0:remove 始终过不去

错误内容:
Failed to execute goal com.mycila:license-maven-plugin:3.0:remove (default) on project sofa-boot-run: Execution default of goal com.mycila:license-maven-plugin:3.0:remove failed: Cannot read header document /Users/XXX/CODE/ThirdParty/sofa-boot/sofaboot-samples/sofaboot-sample-with-isle/sofa-boot-run/../../HEADER. Cause: Resource /Users/XXX/CODE/ThirdParty/sofa-boot/sofaboot-samples/sofaboot-sample-with-isle/sofa-boot-run/../../HEADER not found in file system, classpath or URL: no protocol: /Users/XXX/CODE/ThirdParty/sofa-boot/sofaboot-samples/sofaboot-sample-with-isle/sofa-boot-run/../../HEADER -> [Help 1]
[ERROR]

错误信息中的XXX是我的用户名

pom文件的plugin如下

<plugin> <groupId>com.mycila</groupId> <artifactId>license-maven-plugin</artifactId> <version>${license.maven.plugin}</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>remove</goal> <goal>format</goal> </goals> </execution> </executions> <configuration> <quiet>true</quiet> <header>${main.user.dir}/HEADER</header> 这里的HEADER找不到,不知道这个HEADER是什么用意 <includes> <include>**/src/main/java/**</include> <include>**/src/test/java/**</include> </includes> <strictCheck>true</strictCheck> <mapping> <java>SLASHSTAR_STYLE</java> </mapping> </configuration> </plugin>

我尝试清理本地仓库中 com.mycila 依然无效

Environment

  • Jarslink version: 3.5.0
  • JVM version (e.g. java -version):1.8
  • OS version (e.g. uname -a):mac
  • Maven version:3.5.4
  • IDE version:intellij 2018.1 community

支持同进程模块间调用

目前不支持同进程和跨进程的模块调用,扩进程间模块调用用RPC实现,同进程模块调用需要支持。

目前的解决方案是深克隆。

支持注解方式

目前的bean都是只能通过xml注册, 有没有计划支持注解方式

模块的生命周期管理

模块新增生命周期管理分别是初始化状态,类加载状态,对象实例化状态和注册状态。

  • 初始化状态:基本检查。
  • 类加载状态:模块的类已经加载完成。
  • 实例化状态:模块里的对象都已经被实例化完成。
  • 注册状态:把模块加载到模块池中,处于注册状态的模块才能被调用。

关于JarsLink的使用教程和解析

感谢jarslink的作者,让我之前一直想搞的模块化处理实现了,感觉对做审批那一块特别有用,我在我公众号简单整理了一些关于JarsLink的解析和教程,后续会放一些实战的demo和公司实战场景,有兴趣的朋友可以关注下Eshare分享

支持注册模块的多版本

支持加载一个模块的多个版本,并激活其中一个版本

1:可以注册模块的多个版本,可以通过API调用任意一个版本。
2:可以设置默认版本,如果不指定版本调用模块,默认将请求路由到最后版本。
3:增加是否开启多版本开关,默认情况关闭,加载模块新版本会自动卸载旧版本,如果打开多版本开关,则加载成功后不卸载旧版本,需要自己手动卸载旧版本。

模块资源找不到

我按demo新建一模块,在调用模块时报
java.lang.IllegalArgumentException: resources length is 0
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:125)
at com.alipay.jarslink.api.impl.ModuleLoaderImpl.findSpringConfigs(ModuleLoaderImpl.java:183)
at com.alipay.jarslink.api.impl.ModuleLoaderImpl.loadModuleApplication(ModuleLoaderImpl.java:126)
我的模板配置文件在resources/META-INF/spring/*.xml 下

数据库操作怎么处理

按照jarslink的module处理方式,每一个module处理对应的模块,将不同的module放在不同的jar包内,这样隔离性做到位了,我的疑问是对于数据库操作这种公共操作是怎么做的?是每一个module配置一个数据源,还是有其他手段使得module共享主项目的数据源?还有一个问题,对于公共的model类就需要在主项目、module上都配置一遍或者单独抽出一个jar维护这些公共model,这样设计是否会使项目结构反而变得混乱?

JarsLink1.0暂停更新,即将推出JarsLink2.0

目前 Jarslink 2.0 在紧张开发之中,Jarslink2.0是在 Jarslink1.0 基础之上,结合 SOFABoot类隔离框架,提供了更加通用的应用(模块)隔离和通信的实现方案,敬请期待!

预计7月份发布第一个版本。

提议

1、需要类似springboot有一套特有打包机制(参考springboot-loader),利于开发过程调试、上线构建;
2、模块独立化已经实现,实际开发过程中的依赖包管理问题尚在,需要额外考虑;
3、模块依赖需要自动发现,可以参考springboot的自动扫描加载机制,简单的添加到maven pom文件依赖,并自动从当前classpath扫描加载即可;
4、业务场景问题,感觉目前需要此应用的场景基本集中在移动端APP开发,对于服务端场景,本身热升级不是特别困难的事情,不需要牺牲开发效率去满足。

总结:实际上springboot1.5.x目前已有功能基本满足模块化开发,唯独不足的是,目前springboot中的classloader没有提供特定API对外支持动态装载class,需要通过特定方式解决。

更新jar包 moduleConfig修改version字段提示这个错误

提示 LogFactory.release(classLoader); 没有release这个方法
java.lang.NoSuchMethodError: org.apache.commons.logging.LogFactory.release(Ljava/lang/ClassLoader;)V
at com.alipay.jarslink.api.impl.SpringModule.clear(SpringModule.java:203) ~[jarslink-api-1.6.1.20180301.jar:na]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.