Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

服务地图支持RPC调用关系 #30

Open
wertycn opened this issue Apr 11, 2022 · 13 comments
Open

服务地图支持RPC调用关系 #30

wertycn opened this issue Apr 11, 2022 · 13 comments
Assignees
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
Milestone

Comments

@wertycn
Copy link

wertycn commented Apr 11, 2022

Is your feature request related to a problem? Please describe.
当前服务地图仅支持HTTP API 调用关系,但对于微服务系统,服务间内部调用主要依赖于RPC调用(如Dubbo,GRPC等),这部分信息比HTTP API的调用关系在评价分布式系统状态时会更加重要

Describe the solution you'd like
增加RPC服务地图支持

Describe alternatives you've considered
可以提供服务地图依赖信息扫描的接口,基于该接口实现各框架的依赖关系扫描的组件,代码实现可以开放交给社区贡献或者使用方基于自身服务情况进行实现

@phodal phodal added good first issue Good for newcomers help wanted Extra attention is needed labels Apr 11, 2022
@phodal
Copy link
Member

phodal commented Apr 11, 2022

能不能提供一些对应的代码示例

@wertycn
Copy link
Author

wertycn commented Apr 11, 2022

以Dubbo 调用为例:

服务接口声明 (服务提供者和服务消费者都会导入这个interface)

public interface RpcService {
    String hello(String name);
}

服务提供者

@DubboService
public class ProviderImpl implements RpcService{
    @Override
    public String hello(String name) {
        return "RpcService invoke by " + name;
    }
}

服务消费者

public class Consumer {

   // @DubboReference 类似@autowired 字段注入
   @DubboReference
   private RpcService rpcService;

   public void run(){
     rpcServiceA.hello("example consumer")
   }
}

源码扫描分析Dubbo依赖关系过程大概如下:
第一步: 扫描出项目中被打上 @DubboService 注解的类,注解的参数(可选,group version等),及该类实现对应的接口
第二步: 扫描出项目中被 @DubboReference 注入的字段,注解的参数 ,及字段的类型
第三步: 对DubboReference 和 DubboService 的接口进行匹配,接口及注解参数一致 就表明存在调用关系

更进一步,还可以基于Spring Boot 的 Bean 定义分析出服务内部的调用链路

按照我的理解, 不管是什么协议,服务地图依赖关系的扫描总体是分为三块内容,可以提供一个包含以下方法定义的接口,使用者按照该接口去扩展不同协议的调用关系扫描实现

  • 服务提供者扫描
  • 服务消费者扫描
  • 调用关系匹配

@phodal
Copy link
Member

phodal commented Apr 11, 2022

这么详细,考虑来个 PR 吗?相关的代码在这里:backend

主要是要寻找代码库来验证是不是准确的。

@phodal phodal added this to To do in ArchGuard via automation Apr 11, 2022
@phodal phodal added this to the Archguard 2.0 milestone Apr 11, 2022
@wertycn
Copy link
Author

wertycn commented Apr 11, 2022

想写的,最近我先研究下,另外如果方便的话,可以先补充下这块逻辑执行过程的文档,后面其他人的上手成本会更低一些

@phodal
Copy link
Member

phodal commented Apr 11, 2022

我周末写了一部分:https://archguard.org/modules/scanner/sourcecode-api ,我再补充一下。

@wertycn
Copy link
Author

wertycn commented Apr 17, 2022

今天尝试写了一下,目前完成了基于注解的服务提供者的简单扫描支持,半成品代码如下:Dubbo Analyser

