Git Product home page Git Product logo

sofa-dashboard's Introduction

SOFADashboard

Build Status Coverage Status license

SOFADashboard 致力于对 SOFA 框架中组件进行统一管理,包括服务治理、SOFAArk 管控等。SOFADashboard 本身所用技术栈均基于开源社区产品来开发构建,包括:Ant Design Pro、SOFABoot、Spring、MyBatis 等

功能特性

  • 应用面板功能,用于查看应用信息
  • 基于 Zookeeper 的服务治理功能
  • SOFAArk多模块管理功能

运行依赖

编译需要 JDK 8 及以上、Maven 3.2.5 及以上,运行需要 JDK 8 及以上。

SOFAArk 管控需要依赖 MySQL 进行资源数据存储,需要安装 MySQL 并导入 SofaDashboardDB.sql 脚本。

SOFADashboard 中的服务治理、SOFAArk 管控依赖于 Zookeeper,需要启动 Zookeeper 服务。

文档

如何贡献

如何参与 SOFADashboard 代码贡献 

开源许可

SOFADashboard 基于 Apache License 2.0 协议,SOFADashboard 依赖了一些三方组件,它们的开源协议参见依赖组件版权说明

sofa-dashboard's People

Contributors

caojie09 avatar chpengzh avatar dependabot[bot] avatar forsake0120 avatar glmapper avatar khotyn avatar nobodyiam 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

Watchers

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

sofa-dashboard's Issues

插件查询之后无法获取应用实例问题

@RequestMapping("/search-plugin")
public List<ArkPluginModel> searchPlugins(@RequestParam("pluginName") String pluginName) {
        if (StringUtils.isEmpty(pluginName)) {
            // 返回全部
            return arkMngService.fetchRegisteredPlugins();
        }
        return arkMngService.fetchPluginsByName(pluginName);
    }

此端代码为插件查询的逻辑,仅获取到了插件列表,插件关联到的应用实例信息没有被计算出来。导致默认列表展示和查询结果展示在应用实例数和关联应用展示部分不一致

支持移除版本

SOFADashboard 需要增强在对动态模块版本管理部分的能力,例如支持移除版本

完善应用面板展示信息

1、查看应用内存状态数据
2、健康检查状态信息
3、Info 信息
4、线程数量信息
5、mappings
6、线程状态
7、loggers
8、Environment

Probably memory leak risk

In RootNodeChangeListener, we create pathChildrenCache when CHILD_ADDED.Howver,there is no close method invoked when CHILD_REMOVED

Integration SOFARegistry

SOFADashboard currently only support a Zookeeper as a registry.As the management server of the SOFA, need support SOFARegistry

账号管控、配置管理、服务治理相关问题讨论

该issue是对功能实施的一个讨论贴...细节还待补充

一. 数据流模型

数据流图如下:

    1. 当应用进入readiness状态后,SDK会上报应用实例和服务相关的会话;
    1. SOFADashboard 读取zk的会话信息,以应用为维度对配置进行管理;
    1. SOFADashboard 调用 apollo-portal-server 接口,通过应用维度修改配置;
    1. apollo-meta-server 下发配置,RPCSDK 读取配置变更,执行上下线切换LB等操作指令;

image

二. 方案流程细节说明

该方案仅为草案,请各位进行讨论和补充

1. 关于应用实例上报和应用读取

方案图中以Zookeeper作为集群实例上报,目前该 Application SDK 项目地址sofa-dashboard-client.

假设存在应用实例 a(ip:10.1.1.1,rpc-port:9090, http-port:8080), 服务名A

如下为实例对应的会话节点, 其中/app/instance/A为永久节点, 其value值可以记录应用维度的一些配置:

/apps/instance/A/10.1.1.1:8080?startTime=<startTime>&lastRecover=<lastRecover>

2. 关于接入apollo(Important)

系统账号对接

通过接口直接对接apollo-portal,不关心apollo背后对接的用户体系实现.

由于 apollo 有一套良好的账号系统逻辑,支持通过LDAP或者自定义逻辑接入企业已有的账号系统,因此Dashboard这边只需要考虑对apollo的账号系统进行对接。关于apollo的账号系统拓展参考apollo认证逻辑

该对接功能包含如下几个不足之处:

  • apollo 用户账号系统中用户定义较为简单,如果后需要拓展账号相关功能(比如邮箱验证等需求),需要对apollo-portal进行二次开发

关于对 Portal Server 的调用

用户登录后,使用apollo操作过程过程可以参考使用文档,简要包含了如下几个过程:

  • 创建应用
  • 创建namespace(如果有必要)
  • 以app为维度或namespace为维度创建/修改一些下发配置

通过上报应用信息自动创建apollo应用定义

我们期望在SOFADashboard在管理的时候简化创建应用过程,使用上报的应用信息自动创建一个缺省应用。这样在用户行为上就只保留对namespace的操作和配置修改操作,增强易用性。

使用和 apollo-portal 接口直接对接方式而不是 OpenApi 对接

