Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d136b09d0f |
122
OSRC.md
Normal file
122
OSRC.md
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
## HertzBeat 赫兹跳动在开源运行时OSRC部署流程
|
||||
|
||||
### HertzBeat介绍
|
||||
|
||||
> 易用友好的监控告警系统。
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
**官网: [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页面连接即可使用服务!
|
||||
|
||||
|
||||
@@ -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,端口,数据库,操作系统等监控类型,拥有易用友好的可视化操作界面的开源监控告警项目。
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,37 +133,82 @@ 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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
paramDefines.put(paramDefine.getApp().toLowerCase(), paramDefine.getParam());
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new IOException(e);
|
||||
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());
|
||||
stream.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("define param yml not exist");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
{
|
||||
"name": "web-app",
|
||||
"name": "hertzbeat-web-app",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
|
||||
@@ -4,7 +4,7 @@ export const environment = {
|
||||
production: true,
|
||||
useHash: false,
|
||||
api: {
|
||||
baseUrl: '/',
|
||||
baseUrl: '/api/',
|
||||
refreshTokenEnabled: true
|
||||
}
|
||||
} as Environment;
|
||||
|
||||
Reference in New Issue
Block a user