同时也遇到了一些问题及困惑:

  • 分析服务消费者时需要获取到类字段的注解,但现有CodeDataStruct 对象中的Annotaiton 属性是空的
    如图:
    image

  • 方法分析中,扫描出注解包含 Override,但Override属性值仍为false
    image

  • 现有的分析似乎都是基于单文件的,在一些情况下相关的信息会跨文件甚至跨项目(如maven引入的包), 这种情况下基于包含完整依赖的编译产物分析会更加精准,我记得文档中有提到java分析还支持ByteCode, 但按照我的理解目前Archguard 是在服务端拉取代码后进行扫描,如果要进行ByteCode 分析,则需要在服务端完成编译操作,这对服务端的要求会很高,相当于内部集成一个完整的CI 系统,因此 是否可以考虑将代码扫描从服务端拆分出去,服务端提供代码扫描结果上报的HTTP API , 基于maven 、gradle 或者cli 实现代码分析的client ,由client将扫描结果上报到服务端

类似SonarQube 的扫描方式,基于Sonar-Scanner-Cli 或者maven插件完成扫描后,扫描结果会上报到SonarQube的服务端API
提供HTTP API 后还有一个好处,依赖关系的来源将不限于代码扫描,可以基于运行时数据,也可以基于APM 的链路数据,甚至可以是手工填写的

  • 现有服务地图 HTTP API 的类型对象是定制的,新增协议支持需要再定制相关的对象,扩展性不太好,我们可能需要对服务依赖的协议调用情况进行一定的抽象,便于后续新增协议的扩展, 这也是提供HTTP API 上报依赖基础之一

@phodal
Copy link
Member

phodal commented Apr 17, 2022

嗯,问题有点多。我先按类别说一下,针对于前面的 Annotaion:

  1. Annotation 的问题需要在 Chapi 中解决,针对于 Field(也就是上面的 HelloService)的注解。先前没有考虑到这种情况,需要添加一下支持。看是你来 PR,还是我直接修了?

针对于跨项目的情况:

  1. Scanner 本身是可以离线构建的,只是需要一条数据上传的链路。这个可以考虑加一个新的 HTTP API @isixline
  2. ByteCode 在分析变量的时候是有问题的,也就是为什么后来使用更多的是源码。理想情况下,应该是两种情况结合的。

针对于 Scanner 的问题:

  1. @Anddd7 正在看对应的插件化方案、
  2. 再有的 Scanner 的扩展性,也有了初步的方案:rule_core,需要进一步完善。

@phodal
Copy link
Member

phodal commented Apr 17, 2022

@wertycn 针对于现状,是直接 PR,我把 Chapi 的问题一起修了?还是你看你对 Chapi 有没有修改的兴趣?

@wertycn
Copy link
Author

wertycn commented Apr 17, 2022

Chapi 目前还没有怎么了解过,估计提PR的话周期会比较久, 方便说下这块逻辑大概在什么位置吗? 我先看看

@phodal
Copy link
Member

phodal commented Apr 17, 2022

你可以先看一下,这部分是结合 Antlr 做语法树分析的。

https://github.com/modernizing/chapi/blob/ef068f566fd403edf90a8ea4c326ddf1c564638a/chapi-ast-java/src/main/kotlin/chapi/ast/javaast/JavaFullIdentListener.kt#L516

理论上在 this.currentAnnotations 就可以拿到 Annotation 了:

https://github.com/modernizing/chapi/blob/ef068f566fd403edf90a8ea4c326ddf1c564638a/chapi-ast-java/src/main/kotlin/chapi/ast/javaast/JavaFullIdentListener.kt#L542

按当前的 Antlr 解析器的语法,会先进行 enterAnnotation 里构建出 Annotation,所以逻辑上会在全局设置一下 currentAnnotations 实现起来比较简单

@wertycn
Copy link
Author

wertycn commented Apr 17, 2022

非常感谢 , 我试试

phodal added a commit to phodal/chapi that referenced this issue Apr 17, 2022
@phodal
Copy link
Member

phodal commented Apr 17, 2022

发布了 Chapi 1.5.7,估计要 10 分钟以后才能在 Maven 仓库下载到

@wertycn
Copy link
Author

wertycn commented Apr 17, 2022

Good ~ 已经可以使用了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
No open projects
Development

No branches or pull requests

2 participants