From 8dc076c126bdc209307c089561440dcb34ca229f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=8C=E6=A3=AE?= Date: Mon, 29 Jan 2024 18:39:59 +0800 Subject: [PATCH] Add Sentinel-Dashboard --- apps/sentinel-dashboard/1.8.6/data.yml | 18 +++++++ .../1.8.6/docker-compose.yml | 12 +++++ apps/sentinel-dashboard/README.md | 47 ++++++++++++++++++ apps/sentinel-dashboard/data.yml | 19 +++++++ apps/sentinel-dashboard/latest/data.yml | 18 +++++++ .../latest/docker-compose.yml | 12 +++++ apps/sentinel-dashboard/logo.png | Bin 0 -> 12548 bytes 7 files changed, 126 insertions(+) create mode 100644 apps/sentinel-dashboard/1.8.6/data.yml create mode 100644 apps/sentinel-dashboard/1.8.6/docker-compose.yml create mode 100644 apps/sentinel-dashboard/README.md create mode 100644 apps/sentinel-dashboard/data.yml create mode 100644 apps/sentinel-dashboard/latest/data.yml create mode 100644 apps/sentinel-dashboard/latest/docker-compose.yml create mode 100644 apps/sentinel-dashboard/logo.png diff --git a/apps/sentinel-dashboard/1.8.6/data.yml b/apps/sentinel-dashboard/1.8.6/data.yml new file mode 100644 index 000000000..ca5f82f11 --- /dev/null +++ b/apps/sentinel-dashboard/1.8.6/data.yml @@ -0,0 +1,18 @@ +additionalProperties: + formFields: + - default: 8858 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Web port + labelZh: Web 端口 + required: true + rule: paramPort + type: number + - default: 8719 + edit: true + envKey: COMMUNICATION_PORT + labelEn: Communication port + labelZh: 通讯端口 + required: true + rule: paramPort + type: number diff --git a/apps/sentinel-dashboard/1.8.6/docker-compose.yml b/apps/sentinel-dashboard/1.8.6/docker-compose.yml new file mode 100644 index 000000000..f6fa92041 --- /dev/null +++ b/apps/sentinel-dashboard/1.8.6/docker-compose.yml @@ -0,0 +1,12 @@ +version: "3" +services: + "sentinel-dashboard": + image: bladex/sentinel-dashboard:1.8.6 + container_name: ${CONTAINER_NAME} + restart: always + ports: + - "${PANEL_APP_PORT_HTTP}:8858" + - "${COMMUNICATION_PORT}:8719" +networks: + 1panel-network: + external: true diff --git a/apps/sentinel-dashboard/README.md b/apps/sentinel-dashboard/README.md new file mode 100644 index 000000000..c59ae8bde --- /dev/null +++ b/apps/sentinel-dashboard/README.md @@ -0,0 +1,47 @@ +# Sentinel-Dashboard + +随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 + +## 快速启动 + +访问地址 +`http://IP:8858/sentinel` + +> 用户名 +> sentinel +> +> 密码 +> sentinel + +## Sentinel 的历史 + ++ 2012 年,Sentinel 诞生,主要功能为入口流量控制。 ++ 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。 ++ 2018 年,Sentinel 开源,并持续演进。 ++ 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 + Service Mesh 架构下多语言限流的问题。 ++ 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。 ++ 2021 年,Sentinel 正在朝着 2.0 云原生高可用决策中心组件进行演进;同时推出了 Sentinel Rust 原生版本。同时我们也在 Rust + 社区进行了 Envoy WASM extension 及 eBPF extension 等场景探索。 ++ 2022 年,Sentinel 品牌升级为流量治理,领域涵盖流量路由/调度、流量染色、流控降级、过载保护/实例摘除等;同时社区将流量治理相关标准抽出到 + OpenSergo 标准中,Sentinel 作为流量治理标准实现。 + +## Sentinel 基本概念 + +### 资源 + +资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。 + +只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。 + +### 规则 + +围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。 + +## Sentinel 是如何工作的 + +Sentinel 的主要工作机制如下: + ++ 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。 ++ 根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。 ++ Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态。 diff --git a/apps/sentinel-dashboard/data.yml b/apps/sentinel-dashboard/data.yml new file mode 100644 index 000000000..e222608ef --- /dev/null +++ b/apps/sentinel-dashboard/data.yml @@ -0,0 +1,19 @@ +name: sentinel-dashboard +tags: + - 中间件 +title: Sentinel-Dashboard +type: 中间件 +description: 阿里巴巴流量卫兵 +additionalProperties: + key: sentinel-dashboard + name: Sentinel-Dashboard + tags: + - Middleware + shortDescZh: 阿里巴巴流量卫兵 + shortDescEn: Alibaba Traffic Guard + type: runtime + crossVersionUpdate: false + limit: 0 + website: https://sentinelguard.io/ + github: https://github.com/alibaba/Sentinel + document: https://sentinelguard.io/zh-cn/docs/introduction.html diff --git a/apps/sentinel-dashboard/latest/data.yml b/apps/sentinel-dashboard/latest/data.yml new file mode 100644 index 000000000..ca5f82f11 --- /dev/null +++ b/apps/sentinel-dashboard/latest/data.yml @@ -0,0 +1,18 @@ +additionalProperties: + formFields: + - default: 8858 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Web port + labelZh: Web 端口 + required: true + rule: paramPort + type: number + - default: 8719 + edit: true + envKey: COMMUNICATION_PORT + labelEn: Communication port + labelZh: 通讯端口 + required: true + rule: paramPort + type: number diff --git a/apps/sentinel-dashboard/latest/docker-compose.yml b/apps/sentinel-dashboard/latest/docker-compose.yml new file mode 100644 index 000000000..bff233bc5 --- /dev/null +++ b/apps/sentinel-dashboard/latest/docker-compose.yml @@ -0,0 +1,12 @@ +version: "3" +services: + "sentinel-dashboard": + image: bladex/sentinel-dashboard:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - "${PANEL_APP_PORT_HTTP}:8858" + - "${COMMUNICATION_PORT}:8719" +networks: + 1panel-network: + external: true diff --git a/apps/sentinel-dashboard/logo.png b/apps/sentinel-dashboard/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3f493afc779f6e2021bbbcae4696dce4b7a6219d GIT binary patch literal 12548 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 s-+rP&