apollo除了前端调用的接口以外,还支持OpenApi的方式进行接入。

但是该方案有一定局限性:

首先,只有超级管理员能创建 OpenApi token; 事实上下发配置者几乎不是超级管理员,而是应用管理者;

其次 OpenApi 的局限性很强,比如不支持创建用户,不支持创建应用等功能;

最后,有的用户在自己的环境下已经有一套独立运行的 apollo 服务了,我们希望 Dashboard 的调用逻辑和 portal 保持一致,而不是魔改一些逻辑,这样即使使用了Dashboard也不会影响到apollo独立运行的状态.

因此综上所述,我们采用直接对接 portal 接口的方式对 apollo-portal进行调用

3. 关于服务管控维度

apollo 本质上是依靠多维度的方式去管理一个config,为了实现服务管控,需要在RPC SDK中针对下发配置进行监控并执行相关操作。

目前我想的方案是先支持应用维度的环境变量,形如:

@RestController
public class HelloController {

    @SofaReference(binding = @SofaReferenceBinding(bindingType = "bolt", lb="${hello.service.lb:roundRobin}"))
    private HelloService service;

    @GetMapping
    public String hello(@RequestParam("name") String name) {
        return service.sayHello(name);
    }

}

使用环境变量注入的方式和apollo用户使用习惯一致,也较容易实现。

后期的方案,则可以脱离环境变量,直接在Dashboard界面上通过服务维度进行操作;

npm install failed

Run npm install in the frontend project, got the following error:

❯ npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/antd
npm ERR!   antd@"^3.20.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer antd@"4.x" from @ant-design/[email protected]
npm ERR! node_modules/@ant-design/pro-layout
npm ERR!   @ant-design/pro-layout@"^4.5.10" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/khotyn/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/khotyn/.npm/_logs/2022-02-09T06_48_58_451Z-debug-0.log

This is because the newest ant-design/[email protected] depends on [email protected] which is conflict with the project version [email protected]

优化 SOFADashboard 获取动态模块插件方式

目前 SOFADashboard 插件列表依赖前端分页方式,在展示上延迟较大的情况下会出现一定时间的页面空白,此处需要增加数据动态载入样式,并且需要基于后面分页

启动运行问题咨询

问题1:<dashboard.client.version>1.1.1-SNAPSHOT 这个版本不不存在,且这块代码在哪里?
问题2:现在支持注册中心是 sofaRegistry了吗?

ZookeeperRegistryDataCacheImpl may be not threadSafe

The way we use ConcurrentHashMap may be not correct.
For example:

 List<RpcProvider> currentProviderList = providers.get(rpcService);
        if (currentProviderList == null) {
            //todo 2019-07-05 11:23 线程安全问题
            providers.put(rpcService, providerList);
        } else {
            for (RpcProvider provider : providerList) {
                if (currentProviderList.contains(provider)) {
                    continue;
                }
                currentProviderList.add(provider);
            }
        }

Sometimes put() method may be invoked twice, it is not we expected.

Quick Start Issues

I followed the quick start guides and found several issues.

  1. The documentation needs to add a configuration section
    Right now, there is no instructions in how to configure the database connection properties, how to integrate with sofa registry, etc.

  2. The service port displayed in service governance page is wrong
    I started the sofa service with port 12200 and registered with sofa registry, but the port displayed is 49247 which is the source port of the connection to sofa registry instead of the port listened.
    image

TCP *:12200 (LISTEN)
TCP xx.xx.xx.xx:49247->yy.yy.yy.yy:9600 (ESTABLISHED)
  1. This project might need to provide options to specify whether certain modules is enabled or not
    Currently, there are 3 modules: Application Panel, Service Governance and Dynamic Modules. Each module is independent with each other and has different external dependencies, e.g. Application Panel depends on redis, Dynamic Modules depends on zookeeper, etc. So it would be better to provide options so that users could choose to enable/disable some modules they don't need, e.g. via spring profiles.

npm i和npm start问题,急盼大神指点

npm http GET https://registry.npmjs.org/umi
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /root/sofa/sofa-dashboard-master/sofa-dashboard-front/npm-debug.log
npm ERR! not ok code 0
[root@10-205-208-151 sofa-dashboard-front]# npm start

[email protected] start /root/sofa/sofa-dashboard-master/sofa-dashboard-front
cross-env APP_TYPE=site umi dev

sh: cross-env: command not found
npm ERR! weird error 127
npm ERR! not ok code 0

Backend lacks dependencies, can&#39;t be packaged, help

在学习中, 遇到问题无法进行, 前端已经可以正常启动, 现在后端发现如下问题:

后端sofa-dashboard-application中缺少如下依赖, 无法引入:

        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>dashboard-support</artifactId>
        </dependency>

后端sofa-dashboard-core中缺少如下依赖, 无法引入:

        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>dashboard-client-core</artifactId>
        </dependency>

应用依赖图

做了一个应用依赖图的功能, 前端代码抄的 Jaeger 的依赖图:

