Sfoglia il codice sorgente

[deploy]support deploy with osrc.com

tomsun28 4 anni fa
parent
commit
d136b09d0f

+ 122 - 0
OSRC.md

@@ -0,0 +1,122 @@
+
+## HertzBeat 赫兹跳动在开源运行时OSRC部署流程      
+
+### HertzBeat介绍   
+
+> 易用友好的监控告警系统。
+
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/web-monitor.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/ping-connect.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/port-available.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/database-monitor.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/os-monitor.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/custom-monitor.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/threshold.svg)
+![tan-cloud](https://cdn.jsdelivr.net/gh/dromara/hertzbeat@gh-pages/img/badge/alert.svg)
+
+**官网: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://tancloud.cn)**
+
+> [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是由[Dromara](https://dromara.org)孵化,[TanCloud](https://tancloud.cn)开源的一个支持网站,API,PING,端口,数据库,操作系统等监控类型,拥有易用友好的可视化操作界面的开源监控告警项目。  
+> 提供了对应的 **[SAAS版本监控云](https://console.tancloud.cn)**,中小团队和个人无需再为了监控自己的网站资源,而去部署一套繁琐的监控系统,**[登录即可免费开始](https://console.tancloud.cn)**。     
+> HertzBeat 支持[自定义监控](https://hertzbeat.com/docs/advanced/extend-point) ,只用通过配置YML文件我们就可以自定义需要的监控类型和指标,来满足常见的个性化需求。   
+> HertzBeat 模块化,`manager, collector, scheduler, warehouse, alerter` 各个模块解耦合,方便理解与定制开发。       
+> HertzBeat 支持更自由化的告警配置(计算表达式),支持告警通知,告警模版,邮件钉钉微信飞书等及时通知送达          
+> 欢迎登录 HertzBeat 的 [云环境TanCloud](https://console.tancloud.cn) 试用发现更多。          
+> 正在快速迭代中,欢迎参与加入一起共建项目开源生态。
+
+> `HertzBeat`的多类型支持,易扩展,低耦合,希望能帮助开发者和中小团队快速搭建自有监控系统。
+
+----   
+
+### 在开源运行时社区的部署过程
+
+1. 注册开源运行时社区账户 osrc.com
+
+进入网站 osrc.com 登录注册,购买需要的云服务器或Serverless  
+
+2. 本地安装osrc开发者工具  
+```
+# clone maplecloudy-osrc-tools to local
+git clone https://github.com/maplecloudy/maplecloudy-osrt-tools.git
+# 下载后通过maven在本地安装
+mvn clean install
+# 进入osrc-cli目录安装cli
+npm install
+npm link
+# 支持 osrc 看cli是否安装成功
+osrc 
+```
+
+4. 部署依赖服务-MYSQL和TDengine    
+
+> HertzBeat最少依赖于 关系型数据库[MYSQL5+](https://www.mysql.com/) 和 时序性数据库[TDengine2+](https://www.taosdata.com/getting-started)    
+> 我们需要将依赖服务部署到公有云上,即数据存储自己保存,计算运行在开源运行时社区,保证数据安全性。     
+
+###### 部署MYSQL   
+- docker安装MYSQl    
+   `docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7`   
+- 创建名称为hertzbeat的数据库    
+- 执行位于项目仓库/script/sql/目录下的数据库脚本 [schema.sql](https://gitee.com/dromara/hertzbeat/raw/master/script/sql/schema.sql)    
+
+详细步骤参考 [依赖服务MYSQL安装初始化](https://hertzbeat.com/docs/start/mysql-init)
+
+###### 部署TDengine     
+- docker安装TDengine         
+   `docker run -d -p 6030-6049:6030-6049 -p 6030-6049:6030-6049/udp --name tdengine tdengine/tdengine:2.4.0.12`   
+- 创建名称为hertzbeat的数据库   
+
+详细步骤参考 [依赖服务TDengine安装初始化](https://hertzbeat.com/docs/start/tdengine-init)
+
+2. 拉取hertzbeat项目代码,git切换到`osrc`分支     
+
+[github仓库](https://github.com/dromara/hertzbeat) [gitee仓库](https://github.com/dromara/hertzbeat)
+```
+git clone https://github.com/dromara/hertzbeat.git   
+git checkout osrc  
+```
+3. 配置MYSQL-TDengine服务连接   
+
+修改位于 `hertzbeat/manager/resources/application.yml` 的配置文件        
+需要替换里面的MYSQL服务和TDengine服务参数,IP端口账户密码    
+具体替换参数如下:   
+   ``` 
+   spring.datasource.url
+   spring.datasource.username
+   spring.datasource.password
+   
+   warehouse.store.td-engine.url
+   warehouse.store.td-engine.username
+   warehouse.store.td-engine.password
+   
+   ```
+
+4. 注册OSRC账户,上传部署hertzbeat后端服务      
+
+进入网站 https://osrc.com , 注册用户      
+在本地hertzbeat项目下执行 `mvn clean intall` 部署上传到osrc       
+注意交互控制台会提示输入账户密码登录。   
+
+5. 启动hertzbeat后端服务     
+
+进入网站 https://osrc.com, 个人中心 -> 我的应用 -> 启动服务     
+
+<img alt="tan-cloud" src="https://tancloud.gd2.qingstor.com/tmp/%E6%88%AA%E5%B1%8F2022-04-19%2017.59.20.png" width="1000"/>
+
+6. 构建前端项目   
+
+在本地hertzbeat项目下 `web-app` 目录下执行 `yarn build`     
+
+7. 上传部署hertzbeat前端服务  
+
+在本地hertzbeat项目下 `web-app` 目录下执行 `osrc deploy`  
+
+8. 配置前端代理     
+
+进入网站 https://osrc.com, 个人中心 -> 我的pages -> 代理配置      
+配置前端调用接口流量走刚刚部署的后台服务      
+<img alt="tan-cloud" src="https://tancloud.gd2.qingstor.com/tmp/cc.png" width="1000"/>     
+
+9. 部署完成,发布应用    
+部署OK,点击page页面连接即可使用服务!     
+
+

+ 2 - 0
README.md

@@ -21,6 +21,8 @@
 
 **官网: [hertzbeat.com](https://hertzbeat.com) | [tancloud.cn](https://tancloud.cn)**
 
+在开源运行时社区[OSCR.COM](https://osrc.com)快速运行HertzBeat - [部署流程](https://osrc.com/user/articles/wiki_776513931985080320)       
+
 ## 🎡 <font color="green">介绍</font>
 
 > [HertzBeat赫兹跳动](https://github.com/dromara/hertzbeat) 是由[Dromara](https://dromara.org)孵化,[TanCloud](https://tancloud.cn)开源的一个支持网站,API,PING,端口,数据库,操作系统等监控类型,拥有易用友好的可视化操作界面的开源监控告警项目。  

+ 5 - 52
manager/pom.xml

@@ -107,64 +107,17 @@
     </dependencies>
 
     <build>
-        <finalName>hertzbeat</finalName>
-        <resources>
-            <resource>
-                <directory>src/main/resources</directory>
-                <filtering>true</filtering>
-                <includes>
-                    <include>application.yml</include>
-                    <include>sureness.yml</include>
-                    <include>banner.txt</include>
-                    <include>define/**</include>
-                    <include>**/*.html</include>
-                </includes>
-            </resource>
-        </resources>
         <plugins>
             <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <version>3.2.0</version>
-                <configuration>
-                    <classesDirectory>target/classes/</classesDirectory>
-                    <archive>
-                        <!--生成的jar包不包含maven描述相关文件-->
-                        <addMavenDescriptor>false</addMavenDescriptor>
-                        <manifest>
-                            <!--项目启动类-->
-                            <mainClass>com.usthe.manager.Manager</mainClass>
-                            <useUniqueVersions>false</useUniqueVersions>
-                            <!--第三方JAR加入类构建的路径maven-dependency-plugin-->
-                            <addClasspath>true</addClasspath>
-                            <!--外部依赖jar包的位置-->
-                            <classpathPrefix>lib/</classpathPrefix>
-                        </manifest>
-                        <manifestEntries>
-                            <Class-Path>. config</Class-Path>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-            <!--关键插件,maven提供的assembly插件,需要放在最后-->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>3.3.0</version>
+                <groupId>com.maplecloudy.osrt</groupId>
+                <artifactId>maplecloudy-osrt-maven-plugin</artifactId>
+                <version>1.0.0-RELEASE</version>
                 <executions>
                     <execution>
-                        <id>make-zip</id>
-                        <!--绑定的maven操作-->
-                        <phase>package</phase>
-                        <!--运行一次-->
                         <goals>
-                            <goal>single</goal>
+                            <goal>repackage</goal>
+                            <goal>install-osrt-app</goal>
                         </goals>
-                        <configuration>
-                            <descriptors>
-                                <descriptor>../script/assembly/server/assembly.xml</descriptor>
-                            </descriptors>
-                        </configuration>
                     </execution>
                 </executions>
             </plugin>

+ 74 - 28
manager/src/main/java/com/usthe/manager/service/impl/AppServiceImpl.java

@@ -11,6 +11,9 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.core.annotation.Order;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.yaml.snakeyaml.Yaml;
@@ -18,12 +21,8 @@ import org.yaml.snakeyaml.Yaml;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.io.InputStream;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -122,6 +121,8 @@ public class AppServiceImpl implements AppService, CommandLineRunner {
 
     @Override
     public void run(String... args) throws Exception {
+        boolean loadFromFile = true;
+        final List<InputStream> inputStreams = new LinkedList<>();
         // 读取app定义配置加载到内存中 define/app/*.yml
         Yaml yaml = new Yaml();
         String classpath = this.getClass().getClassLoader().getResource("").getPath();
@@ -132,36 +133,81 @@ public class AppServiceImpl implements AppService, CommandLineRunner {
             defineAppPath = classpath + File.separator + "define" + File.separator + "app";
             directory = new File(defineAppPath);
             if (!directory.exists() || directory.listFiles() == null) {
-                throw new  IllegalArgumentException("define app directory not exist: " + defineAppPath);
+                // load define app yml in jar
+                log.info("load define app yml in internal jar");
+                loadFromFile = false;
+                try {
+                    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+                    Resource[] resources = resolver.getResources("classpath:define/app/*.yml");
+                    for (Resource resource : resources) {
+                        inputStreams.add(resource.getInputStream());
+                    }
+                } catch (Exception e) {
+                    log.error("define app yml not exist");
+                    throw e;
+                }
             }
         }
-        log.info("query define path {}", defineAppPath);
-        for (File appFile : Objects.requireNonNull(directory.listFiles())) {
-            if (appFile.exists()) {
-                try (FileInputStream fileInputStream = new FileInputStream(appFile)) {
-                    Job app = yaml.loadAs(fileInputStream, Job.class);
-                    appDefines.put(app.getApp().toLowerCase(), app);
-                } catch (IOException e) {
-                    log.error(e.getMessage(), e);
-                    throw new IOException(e);
+        if (loadFromFile) {
+            log.info("load define path {}", defineAppPath);
+            for (File appFile : Objects.requireNonNull(directory.listFiles())) {
+                if (appFile.exists()) {
+                    try (FileInputStream fileInputStream = new FileInputStream(appFile)) {
+                        Job app = yaml.loadAs(fileInputStream, Job.class);
+                        appDefines.put(app.getApp().toLowerCase(), app);
+                    } catch (IOException e) {
+                        log.error(e.getMessage(), e);
+                        throw new IOException(e);
+                    }
                 }
             }
+        } else {
+            if (inputStreams.isEmpty()) {
+                throw new IllegalArgumentException("define app directory not exist");
+            } else {
+                inputStreams.forEach(stream -> {
+                    try {
+                        Job app = yaml.loadAs(stream, Job.class);
+                        appDefines.put(app.getApp().toLowerCase(), app);
+                        stream.close();
+                    } catch (Exception e) {
+                        log.error(e.getMessage(), e);
+                    }
+                });
+            }
         }
+
         // 读取监控参数定义配置加载到数据库中 define/param/*.yml
-        String defineParamPath = classpath + File.separator + "define" + File.separator + "param";
-        directory = new File(defineParamPath);
-        if (!directory.exists() || directory.listFiles() == null) {
-            throw new  IllegalArgumentException("define param directory not exist: " + defineParamPath);
-        }
-        for (File appFile : Objects.requireNonNull(directory.listFiles())) {
-            if (appFile.exists()) {
-                try (FileInputStream fileInputStream = new FileInputStream(appFile)) {
-                    ParamDefineDto paramDefine = yaml.loadAs(fileInputStream, ParamDefineDto.class);
+        if (loadFromFile) {
+            String defineParamPath = classpath + File.separator + "define" + File.separator + "param";
+            directory = new File(defineParamPath);
+            if (!directory.exists() || directory.listFiles() == null) {
+                throw new  IllegalArgumentException("define param directory not exist: " + defineParamPath);
+            }
+            for (File appFile : Objects.requireNonNull(directory.listFiles())) {
+                if (appFile.exists()) {
+                    try (FileInputStream fileInputStream = new FileInputStream(appFile)) {
+                        ParamDefineDto paramDefine = yaml.loadAs(fileInputStream, ParamDefineDto.class);
+                        paramDefines.put(paramDefine.getApp().toLowerCase(), paramDefine.getParam());
+                    } catch (IOException e) {
+                        log.error(e.getMessage(), e);
+                        throw new IOException(e);
+                    }
+                }
+            }
+        } else {
+            try {
+                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+                Resource[] resources = resolver.getResources("classpath:define/param/*.yml");
+                for (Resource resource : resources) {
+                    InputStream stream = resource.getInputStream();
+                    ParamDefineDto paramDefine = yaml.loadAs(stream, ParamDefineDto.class);
                     paramDefines.put(paramDefine.getApp().toLowerCase(), paramDefine.getParam());
-                } catch (IOException e) {
-                    log.error(e.getMessage(), e);
-                    throw new IOException(e);
+                    stream.close();
                 }
+            } catch (Exception e) {
+                log.error("define param yml not exist");
+                throw e;
             }
         }
     }

+ 2 - 2
manager/src/main/resources/application.yml

@@ -29,7 +29,7 @@ spring:
     driver-class-name: com.mysql.cj.jdbc.Driver
     username: root
     password: 123456
-    url: jdbc:mysql://localhost:3306/hertzbeat?useUnicode=true&characterEncoding=utf-8&useSSL=false
+    url: jdbc:mysql://103.20.220.86:3306/hertzbeat?useUnicode=true&characterEncoding=utf-8&useSSL=false
     platform: mysql
     hikari:
       max-lifetime: 120000
@@ -66,7 +66,7 @@ warehouse:
     td-engine:
       enabled: true
       driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
-      url: jdbc:TAOS-RS://localhost:6041/hertzbeat
+      url: jdbc:TAOS-RS://103.20.220.86:6041/hertzbeat
       username: root
       password: taosdata
 

+ 1 - 1
web-app/package.json

@@ -1,5 +1,5 @@
 {
-  "name": "web-app",
+  "name": "hertzbeat-web-app",
   "version": "0.0.0",
   "scripts": {
     "ng": "ng",

+ 1 - 1
web-app/src/environments/environment.prod.ts

@@ -4,7 +4,7 @@ export const environment = {
   production: true,
   useHash: false,
   api: {
-    baseUrl: '/',
+    baseUrl: '/api/',
     refreshTokenEnabled: true
   }
 } as Environment;