WechatIMG132

不知道会不会在 license 方面有问题?

ZK:RPC服务缓存更新/回收失效

问题描述

当服务提供者接收到shutdown指令并结束后,服务列表中还存在服务提供者信息;

当服务消费者接收到shutdown指令并结束后,服务列表中还存在服务消费者信息;

问题定位

  • ProviderNodeChangeListener line: 72,81调用参数错误

  • RpcConsumer 缺少equalshashcode方法导致remove调用失效

前端部分构建后,访问页面403


image

npm run build 构建前端项目后,将前端资源放入后端web工程下,配置静态资源目录,然后访问该应用时,发现/api/currentUser 接口在后端项目中没有对应的controller,服务治理页面报403.

在前端项目中,发现该接口是随意返回了一些用户数据,将其迁移到后端后,访问正常。

Hope to add dashboard support for k8s

目前dashboard对于docker和k8s支持略显薄弱,希望增加:

  1. dashboard对于虚拟端口、虚拟地址的支持(如果sofa_rpc配置了虚拟端口、地址,则dashboard优先显示虚拟地址、虚拟端口)
  2. 如果容器运行于k8s,不同pod上的服务无法在dashboard中展示(我在本地增加了dashboard对虚拟地址、端口的支持,但是尚未增加对podIp的读取,如果不同pod运行于相同主机,就不太好分辨)
    不知提议是否合理,烦请评估,谢谢

前端路由规则问题

前端使用的是路由方式是 browserHistory ,原地刷新会导致 404 的问题, 官方文档的解决方案是 : https://pro.ant.design/docs/deploy-cn#%E4%BD%BF%E7%94%A8-spring-boot .
总结一下,有两种方式:

  1. 使用 hash 模式来做路由
  2. 添加一个 Controller 来处理

但是文档中没有给出方法 2 的具体代码, 比较好奇有没有什么优雅的方式来实现这个功能, 不知道蚂蚁内部的最佳实践是什么样的?

希望能为开发者提供一个样例应用模板

sofa-dashboard 目前会新增很多新特性,为了方便调试,同时也为了能更直观的让各位使用者更直观地了解到dashboard应用应该如何配置,建议添加一个sofa-dashboard-sample模块。

这个想法来源于spring-boot项目下的sample。这个模块默认处于非激活的maven profile下, 激活后能方便研发人员或者用户点击学习如何进行相关特性的客户端配置。

image

RegistryDataCache 缓存更新操作线程安全问题

目前zk在做服务注册发现的时候操作RegistryDataCache是在childEvent中调用的。

在这种情况下,无论是生产者还是消费者,其增删改事件都是在一个watcher线程顺序消费的,因此RegistryDataCache的实现可以不是线程安全的,且不存在线程安全问题。

但是registry那边的实现,是在Controller(tomcat线程池)中跟新cache

/**
 * 获取服务列表
 *
 * @return
 */
@GetMapping("all")
public List<ServiceModel> queryServiceList() {
    doRefreshCache();
    List<ServiceModel> data = new ArrayList<>();
    Map<String, RpcService> rpcServices = registryDataCache.fetchService();
    for (Map.Entry<String, RpcService> rpcServiceEntry : rpcServices.entrySet()) {
        final String serviceName = rpcServiceEntry.getKey();
        ServiceModel model = fetchServiceModel(serviceName);
        data.add(model);
    }

    return data;
}

此时由于RegistryDataCache实现地非线程安全,就可能会出现问题。

解决方案是让RegistryDataCache实现变得线程安全,比如使用ConcurrentHashMap#compute更新缓存map,或者添加轻量级锁比如stampedlock等。

比如:

@Override
public void addProviders(String serviceName, List<RpcProvider> providerList) {

    RpcService rpcService = services.get(serviceName);

    if (rpcService == null) {
        LOGGER.warn("receive provider registry data add, but service name is not exist now,{}",
            serviceName);
        return;
    }

    providers.compute(rpcService, (key, origin) -> { //This might be thread-safe
        if (origin == null) {
            return providerList;
        }
        List<RpcProvider> aggregate = new ArrayList<>(origin);
        aggregate.addAll(providerList);
        return aggregate;
    });
    LOGGER.info("receive provider registry data add, data is {}", providerList);
}

Update Dynamic Module Sql Model

Previously , in the dynamic module management section, the file address was uniquely determined depending on the module name and version. as follows:

pluginName binding to address prefix , such as : http://ip:port/basepath
Version binding to address suffix , such as : /version/xxx-ark-biz.jar

so,the target file address is http://ip:port/basepath/version/xxx-ark-biz.jar

Considering that different versions may have their target files from different places, it may be a file server or a file system. So on the model, the file will not be dependent on the pluginName, but will be directly bound to the version information.

动态模块管控增加应用维度的查看

目前 SOFADashboard 仅支持基于插件维度的应用查看,在一定程度上基于插件维度的查看方式无法覆盖一些场景,如基于应用维度的插件管理能力

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.