diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml new file mode 100644 index 0000000000..2316c3055d --- /dev/null +++ b/.github/workflows/deploy-website.yml @@ -0,0 +1,49 @@ +# 构建vuepress,并提交到pages分支 +name: deploy + +on: + push: + paths: + - "website/**" + branches: + - "master" + +jobs: + build: + runs-on: ubuntu-latest + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # 首先生成拉取node文件 + - name: Node install + uses: actions/setup-node@v1 + with: + node-version: "16.x" + + # 缓存 node_modules + - name: Cache dependencies + uses: actions/cache@v2 + id: npm-cache + with: + path: | + **/node_modules + key: ${{ runner.os }}-npm-cache + restore-keys: | + ${{ runner.os }}-npm- + + # 如果缓存没有命中,安装依赖 + - name: Install dependencies + if: steps.npm-cache.outputs.cache-hit != 'true' + run: cd website && npm install vuepress + + # 运行构建脚本 + - name: Build VuePress site + run: cd website && npm run docs:build + + # 提交 + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@4.1.4 + with: + branch: pages + folder: ./website/docs/.vuepress/dist diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9cf87e33a1..722a02de00 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,9 +2,13 @@ name: Go on: push: + paths-ignore: + - "website/**" branches: - "master" pull_request: + paths-ignore: + - "website/**" branches: - "master" @@ -42,7 +46,10 @@ jobs: go env go get -v -t -d ./... - - uses: actions/checkout@v3.1.0 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3.3.0 + with: + version: v1.50.1 - name: Build run: go build -v . diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml deleted file mode 100644 index 11ce130359..0000000000 --- a/.github/workflows/lint-go.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: golangci-lint -on: - push: - tags: - - v* - branches: - - "*" - pull_request: -permissions: - contents: read - # Optional: allow read access to pull request. Use with `only-new-issues` option. - # pull-requests: read -jobs: - golangci: - name: lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3.1.0 - - name: Set up Go go1.18 - uses: actions/setup-go@v3 - with: - go-version: 1.18 - - uses: actions/cache@v3 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - name: Get dependencies - run: | - go env - go get -v -t -d ./... - - - name: golangci-lint - uses: golangci/golangci-lint-action@v3.3.0 - with: - args: "--out-${NO_FUTURE}format colored-line-number" - # Optional: working directory, useful for monorepos - # working-directory: somedir - - # Optional: golangci-lint command line arguments. - # args: --issues-exit-code=0 - - # Optional: show only new issues if it's a pull request. The default value is `false`. - # only-new-issues: true - - # Optional: if set to true then the action will use pre-installed Go. - # skip-go-installation: true - - # Optional: if set to true then the action don't cache or restore ~/go/pkg. - # skip-pkg-cache: true - - # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. - # skip-build-cache: true diff --git a/pkg/client/grpc/client.go b/pkg/client/grpc/client.go index 96109ab3c5..756f032f18 100644 --- a/pkg/client/grpc/client.go +++ b/pkg/client/grpc/client.go @@ -72,6 +72,7 @@ func getDialOptions(config *Config) []grpc.DialOption { dialOptions = append(dialOptions, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(resolver.NewEtcdBuilder("etcd", config.RegistryConfig)), + grpc.WithDisableServiceConfig(), ) svcCfg := fmt.Sprintf(`{"loadBalancingPolicy":"%s"}`, config.BalancerName) diff --git a/pkg/core/application/application.go b/pkg/core/application/application.go index 7697186b24..a25c09424e 100644 --- a/pkg/core/application/application.go +++ b/pkg/core/application/application.go @@ -32,9 +32,7 @@ import ( "github.com/douyu/jupiter/pkg/core/ecode" "github.com/douyu/jupiter/pkg/core/executor" "github.com/douyu/jupiter/pkg/core/hooks" - "github.com/douyu/jupiter/pkg/core/rocketmq" "github.com/douyu/jupiter/pkg/core/signals" - "github.com/douyu/jupiter/pkg/core/xgrpclog" "github.com/douyu/jupiter/pkg/flag" "github.com/douyu/jupiter/pkg/registry" "github.com/douyu/jupiter/pkg/server" @@ -111,14 +109,14 @@ func (app *Application) initialize() { _ = app.parseFlags() _ = app.printBanner() - app.initLogger() + // app.initLogger() }) } -func (app *Application) initLogger() { - xgrpclog.SetLogger(xlog.Jupiter()) - rocketmq.SetLogger(xlog.Jupiter()) -} +// func (app *Application) initLogger() { +// xgrpclog.SetLogger(xlog.Jupiter()) +// rocketmq.SetLogger(xlog.Jupiter()) +// } // // start up application // // By default the startup composition is: diff --git a/pkg/core/rocketmq/log.go b/pkg/core/rocketmq/log.go index 4e78571b72..e365c2e1f4 100644 --- a/pkg/core/rocketmq/log.go +++ b/pkg/core/rocketmq/log.go @@ -17,6 +17,8 @@ package rocketmq import ( "github.com/apache/rocketmq-client-go/v2/rlog" "github.com/douyu/jupiter/pkg/core/ecode" + "github.com/douyu/jupiter/pkg/core/hooks" + "github.com/douyu/jupiter/pkg/xlog" "go.uber.org/zap" ) @@ -28,6 +30,12 @@ const ( defaultCallerSkip = 2 ) +func init() { + hooks.Register(hooks.Stage_AfterLoadConfig, func() { + SetLogger(xlog.Jupiter()) + }) +} + func SetLogger(logger *zap.Logger) { rlog.SetLogLevel("debug") rlog.SetLogger(&mqLogger{ diff --git a/pkg/core/xgrpclog/logger.go b/pkg/core/xgrpclog/logger.go index 4d98b86e6e..7ec9a323d5 100644 --- a/pkg/core/xgrpclog/logger.go +++ b/pkg/core/xgrpclog/logger.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/douyu/jupiter/pkg/core/ecode" + "github.com/douyu/jupiter/pkg/core/hooks" "github.com/douyu/jupiter/pkg/xlog" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -29,6 +30,12 @@ var ( } ) +func init() { + hooks.Register(hooks.Stage_AfterLoadConfig, func() { + SetLogger(xlog.Jupiter()) + }) +} + // SetLogger sets loggerWrapper to grpclog func SetLogger(logger *xlog.Logger) { logger = logger.Named(ecode.ModClientGrpc).WithOptions(zap.AddCallerSkip(defaultCallerSkip)) diff --git a/pkg/xlog/rotate/lumberjack_darwin.go b/pkg/xlog/rotate/lumberjack_darwin.go index b8bf9b231d..53b05ffec1 100644 --- a/pkg/xlog/rotate/lumberjack_darwin.go +++ b/pkg/xlog/rotate/lumberjack_darwin.go @@ -34,6 +34,7 @@ // Using the same rotate configuration from multiple processes on the same // machine will result in improper behavior. +//go:build darwin // +build darwin package rotate @@ -163,29 +164,29 @@ var ( megabyte = 1024 * 1024 ) -func (l *Logger) write(p []byte) (n int, err error) { - l.mu.Lock() - defer l.mu.Unlock() - select { - case <-l.reopen: - if err := l.rotate(); err != nil { - panic(err) - } - // n, err = l.file.Write(p) - // l.size += int64(n) - n = len(p) - for len(p) > 0 { - buf := _asyncBufferPool.Get().([]byte) - num := copy(buf, p) - l.queue <- buf[:num] - p = p[num:] - } - - default: - l.queue <- append(_asyncBufferPool.Get().([]byte)[0:], p...)[:len(p)] - } - return n, err -} +// func (l *Logger) write(p []byte) (n int, err error) { +// l.mu.Lock() +// defer l.mu.Unlock() +// select { +// case <-l.reopen: +// if err := l.rotate(); err != nil { +// panic(err) +// } +// // n, err = l.file.Write(p) +// // l.size += int64(n) +// n = len(p) +// for len(p) > 0 { +// buf := _asyncBufferPool.Get().([]byte) +// num := copy(buf, p) +// l.queue <- buf[:num] +// p = p[num:] +// } + +// default: +// l.queue <- append(_asyncBufferPool.Get().([]byte)[0:], p...)[:len(p)] +// } +// return n, err +// } // buffer pool for asynchronous writer var _asyncBufferPool = sync.Pool{ @@ -424,9 +425,7 @@ func (l *Logger) millRunOnce() error { // Only count the uncompressed log file or the // compressed log file, not both. fn := f.Name() - if strings.HasSuffix(fn, compressSuffix) { - fn = fn[:len(fn)-len(compressSuffix)] - } + fn = strings.TrimSuffix(fn, compressSuffix) preserved[fn] = true if len(preserved) > l.MaxBackups { diff --git a/pkg/xlog/rotate/lumberjack_windows.go b/pkg/xlog/rotate/lumberjack_windows.go index 0ccdd16ba8..f48bb8671b 100644 --- a/pkg/xlog/rotate/lumberjack_windows.go +++ b/pkg/xlog/rotate/lumberjack_windows.go @@ -370,9 +370,7 @@ func (l *Logger) millRunOnce() error { // Only count the uncompressed log file or the // compressed log file, not both. fn := f.Name() - if strings.HasSuffix(fn, compressSuffix) { - fn = fn[:len(fn)-len(compressSuffix)] - } + fn = strings.TrimSuffix(fn, compressSuffix) preserved[fn] = true if len(preserved) > l.MaxBackups { diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000000..81f201c443 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,8 @@ +node_modules +.idea +package-lock.json +yarn.lock +.vuepress/dist +docs/.vuepress/dist/* +jupiter-website.tar.gz +yarn.lock diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000000..08b8222222 --- /dev/null +++ b/website/README.md @@ -0,0 +1,7 @@ +# Jupiter +Jupiter的官方文档,介绍了Jupiter框架、Juno微服务管理系统,帮助用户更好的使用Jupiter。 + +# 构建方式 +* 1.安装vuepress,``npm install vuepress`` +* 2.本地执行,``npm run docs:dev`` +* 3.访问``http://127.0.0.1:8080/`` diff --git a/website/docs/.vuepress/config.js b/website/docs/.vuepress/config.js new file mode 100644 index 0000000000..e900d0f096 --- /dev/null +++ b/website/docs/.vuepress/config.js @@ -0,0 +1,282 @@ +const moment = require("moment"); +module.exports = { + base: "/", + title: "Jupiter", + description: "Governance-oriented Microservice Framework", + head: [ + ["link", { rel: "icon", href: "/icon.png" }], + [ + "script", + { type: "text/javascript" }, + `var _hmt = _hmt || []; + (function() { + var hm = document.createElement("script"); + hm.src = "https://hm.baidu.com/hm.js?c77f15742ac7b6883fb18421ee33a702"; + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(hm, s); + })(); + `, + ], + [ + "meta", + { + name: "keywords", + content: "Go,golang,jupiter,gRPC,micro service,govern,web-framework", + }, + ], + ], + + markdown: { + lineNumbers: true, // 代码块显示行号 + }, + themeConfig: { + nav: [ + { + text: "首页", + link: "/", + }, + { + text: "框架", + link: "/jupiter/", + }, + { + text: "管理平台", + link: "/juno/", + }, + { + text: "加入我们", + link: "/join/", + }, + { + text: "了解更多", + items: [ + { text: "微服务治理框架", link: "https://github.com/douyu/jupiter" }, + { text: "微服务管理平台", link: "https://github.com/douyu/juno" }, + ], + }, + { + text: "GitHub", + link: "https://github.com/douyu/jupiter", + }, + ], + // 假定是 GitHub. 同时也可以是一个完整的 GitLab URL + repo: "douyu/jupiter", + // 自定义仓库链接文字。默认从 `themeConfig.repo` 中自动推断为 + // "GitHub"/"GitLab"/"Bitbucket" 其中之一,或是 "Source"。 + repoLabel: "查看文档源码", + // 假如文档不是放在仓库的根目录下: + docsDir: "docs", + // 假如文档放在一个特定的分支下: + docsBranch: "master", + editLinks: true, + editLinkText: "在github.com上编辑此页", + sidebar: { + "/summary/": [""], //这样自动生成对应文章 + "/jupiter/": [ + { + title: "第1章 Jupiter简介", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/jupiter/1.1quickstart", + "/jupiter/1.2example", + "/jupiter/1.3feature", + "/jupiter/1.4contribute", + ], + }, + { + title: "第2章 基础模块", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/jupiter/2.1startup", + "/jupiter/2.2config", + "/jupiter/2.3logger", + ], + }, + { + title: "第3章 服务模块", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/jupiter/3.1http", + "/jupiter/3.2grpc", + "/jupiter/3.3worker", + ], + }, + { + title: "第4章 调用模块", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/jupiter/4.1clientetcd", + "/jupiter/4.2clientgrpc", + "/jupiter/4.3clientgorm", + "/jupiter/4.4clientredis", + "/jupiter/4.5mongodb", + "/jupiter/4.6rocketmq", + "/jupiter/4.7sentinel", + "/jupiter/4.8trace", + ], + }, + { + title: "第5章 服务治理", + collapsable: false, // 可选的, 默认值是 true, + children: ["/jupiter/5.1governintro"], + }, + { + title: "第6章 配置范式", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/jupiter/6.1logger", + "/jupiter/6.2httpserver", + "/jupiter/6.3grpcserver", + "/jupiter/6.4worker", + "/jupiter/6.5clientetcd", + "/jupiter/6.6clientgrpc", + "/jupiter/6.7clientgorm", + "/jupiter/6.8clientredis", + "/jupiter/6.9mongodb", + "/jupiter/6.10rocketmq", + "/jupiter/6.11sentinel", + ], + }, + { + title: "第7章 自动治理", + collapsable: false, // 可选的, 默认值是 true, + children: ["/jupiter/7.1autologger"], + }, + ], //这样自动生成对应文章 + "/juno/": [ + { + title: "第一章 基本介绍", // 必要的 + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/juno/1.1quickstart", + "/juno/1.2install_docker", + "/juno/1.3install_binary", + "/juno/1.4install_docker_compose", + "/juno/1.5quickuse", + "/juno/1.6contribution", + ], + }, + { + title: "第二章 资源中心", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/2.1intro"], + }, + { + title: "第三章 配置中心", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/juno/3.1intro", + "/juno/3.2feature", + "/juno/3.3design", + "/juno/3.4ui", + ], + }, + { + title: "第四章 治理中心", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/4.1govern", "/juno/4.2pprof"], + }, + { + title: "第五章 监控中心", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/5.1monitor"], + }, + + { + title: "第六章 注册中心", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/6.1register"], + }, + { + title: "第七章 任务平台", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/7.1task"], + }, + { + title: "第八章 测试平台", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/8.1grpc_test", "/juno/8.2http_test"], + }, + { + title: "第九章 Juno-Agent", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/juno/9.1quickstart", + "/juno/9.2configuration", + "/juno/9.3config_get", + "/juno/9.4configdown", + "/juno/9.5configparse", + "/juno/9.6agentReport", + "/juno/9.7pmt", + "/juno/9.8proxy", + ], + }, + { + title: "第十章 日志中心", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/10.1applog"], + }, + { + title: "第十一章 授权模块", + collapsable: false, // 可选的, 默认值是 true, + children: [ + "/juno/11.1intro", + "/juno/11.2authproxy", + "/juno/11.3gitlab", + ], + }, + { + title: "第十二章 API文档", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/12.1apiauth", "/juno/12.2openapi"], + }, + { + title: "第十三章 系统设置", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/13.1system_setting", "/juno/13.2junoevent.md"], + }, + { + title: "第十四章 操作统计", + collapsable: false, // 可选的, 默认值是 true, + children: ["/juno/14.1statistics"], + }, + ], + "/awesome/": [ + { + title: "扩展阅读", // 必要的 + collapsable: false, // 可选的, 默认值是 true, + children: ["/awesome/register"], + }, + ], + }, + sidebarDepth: 2, + lastUpdated: "上次更新", + serviceWorker: { + updatePopup: { + message: "发现新内容可用", + buttonText: "刷新", + }, + }, + }, + plugins: [ + [ + "@vuepress/last-updated", + { + transformer: (timestamp, lang) => { + // 不要忘了安装 moment + const moment = require("moment"); + moment.locale("zh-cn"); + return moment(timestamp).format("YYYY-MM-DD HH:mm:ss"); + }, + + dateOptions: { + hours12: true, + }, + }, + ], + "@vuepress/back-to-top", + "@vuepress/active-header-links", + "@vuepress/medium-zoom", + "@vuepress/nprogress", + ], +}; diff --git a/website/docs/.vuepress/public/icon.png b/website/docs/.vuepress/public/icon.png new file mode 100644 index 0000000000..20dac682e7 Binary files /dev/null and b/website/docs/.vuepress/public/icon.png differ diff --git a/website/docs/.vuepress/public/logo.png b/website/docs/.vuepress/public/logo.png new file mode 100644 index 0000000000..b17f48e0e9 Binary files /dev/null and b/website/docs/.vuepress/public/logo.png differ diff --git a/website/docs/README.md b/website/docs/README.md new file mode 100644 index 0000000000..3414b09aa4 --- /dev/null +++ b/website/docs/README.md @@ -0,0 +1,18 @@ +--- +home: true +heroImage: /logo.png +actionText: 快速上手 → +actionLink: /jupiter/ +heroText: 罗马神话中的众神之神 +tagline: 在天界掌管诸神,在互联网掌管所有微服务! +sidebar: auto +features: +- title: 大道至简 + details: 简单配置快速构建项目,以最少的操作帮助你专注于业务。 +- title: 极致性能 + details: 全链路压测,发挥框架的极致性能。 +- title: 全面治理 + details: Jupiter配套组件,轻松治理你的服务。 + +footer: Apache Licensed | Copyright © 2020-present Douyu +--- diff --git a/website/docs/join/readme.md b/website/docs/join/readme.md new file mode 100644 index 0000000000..b203c25c7e --- /dev/null +++ b/website/docs/join/readme.md @@ -0,0 +1,15 @@ +## 加入开发群 + +### 钉钉群 + +![image](../static/join/jupiter-join-dingding.jpg) + +### 微信 + +> 以下微信为开发者微信,添加之后会直接拉到jupiter的开发群,添加时候简单说明下目的,感谢。 +> +![image](../static/join/jupiter-join-wechat.png) + +## 加入我司 + +![image](../static/join/join1.jpg) diff --git a/website/docs/juno/1.1quickstart.md b/website/docs/juno/1.1quickstart.md new file mode 100644 index 0000000000..95de954da5 --- /dev/null +++ b/website/docs/juno/1.1quickstart.md @@ -0,0 +1,28 @@ +# 1.1 快速开始 + +## 1.1.1 介绍 + +Juno 斗鱼的微服务管理系统,提供了对微服务进行管理的多项能力,包括应用监控、依赖分析、配置管理等。 + +Juno-proxy Juno-Agent是一个提供服务代理、应用配置下发、应用配置解析、shell沙箱、探活、消息总线的Agent。 + +## 1.1.2 安装方式 + +* [docker all in one](./1.2install_docker.md) +* [binary install](./1.3install_binary.md) +* [docker-compose](./1.4install_docker_compose.md) + +## 1.1.3 定义 +* Juno将资源分为三大类,应用、机房、节点。 +* 机房定义了地区Region、可用区Zone、环境Env,三个值作为唯一值,确定一个机房信息。 +* 节点定义了节点名称host_name和节点IDnode_id作为唯一值,确定一个节点。 +* 定义了应用名称app_name和应用IDaid作为唯一值,确定一个应用。我们可以通过这些数据查询应用。 +* 资源管理将agent部署到节点上。agent会读取节点上环境变量里的节点和机房信息上报给juno。 + +## 1.1.4 安装模式 + +不同的公司有不同的业务类型大小,提供了两种安装模式。 +- 单机房+MySQL+ETCD+Juno+Juno-agent 模式 +- 多机房+MySQL+ETCD+Juno+Juno-proxy+Juno-agent 模式 + +感谢 [@feixiao](https://github.com/feixiao) 对该章节的修改的贡献 [https://github.com/feixiao/service/blob/master/jupiter/](https://github.com/feixiao/service/blob/master/jupiter/) diff --git a/website/docs/juno/1.2install_docker.md b/website/docs/juno/1.2install_docker.md new file mode 100644 index 0000000000..2963d94ecc --- /dev/null +++ b/website/docs/juno/1.2install_docker.md @@ -0,0 +1,27 @@ +## 1.2 docker安装 +### 1.2.1 安装 +```bash +git clone https://github.com/douyu/juno-install.git + +cd juno-install + +docker build -t juno-install:v1 -f ./docker/all-in-one/Dockerfile ./ + +docker run -itd --name juno-demo -p 50000:50000 -p 50004:50004 --privileged=true juno-install:v1 /usr/sbin/init + +docker exec -it juno-demo /bin/bash + +./install.sh + +``` +## 1.2.2 调试 +```bash +#查看mysql +mysql -uroot +#查看etcd里内容 +etcdctl get "" --prefix +#查看go +go version +#查看pprof +go tool pprof -http=":8081" http://127.0.0.1:50004/debug/pprof/profile +``` diff --git a/website/docs/juno/1.3install_binary.md b/website/docs/juno/1.3install_binary.md new file mode 100644 index 0000000000..3dd8af54e0 --- /dev/null +++ b/website/docs/juno/1.3install_binary.md @@ -0,0 +1,7 @@ +## 1.3 二进制安装 +```bash +git clone https://github.com/douyu/juno-install.git +cd juno-install/ +cd shell +sh ./install.sh +``` diff --git a/website/docs/juno/1.4install_docker_compose.md b/website/docs/juno/1.4install_docker_compose.md new file mode 100644 index 0000000000..91109ea3e3 --- /dev/null +++ b/website/docs/juno/1.4install_docker_compose.md @@ -0,0 +1,27 @@ +# 1.4 docker-compose 安装 + +此方式将juno以及所依赖组件分容器进行启动 + +> 参考: https://github.com/douyu/juno-install/blob/master/docker-compose.yml + +```bash +docker-compose up --build +``` + +执行初始化juno + +```bash +docker exec -it juno-install_juno-admin_1 docker_juno_init.sh +``` + +mock数据 + +```bash +docker exec -it juno-install_juno-admin_1 docker_juno_mock.sh +``` + +Note + +- 相关配置文件在config目录中 +- 若需登陆grafana修改 juno管理界面-系统设置-Grafana地址 配置grafana地址为 "http://grafana:3000" + diff --git a/website/docs/juno/1.5quickuse.md b/website/docs/juno/1.5quickuse.md new file mode 100644 index 0000000000..d2134cfa1d --- /dev/null +++ b/website/docs/juno/1.5quickuse.md @@ -0,0 +1,43 @@ +# 1.5 平台使用介绍 + +当前平台闭环流程为: + +节点心跳上报->应用节点关联->应用配置下发->配置下发状态监控->节点状态正常->节点心跳上报 + +## 1.5.1 节点心跳上报 + +节点心跳上报后,管理平台获取当前可用的实例列表。 + +![节点心跳上报](../static/juno/9.1.1-1.png) + +## 1.5.2 应用节点关联 + +在应用服务中找到当前可用的节点,分配给目标应用。 + +![应用节点关联](../static/juno/9.1.2-1.png) + +## 1.5.3 配置下发 + +测试应用:douyu-edogawa-konan + +将 agent 上报的两个节点:`4d4c08f6af1e`和`289df862ff2d`分布用于进行两种不同的配置下发模式验证。 + +### 1.5.3.1 本地文件监听 + +节点`4d4c08f6af1e`上报的信息标识:环境-dev、可用区-武汉光谷可用区 F3,进行对应对应环境的配置文件设置 + +![--](../static/juno/9.1.3-1.png) + +点击发布按钮,配置会发布到目标节点,可用看到当前文件状态为已同步。 +![--](../static/juno/9.1.3-2.png) + + +### 1.5.3.2 HTTP 长轮询 + +节点`289df862ff2d`上报的信息标识:环境-live、可用区-武汉光谷可用区 F1,进行对应对应环境的配置文件设置 + +![--](../static/juno/9.1.3-3.png) + +点击发布按钮,配置会发布到目标节点,可用看到当前文件状态为已同步。 + +![--](../static/juno/9.1.3-4.png) diff --git a/website/docs/juno/1.6contribution.md b/website/docs/juno/1.6contribution.md new file mode 100644 index 0000000000..6d2bbee5bc --- /dev/null +++ b/website/docs/juno/1.6contribution.md @@ -0,0 +1,196 @@ +# 1.6 参与JUNO开发 + +## 目录结构 + +```bash +── CONTRIBUTING.md +├── LICENSE +├── Makefile +├── README.md +├── api +│   └── apiv1 # 对外api提供 +├── assets # 前端资源 +├── cmd +│   ├── juno-admin +│   └── juno-proxy +├── config # config demo +│   ├── casbin_test +│   ├── install.toml +│   ├── juno-grafana.ini +│   ├── juno-prometheus.yml +│   ├── model.conf +│   ├── multiple-region-admin.toml +│   ├── multiple-region-proxy.toml +│   ├── resource.yaml +│   └── single-region-admin.toml +├── configs # 本地开发配置,不要推送到仓库 +│   ├── config-multiple-region-admin.toml +│   └── config-single-region-admin.toml +├── data # mock 数据 +│   ├── docker +│   ├── grafana +│   └── mockdata +├── docs +│   ├── LICENSEHEADER.txt +│   ├── logo.png +│   └── wiki-cn +├── go.mod +├── go.sum +├── internal # 内部逻辑 +│   ├── app +│   └── pkg +├── logs # 本地开发日志 +│   ├── biz.json +│   └── system.json +├── pkg # 外部可引用代码 +│   ├── auth +│   ├── cfg +│   ├── constx +│   ├── errorconst +│   ├── model +│   ├── pb +│   └── util +└── script +    └── build +``` + +### internal + +```bash +├── app +│   ├── adminengine # router +│   │   ├── engine_admin.go +│   │   ├── engine_install.go +│   │   ├── form_validator.go +│   │   ├── router_admin.go +│   │   └── router_api.go +│   ├── core +│   │   └── core.go +│   ├── middleware +│   │   ├── casbin.go +│   │   ├── gateway.go +│   │   ├── login.go +│   │   ├── openauth.go +│   │   └── openauth_test.go +│   └── proxyengine +│   └── engine.go +└── pkg + ├── datasource + │   └── datasource.go + ├── install + │   ├── base.go + │   ├── mock_app.go + │   └── mock_setting.go + ├── invoker # 数据源初始化 + │   └── invoker.go + ├── packages + │   ├── contrib + │   └── roundtrip + └── service + ├── agent + ├── analysis + ├── app_topology.go + ├── appevent + ├── applog + ├── assist + ├── auth + ├── casbin + ├── clientproxy + ├── confgo + ├── confgov2 + ├── configresource + ├── gateway + ├── grafana + ├── grpcgovern + ├── init.go + ├── notify + ├── openauth + ├── parse + ├── permission + ├── pprof + ├── proxy + ├── report + ├── resource + ├── service_suite_test.go + ├── supervisor + ├── system + ├── tool.go + └── user + ``` + +## 开发方式 + +### 数据库初始化与调整 + +参考Makefile文件,以下是相关的数据库操作,初始化、数据清理、数据mock + +相关代码逻辑在 `internal/pkg/install`中 + +```bash +database.install: + @go run cmd/juno-admin/main.go --config=config/install.toml --install=true +database.clear: + @go run cmd/juno-admin/main.go --config=config/install.toml --clear=true +database.mock: + @go run cmd/juno-admin/main.go --config=config/install.toml --mock=true +database.debug: database.clear database.install database.mock +``` + +### 后端启动 + +有两种模式: + +- single-region-admin + +只调整juno功能、不涉及跨机房通信开发使用`make run.single-region-admin`即可 + +```bash +run.single-region-admin: + @go run cmd/juno-admin/main.go --config=config/single-region-admin.toml +``` + +- multiple-region-admin+multiple-region-proxy + +需要跨机房数据调用调试使用`make run.multiple-region-admin`和`make run.multiple-region-proxy` + +``` bash +run.multiple-region-admin: + @go run cmd/juno-admin/main.go --config=config/multiple-region-admin.toml +run.multiple-region-proxy: + @go run cmd/juno-proxy/main.go --config=config/multiple-region-proxy.toml +``` + +#### 开发配置不要推送到远端仓库 + +本地开发配置放在`configs`文件夹中,使用`.gitignore`进行文件忽略,切记不要推送、不要推送、不要推送 + +推送前代码做好审核工作 + +### 前端启动 + +进入`assest`文件夹执行`npm run start` + +修改 config/proxy.ts 里面的后端代理端口配置,即可打通本地调试 + +生产环境进行`npm run build`进行dist构建推送即可 + +```bash +├── README.md +└── config + ├── config.ts + ├── defaultSettings.ts + └── proxy.ts +├── dist +├── favicon.png +├── jest.config.js +├── jsconfig.json +├── mock +├── node_modules +├── package.json +├── public +├── src +├── tests +└── tsconfig.json +``` + +访问 `localhost:8000` 进入本地调试 diff --git a/website/docs/juno/10.1applog.md b/website/docs/juno/10.1applog.md new file mode 100644 index 0000000000..a97773d3df --- /dev/null +++ b/website/docs/juno/10.1applog.md @@ -0,0 +1,11 @@ +# 10.1 日志中心 + +日志中心目前提供两种使用方式 +- default 阿里云日志自定义实现接入 +- aliyun 阿里云日志原生SDK接入 + +## 10.1.1 阿里云日志自定义实现接入 + + +## 10.1.1 阿里云日志原生SDK接入 + diff --git a/website/docs/juno/11.1intro.md b/website/docs/juno/11.1intro.md new file mode 100644 index 0000000000..082a448778 --- /dev/null +++ b/website/docs/juno/11.1intro.md @@ -0,0 +1,13 @@ +# 4.1 授权介绍 +Juno提供了多种方式进行用户授权。可以通过一些接口,同步用户的权限和组织信息。 + +## 4.1.1 OAuth授权 +* Gitlab OAuth +* Github OAuth +* Wechat OAuth + +## 4.1.2 Auth Proxy +你可以在``Juno``之前,采用一个服务器进行授权,然后在将Auth数据代理给Juno。 + +## 4.1.3 Juno Auth +你可以使用Juno自带的用户系统,进行授权登录。 diff --git a/website/docs/juno/11.2authproxy.md b/website/docs/juno/11.2authproxy.md new file mode 100644 index 0000000000..876eced17a --- /dev/null +++ b/website/docs/juno/11.2authproxy.md @@ -0,0 +1,44 @@ +# 4.2 反向代理授权 + +功能开发中。 + +你可以使用`HTTP`反向代理服务器进行授权。启用该功能,我们可以对`JUNO`配置如下。 + +```toml +[auth.proxy] +# Defaults to false, but set to true to enable this feature +enabled = true +# HTTP Header name that will contain the username or email +header_name = "X-WEBAUTH-USER" +# HTTP Header property, defaults to `username` but can also be `email` +header_property = "username" +# Set to `true` to enable auto sign up of users who do not exist in Grafana DB. Defaults to `true`. +auto_sign_up = true +# Define cache time to live in minutes +# If combined with Grafana LDAP integration it is also the sync interval +sync_ttl = 60 +# Limit where auth proxy requests come from by configuring a list of IP addresses. +# This can be used to prevent users spoofing the X-WEBAUTH-USER header. +# Example `whitelist = 192.168.1.1, 192.168.1.0/24, 2001::23, 2001::0/120` +whitelist = "" +# Optionally define more headers to sync other user attributes +# Example `headers = Name:X-WEBAUTH-NAME Email:X-WEBAUTH-EMAIL Groups:X-WEBAUTH-GROUPS` +headers = "" +# Check out docs on this for more details on the below setting +enable_login_token = false +``` + +## 4.2.1 与 Juno 的交互 + +```bash +curl -H "X-WEBAUTH-USER: admin" http://localhost:50000/api/users +[ + { + "id":1, + "name":"", + "login":"admin", + "email":"admin@localhost", + "isAdmin":true + } +] +``` diff --git a/website/docs/juno/11.3gitlab.md b/website/docs/juno/11.3gitlab.md new file mode 100644 index 0000000000..0a91a1b826 --- /dev/null +++ b/website/docs/juno/11.3gitlab.md @@ -0,0 +1,26 @@ +# 4.3 Gitlab Auth + +功能开发中。 + +我们开启 Gitlab OAuth2,需要首先在 Gitlab 系统里生成一个 Client ID 和 Secret Key。 + +## 4.3.1 创建一个 Gitlab OAuth keys + +你需要创建一个[Gitlab OAuth 应用](https://docs.gitlab.com/ce/integration/oauth_provider.html) + +## 4.3.2 在 Juno 里启用 Gitlab + +启用 Gitlab 的授权 + +```toml +[auth.gitlab] +enabled = true +allow_sign_up = false +client_id = "GITLAB_APPLICATION_ID" +client_secret = "GITLAB_SECRET" +scopes = "api" +auth_url = "https://gitlab.com/oauth/authorize" +token_url = "https://gitlab.com/oauth/token" +api_url = "https://gitlab.com/api/v4" +allowed_groups = +``` diff --git a/website/docs/juno/12.1apiauth.md b/website/docs/juno/12.1apiauth.md new file mode 100644 index 0000000000..a1426b2676 --- /dev/null +++ b/website/docs/juno/12.1apiauth.md @@ -0,0 +1,63 @@ +# 12.1 API 授权 + +## 12.1.1 创建一个 Access Token + +1. 打开后台菜单: 系统设置 / AccessTokens,点击新建按钮 + +![](../static/jupiter/access_token_create_1.png) + +2. 输入授权应用名称 + +![](../static/jupiter/access_token_create_2.png) + +3. 创建成功后,点击小眼睛图表即可看到AppSecret + +![](../static/jupiter/access_token_create_3.png) + +## 12.1.2 访问Open API + +### 公共参数 + +所有Open API都需要携带如下公共参数: + +| 参数名 | 类型 | 说明 | +| --------- | ------ | ------------------------------------------------------------ | +| app_id | string | 在Juno后台申请的App ID | +| timestamp | int | 当前Unix时间戳(秒),如果Juno服务端收到过期的时间戳,授权失败 | +| nonce_str | string | 随机字符串,16位 | +| sign | string | 签名 | + +如果是`POST`请求,那么以上参数在 `Body` 中,为 `JSON` 请求体的字段。如果是 `GET` 请求,以上参数为 `Query` 参数。 + + + +### 签名方法 + +1. 拼接签名原文 + + 签名原文由 `app_id`、`nonce_str`、`secret` 、 `timstamp` 组成,拼接方式如下: + + ```plainText = app_id + nonce_str+ secret + timestamp ``` + +2. 计算签名 + + 目前使用的签名算法是 `md5`,对签名原文使用md5进行签名即可: + + ```sign = md5(plainText)``` + + + +Go 语言示例: + +```go +//计算签名 +//md5(appId + nonceStr + secret + timestamp) +func openAuthSign(appId, nonceStr, secret string, timestamp int64) (sign string) { + plainText := fmt.Sprintf("%s%s%s%d", appId, nonceStr, secret, timestamp) + + return util.Md5Str(plainText) +} +``` + + + diff --git a/website/docs/juno/12.2openapi.md b/website/docs/juno/12.2openapi.md new file mode 100644 index 0000000000..7dbc111d62 --- /dev/null +++ b/website/docs/juno/12.2openapi.md @@ -0,0 +1,205 @@ +# 12.2 Open API + +> Open API授权公共参数和签名方式请参考 [API授权](./12.1apiauth.md) +> +> 本文档包含了主要的接口清单,详细文档正在编写中 + +## 接口总览 + +```go +GET api/v1/confgo/config/list +GET api/v1/confgo/config/detail +GET api/v1/confgo/config/diff +GET api/v1/confgo/config/instance/list +GET api/v1/confgo/config/history +POST api/v1/confgo/config/create +POST api/v1/confgo/config/update +POST api/v1/confgo/config/publish +POST api/v1/confgo/config/delete +GET api/v1/confgo/config/diffVersion + +GET api/v1/resource/app_env_zone/list +``` + + +## 接口详情 +### GET api/v1/confgo/config/list +#### input +```go +AppName string `query:"app_name"` +Env string `query:"env"` +``` +#### output +```go + [{ + ID uint `json:"id"` + AID uint `json:"aid"` + Name string `json:"name"` + Format string `json:"format"` // Yaml/Toml + Env string `json:"env"` // 环境 + Zone string `json:"zone"` // 机房Zone + CreatedAt time.Time `json:"created_time"` + UpdatedAt time.Time `json:"update_time"` + DeletedAt *time.Time `json:"deleted_at"` + PublishedAt *time.Time `json:"published"` // 未发布/发布时间 + }] +``` +### GET api/v1/confgo/config/detail +#### input +```go +ID uint `json:"id"` +``` +#### output +```go +ID uint `json:"id"` +AID uint `json:"aid"` +Name string `json:"name"` +Content string `json:"content"` +Format string `json:"format"` // Yaml/Toml +Env string `json:"env"` // 环境 +Zone string `json:"zone"` // 机房Zone +CreatedAt time.Time `json:"created_time"` +UpdatedAt time.Time `json:"update_time"` +PublishedAt *time.Time `json:"published"` // 未发布/发布时间 +``` +### api/v1/confgo/config/diff +#### input +```go +ID uint `query:"id" valid:"required"` // 配置ID +HistoryID uint `query:"history_id" valid:"required"` // 版本ID +``` +#### output +```go +Origin *RespDetailConfig `json:"origin,omitempty"` +Modified RespDetailConfig `json:"modified"` +``` +### api/v1/confgo/config/instance/list +#### input +```go +ConfigurationID uint `json:"id" query:"id" validate:"required"` +Env string `json:"env" query:"env" validate:"required"` +ZoneCode string `json:"zone_code" query:"zone_code" validate:"required"` +``` +#### output +```go +[{ + ConfigurationStatusID uint `json:"configuration_status_id"` + Env string `json:"env"` + IP string `json:"ip"` + HostName string `json:"host_name"` + DeviceID int `json:"device_id"` + RegionCode string `json:"region_code"` + RegionName string `json:"region_name"` + ZoneCode string `json:"zone_code"` + ZoneName string `json:"zone_name"` + ConfigFilePath string `json:"config_file_path"` + ConfigFileUsed uint `json:"config_file_used"` // 1 supervisor 2 systemd + ConfigFileSynced uint `json:"config_file_synced"` + ConfigFileTakeEffect uint `json:"config_file_take_effect"` + SyncAt time.Time `json:"sync_at"` + }] +``` +### api/v1/confgo/config/history +#### input +```go +ID uint `json:"id"` // 配置文件ID +Size uint `json:"size"` +Page uint `json:"page"` +``` +#### output +```go +{ + Pagination { + Current int `json:"current"` + Total int `json:"total"` + PageSize int `json:"pageSize"` + } `json:"pagination"` + List[{ + ID uint `json:"id"` + UID uint `json:"uid"` // 发布人ID + UserName string `json:"user_name"` + ChangeLog string `json:"change_log"` + ConfigurationID uint `json:"configuration_id"` + Version string `json:"version"` // 发布到Juno Proxy的版本号 + CreatedAt time.Time `json:"created_at"` + }] `json:"list"` +} + +``` +### POST api/v1/confgo/config/create +#### input +```go +AppName string `json:"app_name"` +Env string `json:"env"` +Zone string `json:"zone"` +FileName string `json:"file_name"` // 文件名(不带后缀) +Format ConfigFormat `json:"format"` // 格式后缀名(比如: toml, yaml) +``` +### POST api/v1/confgo/config/update +#### input +```go +ID uint `json:"id"` +Message string `json:"message"` +Content string `json:"content"` +``` +### POST api/v1/confgo/config/publish +#### input +```go +ID uint `json:"id"` // 配置ID +Version *string `json:"version"` // 版本号 +``` +### api/v1/confgo/config/delete +#### input +```go +ID uint `json:"id"` +``` + +### POST api/v1/confgo/config/diffVersion + +| 参数名 | 必选 | 类型 |说明 | +| ------------- |:-------------:| -----:|------| +| ipList | 是 | []string | ip地址列表 | +| appName | 是 | string |应用名称 | +| env | 是 | string | 环境名称 | + +- **请求参数示例** +```javascript +{ +http://10.117.22.35:50000/api/v1/confgo/config/diffVersion?ips=10.117.22.35&appName=jupiter-demo&env=live +} +``` + +- **返回值** +```javascript +{ + "code": 0, + "msg": "", + "data": { + "hasNew": false, + "diffUrlList": [{ + "name": "single-rexxx:qgion-admin", + "diffUrl": "http://jupiterxxxconsole.douyu.com/app?aid=1\u0026appName=jupiter-demo\u0026env=live\u0026tab=confgo\u0026publishVersion=\u0026serviceVersion=fa041303713cc4d198f6feb282f23a98" + }] + } +} +``` + + + +### GET api/v1/resource/app_env_zone/list +#### input +```go +AppName string `query:"app_name"` +``` +#### output +```go +[ + { + Env string `json:"env"` + ZoneList []struct { + ZoneCode string `json:"zone_code"` + ZoneName string `json:"zone_name"` + } `json:"zone_list"` + } +] +``` \ No newline at end of file diff --git a/website/docs/juno/13.1system_setting.md b/website/docs/juno/13.1system_setting.md new file mode 100644 index 0000000000..4ca12de37e --- /dev/null +++ b/website/docs/juno/13.1system_setting.md @@ -0,0 +1,46 @@ +# 14.1 系统设置 + +介绍 JUNO 系统设置相关模块 + +## 14.2 Pprof 环境检测 + +检测服务 pprof 环境依赖,如果三个状态都是`已安装`,则可以正常使用应用服务中的 Pprof 分析功能。 + +## 14.3 配置依赖解析 + +调整配置依赖解析定时任务的时间间隔。 + +## 14.4 Grafana 设置 + +| 名称 | 类型 | 描述 | +| :------- | :----- | :------------- | +| `Host` | string | 127.0.0.1 | +| `Scheme` | string | HTTP | +| `Header` | string | X-WEBAUTH-USER | + +## 14.5 网关设置 + +直接进行访问转发并条件对应的`headers` + +## 14.6 Etcd 查询前缀设置 + +应用服务中 Etcd 查询下拉框中的默认值设定 + +## 14.7 应用版本设置 + +目的是为了兼容不同版本的 jupiter 版本,目前不需要进行多版本设置,后期如果出现了大版本更新,无法兼容历史版本,则需要新建一套配置。 + +| 名称 | 类型 | 描述 | +| :------------- | :----- | :-------------------------------- | +| `应用版本名称` | string | 用户可读名称 | +| `应用版本号` | string | 关联应用依赖解析中 jupiter 的版本 | +| `应用版本Key` | string | 系统内部使用 | +| `Dashboard配置` | string | 应用监控各个模板访问地址配置 | + +![架构设计](../static/juno/14.1-1.png) + +## 14.8 K8s 集群设置 + +指定机房和环境的集群设置。 + +![架构设计](../static/juno/14.1-2.png) diff --git a/website/docs/juno/13.2junoevent.md b/website/docs/juno/13.2junoevent.md new file mode 100644 index 0000000000..37a254fbe8 --- /dev/null +++ b/website/docs/juno/13.2junoevent.md @@ -0,0 +1,108 @@ +# 13.2 系统消息事件配置 + +默认情况下,`Juno` 系统会将事件写入名为 `appevent` 的数据表中。如果你希望通过 `MQ` 获取 `Juno` 系统的事件,那么可以通过下述配置来实现。目前系统事件消息只支持了 `RocketMQ`。 + +## 配置示例: +```toml +[junoevent.rocketmq] +enable = false # 开关.如果为false,则系统事件不写MQ. +addr = ["127.0.0.1:9876"] # mq地址 +topic = "juno_test_job" # mq topic +group = "juno_devops_go" # mq producer group +retry = 3 # MQ写重试次数 +dialTimeout = "3s" # MQ连接超时时间 +``` + +### 配置项说明: + +| 配置项 | 字段说明 | 示例值 | +| :- | :- | -: | +| `enable` | 开关。是否打开本功能,如果为 true , JUNO 系统事件会发送消息到配置的 MQ | `true` | +| `addr` | MQ 地址 | `["127.0.0.1:9876"]` | +| `topic` | RocketMQ 的Topic名称 | `"xxxx"` | +| `group` | Producer Group 名称 | `xxx` | +| `retry` | 重试次数 | 3 | +| `dialTimeout` | 连接超时时间 | `"3s"` | + +## 消息格式: + +```javascript +{ + "id": 1, // 事件ID + "app_name": "", // 应用名称 + "aid": "", // 应用ID + "zone_code": "", // Zone Code + "env": "", // 环境 + "host_name": "", // 主机名称 + "operator_type": "", // 用户类型 (user | openapi) + "user_name": "", // 用户名 + "uid": "", // 用户ID + "operation": "", // 事件类型 + "create_time": "", // 事件创建时间 + "source": "", // 来源 + "metadata": "", // 事件详情 (与事件类型有关) + "operation_name": "", // 事件操作名称 + "source_name": "" // 来源名称 +} +``` + +### 消息字段说明: + +| 字段名 | 说明 | +| :- | :- | +| id | 事件ID | +| app_name | 应用名称 | +| aid | 应用ID | +| zone_code | Zone Code | +| env | 环境 | +| host_name | 主机名称 | +| operator_type | 用户类型 (user: 用户操作; openapi: 通过OpenAPI操作) | +| user_name | 用户名 | +| uid | 用户ID | +| operation | 事件类型,见 [事件类型](#事件类型) | +| create_time | 事件创建时间 | +| source | 来源,见 [来源](#来源类型) | +| metadata | 事件详情 (与事件类型有关,不同的事件类型数据格式不同) | +| operation_name | 事件操作名称 | +| source_name | 来源名称 | + +事件消息示例: + +```javascript +{ + "id": 11979, + "app_name": "bj-im-srv-tencent-callback-go", + "aid": 14185, + "zone_code": "ALIYUN-HB2-G", + "env": "prod", + "host_name": "", + "user_name": "杜旻翔_gitlab", + "uid": 1, + "operation": "confgo_file_update", + "create_time": 1603942730, + "source": "confgo", + "metadata": "{\"access_token_id\":0,\"change_log\":\"1\",\"configuration_id\":988,\"format\":\"toml\",\"id\":0,\"name\":\"test\",\"uid\":1,\"version\":\"50347a3f14aea923e9f8eac867fd3bb1\"}", + "operator_type": "user" +} +``` + +### 事件类型 + +| 事件类型 | 说明 | +| :- | :- | +| `confgo_file_create` | 配置创建 | +| `confgo_file_update` | 配置更新 | +| `confgo_file_delete` | 配置删除 | +| `confgo_file_publish` | 配置发布 | +| `confgo_file_rollback` | 配置回滚 | +| `app_node_restart` | 应用重启 | +| `grafana_alert_notification` | `Grafana` 监控告警 | + +### 来源类型 + +| Source | 说明 | +| :- | :- | +| confgo | 配置中心 | +| git | git 事件 | +| devops | 发布事件 | +| grafana | 监控告警 | diff --git a/website/docs/juno/14.1statistics.md b/website/docs/juno/14.1statistics.md new file mode 100644 index 0000000000..47a6f34866 --- /dev/null +++ b/website/docs/juno/14.1statistics.md @@ -0,0 +1,29 @@ +# 14.1 操作统计 + +## 统计平台活跃用户 +- 访问平台次数最多的用户 +- 用户操作了多少应用 + +## 平台活跃应用 +- 使用次数最多的应用 + +## 平台活跃Tab +- 记录了被用户使用最多的页面,即应用下的配置,监控,事件等 + + +## 配置中心统计 +- 统计数据针对于生产环境 +- 记录了应用的总数量 +- 配置中心接入应用的数量 +- 配置中心未接入的应用列表 + + + +## 定时清理数据 +- 由于统计的数据庞大,所以juno会定时清理一段时间以前的数据 +- 系统默认的是九十天,即juno会定期清理90天的统计数据 +- 如需手动指定清理的时间,在配置文件中配置以下内容即可 + ``` + [user_visit] + cleanDay=90 + ``` \ No newline at end of file diff --git a/website/docs/juno/2.1intro.md b/website/docs/juno/2.1intro.md new file mode 100644 index 0000000000..d7785b479b --- /dev/null +++ b/website/docs/juno/2.1intro.md @@ -0,0 +1,35 @@ +# 2.1 资源中心介绍 + +## 2.1.1 概念 +资源是微服务的基础。为了更好的管理微服务的资源,``juno``会将所有的资源数据进行管理。我们将资源分为三大类,应用、机房、节点。 + +### 2.1.1.1 应用 +我们定义了应用名称``app_name``和应用ID``aid``作为唯一值,确定一个应用。我们可以通过这些数据查询应用。 + +### 2.1.1.2 机房 +我们定义了地区``Region``、可用区``Zone``、环境``Env``,三个值作为唯一值,确定一个机房信息。 + +### 2.1.1.3 节点 +我们定义了节点名称``host_name``和节点ID``node_id``作为唯一值,确定一个节点。 + + +## 2.1.2 管理资源 +### 2.1.2.1 自发现方式 +我们可以将``agent``部署到节点上。``agent``会读取节点上环境变量里的节点和机房信息上报给``juno``。 + +``juno``拿到节点和机房信息后,会将节点和机房信息写入到``MySQL``中。 + +### 2.1.2.2 接口方式 +我们可以将``agent``关闭上报的资源信息,``agent``这个时候只会上报心跳数据。 + +我们能够根据自己的``CMDB``系统,将机房、节点信息,通过调用``juno``的接口,写入到系统里。 + +### 2.1.2.3 后台方式 +我们可以将``agent``关闭上报的资源信息,``agent``这个时候只会上报心跳数据。 + +我们能够自己在后台,创建和更改这些资源数据 + + +通过以上三种方式,管理员可以创建应用后,将节点分配给应用。这样应用就可以进行发布、配置和治理了。 + + diff --git a/website/docs/juno/3.1intro.md b/website/docs/juno/3.1intro.md new file mode 100644 index 0000000000..111edff734 --- /dev/null +++ b/website/docs/juno/3.1intro.md @@ -0,0 +1,64 @@ +# 3.1 配置中心介绍 + + +## 3.1.1 前言 + +    伴随微服务的推广,程序粒度的日趋小型化,配置文件的数量成几何级数增长,采用传统的本地文件方式管理应用,凸显的问题越来越多,很难适应于快速发展的微服务架构和容器虚拟化技术。我们需要对配置进行治理,能够对配置进行下发管理、版本管理、安全管理、权限管理等,因此斗鱼的配置中心应运而生。 + 
Juno配置中心是斗鱼研发的配置管理中心,集中化管理在不同机房、不同环境的应用配置,配置采用Key-Value 的数据结构,存储使用MySQL和ETCD,支持配置快速搜索,支持配置修改实时生效、 支持K8S 下使用配置中心、支持配置关系可视化等功能,适用于微服务的配置管理。 + + +## 3.1.2 为什么需要配置中心 + + +|   | 应用数量 | 配置数量 | 配置体积 | 变更频率 | +| --- | --- | --- | --- | --- | +| 单体应用时代 | 较少 | 较少 | 内容少 | 低 | +| 微服务时代 | 增多,机器节点增多 | 与应用数量呈正相关增加 | 增加大量依赖关系配置 | 变更频率远大于版本发布频率 | + +   
    在单体应用时代,应用特点是:集成化、中心化、总量少;服务间依赖关系简单,较少考虑上下游依赖配置,迭代速度慢,配置变更频率低,只需要维护一个集成类型的配置文件,部署在数量可控的高性能机器上即可,遇到紧急情况可以让运维同事之间上机器操作便可以快速解决问题。
    到微服务时代,应用开始进行功能化拆分,总量呈几何上升;采用低配置机器,注重弹性扩容,部署节点显著增多;更关注上下游服务相关配置,且配置文件的修改频率因为精细化操作、依赖管理等远高于代码本身的修改频率。
所有的这些麻烦是由于我们对配置和代码在管理和发布过程中不加区分造成的。配置本身源于代码,是为了提高代码的灵活性而提取出来的一些经常变化的或需要定制的内容,正是配置的这种天生的变化特征给我们带了很大的麻烦。
因此,在借鉴了业内其他分布式配置中心的设计和实现后,我们设计了下面的分布式配置管理系统,致力于将配置内容从代码中完全分离出来,及时可靠高效地提供配置访问和更新服务。
  + +## 3.1.3 主流产品差异性

+ +|   | 优点 | 缺点 | +| --- | --- | --- | +| QConf 方案 | 设计简单清晰 | 重度依赖 ZK 集群
横向扩展困难 | +| 淘宝 Diamond 方案 | 简单
可靠
易用 | 过于依赖 MYSQL 数据库
客户端性能存在瓶颈
高可用性受限 | +| 携程 Apollo 方案 | 基于 JAVA+Eureka 集群
多层负载,多级缓存保证高可用
权限管理,审计操作完善 | 设计复杂,部署维护成本高 | + + +    综合各种方案调研,考虑到现有的技术积累,在斗鱼实际业务场景中没有大规模使用ZK集群,实际服务部署架构上存在大量多机房部署的现象,我们希望配置中心:设计简单清晰;可靠易用;支持多机房高可用。携程的Apollo是不错的实现方案,功能完善设计完整。但是对斗鱼而言略显臃肿、维护成本高、对斗鱼的多机房架构和k8s结构支持不友好,所以我们必须要有一套更加适合斗鱼的配置中心。 + + +## 3.1.4 配置中心理念 + +    配置中心有三个核心理念:配置完整性定义;配置下发回显功能;配置缓存优先级设计。 + +### 3.1.4.1 配置完整性定义 + +    配置完整性定义是:环境变量、编译注入配置、命令行配置、文本文件、远端配置,这五类数据共同构成了一份完整配置,形成一份完整配置。配置中心会对以下五类配置进行管理,涉及应用全生命周期的所有配置数据。 +![image](../static/juno/config3.1.1.png) + +| 环境变量 | 运维初始化机器时或服务初次部署时定义的配置; | +| --- | --- | +| 编译注入配置 | 应用在源码编译过程中注入的配置; | +| 命令行配置 | 服务启动时写入的配置; | +| 文本文件 | 以文本方式更随服务或下发到服务的配置; | +| 远端配置 | 服务通过API获取到的远端配置; | + +  +### 3.1.4.2 配置下发回显 + +    配置下发后会经过以下流程,保证配置下发成功。这是配置中心的核心所在,保证配置在跨机房下发过程中数据正常,保证服务能适应新版本的配置。 + +1. 下发配置,等待配置下发状态回传; +1. 等待配置生效状态监测; +1. 双重确认完成配置发布。 + +![image](../static/juno/config3.1.2.png) + +### 3.1.4.3 配置缓存优先级 + +    应用程序向 Juno Agent 请求配置,优先返回 Juno Agent 内存缓存配置;其次是文件系统本地缓存;最后请求管理中心存储的持久化配置数据。如果整个流程走完没有获取到配置,则会在配置回显流程中产生错误提示,重新进入配置发布流程。保证如果有配置,应用一定可以获取到。 + +![image](../static/juno/config3.1.3.png) + diff --git a/website/docs/juno/3.2feature.md b/website/docs/juno/3.2feature.md new file mode 100644 index 0000000000..53cd8505dc --- /dev/null +++ b/website/docs/juno/3.2feature.md @@ -0,0 +1,12 @@ +# 3.2 配置中心特点 + +| 跨机房 | 集中管理不同机房、不同环境的配置;提供了一个统一的管理界面,处理不同环境(env),不同机房(idc)的配置; | +| --- | --- | +| 实时生效 | 配置修改实时生效;在秒级范围内可接收到最新的配置; | +| 版本管理/灰度发布支持 | 版本发布管理且支持灰度发布;每次发布配置会产生一个版本,支持各个版本的回滚操作;
  | +| 配置监控 | 客户端配置信息监控;管理后台直接展示配置在哪些实例上被哪些服务使用 | +| 权限管理,发布审核 | 1. 对线上环境与线下环境进行用户的权限角色区分,用户经历三个流程完成操作:编辑、保存、发布,流程的拆分一定程度上避免了人为操作失误
2. 每次操作都有日志记录,并且有直观的配置差异比对,类似 git diff | +| 全局资源管理 | 1. 将配置片段设置为特定的变量,管理后台直接选择该配置即可使用;
2. 对所有资源进行默认加密,prod 环境配置管理员设置对应 CURD 权限;其他环境进行权限开放;
3. 支持全局替换。 | +| 提供开放平台 API | 提供丰富的API,并包含完善的权限机制 | +| 高可用 | 支持高可用,横向节点扩展便捷 | +| 静态配置与动态配置区分 | 1. 静态配置经过配置发布后,重启服务生效;
2. 动态配置,可进行应用无感热更新操作 | diff --git a/website/docs/juno/3.3design.md b/website/docs/juno/3.3design.md new file mode 100644 index 0000000000..ba4219053d --- /dev/null +++ b/website/docs/juno/3.3design.md @@ -0,0 +1,113 @@ +# 3.3 配置中心设计 + +## 3.3.1 关键概念 + +**应用(APP)**
    客户端在运行过程中,Juno Agent 根据已有的应用属性从配置中心获取该应用对应的配置。应用的表示采用的是全局唯一应用名称。
**
**环境(ENV)** +配置对应不同的环境,Juno Agent 需要知道当前应用所属环境,根据环境获取对应的配置,获取环境的途径是根据环境变量而来。
**
**机房(IDC)**
    跨机房配置集中化管理,例如我们的管理后台部署在机房 A,应用部署在机房 B 和机房 C,管理后台集中化管理各个机房的配置数据。 +## 3.3.2 总体设计 + +### 3.3.2.1 层次设计 + +    下图描述配置中心的总体设计,从下往上分析: +![image](../static/juno/config3.3.1.png) + +- 配置管理中心提供了配置的修改发布功能,配置数据存入 MySQL 进行持久化; +- 配置管理中心通过 Juno Proxy 代理服务将配置发送到对应机房的 ETCD 中; +- 服务器或宿主机上部署的 Juno Agent 通过 Watch ETCD 获取到配置数据的变化,进一步调整硬盘以及内存中的配置数据; +- 客户端可直接读取 Juno Agent 更新的配置文件,也可以通过 API 直接获取配置数据。 + +### 3.3.2.2 客户端设计 + +    下图简要描述了配置中心客户端(Juno Agent)的实现原理: +![image](../static/juno/config3.3.2.png) + +1. 用户在配置中心进行配置新增或变更操作,在点击发布之后配置会同步到机房代理服务(Juno Proxy),再将配置数据写入机房内的ETCD中; +1. 客户端(Juno Agent)监听 ETCD 的数据变化来更新配置数据; +1. 客户端(Juno Agent)从配置中心获取到应用程序相关的最新版本配置文件后,更新本地的内存缓存; +1. 客户端(Juno Agent)在更新内存缓存的同时会在本地文件系统中缓存一份,在服务不可用或者网络故障时,让应用程序直接使用本地文件配置; +1. 应用程序从客户端(Juno Agent)获取最新的配置。 + +### 3.3.3.3 容器虚拟化方案设计 + +    虚拟容器化是大势所趋,配置中心对该场景有强大的技术支撑,设计思路是在宿主机中部署Juno Agent,保留整体层次结构,由Juno Agent对所有的pod提供配置支持,如下图所示。 + +1. Node 中部署 Juno Agent,以获取配置信息; +1. Pod 通过 API 借口获取当前应用的配置信息; + +![image](../static/juno/config3.3.3.png) +### 3.3.2.4 多机房方案设计 + +    Juno 配置中心支持多机房(IDC)统一管理,在实际场景中会同时使用多个地区的机房,机房之间不进行跨机房通信,所有的数据流转由某一个部署配置中心管理后台的机房完成,该机房依靠专线与其他机房进行通信,在遭遇专线网络故障时,可直接切换到外网IP保证服务稳定,对不同机房间的操作互相隔离,不产生依赖影响。
![](https://cdn.nlark.com/yuque/0/2020/png/594625/1582710830858-66eebc4e-a31d-4353-98da-3f035c4fee9b.png#align=left&display=inline&height=402&originHeight=402&originWidth=649&size=0&status=done&style=none&width=649) +## 3.3.2 技术点详解 + +### 3.3.2.1 配置推送实现 + +1. 配置通过 Juno Proxy 由管理后台推送到对应机房的 ETCD 中; +1. Juno Agent 监听 ETCD 数据变化,获取到更新的配置数据; +1. 配置数据在内存缓存和服务器/宿主机文件系统中更新。 + +  +### 3.3.2.2 配置时序图 + +    配置的整个生命周期流转如下图所示,归纳为四个配置点进行表述:管理后台(前端交互UI)、配置服务(管理后台服务)、下发服务(Juno Proxy+Juno Agent)、应用。
![](https://cdn.nlark.com/yuque/0/2020/png/594625/1582710830907-eba0d3f9-58ba-4571-85d7-8600ee91f35b.png#align=left&display=inline&height=564&originHeight=564&originWidth=733&size=0&status=done&style=none&width=733)
  +### 3.3.3.3 兜底配置策略 + +    用户下发配置如果存在某些参数遗漏,例如MySQL或者Redis连接配置,用户对超时或者连接数没有配置,其中比较重要的就是超时,如果漏掉了会引发严重的线上问题,Jupiter SDK为了解决这个问题,开发了相关的兜底配置,对这些关键配置进行默认值补充。
![](https://cdn.nlark.com/yuque/0/2020/png/594625/1582710830847-86dbcb8e-e994-4222-8b97-7b36f9fb874e.png#align=left&display=inline&height=454&originHeight=454&originWidth=808&size=0&status=done&style=none&width=808) +### 3.3.2.4 配置回显实现 + +    配置中心涉及配置下发后批量重启服务的执行流程如下,过程中强制配置回显,可保证配置下发状态和内容一定正确。
![](https://cdn.nlark.com/yuque/0/2020/png/594625/1582710830859-2a01bff0-6253-4352-a12d-ac081505b14e.png#align=left&display=inline&height=465&originHeight=465&originWidth=474&size=0&status=done&style=none&width=474) + +1. 配置通过前一步的流程下发到应用程序; +1. Juno Agent 获取到配置数据之后,执行 Report 流程上报当前配置数据内容到配置中心; +1. 应用程序给配置中心上报服务运行版本,以及当前服务状态; +1. 配置中心接收到应用程序上报的版本符合下发版本,并且服务状态正常,便认可配置下发流程完成。 + +### 3.3.2.5 高可用性分析 + +    分析多故障场景,当前Juno配置中心的降级方案如下: + +| 场景 | 影响 | 降级方案 | +| --- | --- | --- | +| 某台 juno-agent 挂掉 | 无影响 | juno-agent 无状态,客户端重连其他的 juno-agent | +| 全部的 juno-agent 挂掉 | 客户端无法读取 admin 配置的最新数据 | 客户端可以读取本地的文件缓存,新扩的机器可以从其他客户端获取缓存配置 | +| 某个 ETCD 节点挂掉 | 无影响 | juno-agent 可以重连其他 ETCD 节点 | +| 全部 ETCD 节点挂掉 | juno-agent 无法读取 admin 配置的最新数据,无法推送配置更新 | juno-agent 读取本地文件缓存提供给客户端 | +| AdminServer 挂掉 | 客户端无影响,admin 无法管理配置 |   | +| ConfigDB 宕机 | 客户端无影响,admin 配置的新数据无法持久化 |   | +| 专线故障 | 配置中心相关发布、回滚操作失败 | 使用公网 IP 继续相关操作 | + + +### 3.3.2.6 敏感配置信息 + +- 适度隔离:将敏感配置信息同源代码、普通配置信息隔离存储。 +- 访问控制:通过白名单等方式,限制敏感配置信息的访问权限。 +- 加密存储:将敏感配置信息加密后存储,仅在使用前临时解密,以进一步防止信息泄露。 +- 安全传输:企业内网环境并非 100%可信,通过 HTTPS 等加密手段以保证敏感配置信息的传输安全。 +- 日志记录:尽量详细记录下针对配置信息的操作,以便于事后追查或者合规审查。 +- 差别配置:不同的环境(例如生产环境,灰度环境,开发环境等)使用不同的证书或秘钥,以避免“把鸡蛋放到一个篮子里”。 + +### 3.3.2.7 为什么选择 ETCD + +    为什么采用 ETCD 作为服务注册中心和配置存储/订阅通知引擎,而不是使用传统的 ZK,Eureka?我们大致总结了一下,有以下几方面的原因: + +- 它提供了强大和灵活的 K-V 存储能力,可以在保证性能的前提下对配置项进行最小粒度对存储 +- 它提供了对 key 或者 key 前缀的监听功能,正好满足我们对某些配置项需要动态下发的需求 +- 我们的项目本身就使用了 ETCD 做服务注册与发现和存储功能,维护和使用相对于 zk,Eureka 会熟练的多 + +### 3.3.2.8 为什么采用 GRPC + +    为什么 Juno Agent 与 Client 之间的长链接通信我们采取 GRPCStream,而不是其他配置中心使用的 tcp 长链接,Http long polling?其实有下面一些考虑: + +- 相比于自己搭建和维护一套 TCP 长链接服务,GRPCStream 是现成的解决方案,可以帮我们屏蔽底层的通信细节和长链接管理 +- 相比于 Http long polling 服务器 hold 连接会消耗资源,GRPCStream 消耗更少的服务器资源 +- 我们内部基于 GRPC 服务的开发体系已经很成熟了,当 client 很多时,可以轻松解决横向扩展的问题 +- ETCDv3 本身也是 GRPC 实现的,可用性与可靠性比较有保证 + + +### 3.3.2.9 其他场景 + +**
**开关**
    有时候 a 应用依赖 b 应用的新接口,但是 b 应用的发布时间点比较靠后,这时候 a 应用发布时可以加上一个默认关闭的开关,等 b 应用发布后再打开开关。有些新功能上线存在较高的风险,可以加个开关,一旦发现问题可以迅速关闭。
 
**限流**
    一般的做法是在开关或 RPC 框架层添加限流逻辑,结合配置中心的动态推送能力实现动态调整限流规则配置。 + +**数据源迁移**
    比如:需要将服务从 A 数据库迁移到 B 数据库,通过配置中心配置读写开关和比例配置,来达到动态读写数据库的操作,配合线下的旧数据补齐,平滑的完成数据迁移。 + +**动态日志级别**
    服务运行过程中发生故障,我们一般会通过日志进行排查,如果 ERROR 日志查不出问题,一般需要打印 DEBUG 日志。相比于花费更多的时间去修改代码,发布部署应用,通过配置中心动态调整应用的日志打印级别显然更加安全和快速。 diff --git a/website/docs/juno/3.4ui.md b/website/docs/juno/3.4ui.md new file mode 100644 index 0000000000..822832a1b7 --- /dev/null +++ b/website/docs/juno/3.4ui.md @@ -0,0 +1,47 @@ +# 3.4 交互设计 + +## 3.4.1 基本交互 + +下图是配置中心的项目配置首页。 + +- 上方,进行应用环境切换 +- 左侧,对当前应用的编辑操作;对当前应用的发布操作 +- 右侧,配置的核心编辑区域 + +![image](../static/juno/config3.4.1.png) + + +### 3.4.1.1 新建配置 + +选择目标环境,进行应用在对应环境进行操作,在选择环境后可以看到对应环境内相关的机房以及具体的配置文件。 + + +![image](../static/juno/config3.4.2.png) + +如果没有选择环境,则无法选择机房,便不能新增配置。点击红框按钮进行配置新增。 + +![image](../static/juno/config3.4.3.png) + + +### 3.4.1.2 配置编辑保存 + +点击配置文件,右侧可直接编辑,点击红框按钮进行保存,保存的时候填写当前修改信息。 + +![image](../static/juno/config3.4.4.png) + +### 3.4.1.3 配置提交记录 + +配置提交历史记录,点击Version可进行配内容比较。 + +![image](../static/juno/config3.4.5.png) + +### 3.4.1.4 配置发布 + +选择配置文件,点击发布按钮,选择对应的提交记录进行配置下发 +![image](../static/juno/config3.4.6.png) + +### 3.4.1.5 配置使用 + +文件会下发到目标机器上,文件路径如下所示,直接使用即可 +![image](../static/juno/config3.4.7.png) + diff --git a/website/docs/juno/3.5read.md b/website/docs/juno/3.5read.md new file mode 100644 index 0000000000..822310acab --- /dev/null +++ b/website/docs/juno/3.5read.md @@ -0,0 +1,16 @@ +# 3.5 通过Juno Agent读取服务配置 + +配置通过admin->proxy->etcd进行存储,应用通过http接口的方式读取配置可以按照以下的方式: + +http://xxx.xxx.xxx.xxx.xxx:59247/api/config/config-stress.toml?name=appname&env=stress + +解析说明: + +| 参数 | 说明 | +|:--------------|:-----| +|`xxx.xxx.xxx.xxx.xxx`| juno-agent部署的机器ip | +|`59247`| juno-agent 端口 | +|`/api/config/`| api | +|`config-stress.toml` | admin下发的配置名称| +|`appname` | 应用名称| +|`stress` | 环境名称| diff --git a/website/docs/juno/4.1govern.md b/website/docs/juno/4.1govern.md new file mode 100644 index 0000000000..d999c0c41e --- /dev/null +++ b/website/docs/juno/4.1govern.md @@ -0,0 +1,3 @@ +# 4.1 治理中心 + +* [Pprof](./4.2pprof.md) diff --git a/website/docs/juno/4.2pprof.md b/website/docs/juno/4.2pprof.md new file mode 100644 index 0000000000..eff57a416f --- /dev/null +++ b/website/docs/juno/4.2pprof.md @@ -0,0 +1,60 @@ +# 4.2 Pprof + +## 4.2.1 Pprof 是什么 + +在计算机性能调试领域里,profiling 是指对应用程序的画像,画像就是应用程序使用 CPU 和内存的情况。 + +Golang 是一个对性能特别看重的语言,因此语言中自带了 profiling 的库,在程序运行过程中可以获取 cpu、heap、block、traces 等执行信息。 + +Golang 中的性能优化主要有以下几个方面: + +- CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据 + +- Memory Profile(Heap Profile):报告程序的内存使用情况 + +- Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈 + +- Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的 + +## 4.2.2 Juno 中 环境依赖 + +* Profiling查看需要我们安装Juno的机器上拥有Golang Go-torch Graphviz环境,在应用服务-Pprof页面可以看到所需要的环境是否安装。 +![image](../static/juno/pprof6.1.png) +* 若发现有依赖项没有安装,我们需要到系统管理-系统设置里面去手动安装这些依赖项 +![image](../static/juno/pprof6.2.png) + + +## 4.2.3 Juno 中 pprof 的生成和查看 + +在应用服务-Pprof 下我们可以方便的获取和查看应用在某个实例下的 profiling 数据以及火焰图 + +![image](../static/juno/pprof1.1.png) + + + +选择实例后点击更新分析图标我们可以获取该应用当前的 profiling 数据,并以 svg 格式展示出来,方便我们查看 + +![image](../static/juno/pprof1.2.png) + +我们可以点击查看对应的 profiling 数据 + +- Goroutine 分析 + ![image](../static/juno/pprof2.1.png) + +- Goroutine 火焰图 + ![image](../static/juno/pprof2.2.png) + +- Memory 分析 + ![image](../static/juno/pprof3.1.png) + +- Memory 火焰图 + ![image](../static/juno/pprof3.2.png) + +- Cpu 分析 + ![image](../static/juno/pprof5.1.png) + +- Cpu 火焰图 + ![image](../static/juno/pprof5.2.png) + +- Block 分析 + ![image](../static/juno/pprof4.1.png) diff --git a/website/docs/juno/5.1monitor.md b/website/docs/juno/5.1monitor.md new file mode 100644 index 0000000000..12f44e5ceb --- /dev/null +++ b/website/docs/juno/5.1monitor.md @@ -0,0 +1,90 @@ +# 5.1 监控配置 + +## 5.1.1 流程 +- [安装Grafana](#5.1.2 Grafana安装),不限制版本,建议使用最新版 +- [修改配置](#5.1.3 配置调整),Grafana开始子域名访问与header头鉴权,开启iframe访问支持;Juno修改相应的配置 +- [导入Dashboard模板](#5.1.4 导入Dashboard模板) +- [Juno系统设置](#5.1.5 Juno系统设置) + +## 5.1.2 Grafana安装 + +按照官方文档安装即可 + +[https://grafana.com/docs/grafana/latest/installation/debian/](https://grafana.com/docs/grafana/latest/installation/debian/) + +``` +sudo rpm -Uvh grafana-7.1.1-1.x86_64.rpm +``` + +## 5.1.3 配置调整 + +### 5.1.3.1 Grafana配置调整 + + +``` +root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana + +serve_from_sub_path = true + +allow_embedding = true +``` + +其他的鉴权配置,例如:是否开启登录界面、是否支持匿名访问等,根据自己的需求来即可。 + +### 5.1.3.2 Juno文件配置 + +配置文件里面增加如下配置 +``` +[grafanaProxy] + enable = true + name = "grafana" +``` + +## 5.1.4 导入Dashboard模板 + +访问:`http://127.0.0.1:50000/grafana/`; + +![image-20200904150251572](../static/juno/monitor-5.1-aaaa.png) + +image-20200904150421375 + +在仓库[路径](https://github.com/douyu/juno/blob/master/data/grafana)中,有三个配置好的dashboard配置文件。分别导入即可。 + +例如,此处,导入API-xxxxxx.json。 + +image-20200904151458986 + +此处`uid`是文件中的配置项,同时,在Juno中,也是此dashboard的访问路径。 + +## 5.1.5 Juno系统设置 + + +### 5.1.5.1 Grafana设置 +进入管理后台: +系统设置——>系统设置 + +![../static/juno/monitor-5.1.5.1.png](../static/juno/monitor-5.1.5.1.png) + +Host:Grafana实际访问的地址,只填写 `IP:PORT`,例如:`127.0.0.1:3000`。 + +``` +X-WEBAUTH-USER +``` + +### 5.1.5.2 应用监控设置 +`系统设置`页面下方,找到`应用版本相关设置`。 + +这里设计的目的是支持不同版本的监控Dashboard展示,一般情况下只需要配置一条记录即可。 +![../static/juno/monitor-5.1.5.2.png](../static/juno/monitor-5.1.5.2.png) + + +- 应用版本名称,会在监控界面应用版本展示部分显示 +- 应用版本号,指的是jupiter的版本,使用 `,`进行分割 +- 应用版本key,目前配置应用监控版本的唯一标识,适用于Prometheus数据源指定 + +Dashboard配置,`/grafana/d/`为固定前缀,不得更改,`api`则是`dashboard`导入时,配置的`uid`。 + +image-20200904151850462 + + + diff --git a/website/docs/juno/6.1register.md b/website/docs/juno/6.1register.md new file mode 100644 index 0000000000..a71e85d454 --- /dev/null +++ b/website/docs/juno/6.1register.md @@ -0,0 +1,2 @@ +# 6.1 注册中心 +敬请期待 diff --git a/website/docs/juno/7.1task.md b/website/docs/juno/7.1task.md new file mode 100644 index 0000000000..ffab9d628e --- /dev/null +++ b/website/docs/juno/7.1task.md @@ -0,0 +1,74 @@ +# 7.1 任务平台 + +juno-admin后台编辑编辑定时任务信息的时候,按组区分定时任务类别,组名即为应用名称,后面定时任务信息只会被应用所部属的机房消费到,并最终只有一台机器成功执行定时任务信息 + +有juno-admin后台统编辑带应用名的定时任务信息,并以应用名划分定时任务所在组。后台编辑好的定时任务信息在发布到etcd后,只会被任务信息所在的应用下的机房机器所消费到,机器得到消费的信息后,需要去获取锁,得锁者响应定时任务,未得锁者不响应定时任务。 这个锁可以用mysql的行锁+多版本去满足。 + +## 7.1.1 业内调研 +- [XXL-JOB](https://www.xuxueli.com/xxl-job/#c%E3%80%81%E8%A7%A6%E5%8F%91%E4%BB%BB%E5%8A%A1) +- [cronsun](https://github.com/shunfei/cronsun) + +## 7.1.2 架构设计 + +![架构设计](../static/juno/7.1-1.png) + +## 7.1.3 任务执行时序图 + +### 添加任务,执行任务 + +![任务时序图](../static/juno/7.1-2.png) + +```mermaid +sequenceDiagram +admin->>etcd: 写入待执行指令 +etcd->>etcd: event消息产生 +agent->>etcd: 获取cmd执行指令内容与执行规则 +agent->>+agent: 获取定时任务后完成加锁操作 +agent->>agent: 解析规则策略,注册定时任务 +agent->>etcd: 将任务执行信息写入etcd +agent->>-etcd: 执行完成后删除对应的key +agent-->>etcd: 执行结果反馈 +etcd-->>admin: 获取执行结果进行MySQL落地 +``` + +### 立即执行任务 + +![立即执行任务时序图](../static/juno/7.1-3.png) + +```mermaid +sequenceDiagram +admin->>etcd: 写入待执行指令 +etcd->>etcd: event消息产生 +agent->>etcd: 获取cmd执行指令内容与执行规则 +agent->>+agent: 获取定时任务后完成加锁操作 +agent->>agent: 解析规则策略,注册定时任务 +agent->>etcd: 将任务执行信息写入etcd +agent->>-etcd: 执行完成后删除对应的key +agent-->>etcd: 执行结果反馈 +etcd-->>admin: 获取执行结果进行MySQL落地 +``` + + +### 强杀任务 + +![强杀任务时序图](../static/juno/7.1-4.png) + + +## 7.1.4 业务流程 + +1. 由Agent心跳上报到Admin,Admin存储应用和agent的对应关系 +2. 在Admin进行定时任务的逻辑处理,定时任务和应用强绑定,某个应用的定时任务执行逻辑指挥在对应的Agent上进行 +3. 执行结果通过ETCD进行回调,再有Admin统一处理 +4. 对异常执行任务进行重试 + +## 7.1.5 关键设计 + +``` +/juno/task/proc/pid/jobId/appName/hostName #关闭进程 +/juno/task/cmd/appName/jobId # 任务下发 +/juno/task/once/appName/jobId/hostName # 任务执行 +/juno/task/lock/jobId # 执行锁 +/juno/task/noticer/hostName # 执行结果通知 +/juno/task/csctl/ # 临时指令 +``` + diff --git a/website/docs/juno/8.1grpc_test.md b/website/docs/juno/8.1grpc_test.md new file mode 100644 index 0000000000..999e2caa8d --- /dev/null +++ b/website/docs/juno/8.1grpc_test.md @@ -0,0 +1,33 @@ +# 8.1 GRPC 测试 + +## 8.1.1 使用前提 + +1. 所有应用的PB文件必须集中管理 + +2. 使用本功能前,需要在 `juno` 的配置文件中设置 `pb` 文件的根文件夹(该文件下所有PB文件会被 `juno` 系统解析) + + ```toml + [grpcTest] + enable = true # 开启Grpc 测试功能 + protoDir = "/path/to/pb" # PB文件的目录 + ``` + +3. 重启 `juno` + + 重启后,`juno` 会解析文件夹下所有的 `pb` 文件,启动后解析需要一段时间。 + + `juno` 会监听 `pb` 目录的文件事件,当该文件夹下发生修改时,进行自动解析。通过这个特性,用户可以使用代码托管平台的发布事件进行 `pb` 文件的自动发布,进而触发 `juno` 的自动文件解析。 + +## 8.1.2 关联应用到 PB + +解析完毕后,用户需要在 `测试平台 > GRPC测试` 页面将 `PB` 文件绑定到应用: + +1. 点开应用绑定窗口 +![](../static/jupiter/grpctest-bindapp-1.png) + +2. 选择 PB 和应用进行绑定 +![](../static/jupiter/grpctest-bindapp-2.png) + +## 8.1.3 使用 + +![](../static/jupiter/grpctest-usage.png) \ No newline at end of file diff --git a/website/docs/juno/8.2http_test.md b/website/docs/juno/8.2http_test.md new file mode 100644 index 0000000000..2f13f3285a --- /dev/null +++ b/website/docs/juno/8.2http_test.md @@ -0,0 +1,9 @@ +# 8.2 HTTP 测试 + +HTTP测试和 `Postman` 的使用方法类似,如下图所示 + +![](../static/jupiter/httptest-usage.png) + +`Juno` 会根据应用信息帮助用户填写应用的 `http` 访问地址: + +![](../static/jupiter/httptest-url.png) \ No newline at end of file diff --git a/website/docs/juno/9.1quickstart.md b/website/docs/juno/9.1quickstart.md new file mode 100644 index 0000000000..9a7643721e --- /dev/null +++ b/website/docs/juno/9.1quickstart.md @@ -0,0 +1,61 @@ +# 9.1 运行和部署 +Juno Agent管理了节点信息、注册信息、配置信息、探活信息、消息总线等功能。 + +## 9.1.1 部署Agent模式 +我们有两种运行Juno-Agent的模式:Client模式和Server模式。 +* Client模式:该模式需要我们将Agent部署到每个应用的节点上,这样我们的Juno-Agent,可以获取更多应用的信息,例如机器上的启动信息,还可以执行HShell指令,帮助我们排查线上问题。 +* Server模式:该模式需要我们将多个Agent组成一个Server进行部署,虽然这种模式,有部分组件功能无法启用,但是这种模式下,我们可以更方便的部署我们的Agent,减少我们的运维成本。 + + +## 9.1.2 运行一个Agent +Juno-Agent可以通过命令行启动。当Juno-Agent运行后,你可以看到以下输出 +```bash + + (_)_ _ _ __ (_) |_ ___ _ __ + | | | | | '_ \| | __/ _ \ '__| + | | |_| | |_) | | || __/ | + _/ |\__,_| .__/|_|\__\___|_| + |__/ |_| + + Welcome to jupiter, starting jupiter ... + +1590412508 INFO load local file {"mod": "config", "addr": "./config/config-live.toml"} +1590412508 INFO auto max procs {"mod": "proc", "procs": 4} +1590412508 INFO plugin {"reportAgentStatus": "start"} +1590412508 INFO plugin {"process": "start"} +1590412508 INFO plugin {"appConf.etcd": "start"} +1590412508 INFO dial etcd server {"mod": "client.etcd", "addr": ["wsd-projecta-etcd-cc.pre.unp.oyw:2379"]} +1590412508 ERROR init get update error {"plugin": "confProxy", "msg": "key check: port empty", "hostKey": "/Juno-agent/ubuntu", "err": "key check: port empty"} +1590412508 ERROR init get update error {"plugin": "confProxy", "msg": "open /home/www/server: is a directory", "hostKey": "/Juno-agent/ubuntu", "err": "open /home/www/server: is a directory"} +1590412508 INFO dial etcd server {"mod": "client.etcd", "addr": ["wsd-projecta-etcd-rd.pre.unp.oyw:2379"]} +1590412508 INFO plugin {"supervisorScanner": "start"} +1590412508 ERROR fsnotify add dir err {"msg": "no such file or directory"} +1590412508 INFO plugin {"systemdScanner": "start"} +1590412508 ERROR SystemdScanner add dir err {"err": "no such file or directory"} +1590412508 INFO plugin {"healCheck": "start"} +1590412508 INFO start governor {"mod": "app", "addr": "http://127.0.0.1:9099"} +1590412508 INFO start servers {"mod": "app", "addr": "http://0.0.0.0:50000"} +1590412508 INFO start servers {"mod": "app", "addr": "grpc://0.0.0.0:50001"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "POST", "path": "/api/v1/conf/command_line/status"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "GET", "path": "/api/v1/agent/config"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "GET", "path": "/api/agent/reload"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "GET", "path": "/api/agent/process/status"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "GET", "path": "/api/process/status"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "POST", "path": "/api/agent/process/shell"} +1590412508 INFO echo add route {"mod": "server.echo", "method": "GET", "path": "/api/v1/agent/:target"} +⇨ http server started on [::]:50000 + +``` + +以下为输出的描述: +* Info: 输出Agent的基本信息。 +* Plugin: 输出Agent启动的组件 +* Server: 输出Agent提供的服务 + + + + + + + + diff --git a/website/docs/juno/9.2configuration.md b/website/docs/juno/9.2configuration.md new file mode 100644 index 0000000000..b8e256be16 --- /dev/null +++ b/website/docs/juno/9.2configuration.md @@ -0,0 +1,89 @@ +# 9.2 Agent配置 + +Juno Agent加载配置会通过以下步骤处理配置。当Agent获得环境变量、文本配置、命令行变量、ETCD配置后,会根据优先级,合并配置。运行后,我们可以通过SIGHUP信号量,对配置进行reload。 + +我们通常可以指定以下两种方式启动Juno Agent: +* 命令行启动 +* 配置启动 +* ETCD配置 + +以下我们开始介绍Juno Agent里的三种配置 + +## 9.2.1 环境变量 +环境变量用于配置不做更改的基础信息,例如本机IP +* JUNO_HOST: 本机地址 +* JUNO_GRPC_PORT:启动gRPC端口 +* JUNO_HTTP_PORT:启动HTTP端口 +* JUNO_GOVEN_PORT:启动治理端口 +* JUNO_DEBUG: 开启调试信息 + +## 9.2.2 文本配置 +```toml + +[plugin] + [plugin.regProxy] + # 注册中心地址 + endpoints=["wsd-projecta-etcd-rd.pre.unp.oyw:2379"] + timeout="3s" + secure=false + enable = false + [plugin.confProxy] + # 配置中心地址 + env=["dev","live","pre"] + prefix = "/Juno-agent" + timeout="3s" + enable = true + #配置中心数据源 + [pugin.confProxy.mysql] + enable=false + dsn="" + secure=false + [plugin.confProxy.etcd] + enable=true + endpoints=["wsd-projecta-etcd-cc.pre.unp.oyw:2379"] + [plugin.supervisor] + enable = true + dir = "/etc/supervisor/conf.d1" + [plugin.systemd] + enable = true + dir = "/etc/systemd/system1" + [plugin.report] + enable = true + addr = "http://10.1.50.13:60812/api/v1/resource/node/heartbeat" + internal = "60s" + hostName = "JUNO_HOST" # 环境变量的名称,或者命令行参数的名称 + regionCode = "REGION_CODE" # 环境变量的名称,或者命令行参数的名称 + regionName = "REGION_NAME" + zoneCode = "ZONE_CODE" + zoneName = "ZONE_NAME" + env = "env" + [plugin.healthCheck] + enable = true + [plugin.process] + enable = true +[jupiter.logger.default] + name = "test" + debug = true +[jupiter.server] + [jupiter.server.grpc] + host = "0.0.0.0" + port = 60813 + + [jupiter.server.http] + host = "0.0.0.0" + port = 60814 + +``` +* plugin 设置组件信息,配置了该组件,开启enable,那么该组件启用 +* server 设置服务的gRPC,HTTP,govern端口 + +## 9.2.3 命令行配置 +使用文本配置,启用一个``test``组件 +```cmd +Juno-agent --config=Juno-agent.toml --report 代表打开report插件 +``` + +## 9.2.4 ETCD配置 +todo + + diff --git a/website/docs/juno/9.3config_get.md b/website/docs/juno/9.3config_get.md new file mode 100644 index 0000000000..cabf04e5c1 --- /dev/null +++ b/website/docs/juno/9.3config_get.md @@ -0,0 +1,13 @@ +# 13.1 JUNO AGENT +跟随机器部署的基础服务。Juno Agent所支持的功能都采用插件化的方式进行开发,在部署中可选择性进行功能开启。 + +## 13.2 功能解析 + +[参考配置](https://github.com/douyu/juno-agent/blob/master/config/config.toml) + +目前Agent具备功能包括 +- 监听jupiter上报到etcd的监控k-v生成对应的Prometheus Target配置 +- 配置中心配置文件同步 +- 服务supervisor或systemd接入状态扫描 +- 服务健康检查,心跳上报 +- 分布式定时任务worker diff --git a/website/docs/juno/9.4configdown.md b/website/docs/juno/9.4configdown.md new file mode 100644 index 0000000000..b53480deb6 --- /dev/null +++ b/website/docs/juno/9.4configdown.md @@ -0,0 +1,13 @@ +# 9.4 应用配置下发 +应用配置是结合``confgo``一起使用。 + +## 9.4.1 配置下发流程 +配置下发流程如下所示 +![image](../static/agent/configdown1.png) + +* 用户在Juno配置中心进行配置新增或变更操作,在点击发布之后配置会同步到机房代理服务(Juno Proxy),再将配置数据写入机房内的ETCD中; +* 客户端(Juno Agent)监听 ETCD 的数据变化来更新配置数据; +* 客户端(Juno Agent)从配置中心获取到应用程序相关的最新版本配置文件后,更新本地的内存缓存; +* 客户端(Juno Agent)在更新内存缓存的同时会在本地文件系统中缓存一份,在服务不可用或者网络故障时,让应用程序直接使用本地文件配置; +* 应用程序从客户端(Juno Agent)获取最新的配置。 +* 客户端(Juno Agent)维护应用配置的关系,通过长轮询,用户可以实时获取应用最新配置 diff --git a/website/docs/juno/9.5configparse.md b/website/docs/juno/9.5configparse.md new file mode 100644 index 0000000000..02157fd037 --- /dev/null +++ b/website/docs/juno/9.5configparse.md @@ -0,0 +1,117 @@ +# 9.5 应用配置解析 +配置是微服务治理里最重要的环节之一。但现在的行业内,大部分都只做到配置的下发,而没有梳理配置的关系,依赖配置的探活。 +因此本文主要介绍以上的配置治理。 + +## 9.5.1 用户配置玩法多样性 +因为用户的配置的格式是多种多样,我们需要用户自己设置的配置模板,来解析对应的配置。以下举一个例子 +例如一个用户的MySQL配置可能存在如下三种配置方式。 +``` +[mysqlconfig] + addr = "ip:port" + user = "hello" + password = "world" +``` +``` +[mysqlconfig] + ip = "ip" + port = "port" + user = "hello" + password = "world" +``` +``` +[mysqlconfig] + dsn = "user:password@ip:port" +``` + +在我们不清楚用户配置的字段情况下,我们是无法将这些配置解析出来。所以我们必须设计一种方式,能够让我们的``Juno agent``能够准确理解用户的这些配置。 + +## 9.5.2 配置模板 +为了适应用户不同配置方式,所以我们首先需要引入模板的概念。 +我们要将用户不同的配置方式,配置成一个解析模板,将这种模板存入到数据库中,将其标记为一种类型,我们把这种类型称之为``JunoTpl``,那么我们可以把上面的三种mysql配置方式,可以将配置设置为``JunoTpl``=1,``JunoTpl``=2,``JunoTpl``=3,这样我们就可以去类型去解析不同的配置方式。 + +## 9.5.3 配置基础结构 +但这样只是解决了配置的方式,但是我们的``Juno agent``还是无法理解模板里的字段类型,这个字段是将起解析为ip,还是port,还是dsn,我们需要一个基础结构去识别。 +在这里``Juno agent``规范了基本的几个基础结构,定义如下: +* $SCHEME +* $IP +* $PORT +* $DSN +* $USERNAME +* $PASSWORD + +## 9.5.4 配置类型 +``Juno agent``可以通过模板和基础结构,很好的解析出配置。但是他仍然不知道这个配置类型,因为配置解析出来,他可以是MySQL,也可能是Redis,我们还需要识别配置的类型。这样的好处,是为了根据不同类型,去做该类型的探活,这样效果更准确。(例如MySQL,如果只做接口探活,那么有可能你可以访问端口,但你该机器其实是没有访问权限。而``Juno agent``用MySQL客户端方式访问,就可以提前知道你的应用[agent和你的应用同机部署]部署的机器是否有该MySQL权限)。 + +目前``Juno agent``支持以下类型 +* $MYSQL +* $REDIS +* $GRPC + +后续会支持更多类型 + + +## 9.5.5 配置结构 +根据上述的介绍,我们的``Juno agent``可以将之前多样性的而用户配置完全解析。 + +### 9.5.5.1 第一种配置 +我们在用户端的配置的表现形式将是 +``` +[mysqlconfig] + addr = "ip:port" + user = "hello" + password = "world" + JunoTpl = 1 +``` +我们在后台配置JunoTpl为1的模板内容以下所示,该数据存储在ETCD中。 +keyname为/Juno-agent/configtpl/1 +value如下所示 + +``` +addr = $IP:$PORT +user = $USERNAME +password = $PASSWORD +JunoType = $MYSQL +``` + + + +### 9.5.5.2 第二种配置 +我们在用户端的配置的表现形式将是 +``` +[mysqlconfig] + ip = "ip" + port = "port" + user = "hello" + password = "world" + JunoTpl = 2 +``` +我们在后台配置JunoTpl为2的模板内容以下所示,该数据存储在ETCD中。 +keyname为/Juno-agent/configtpl/2 +value如下所示 + +``` +ip = $IP +port = $PORT +user = $USERNAME +password = $PASSWORD +JunoType = $MYSQL +``` + + +### 9.5.5.3 第三种配置 +我们在用户端的配置的表现形式将是 +``` +[mysqlconfig] + dsn = "user:password@ip:port" + JunoTpl = 3 +``` +我们在后台配置JunoTpl为3的模板内容以下所示,该数据存储在ETCD中。 +keyname为/Juno-agent/configtpl/3 +value如下所示 + +``` +dsn = $DSN +JunoType = $MYSQL +``` + + diff --git a/website/docs/juno/9.6agentReport.md b/website/docs/juno/9.6agentReport.md new file mode 100644 index 0000000000..52b804658a --- /dev/null +++ b/website/docs/juno/9.6agentReport.md @@ -0,0 +1,37 @@ +# 9.6 agent状态上报 + +agent状态上报主要用于监听agent部署的机器的一个健康状况,通过定时上报机器的信息来判断机器的健康状况 + +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`Enable`| bool| 是否开启agent上报 | +|`Addr`| string| 上报地址 | +|`Internal`| time.Duration| 上报间隔时长 | +|`HostName`| string | 部署机器的hostname| +|`RegionCode`| string | 部署机器的region| +|`zoneCode`| string | 部署机器的zone| +|`ZoneName`| string | 部署机器的zone名称| +|`Env`| string | 部署机器的env环境| + +## 9.6.1 配置下发方式 + +配置文件中的格式为: +```toml +[plugin.report] + enable = true + addr = "http://127.0.0.1:50000/api/v1/resource/node/heartbeat" + internal = "60s" + hostName = "JUPITER_HOST" # 环境变量的名称,或者命令行参数的名称 + regionCode = "REGION_CODE" # 环境变量的名称,或者命令行参数的名称 + regionName = "REGION_NAME" + zoneCode = "ZONE_CODE" + zoneName = "ZONE_NAME" + env = "env" +``` + + +### 9.6.2 http模式 + +agent上报方式进行了接口化处理,目前默认http方式 + +agent将该部署机器的对应的信息上报给配置文件中的addr。 diff --git a/website/docs/juno/9.7pmt.md b/website/docs/juno/9.7pmt.md new file mode 100644 index 0000000000..61a2606a3d --- /dev/null +++ b/website/docs/juno/9.7pmt.md @@ -0,0 +1,38 @@ +# 9.7 扫描器 + +配合```配置中心```使用 + +应用启动扫描器,主要用于监听应用启动配置信息,根据监听并且解析启动配置的信息,来判断该应用是否已经接入配置中心,目前支持supervisor和systemd两种。 + + +## 9.7.1 supervisor + +supervisor主要用来监听部署在agent机器上的所有的应用的一个supervisor启动的配置信息,通过解析supervisor文件来获取应用启动使用的配置文件信息,用来判断应用是否接入了配置中心。 + +```toml +[plugin.supervisor] + enable = true // 插件是否开启 + dir = "/etc/supervisor/conf.d1" // 用来配置supervisor的配置目录 +``` + +supercisor插件的主要工作: +* 是否打开supervisor监听 +* agent初始化时,负责将该机器上所有应用的supervisor配置信息记录在内容中 +* 监听supervisor配置文件,当发现supervisor文件发生变化,则更新内存缓存的应用配置信息 +* 提供配置中心应用是否接入配置中心的接口 + +## 9.7.2 systemd + +systemd主要用来监听部署在agent机器上的所有的应用的一个systemd启动的配置信息,通过解析systemd文件来获取应用启动使用的配置文件信息,用来判断应用是否接入了配置中心。 + +```toml +[plugin.systemd] + enable = true // 插件是否开启 + dir = "/etc/systemd/system1" // 用来配置systemd的配置目录 +``` + +systemd插件的主要工作: +* 是否打开systemd监听 +* agent初始化时,负责将该机器上所有应用的systemd配置信息记录在内容中 +* 监听systemd配置文件,当发现systemd文件发生变化,则更新内存缓存的应用配置信息 +* 提供配置中心应用是否接入配置中心的接口 diff --git a/website/docs/juno/9.8proxy.md b/website/docs/juno/9.8proxy.md new file mode 100644 index 0000000000..d343358d42 --- /dev/null +++ b/website/docs/juno/9.8proxy.md @@ -0,0 +1,41 @@ +# 9.3 服务代理 +``Juno-agent``可以做``gRPC``到``ETCD``的代理,用于减少``ETCD``,提升``ETCD``性能和服务可靠性。 + +> todo: 为了让大家更好的理解服务代理的必要性,请大家先阅读[服务注册痛点](../awesome/register.md)。 + +## 9.3.1 功能描述 +* Register +* Lease +* Watch +* Discovery(todo) + + +## 9.3.2 数据拦截 +会将Register,Lease,Watch,Discovery里的方法设置拦截器,将数据放入到消息总线,方便数据分析。 + +## 9.3.3 开启服务代理 +我们可以使用``Juno-agent``接管应用的注册、注销、租期、发现等功能。 + +我们需要在管理后台,需要设置五个信息 +* 注册key的前缀 +* 如何解析注册里的ip,port信息 +* 探活的路径 +* 流控数据 +* lease周期 + + +设置完拦截的代理信息后,我们就可以开启此功能。 + +这个时候``Juno-agent``将会拦截该应用的注册key,解析出该应用需要注册的ip port,根据探活路径进行探活。探活成功后,才会将该应用的服务注册到``ETCD``里。这个时候还可以根据``ETCD``里的配置,对服务按权重进行逐步导流。 + +同时根据配置的周期探活,对服务注册进行lease操作。 + +同理注销操作。 + + + + + + + + diff --git a/website/docs/juno/README.md b/website/docs/juno/README.md new file mode 100644 index 0000000000..6557ada1d1 --- /dev/null +++ b/website/docs/juno/README.md @@ -0,0 +1,87 @@ +# Juno + +> A Distributed Application Management System + +Juno 译名朱诺。这个名字来源于古罗马神话中的众神之母。它是斗鱼的微服务管理系统, +如同众神之母一样守护着所有微服务系统。 + +## Overview + +Juno 提供了对微服务进行管理的多项能力,包括应用监控、依赖分析、配置管理等。 + +## 定义 + +| 名词 | 含义 | +|:--------------|:-----| +|`节点`| 单台ECS服务器、容器里的某个pod | +|`应用`| 某个服务 | +|`可用区`| 地区-机房-环境,这三个因素组成例如:ali(阿里云-华北 2)-ALIYUN-HB2-G(阿里云-北京可用区G)-gray| + + +## 功能 + +- 工作台:平台整体概览,默认权限即可查看 +- 应用服务 + - 详情,应用和节点的关联关系 + - 监控,服务监控 + - 配置,服务配置下发 + - 日志,服务日志 + - pprof,线上实时分析 + - etcd, k-v查询 + - 事件,服务事件流 +- 功能看板 + - 大盘,更全面的平台数据概览 + - Grafana,内嵌grafana + - 依赖拓扑,根据服务配置进行的依赖解析 + - 版本管理,继续go.mod文件内容获取各个服务依赖的数据版本 + - 注册信息,ETCD数据查询 +- 任务中心,分布式定时任务 +- 资源中心,管理应用、节点、可用区的原始数据以及相关依赖 +- 配置中心,配置模板和全局资源配置 +- 测试中心,提供GRPC和HTTP测试工具 +- 权限管理,接入Casbin权限管理 +- 系统设置 + +## 快速开始 + +### Requirements + +1. Etcd +2. MySQL + +### 二进制安装包和安装 + +```bash +## 下载 +wget https://github.com/douyu/juno/release/juno.tar.gz + +## 解压 +tar -zxvf juno.tar.gz +``` + +### 初始化和启动 + +[参考配置](https://github.com/douyu/juno/blob/master/config/single-region-admin.toml) + +```bash +cd juno + +# 安装数据库 +./bin/install --config=./参考配置 + +# 启动juno后台 +./bin/juno --config=./参考配置 + +# 启动juno的agent +./bin/juno-agent --config=./参考配置 + +``` + +完成以上步骤后,Juno 后台会默认使用 50000 端口提供后台管理界面服务。 +在浏览器中打开 `http://localhost:50000`,可以看到登录界面。 + +初始的用户名: `admin` + +初始密码: `admin` + +登录后可以看到如下界面代表安装成功: diff --git a/website/docs/juno/backup/1.4installcode.md b/website/docs/juno/backup/1.4installcode.md new file mode 100644 index 0000000000..d5b92ab37e --- /dev/null +++ b/website/docs/juno/backup/1.4installcode.md @@ -0,0 +1,19 @@ +# 1.3 源码安装 + +## 1.3.1 单机房模式 +* juno make run +* juno-agent make run +* 页面打开http://127.0.0.1:50000/resource/node/list?currentPage=1&pageSize=10 + +## 1.3.2 多机房部署 + + + +## 1.4.3 使用代理登录,如果没有admin用户 +update user set is_admin=1 where id = 2 +update org_user set role="Admin" where id = 2; + +## +wget +unzip +/home/www diff --git a/website/docs/jupiter/1.1quickstart.md b/website/docs/jupiter/1.1quickstart.md new file mode 100644 index 0000000000..e9bdfcfef1 --- /dev/null +++ b/website/docs/jupiter/1.1quickstart.md @@ -0,0 +1,64 @@ +# 1.1 快速开始 + +为了让大家快速了解 ``Jupiter`` 框架,我们提供了大量的 [example](https://github.com/douyu/jupiter-examples) 以及标准化的项目模版 [jupiter-layout](https://github.com/douyu/jupiter-layout) + +在这一节,我们将通过 jupiter-layout 向大家演示如何基于 Jupiter 快速搭建并启动一个项目。 + +## 1.1.1 安装依赖 + +### 安装 [Golang](https://golang.org/dl/) + +Jupiter 是基于 Golang 开发的,所以在开始之前,你需要先安装 Golang 环境。 + +### 安装 Jupiter 脚手架 + +```bash +go install github.com/douyu/jupiter/cmd/jupiter@latest +``` + +## 1.1.2 创建项目 + +### 创建项目 + +```bash +jupiter new jupiter-layout-demo +``` + +### 进入项目 + +```bash +cd jupiter-layout-demo +``` + +## 1.1.3 启动项目 + +### 启动依赖中间件 + +```bash +docker-compose -f deployment/docker-compose.yml up -d +``` + +### 启动项目 + +```bash +jupiter run -c config/exampleserver/local-live.toml +``` + +### 测试接口 + + +* HTTP + +```bash +curl "localhost:9527?name=bob" +``` + +```json +{"error":0,"msg":"请求正常","data":{"message":"hello wolrd"}} +``` + +## Jaeger Admin + +open [http://localhost:16686/search](http://localhost:16686/search) to checkout opentelemtry trace data. + +![Jaeger](https://raw.githubusercontent.com/hnlq715/imgs-all-in-one/main/obsidian/%E6%88%AA%E5%B1%8F2022-09-30%2018.31.27.png) diff --git a/website/docs/jupiter/1.2example.md b/website/docs/jupiter/1.2example.md new file mode 100644 index 0000000000..1c074a3d46 --- /dev/null +++ b/website/docs/jupiter/1.2example.md @@ -0,0 +1,25 @@ +# 1.2 Example +* [Helloworld示例](https://github.com/douyu/jupiter-examples/tree/main/helloworld) +* [配置示例](https://github.com/douyu/jupiter-examples/tree/main/config) + * [通过文件配置读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByFile) + * [通过文件配置读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByFile) + * [监听文件配置读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByFileWatch) + * [监听文件配置读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByFileWatch) + * [通过远端配置读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByRemoteConfig) + * [通过远端配置读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByRemoteConfig) + * [监听远端配置读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByRemoteConfigWatch) + * [监听远端配置读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByRemoteConfigWatch) +* [日志示例](https://github.com/douyu/jupiter-examples/tree/main/logger) + * [日志终端展示示例](https://github.com/douyu/jupiter-examples/tree/main/logger/command) + * [日志文本展示示例](https://github.com/douyu/jupiter-examples/tree/main/logger/file) + * [动态修改日志级别示例](https://github.com/douyu/jupiter-examples/tree/main/logger/fileByWatch) +* [gRPC示例](https://github.com/douyu/jupiter-examples/tree/main/grpc) + * [gRPC直连示例](https://github.com/douyu/jupiter-examples/tree/main/grpc/direct) + * [gRPC和ETCD示例](https://github.com/douyu/jupiter-examples/tree/main/grpc/etcd) +* [Worker示例](https://github.com/douyu/jupiter-examples/tree/main/worker/cron) +* [组件示例](https://github.com/douyu/jupiter-examples/tree/main/client) + * [组件ETCD示例](https://github.com/douyu/jupiter-examples/tree/main/client/etcd) + * [组件gRPC直连示例](https://github.com/douyu/jupiter-examples/tree/main/grpc/direct/direct-client) + * [组件gRPC和ETCD示例](https://github.com/douyu/jupiter-examples/tree/main/grpc/etcd/etcd-client) + * [组件Gorm示例](https://github.com/douyu/jupiter-examples/tree/main/client/gorm) + diff --git a/website/docs/jupiter/1.3feature.md b/website/docs/jupiter/1.3feature.md new file mode 100644 index 0000000000..f2a44cf12e --- /dev/null +++ b/website/docs/jupiter/1.3feature.md @@ -0,0 +1,70 @@ +# 1.3 功能点 +以下是``Jupiter``的功能点,如果你有新的功能点,可以给我们提[issue](https://github.com/douyu/jupiter/issues) + +## 1.3.1 服务注册与发现 +* 支持多种注册中心: + - [ x ] juno内置已支持 + - [ x ] nacos实验性支持 +* 支持多种注册格式: + * juno原生注册格式内置 + * dubbo注册格式内置 + * nacos推荐注册格式实验性支持 +* grpc客户端支持多种服务发现/负载均衡算法 + * wrr: 权重轮询内置 + * p2c 内置 +## 1.3.2 指标、链路和日志 +* 指标采集 + * 服务端指标 + * 客户端指标 +* 链路追踪 + * 服务端链路追踪 + * 客户端链路追踪 + * 存储库链路追踪 +* 日志埋点 + * 所有包内置埋点 +## 1.3.3 多服务端框架 +* 支持多种rpc框架接入: + * echo内置已支持 + * grpc内置已支持 + * gin实验性支持 +* 统一信号管理: Stop/GracefulStop 已支持 +* 统一注册和发现架构 部分支持 +* 统一治理流程 +## 1.3.4 多客户端支持 +* 支持常用存储/缓存服务 + * redis 内置已支持 + * mysql 内置已支持 + * mongo + * leveldb + * groupcache + * freecache + * bigcache +* 支持常用rpc客户端 + * grpc + * http + * dubbo-grpc +* 支持常用MQ + * rocketMQ内置已支持 + * nats + * zeromq + * kafka +* 治理规范 + * 错误码 + * 动态配置 + * 拦截器 +* 统一治理 + * 链路追踪 + * 指标采集 + * 日志埋点 +## 1.3.5 多种可靠性组件 +* 存储慢查询拦截 +* RPC慢响应拦截 +* 熔断限流 +## 1.3.6 多种任务场景 +* 短时任务 +* 长时任务 +## 1.3.7 控制台应用 +* 集成urfave/cli快速创建控制台应用 +* 集成juno平台API,从终端掌控治理 +## 1.3.8 工具链 +* 脚手架,快速创建项目 diff --git a/website/docs/jupiter/1.4contribute.md b/website/docs/jupiter/1.4contribute.md new file mode 100644 index 0000000000..4ac52a1a04 --- /dev/null +++ b/website/docs/jupiter/1.4contribute.md @@ -0,0 +1,48 @@ +# 1.4 贡献者协作 + + +准备工作: 如果你没有github账号, 您需要申请一个Github账号, 接下来可以继续下一步. + +## 1.4.1 Fork 代码 + +1. 访问 [https://github.com/douyu/jupiter](https://github.com/douyu/jupiter) +2. 点击 "Fork" 按钮 (位于页面的右上方) + +## 1.4.2 Clone 代码 + +```bash +git clone https://github.com//jupiter +cd jupiter +git remote add upstream 'https://github.com/douyu/jupiter' +``` + +## 1.4.3 创建 feature 分支 + +```bash +git checkout -b feature/my-feature +``` + +## 1.4.4 同步代码 + +```bash +git fetch upstream +git rebase upstream/master +``` + +## 1.4.5 提交 commit + +```bash +git add . +git commit +git push origin my-feature +``` +## 1.4.6 提交 PR + +```bash +访问 https://github.com/douyu/jupiter, + +点击 "Compare" 比较变更并点击 "Pull request" 提交 PR +``` + +> 可以使用 [github desktop](https://desktop.github.com/) 快速发起 PR + diff --git a/website/docs/jupiter/2.1startup.md b/website/docs/jupiter/2.1startup.md new file mode 100644 index 0000000000..be1cc213a6 --- /dev/null +++ b/website/docs/jupiter/2.1startup.md @@ -0,0 +1,19 @@ +# 2.1 启动 + +## 2.1.1 启动方式 +``Jupiter``内置了命令行指令``config``。你可以设置本地配置,运行``go run main.go --config=config.toml``,启动应用。也可以设置远端配置,运行``go run main.go --config=http://remoteAddr``,启动应用。 + +## 2.1.2 查看版本信息 +``Jupiter``参考了``istio``的[编译工具](https://github.com/douyu/jupiter/blob/master/tools/build/script/shell/build.sh),可以将应用的版本信息、编译时间、编译机器写入到里应用编译里。我们可以运行``go build && ./main --version``,看到以下数据 +```bash +Name: jupiter +Version: c4330a596 +User: askuy@wuhan +GolangVersion: go1.13rc1 +BuildStatus: Modified +BuildTime: 2020-05-18--20:38:45 +``` + +## 2.1.3 查看帮助 +``Jupiter``可以运行``go build && ./main --help``,查看到各个指令的含义和运行模式,还可以通过help中的文档地址,查阅详细的功能使用。 + diff --git a/website/docs/jupiter/2.2config.md b/website/docs/jupiter/2.2config.md new file mode 100644 index 0000000000..ce09f378e9 --- /dev/null +++ b/website/docs/jupiter/2.2config.md @@ -0,0 +1,100 @@ +# 2.2 配置 + +## 2.2.1 配置介绍 +配置完整性定义是:环境变量、编译注入配置、命令行配置、文本配置、远端配置,这五类数据共同构成了一份完整配置,形成一份完整配置。``Jupiter``会对五种类型配置进行整合,最终得到应用使用的配置。 + +## 2.2.2 文本配置 +### 读取单行配置信息 +参考[读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByFile) +```toml +[people] + name = "jupiter" +``` + +```go +peopleName := conf.GetString("people.name") +xlog.Info("people info", xlog.String("name", peopleName), xlog.String("type", "onelineByFile")) +``` + +我们只需要简单两行,就可以读取到配置里的数据,运行``go run main.go --config=config.toml``,可以看到运行结果。 + + +### 读取结构体配置信息 +参考[读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByFile) +```toml +[people] + name = "jupiter" +``` + +```go +type People struct { + Name string +} +p := People{} +err := conf.UnmarshalKey("people", &p) +if err != nil { + panic(err.Error()) +} +xlog.Info("people info", xlog.String("name", p.Name), xlog.String("type", "structByFile")) +``` + +读取结构体配置,使用``conf.UnmarshalKey``方法,第一个参数传入配置里需要解析的Key,第二个参数传入需要解析的结构体对象,运行``go run main.go --config=config.toml``,可以看到运行结果。 + +### 监听文件读取单行配置信息 +参考[监听文件读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByFileWatch) + + +### 监听文件读取单行配置信息 +```toml +[people] + name = "jupiter" +``` + +```go +for { + time.Sleep(10 * time.Second) + peopleName := conf.GetString("people.name") + xlog.Info("people info", xlog.String("name", peopleName), xlog.String("type", "onelineByFileWatch")) +} +``` +使用监听文件功能,需要使用指令``--watch=true``进行开启。获取单行配置的方法,不需要做任何改动,就能够直接使用动态配置功能。,运行``go run main.go --config=config.toml --watch=true``,可以看到运行结果。 + + +### 监听文件读取结构体配置信息 +参考[监听文件读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByFileWatch) + +```toml +[people] + name = "jupiter" +``` + +```go +type People struct { + Name string +} +p := People{} +// 设置监听的结构体 +conf.OnChange(func(config *conf.Configuration) { + err := config.UnmarshalKey("people", &p) + if err != nil { + panic(err.Error()) + } +}) +for { + time.Sleep(10 * time.Second) + xlog.Info("people info", xlog.String("name", p.Name), xlog.String("type", "structByFileWatch")) +} +``` +使用监听文件功能,需要使用指令``--watch=true``进行开启。获取结构体配置的方法,需要在前面增加一个``conf.OnChange``方法,监听配置变动后,改变结构体(这个地方没上锁,生产环境请上锁)。运行``go run main.go --config=config.toml --watch=true``,可以看到运行结果。 + + + + +## 2.2.3 远端配置 +远端配置和文本配置使用方式一致,只需要改变下命令行参数,将原有的``--config=config.toml``换成远端配置地址``--config=http://remoteConfigAddr`` +具体用法参考以下example +* [通过远端配置读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByRemoteConfig) +* [通过远端配置读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByRemoteConfig) +* [监听远端配置读取单行配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/onelineByRemoteConfigWatch) +* [监听远端配置读取结构体配置示例](https://github.com/douyu/jupiter-examples/tree/main/config/structByRemoteConfigWatch) + diff --git a/website/docs/jupiter/2.3logger.md b/website/docs/jupiter/2.3logger.md new file mode 100644 index 0000000000..8558904374 --- /dev/null +++ b/website/docs/jupiter/2.3logger.md @@ -0,0 +1,118 @@ +# 2.3 日志 + +## 2.3.1 日志介绍 +日志定义: 系统日志、框架日志、业务日志。系统日志采集应用的启动、运行、error、panic等信息。框架日志采集应用内部组件的启动、运行、error、panic、应用access、job等信息。业务日志采集业务相关信息。 + +### 日志性能 +* sugar版本 +* 高性能版本 + +### 日志级别 +* debug +* info +* warn +* error +* panic + +### 日志字段 +* lv 日志级别 +* ts 时间戳 +* msg 日志信息 +* aid 应用id +* iid 应用实例id +* tid 请求trace id + +## 2.3.2 配置规范 +[配置说明](../jupiter/6.1logger.md) + +## 2.3.3 框架日志 +我们规范了框架日志,定义了十多个字段用于收敛框架的日志行为。参考于[opentrace](https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/semantic_conventions.md)。 + +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`lv`| string| 日志级别| +|`ts`| string| 时间戳| +|`msg`| string| 日志信息| +|`aid`| string| 应用id| +|`iid`| string| 应用实例id| +|`tid`| string| 请求trace id| +|`color`| string| 染色| +|`mod` | string | 类库或模块。如 `"grpc"`, `"http"`, `"redis"`. | +|`addr` | string | 依赖的实例名称。以mysql为例,`"dsn = "root:juno@tcp(127.0.0.1:3306)/juno?charset=utf8"`,addr为 `"127.0.0.1:3306"`. | +|`cost` | int | 耗时时间 | +|`code` | int | 用户侧响应的状态码 | +|`meth` | string | 对于`redis`是`command`、对于`http`是`url`、对于`mysql`是`sql` | +|`host`| string | 主机名 | +|`ip`| string | 主机IP | +|`peerAid`| string | 对端应用id | +|`peerHost`| string | 对端主机名 | +|`errKind`| string | 错误类型,用于收敛 | +|`err`| string | 错误信息 | + +定义合理的日志schema,我们可以将框架日志全部采集到一个``logstore``里进行分析和报警。如图所示 +![image](../static/jupiter/dashboard1.png) +![image](../static/jupiter/dashboard2.png) + +因为开源时间紧迫,并未将内部收敛的迁移到开源项目中,二期我们将会把这些治理理念放入到框架中,尽情期待。 + +## 2.3.4 业务的命令行日志 +参考[日志终端展示示例](https://github.com/douyu/jupiter-examples/tree/main/logger/command) +```toml +[jupiter.logger.default] + debug = true # 是否在命令行输出 + enableConsole = true # 是否按命令行格式输出 +``` +```go +xlog.DefaultLogger = xlog.StdConfig("default").Build() +for { + xlog.Info("logger info", xlog.String("gopher", "jupiter"), xlog.String("type", "command")) + time.Sleep(1 * time.Second) +} +``` +在线下调试代码的时候,我们可以开启``debug=true``的选项将日志信息输出到终端,并且打开``enableConsole=true``,就可以看到高亮的日志信息,更加方便我们排查日志。运行``go run main.go --config=config.toml``,可以看到以下运行结果。 + +![命令行日志](../static/jupiter/logger-command.png) + +## 2.3.5 业务的文本日志 +参考[日志文本展示示例](https://github.com/douyu/jupiter-examples/tree/main/logger/file) +```toml +[jupiter.logger.default] + debug = false # 是否在命令行输出 + enableConsole = false # 是否按命令行格式输出 + name = "default.json" # 日志名称 + dir = "." # 日志路径 + async = true # 默认异步采集日志 +``` +```go +xlog.DefaultLogger = xlog.StdConfig("default").Build() +for { + xlog.Info("logger info", xlog.String("gopher", "jupiter"), xlog.String("type", "command")) + time.Sleep(1 * time.Second) +} +``` +上线的时候,我们可以关闭调试选项,将他们设置为``debug=false``和``enableConsole=false``,并设置日志路径``dir``和名称``name``。运行``go run main.go --config=config.toml``,可以看到运行结果。 + + +## 2.3.6 动态修改日志级别 +参考[动态修改日志级别示例](https://github.com/douyu/jupiter-examples/tree/main/logger/fileWatch) +```toml +[jupiter.logger.default] + debug = false # 是否在命令行输出 + enableConsole = false # 是否按命令行格式输出 + name = "default.json" # 日志名称 + dir = "." # 日志路径 + async = true # 默认异步采集日志 + level = "info" # 调整日志级别,可以动态修改日志 +``` +```go +xlog.DefaultLogger = xlog.StdConfig("default").Build() +for { + xlog.Info("logger info", xlog.String("gopher", "jupiter"), xlog.String("type", "command")) + xlog.Debug("logger debug", xlog.String("gopher", "jupiter"), xlog.String("type", "command")) + time.Sleep(1 * time.Second) +} +``` +上线的时候,我们一般会开启``info``的日志级别,那么测试的``debug``日志是不会在线上记录。如果线上出现问题后,我们可以通过配置中心,修改这个级别,那么线上会立刻采集``debug``的日志。运行``go run main.go --config=config.toml --watch=true``,调整配置里的日志级别,可以看到运行效果。 + + + diff --git a/website/docs/jupiter/3.1http.md b/website/docs/jupiter/3.1http.md new file mode 100644 index 0000000000..8aff378733 --- /dev/null +++ b/website/docs/jupiter/3.1http.md @@ -0,0 +1,53 @@ +# 3.1 HTTP + +## 3.1.1 HTTP介绍 +``HTTP``是最常用的一种``Server``,``Jupiter``对``HTTP``服务提供了很多可观察性的手段。 + +我们内置了多个中间件,可以采集请求日志、采集trace、采集监控、采集慢日志,更加方便我们对``HTTP``服务的可观测。 + +通过``registry``注册``HTTP``里的信息,提供给网关使用 + +通过``govern``的治理端口,能够查看监控、HTTP实时信息 + +## 3.1.2 配置规范 +[配置说明](../jupiter/6.2httpserver.md) + +## 3.1.3 简单的HTTP +[查看quickstart](../jupiter/1.1quickstart.html) + +## 3.1.4 注册的HTTP +参考[HTTP注册信息示例](https://github.com/douyu/jupiter-examples/tree/main/http/register) + +配置项 +```toml +[jupiter.server.http] + port = 9090 +[jupiter.etcdv3.default] + endpoints=["127.0.0.1:2379"] + secure = false +[jupiter.registry.wh] + configKey="jupiter.etcdv3.default" + timeout = "1s" +``` + +注册``ETCD``信息 +```go +eng.SetRegistry( + compound_registry.New( + etcdv3_registry.StdConfig("wh").BuildRegistry(), + ), +) +``` +设置``HTTP`` +```go +// HTTP地址 +func (eng *Engine) serveHTTP() error { + server := xecho.StdConfig("http").Build() + server.GET("/hello", func(ctx echo.Context) error { + return ctx.JSON(200, "Gopher Wuhan") + }) + return eng.Serve(server) +} +``` +## 3.1.5 完整的HTTP +参考[完整HTTP注册信息示例](https://github.com/douyu/jupiter-examples/tree/main/http/all) diff --git a/website/docs/jupiter/3.2grpc.md b/website/docs/jupiter/3.2grpc.md new file mode 100644 index 0000000000..a13791054f --- /dev/null +++ b/website/docs/jupiter/3.2grpc.md @@ -0,0 +1,652 @@ +# 3.2 gRPC + +## 3.2.1 gRPC介绍 +``Jupiter``微服务目前支持``gRPC``,``Jupiter``对``gRPC``服务提供了很多可观察性的手段。 + +内置了多个中间件,可以采集请求日志、采集trace、采集监控、采集慢日志,更加方便我们对``gRPC``服务的可观测。 + +通过``govern``的治理端口,能够查看监控、HTTP实时信息 + +## 3.2.2 配置规范 +[配置说明](../jupiter/6.3grpcserver.md) + +## 3.2.3 直连的gRPC +参考[gRPC直连示例](https://github.com/douyu/jupiter-examples/tree/main/grpc/direct) + +### 3.2.3.1 启动gRPC服务 +配置项 +```toml +[jupiter.server.grpc] + port = 9091 +``` + +代码 +```go +func main() { + eng := NewEngine() + eng.SetGovernor("127.0.0.1:9092") + if err := eng.Run(); err != nil { + xlog.Panic(err.Error()) + } +} + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + + if err := eng.Startup( + eng.serveGRPC, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func (eng *Engine) serveGRPC() error { + server := xgrpc.StdConfig("grpc").Build() + helloworld.RegisterGreeterServer(server.Server, new(Greeter)) + return eng.Serve(server) +} + +type Greeter struct{} + +func (g Greeter) SayHello(context context.Context, request *helloworld.HelloRequest) (*helloworld.HelloReply, error) { + return &helloworld.HelloReply{ + Message: "Hello Jupiter", + }, nil +} +``` +运行指令``go run main.go --config=config.toml``,可以看到以下运行结果 +![image](../static/jupiter/grpc-direct-server.png) +从图中可以看到,我们启动了一个``gRPC``服务运行在``9091``端口,接下来我们启动客户端 + +### 3.2.3.2 启动gRPC客户端 +配置项 +```toml +[jupiter.client.directserver] + address = "127.0.0.1:9091" + balancerName = "round_robin" # 默认值 + block = false # 默认值 + dialTimeout = "0s" # 默认值 + +``` + +代码 +```go + +func main() { + eng := NewEngine() + if err := eng.Run(); err != nil { + xlog.Error(err.Error()) + } +} + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.consumer, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func (eng *Engine) consumer() error { + conn := grpc.StdConfig("directserver").Build() + client := helloworld.NewGreeterClient(conn) + for { + resp, err := client.SayHello(context.Background(), &helloworld.HelloRequest{ + Name: "jupiter", + }) + if err != nil { + xlog.Error(err.Error()) + } else { + xlog.Info("receive response", xlog.String("resp", resp.Message)) + } + time.Sleep(1 * time.Second) + } + return nil +} +``` +我们的``gRPC``客户端通过配置里的地址和负载均衡算法,可以请求刚才我们启动的``gRPC``服务端。运行指令``go run main.go --config=config.toml``,可以看到以下运行结果 +![image](../static/jupiter/grpc-direct-client.png) +我们定时1s,发送``hello``给``gRPC``服务端,可以收到服务端响应的``Hello Jupiter`` + + +## 3.2.4 注册ETCD的gRPC服务 +参考[gRPC注册ETCD示例](https://github.com/douyu/jupiter-examples/tree/main/grpc/etcd) + +### 3.2.4.2 启动gRPC服务 +配置项 +```toml +[jupiter.server.grpc] + port = 9091 # 服务端grpc绑定端口 +[jupiter.registry.wh] # 注册grpc到etcd的配置 + connectTimeout = "1s" + endpoints=["127.0.0.1:2379"] # grpc注册到目标etcd中 + secure = false + prefix = "wsd-reg" # 服务端注册到etcd的key前缀,配置客户端时候应该保持一致 +``` + +代码 +```go +package main + +import ( + "context" + "fmt" + "github.com/douyu/jupiter" + compound_registry "github.com/douyu/jupiter/pkg/registry/compound" + etcdv3_registry "github.com/douyu/jupiter/pkg/registry/etcdv3" + "github.com/douyu/jupiter/pkg/server/xgrpc" + "github.com/douyu/jupiter/pkg/xlog" + "google.golang.org/grpc/examples/helloworld/helloworld" +) + +func main() { + eng := NewEngine() + eng.SetRegistry( + compound_registry.New( + etcdv3_registry.StdConfig("wh").Build(), + ), + ) + //eng.SetGovernor("0.0.0.0:0") + if err := eng.Run(); err != nil { + xlog.Error(err.Error()) + } +} + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.serveGRPC, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func (eng *Engine) serveGRPC() error { + + server := xgrpc.StdConfig("grpc").Build() + helloworld.RegisterGreeterServer(server.Server, new(Greeter)) + return eng.Serve(server) +} + +type Greeter struct { + server *xgrpc.Server +} + + +func (Greeter) SayHello(context context.Context, request *helloworld.HelloRequest) (*helloworld.HelloReply, error) { + sd := &helloworld.HelloReply{ + Message: "返回信息给client", + } + + fmt.Println(fmt.Sprintf("name:%s",request.Name)) + return sd,nil +} + +``` +运行指令``go run main.go --config=config.toml``,可以看到以下运行结果 +![image](../static/jupiter/grpc-etcd-server.png) +从图中可以看到,我们启动了一个``gRPC``服务运行在``9091``端口,在命令行的第四行,展示了我们注册的``key``和``value``信息。接下来我们在启动客户端。 + +### 3.2.4.2 启动gRPC客户端 +配置项 +```toml +[jupiter.registry.wh] + connectTimeout = "1s" + endpoints=["127.0.0.1:2379"] + secure = false + prefix = "wsd-reg" # 服务端注册到etcd的key前缀,配置客户端时候应该保持一致 + +[jupiter.client.etcdserver] + address = "etcd:///main" #etcd:/// 默认前缀, main 指的是应用执行二进制文件名称(发布平台将它默认为应用名称). 框架内部会把 main解析出来跟前缀做拼接,去etcd找到对应grpc服务端注册key + balancerName = "round_robin" # 默认值,grpc客户端调用服务端采用的 轮训模式 + block = false # 默认值 + dialTimeout = "0s" # 默认值 + +``` + +grpc客户端代码demo +```go +package main + +import ( + "context" + "fmt" + "time" + + "github.com/douyu/jupiter" + "github.com/douyu/jupiter/pkg/client/grpc" + "github.com/douyu/jupiter/pkg/client/grpc/balancer" + "github.com/douyu/jupiter/pkg/client/grpc/resolver" + "github.com/douyu/jupiter/pkg/registry/etcdv3" + "github.com/douyu/jupiter/pkg/xlog" + "google.golang.org/grpc/examples/helloworld/helloworld" +) + +func main() { + eng := NewEngine() + if err := eng.Run(); err != nil { + xlog.Error(err.Error()) + } + fmt.Printf("111 = %+v\n", 111) +} + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.initResolver, + eng.consumer, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func (eng *Engine) initResolver() error { + resolver.Register("etcd", etcdv3.StdConfig("wh").Build()) + return nil +} + +func (eng *Engine) consumer() error { + config := grpc.StdConfig("etcdserver") + //config.BalancerName = balancer.NameSmoothWeightRoundRobin + client := helloworld.NewGreeterClient(config.Build()) + + go func() { + i:=0 + ghj := map[string]int{} + for { + + i++ + resp, err := client.SayHello(context.Background(), &helloworld.HelloRequest{ + Name: fmt.Sprintf("jupiter:%d",i), + }) + if err != nil { + fmt.Printf("err = %+v\n%s", err,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii") + xlog.Error(err.Error()) + } else { + ghj[resp.Message] = ghj[resp.Message] + 1 + fmt.Printf("resp.Message = %+v\n", ghj) + xlog.Info("receive response", xlog.String("resp", resp.Message)) + } + time.Sleep(1 * time.Second) + } + }() + return nil +} +``` +运行指令``go run main.go --config=config.toml``,可以看到以下运行结果 +![image](../static/jupiter/grpc-etcd-client.png) +我们的``gRPC``客户端通过应用名称``main``从``ETCD``中获取到服务地址,并监听了``/wsd-reg/main``,用于后续更新服务地址。 + +客户端会定时1s,发送``hello``给``gRPC``服务端,可以收到服务端响应的``Jupiter 1` 类似信息到服务端` + + + + + + + +### 3.2.4.3 从零开始配置 +环境要求 + jupiter(commit:8b67ebec1ae6dc07e8df27d7240aa9b4d954671b)如果用的minerva就用1.8 + + +生成potobuf + +```go +syntax = "proto3"; +package pb; + +service Hello { + // SayHello + rpc SayHello(SayHelloReq) returns (SayHelloRes); +} + +message SayHelloReq{ + string name = 1; +} + +message SayHelloRes{ + string resp = 1; +} +``` +执行命令: `protoc -I . --go_out=plugins=grpc:. ./hello.proto` 拿到对应pb包放入对应项目的路径 + +`go build -o jupiter-demo main.go` 记得把下面的demo编译成jupiter-demo,再执行 +jupiter 客户端 使用demo +```go +# 配置 +[jupiter.registry.wh] +connectTimeout = "1s" +endpoints=["127.0.0.1:2379"] +secure = false +prefix = "wsd-reg" # 前缀 + +[jupiter.client.etcdserver] +address = "etcd:///jupiter-demo" # jupiter-demo 指的是执行文件名称,在发布平台执行文件名称跟应用名称是一样的 +block = true # 默认值 +dialTimeout = "0s" # 默认值 + +package main + +import ( + "clientb/pb" + "context" + "fmt" + "time" + + "github.com/douyu/jupiter" + "github.com/douyu/jupiter/pkg/client/grpc" + "github.com/douyu/jupiter/pkg/client/grpc/balancer" + "github.com/douyu/jupiter/pkg/client/grpc/resolver" + "github.com/douyu/jupiter/pkg/registry/etcdv3" + "github.com/douyu/jupiter/pkg/xlog" +) + +func main() { + eng := NewEngine() + if err := eng.Run(); err != nil { + xlog.Error(err.Error()) + } + fmt.Printf("111 = %+v\n", 111) +} + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.initResolver, + eng.consumer, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func (eng *Engine) initResolver() error { + resolver.Register("etcd", etcdv3.StdConfig("wh").Build()) + return nil +} + +func (eng *Engine) consumer() error { + config := grpc.StdConfig("etcdserver") + config.BalancerName = balancer.NameSmoothWeightRoundRobin + client := pb.NewHelloClient(config.Build()) + go func() { + i:=0 + ghj := map[string]int{} + for { + + i++ + resp, err := client.SayHello(context.Background(), &pb.SayHelloReq{ + Name: fmt.Sprintf("jupiter:%d",i), + }) + if err != nil { + fmt.Printf("err = %+v\n%s", err,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii") + xlog.Error(err.Error()) + } else { + ghj[resp.Resp] = ghj[resp.Resp] + 1 + fmt.Printf("resp.Message = %+v\n", ghj) + xlog.Info("receive response", xlog.String("resp", resp.Resp)) + } + time.Sleep(1 * time.Second) + } + }() + return nil +} + +``` + +minerva 客户端 demo +```go +# 配置 +[app] +[app.registry.etcd]# 使用etcd作为服务发现 +endpoints=["127.0.0.1:2379"] #etcd的地址,grpc的服务端须已经注册到这个etcd +timeout="2s" +[minerva] +[minerva.grpc] +[minerva.grpc.wsg-reg] # wsg-reg 这里得注意,这是服务端的前缀 +debug = true # Debug开关 +enableMetric = true # 指标采集开关 +enableAccessLog = true # 访问日志开关 +addr = "jupiter-demo" #目标地址。direct=true,该值设为服务ip:port, direct=false,则为服务注册名,其实就是执行文件名称,也就是应用名称 +dialTimeout = "1s" # 拨超时 +readTimeout = "1s" # 读超时 +enableTrace = false # 链路追踪开关 +balancerName = "round_robin" # 默认为round_robin +level = "panic" # 创建时的告警等级,level=panic创建Client失败时panic +wait = true # 默认:true 是否一直等待直到连接建立,wait=true时,dialTimeout失效。注意Wait可能会导致创建过程阻塞 +direct = false # 直连服务,不经过负载均衡器 +slowThreshold = "1s" # slow日志门限值 + + +package main + +import ( + "context" + "demomimi/pb" + "fmt" + "time" +) +import "git.xxxx.com/vega/minerva/client/gusty" +// 新建demo客户端 +var ( + DemoClient pb.HelloClient +) + +// 读取demo的grpc配置,并初始化 +func init() { + + DemoClient = pb.NewHelloClient(gusty.Invoker("wsg-reg")) +} + +func main() { + sdfg := map[string]int{} + for{ + resp,err:=SayHello() + if err !=nil{ + fmt.Println(err,"uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu") + continue + } + sdfg[resp.Resp] = sdfg[resp.Resp] + 1 + fmt.Println("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu",sdfg) + time.Sleep(time.Second * 1) + } + +} + + +// SayHello 调用该grpc的方法 +func SayHello() (*pb.SayHelloRes, error) { + ctx := context.Background() + ctx, grpcTimeOut := context.WithTimeout(ctx, 1*time.Second) + defer grpcTimeOut() + helloRes, err := DemoClient.SayHello( + ctx, + &pb.SayHelloReq{ + Name: fmt.Sprintf("word"), + }, + ) + if err != nil { + return &pb.SayHelloRes{}, err + } + return helloRes, nil +} +``` + +jupiter 服务端调用 +```go + +[jupiter.server.grpc] + port = 20102 +[jupiter.registry.wh] +connectTimeout = "1s" +endpoints=["127.0.0.1:2379"] +secure = false +prefix = "wsd-reg" # 这个前缀记得跟client保持一致 + + + +package main + +import ( + "context" + "fmt" + "github.com/douyu/jupiter" + compound_registry "github.com/douyu/jupiter/pkg/registry/compound" + etcdv3_registry "github.com/douyu/jupiter/pkg/registry/etcdv3" + "github.com/douyu/jupiter/pkg/server/xgrpc" + "github.com/douyu/jupiter/pkg/xlog" + "google.golang.org/grpc/examples/helloworld/helloworld" +) + +func main() { + eng := NewEngine() + eng.SetRegistry( + compound_registry.New( + etcdv3_registry.StdConfig("wh").Build(), + ), + ) + //eng.SetGovernor("0.0.0.0:0") + if err := eng.Run(); err != nil { + xlog.Error(err.Error()) + } +} + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.serveGRPC, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func (eng *Engine) serveGRPC() error { + fmt.Println("YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY") + server := xgrpc.StdConfig("grpc").Build() + helloworld.RegisterGreeterServer(server.Server, new(Greeter)) + return eng.Serve(server) +} + + +type Greeter struct { + server *xgrpc.Server +} +func (Greeter) SayHello(context context.Context, request *helloworld.HelloRequest) (*helloworld.HelloReply, error) { + sd := &helloworld.HelloReply{ + Message: "我是client_b", + } + fmt.Println(fmt.Sprintf("name:%s",request.Name)) + return sd,nil +} + + + +``` + +minerva 服务端 demo +```go +[app] +mode="local" +[app.registry] +[app.registry.etcd] +endPoints = ["127.0.0.1:2379"] +timeout = "2s" +[server.grpc] +port=9001 +name="demo" +[server.grpc.labels] +group = "default" # default: default +weight = "10" # default: 100 +enable = "true" # default: true + + + +package main + +import ( + "context" + "fmt" + "git.xxxx.com/vega/minerva" + "git.xxxx.com/vega/minerva/application" + "git.xxxx.com/vega/minerva/server" + "git.xxxx.com/vega/minerva/server/yell" + "mimi/pb" +) + +// 定义handler +type HelloHandler struct { + yell.Handler +} + + +// 定义方法 +func (s *HelloHandler) SayHello(ctx context.Context, in *pb.SayHelloReq) (out *pb.SayHelloRes, err error) { + fmt.Println(in.Name,"nnnnnnnn") + return &pb.SayHelloRes{Resp:"hello1"},nil +} + + +// 定义一个grpc server,应用微服务的理念,一个服务只能定义一个server +type GrpcServer struct { + *yell.Server +} + + +// 将HelloServer注册到server +func (s *GrpcServer) Mux() { + s.Register(pb.RegisterHelloServer, new(HelloHandler)) + // 这里可以继续注册其他的Handler +} + +// main函数中启动grpc server +func main() { + fmt.Println(application.BuildFlags()) + app := minerva.NewAPP() + app.Serve( + new(GrpcServer), + server.StdConfig("grpc"), + server.Host("127.0.0.1"), + ) + app.Run() +} + +``` + + + + + + + + diff --git a/website/docs/jupiter/3.3worker.md b/website/docs/jupiter/3.3worker.md new file mode 100644 index 0000000000..771266ca4f --- /dev/null +++ b/website/docs/jupiter/3.3worker.md @@ -0,0 +1,37 @@ +# 3.3 Worker + +## 3.3.1 Worker介绍 +Worker主要是用来执行一些需要在特定时间运行的业务逻辑。常见的使用场景,比如在后端服务定时同步数据。 + +## 3.3.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.4worker.html) + + +### 3.3.3 简单的Worker +参考[Worker示例](https://github.com/douyu/jupiter-examples/tree/main/worker/cron) + +配置项 +```toml +[jupiter.cron.test] + withSeconds = false + concurrentDelay= -1 + immediatelyRun = false +``` + +任务逻辑 +```go +func (eng *Engine) execJob() error { + xlog.Info("info job") + xlog.Warn("warn job") + return nil +} +``` + +设置任务 +```go +func (eng *Engine) startJobs() error { + cron := xcron.StdConfig("test").Build() + cron.Schedule(xcron.Every(time.Second*10), xcron.FuncJob(eng.execJob)) + return eng.Schedule(cron) +} +``` diff --git a/website/docs/jupiter/4.1clientetcd.md b/website/docs/jupiter/4.1clientetcd.md new file mode 100644 index 0000000000..2830eac9b3 --- /dev/null +++ b/website/docs/jupiter/4.1clientetcd.md @@ -0,0 +1,41 @@ +# 4.1 调用ETCD + +## 4.1.1 简介 +etcd/clientv3 包是用 go 实现的调用 ETCD 服务的客户端。 + +## 4.1.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.5clientetcd.html) + +```toml +[jupiter.etcdv3.myetcd] + endpoints = ["127.0.0.1:2379"] + connectTimeout = "10s" +``` + +## 4.1.3 用法 +[调用ETCD示例](https://github.com/douyu/jupiter-examples/tree/main/client/etcd) +```go +func main() { + client := etcdv3.StdConfig("myetcd").Build() + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) + defer cancel() + // 添加数据 + _, err := client.Put(ctx, "/hello", "jupiter") + if err != nil { + xlog.Panic(err.Error()) + } + + // 获取数据 + response, err := client.Get(ctx, "/hello", clientv3.WithPrefix()) + if err != nil { + xlog.Panic(err.Error()) + } + + xlog.Info("get etcd info",xlog.String("key",string(response.Kvs[0].Key)),xlog.String("value",string(response.Kvs[0].Value))) +} +``` +运行指令``go run main.go --config=config.toml``,可以得到以下结果 +![image](../static/jupiter/client-etcd.png) +按照``Jupiter``的ETCD格式写入配置,然后创建``ETCD``的客户端,就可以很方便的调用``ETCD``。 + diff --git a/website/docs/jupiter/4.2clientgrpc.md b/website/docs/jupiter/4.2clientgrpc.md new file mode 100644 index 0000000000..6084b34e90 --- /dev/null +++ b/website/docs/jupiter/4.2clientgrpc.md @@ -0,0 +1,16 @@ +# 4.2 调用gRPC +## 4.2.1 简介 + +## 4.2.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.6clientgrpc.html) + + +## 4.2.3 直连调用gRPC +[文档](http://jupiter.douyu.com/jupiter/3.2grpc.html#_3-2-2-1-%E5%90%AF%E5%8A%A8grpc%E6%9C%8D%E5%8A%A1) + +[用例](https://github.com/douyu/jupiter-examples/tree/main/grpc/direct/direct-client) + +## 4.2.4 通过ETCD调用gRPC +[文档](http://jupiter.douyu.com/jupiter/3.2grpc.html#_3-2-2-1-%E5%90%AF%E5%8A%A8grpc%E6%9C%8D%E5%8A%A1) + +[用例](https://github.com/douyu/jupiter-examples/tree/main/grpc/etcd/etcd-client) diff --git a/website/docs/jupiter/4.3clientgorm.md b/website/docs/jupiter/4.3clientgorm.md new file mode 100644 index 0000000000..51e6a2ad50 --- /dev/null +++ b/website/docs/jupiter/4.3clientgorm.md @@ -0,0 +1,40 @@ +# 4.3 调用Gorm +## 4.3.1 简介 + +## 4.3.2 配置 +[Gorm配置说明](http://jupiter.douyu.com/jupiter/6.7clientgorm.html) +```toml +[jupiter.mysql.test] + connMaxLifetime = "300s" + debug = true + dsn = "root:test@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local&readTimeout=1s&timeout=1s&writeTimeout=3s" + level = "panic" + maxIdleConns = 50 + maxOpenConns = 100 +``` + +## 4.3.3 用法 +```go +type User struct { + Id int `gorm:"not null" json:"id"` + Name string `gorm:"not null" json:"name"` +} + +func main() { + gormDB := gorm.StdConfig("test").Build() + models := []interface{}{ + &User{}, + } + gormDB.SingularTable(true) + gormDB.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(models...) + gormDB.Create(&User{ + Name: "jupiter", + }) + + var user User + gormDB.Where("id = 1").Find(&user) + xlog.Info("user info",xlog.String("name",user.Name)) +} +``` +运行指令``go run main.go --config=config.toml``,可以得到以下结果 +![image](../static/jupiter/client-gorm.png) diff --git a/website/docs/jupiter/4.4clientredis.md b/website/docs/jupiter/4.4clientredis.md new file mode 100644 index 0000000000..6cb4c1a119 --- /dev/null +++ b/website/docs/jupiter/4.4clientredis.md @@ -0,0 +1,65 @@ +# 4.4 调用Redis + +## 4.4.1 简介 +client/redis 包是对go-redis 进行二次封装,并提供redisStub和redisClusterStub +两种访问reids方式的客户端 + +## 4.4.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.8clientredis.html) + + +## 4.4.3 用法 +[访问redis示例](https://github.com/douyu/jupiter-examples/tree/main/client/redis) + +```go +// run: go run main.go --config=config.toml +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.exampleForRedisStub, + eng.exampleForRedisClusterStub, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func main() { + app := NewEngine() + if err := app.Run(); err != nil { + panic(err) + } +} + +func (eng *Engine) exampleForRedisStub() (err error) { + //build redisStub + redisStub := redis.StdRedisConfig("myredis").Build() + // set string + setRes := redisStub.Set("jupiter-redis", "redisStub", time.Second*5) + xlog.Info("redisStub set string", xlog.Any("res", setRes)) + // get string + getRes := redisStub.Get("jupiter-redis") + xlog.Info("redisStub get string", xlog.Any("res", getRes)) + return +} +func (eng *Engine) exampleForRedisClusterStub() (err error) { + //build redisClusterStub + redisStub := redis.StdRedisClusterConfig("myredis").Build() + // set string + setRes := redisStub.Set("jupiter-redisCluster", "redisClusterStub", time.Second*5) + xlog.Info("redisClusterStub set string", xlog.Any("res", setRes)) + // get string + getRes := redisStub.Get("jupiter-redisCluster") + xlog.Info("redisClusterStub get string", xlog.Any("res", getRes)) + return +} + +``` +执行 go run main.go --config=config.toml,可以看到如下图结果 +![image](../static/jupiter/client-redis.png) + + diff --git a/website/docs/jupiter/4.5mongodb.md b/website/docs/jupiter/4.5mongodb.md new file mode 100644 index 0000000000..901c4c3edd --- /dev/null +++ b/website/docs/jupiter/4.5mongodb.md @@ -0,0 +1,100 @@ +# 4.5 调用MongoDB + +## 4.5.1 简介 +store/mongox 包是对 `go.mongodb.org/mongo-driver/mongo` 进行二次封装。 + +## 4.5.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.9mongodb.html) + +## 4.5.3 用法 +[访问mongo示例](https://github.com/douyu/jupiter-examples/tree/main/store/mongox) + +```go +// run: go run main.go --config=config.toml + +package main + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/douyu/jupiter" + "github.com/douyu/jupiter/pkg/store/mongox" + "github.com/douyu/jupiter/pkg/xlog" + "go.mongodb.org/mongo-driver/mongo" + "gopkg.in/mgo.v2/bson" +) + +// run: go run main.go -config=config.toml +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.exampleMongo, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func main() { + app := NewEngine() + if err := app.Run(); err != nil { + panic(err) + } +} + +func (eng *Engine) exampleMongo() (err error) { + client := mongox.StdConfig("test").Build() + + write(client) + read(client) + + return +} + +func write(client *mongo.Client) { + collection := client.Database("test").Collection("test") + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + _, err := collection.InsertOne(ctx, bson.M{"rid": 888, "dateline": time.Now().Unix()}) + if err != nil { + panic(err) + } +} + +func read(client *mongo.Client) { + + collection := client.Database("test").Collection("test") + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + cur, err := collection.Find(ctx, bson.M{"rid": 888}) + if err != nil { + log.Fatal(err) + } + defer cur.Close(ctx) + for cur.Next(ctx) { + var result bson.M + err := cur.Decode(&result) + if err != nil { + xlog.Fatal("exampleMongo", xlog.Any("err", err.Error())) + } + fmt.Println("result...", result) + + // do something with result.... + } +} +``` +执行 go run main.go --config=config.toml,可以看到如下图结果 +![image](../static/jupiter/6.9mongodb.png) + + diff --git a/website/docs/jupiter/4.6rocketmq.md b/website/docs/jupiter/4.6rocketmq.md new file mode 100644 index 0000000000..5c47ba56ee --- /dev/null +++ b/website/docs/jupiter/4.6rocketmq.md @@ -0,0 +1,91 @@ +# 4.6 调用RocketMQ + +## 4.6.1 简介 +client/rocketmq 包是对github.com/apache/rocketmq-client-go/v2 进行二次封装 + +## 4.6.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.10rocketmq.html) + + +## 4.6.3 用法 +[访问rocketmq示例](https://github.com/douyu/jupiter-examples/tree/main/client/rocketmq) + +```go +// run: go run main.go --config=config.toml + +package main + +import ( + "context" + "fmt" + "strconv" + + "github.com/apache/rocketmq-client-go/v2/primitive" + "github.com/douyu/jupiter" + "github.com/douyu/jupiter/pkg/client/rocketmq" + "github.com/douyu/jupiter/pkg/xlog" +) + +// run: go run main.go -config=config.toml +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.exampleRocketMQProducer, + eng.exampleRocketMQConsumer, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func main() { + app := NewEngine() + if err := app.Run(); err != nil { + panic(err) + } +} + +func (eng *Engine) exampleRocketMQConsumer() (err error) { + consumerClient := rocketmq.StdPushConsumerConfig("configName").Build() + defer func() { + if consumerClient.Enable { + _ = consumerClient.Close() + } + }() + consumerClient.Subscribe(consumerClient.ConsumerConfig.Topic, func(ctx context.Context, ext *primitive.MessageExt) error { + fmt.Println("msg...", string(ext.Message.Body)) + fmt.Println("msg topic...", string(ext.Message.Topic)) + fmt.Println("msg topic tag...", string(ext.Message.GetTags())) + return nil + }) + err = consumerClient.Start() + return +} + +func (eng *Engine) exampleRocketMQProducer() (err error) { + producerClient := rocketmq.StdProducerConfig("configName").Build() + defer func() { + _ = producerClient.Close() + }() + + err = producerClient.Start() + if err != nil { + return + } + + for i := 0; i < 10; i++ { + msg := "a" + strconv.Itoa(i) + err = producerClient.Send([]byte(msg)) + } + return +} + +``` +执行 go run main.go --config=config.toml,可以看到如下图结果 +![image](../static/jupiter/6.10rocketmq.png) + + diff --git a/website/docs/jupiter/4.7sentinel.md b/website/docs/jupiter/4.7sentinel.md new file mode 100644 index 0000000000..970abf379c --- /dev/null +++ b/website/docs/jupiter/4.7sentinel.md @@ -0,0 +1,81 @@ +# 4.7 调用Sentinel + +## 4.7.1 简介 +对官方库的二次封装。 + +## 4.7.2 配置规范 +[配置说明](http://jupiter.douyu.com/jupiter/6.11sentinel.html) + + +## 4.7.3 用法 +[访问redis示例](https://github.com/douyu/jupiter-examples/tree/main/sentinel) + +```go +// run: go run main.go --config=config.toml + +package main + +import ( + "fmt" + "math/rand" + "time" + + "github.com/douyu/jupiter/pkg/util/xgo" + "github.com/douyu/jupiter" + "github.com/douyu/jupiter/pkg/sentinel" + "github.com/douyu/jupiter/pkg/util/xtime" + "github.com/douyu/jupiter/pkg/xlog" +) + +type Engine struct { + jupiter.Application +} + +func NewEngine() *Engine { + eng := &Engine{} + if err := eng.Startup( + eng.exampleSentinel, + ); err != nil { + xlog.Panic("startup", xlog.Any("err", err)) + } + return eng +} + +func main() { + app := NewEngine() + if err := app.Run(); err != nil { + panic(err) + } +} + +func (eng *Engine) exampleSentinel() (err error) { + err = sentinel.StdConfig("test").Build() + if err != nil { + panic(fmt.Sprintf("sentinel init failed: %s", err.Error())) + } + + for k := 0; k < 20; k++ { + xgo.Go(func() { + e, b := sentinel.Entry("some-test") + if b != nil { + // 请求被拒绝,在此处进行处理 + time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond) + } else { + // 请求允许通过,此处编写业务逻辑 + fmt.Println(xtime.CurrentTimeMillis(), "Passed") + time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond) + + // 务必保证业务结束后调用 Exit + e.Exit() + } + }) + } + + return +} + +``` +执行 go run main.go --config=config.toml,可以看到如下图结果 +![image](../static/jupiter/6.11sentinel.png) + + diff --git a/website/docs/jupiter/4.8trace.md b/website/docs/jupiter/4.8trace.md new file mode 100644 index 0000000000..a0db5b114e --- /dev/null +++ b/website/docs/jupiter/4.8trace.md @@ -0,0 +1,40 @@ +# 4.8 调用Trace + +## 4.8.1 环境准备 + +[jaeger参考文档](https://www.jaegertracing.io/docs/1.21/getting-started/) + + +本地测试需要安装jaegertracing,推荐直接使用docker方式启动。 +> docker pull jaegertracing/all-in-one + + +安装完成后访问 [http://localhost:16686/](http://localhost:16686/) 可以看到ui界面。 + +## 4.8.2 基本说明 +在服务启动的配置文件中加入如下配置后,jupiter 应用启动之后会开启 trace 功能。如果没有配置 LocalAgentHostPort 参数,应用会读取环境变量`JAEGER_AGENT_ADDR`。 +``` +[jupiter.trace.jaeger] +EnableRPCMetrics= true +[jupiter.trace.jaeger.Reporter] +LocalAgentHostPort = "127.0.0.1:6831" +LogSpans = true +[jupiter.trace.jaeger.Sampler] +Param = 0.0001 +``` +trace数据写入方式 + +```go +span, ctx := trace.StartSpanFromContext(ctx, "process1") +defer span.Finish() +``` + +## 4.8.2 使用方案 + +example地址 [https://github.com/douyu/jupiter-examples/tree/main/trace](https://github.com/douyu/jupiter-examples/tree/main/trace) + +## 4.8.3 实际效果 + +![](../static/jupiter/trace2.1.png) +![](../static/jupiter/trace2.2.png) + diff --git a/website/docs/jupiter/5.1governintro.md b/website/docs/jupiter/5.1governintro.md new file mode 100644 index 0000000000..75198a465d --- /dev/null +++ b/website/docs/jupiter/5.1governintro.md @@ -0,0 +1,19 @@ +# 5.1 概述 +## 5.1.1 服务治理接口 + +``Jupiter``内置如下的治理接口: + +| 路由 | 描述 | +|:--------------|:-----| +|`/routes`| 治理路由| +|`/debug/pprof/*`| pprof信息| +|`/buildInfo`| 项目编译信息 | +|`/moduleInfo`| 项目依赖的版本信息 | +|`/configs`| 配置信息 | +|`/status/code/list`| 状态码列表 | +|`/metrics`| 监控信息 | + + + + + diff --git a/website/docs/jupiter/6.10rocketmq.md b/website/docs/jupiter/6.10rocketmq.md new file mode 100644 index 0000000000..3b75514d49 --- /dev/null +++ b/website/docs/jupiter/6.10rocketmq.md @@ -0,0 +1,33 @@ +# 6.10 Client RocketMQ + +## 范式 +[参考地址](https://github.com/douyu/jupiter/blob/master/pkg/client/rocketmq/config.toml) +### RocketMQConfig +#### 配置项 +| 名称 | 类型 | 描述 | +| :------:| :------: | :------: | +|`configName` | string | 该mq配置名 | +|`enable` | bool | 是否开启 | +|`addr` | []string | 地址 | +|`group` | string | 消费组,默认为空 | +|`topic` | string | 消费topic,默认为空 | +|`subExpression` | string | 标签,默认为* | +|`rate` | int | 消费速率,默认为0,不限速 | +.... + +#### 示例 +```toml +[jupiter.rocketmq] +[jupiter.rocketmq.configName] +[jupiter.rocketmq.configName.consumer] +enable = true +addr = ["127.0.0.1:9876"] +group = "test_group" +topic = "test_topic" +subExpression = "*" +rate = 1 +[jupiter.rocketmq.configName.producer] +addr = ["127.0.0.1:9876"] +group = "test_group" +topic = "test_topic" +``` diff --git a/website/docs/jupiter/6.11sentinel.md b/website/docs/jupiter/6.11sentinel.md new file mode 100644 index 0000000000..ef64cfc053 --- /dev/null +++ b/website/docs/jupiter/6.11sentinel.md @@ -0,0 +1,28 @@ +# 6.11 Client Sentinel + +## 范式 +[参考地址](https://github.com/douyu/jupiter/blob/master/pkg/sentinel/config.toml) +### SentinelConfig +#### 配置项 +| 名称 | 类型 | 描述 | +| :------:| :------: | :------: | +| `appName` | string | 应用名称 | +| `logPath` | string | 日志路径 | +|`resource` | string | 资源名称 | +|`metricType` | int | 指标类型 | +|`count` | int | 并发次数限制 | +|`controlBehavior` | int | 操作类型 | +.... + +#### 示例 +```toml +[jupiter.sentinel] +[jupiter.sentinel.test] +appName="test-app" +logPath="/tmp/sentinel/log" +[[jupiter.sentinel.test.flowRules]] +resource="some-test" +metricType =1 # flow.QPS +count=10 +controlBehavior = 0 # flow.Reject +``` diff --git a/website/docs/jupiter/6.1logger.md b/website/docs/jupiter/6.1logger.md new file mode 100644 index 0000000000..0a183bf8b4 --- /dev/null +++ b/website/docs/jupiter/6.1logger.md @@ -0,0 +1,34 @@ +# 6.1 Logger + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/pkg/xlog/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`name`| string| 名称,默认``default.log`` | +|`dir`| string| 路径,默认``当前路径`` | +|`maxSize`| int | 日志轮转大小,单位MB,默认500MB | +|`maxAge`| int | 日志轮转最大时间,单位day,默认1 day| +|`maxBackup`| int | 日志轮转个数,默认10| +|`interval`| int | 日志轮转周期,默认24 hour| +|`callerSkip`| int | 默认1| +|`addCaller`| bool | 默认true| +|`debug`|bool|是否在命令行输出,默认false| +|`enableConsole`| bool | 启用命令行格式输出,默认false| +|`async`| bool | 是否异步采集日志,默认true| +|`queue`| bool | 默认false| +|`queueSleep`| time | 默认100ms| +|`level`| string | 待支持 | + + + +## 示例 +```toml +[jupiter.logger.default] + debug = false # 是否在命令行输出 + enableConsole = false # 是否按命令行格式输出 + name = "default.json" # 日志名称 + dir = "." # 日志路径 + async = true # 默认异步采集日志 + level = "info" # 调整日志级别,可以动态修改日志 +``` + diff --git a/website/docs/jupiter/6.2httpserver.md b/website/docs/jupiter/6.2httpserver.md new file mode 100644 index 0000000000..2ae474ce1b --- /dev/null +++ b/website/docs/jupiter/6.2httpserver.md @@ -0,0 +1,25 @@ +# 6.2 HTTP Server + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/server/xecho/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`host`| string| server的ip地址,默认``127.0.0.1`` | +|`port`| string| server的port地址 | +|`limitListener`| int | 最大监听goroutine数量,待支持| +|`slowThreshold`| time | 大于耗时,记录慢日志,待支持| +|`enableTrace`| bool | 是否开启链路,待支持| +|`enableAccess`| bool | 是否开启日志,待支持| +|`enableMetric`| bool | 是否开监控,待支持| + + +## 示例 +```toml +[jupiter.server.http] + host = "127.0.0.1" + port = 9091 +``` + + + + diff --git a/website/docs/jupiter/6.3grpcserver.md b/website/docs/jupiter/6.3grpcserver.md new file mode 100644 index 0000000000..a7ded11047 --- /dev/null +++ b/website/docs/jupiter/6.3grpcserver.md @@ -0,0 +1,21 @@ +# 6.3 gRPC Server + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/server/xgrpc/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`host`| string| server的ip地址,默认``127.0.0.1`` | +|`port`| string| server的port地址 | +|`network`| string| 网络协议,默认``tcp4`` | +|`enableTrace`| bool | 是否开启链路,待支持| +|`enableAccess`| bool | 是否开启日志,待支持| +|`enableMetric`| bool | 是否开监控,待支持| + + +## 示例 +```toml +[jupiter.server.grpc] + host = "127.0.0.1" + port = "9091" + network = "tcp4" +``` diff --git a/website/docs/jupiter/6.4worker.md b/website/docs/jupiter/6.4worker.md new file mode 100644 index 0000000000..a6290e6d21 --- /dev/null +++ b/website/docs/jupiter/6.4worker.md @@ -0,0 +1,22 @@ +# 6.4 Worker + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/worker/xcron/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`withSeconds`| bool | 是否使用, 默认值 false | +|`concurrentDelay`| int| 任务并发时是否延迟运行, 默认值 -1 | +|`immediatelyRun`| bool| 是否立即运行, 默认值 false| +|`enableTrace`| bool | 是否开启链路,待支持| +|`enableAccess`| bool | 是否开启日志,待支持| +|`enableMetric`| bool | 是否开监控,待支持| + + + +## 示例 +```toml +[jupiter.cron.test] + withSeconds = false + concurrentDelay= -1 + immediatelyRun = false +``` diff --git a/website/docs/jupiter/6.5clientetcd.md b/website/docs/jupiter/6.5clientetcd.md new file mode 100644 index 0000000000..bc03f6f898 --- /dev/null +++ b/website/docs/jupiter/6.5clientetcd.md @@ -0,0 +1,23 @@ +# 6.5 ETCD + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/client/etcd/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`endpoints`| []string| etcd连接地址 | +|`certFile`| string | 证书 | +|`keyFile`| string | 私钥 | +|`caCert`| string | 认证授权文件 | +|`basicAuth`| bool | 是否开启简单用户名/密码验证 | +|`userName`| string | 用户名 | +|`password`| string | 密码 | +|`connectTimeout`| time | 连接超时时间 | +|`secure`| bool | 是否开启与ETCD服务器证书验证,默认false| +|`autoAsyncInterval`| time | 自动同步etcd member list的间隔 | + +## 示例 +```toml +[jupiter.etcdv3.myetcd] + endpoints = ["127.0.0.1:2379"] + connectTimeout = "10s" +``` diff --git a/website/docs/jupiter/6.6clientgrpc.md b/website/docs/jupiter/6.6clientgrpc.md new file mode 100644 index 0000000000..3e0f2aa952 --- /dev/null +++ b/website/docs/jupiter/6.6clientgrpc.md @@ -0,0 +1,23 @@ +# 6.6 Client grpc + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/client/grpc/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`address`| string| 调用地址 | +|`balancerName`| string | 负载均衡算法 | +|`block`| bool | 是否阻塞,默认false | +|`dialTimeout`| time | 连接超时时间、默认0s,不超时| + +## 示例 +```toml +[jupiter.registry.wh] + connectTimeout = "1s" + endpoints=["127.0.0.1:2379"] + secure = false +[jupiter.client.appname] + address = "etcd:///main" + balancerName = "round_robin" # 默认值 + block = false # 默认值 + dialTimeout = "0s" # 默认值 +``` diff --git a/website/docs/jupiter/6.7clientgorm.md b/website/docs/jupiter/6.7clientgorm.md new file mode 100644 index 0000000000..fe979c2468 --- /dev/null +++ b/website/docs/jupiter/6.7clientgorm.md @@ -0,0 +1,25 @@ +# 6.7 Client gorm + +## 范式 +[参考地址](https://github.com/douyu/jupiter/tree/master/client/gorm/config.go) +| 名称 | 类型 | 描述 | +|:--------------|:-----|:-------------------| +|`dsn`| string| 数据库地址 | +|`debug`| bool | 是否debug | +|`maxIdleConns`| int | 最大空闲连接数 | +|`MaxOpenConns`| int | 最大活动连接数 | +|`connMaxLifetime`| time |连接的最大存活时间| +|`level`| string | 创建连接的错误级别,=panic时,如果创建失败,立即panic | +|`slowThreshold`| time | 慢日志阈值| +|`dialTimeout`| time | 拨超时时间| + +## 示例 +```toml +[jupiter.mysql.test] + connMaxLifetime = "300s" + debug = true + dsn = "root:test@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local&readTimeout=1s&timeout=1s&writeTimeout=3s" + level = "panic" + maxIdleConns = 50 + maxOpenConns = 100 +``` diff --git a/website/docs/jupiter/6.8clientredis.md b/website/docs/jupiter/6.8clientredis.md new file mode 100644 index 0000000000..624039a605 --- /dev/null +++ b/website/docs/jupiter/6.8clientredis.md @@ -0,0 +1,54 @@ +# 6.8 Client redis + +## 范式 +[参考地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/config.go) +### RedisConfig +#### 配置项 +| 名称 | 类型 | 描述 | +| :------:| :------: | :------: | +| `addr` | string | 连接地址 | +| `password` | string | 密码 | +|`db` | int | 默认为0, 一般应用不推荐使用DB分片 | +|`poolSize` | int | 集群内每个节点的最大连接池限制 默认每个CPU10个连接 | +|`maxRetries` | int | 网络相关的错误最大重试次数 默认8次 | +|`minIdleConns` | int | 最小空闲连接数 | +|`dialTimeout` | time.Duration | 拨超时时间 | +|`readTimeout` | time.Duration | 读超时 默认3s | +|`writeTimeout` | time.Duration | 写超时 默认3s | +|`idleTimeout` | int | 连接最大空闲时间,默认60s, 超过该时间,连接会被主动关闭 | +|`debug` | bool | 是否开启debug | +|`idleTimeout` | int | 连接最大空闲时间,默认60s, 超过该时间,连接会被主动关闭 | +.... + +#### 示例 +```toml +[jupiter.redis.myredis.stub] + addr = "ip:port" + password = "xxxxxxxx" +``` + +### RedisClusterConfig +#### 配置项 +| 名称 | 类型 | 描述 | +| :------:| :------: | :------: | +| `addrs` | []string | 连接地址 | +| `password` | string | 密码 | +|`db` | int | 默认为0, 一般应用不推荐使用DB分片 | +|`poolSize` | int | 集群内每个节点的最大连接池限制 默认每个CPU10个连接 | +|`maxRetries` | int | 网络相关的错误最大重试次数 默认8次 | +|`minIdleConns` | int | 最小空闲连接数 | +|`dialTimeout` | time.Duration | 拨超时时间 | +|`readTimeout` | time.Duration | 读超时 默认3s | +|`writeTimeout` | time.Duration | 写超时 默认3s | +|`idleTimeout` | int | 连接最大空闲时间,默认60s, 超过该时间,连接会被主动关闭 | +|`debug` | bool | 是否开启debug | +|`idleTimeout` | int | 连接最大空闲时间,默认60s, 超过该时间,连接会被主动关闭 | +|`readOnly` | bool | 集群模式 在从属节点上启用读模式 | +.... + +#### 示例 +```toml +[jupiter.redis.myredis.cluster] + addrs =["ip:port","ip:port","ip:port"] + password = "xxxxxxxx" +``` diff --git a/website/docs/jupiter/6.9mongodb.md b/website/docs/jupiter/6.9mongodb.md new file mode 100644 index 0000000000..6d30d5ee38 --- /dev/null +++ b/website/docs/jupiter/6.9mongodb.md @@ -0,0 +1,22 @@ +# 6.9 Store Mongo + +## 范式 +[参考地址](https://github.com/douyu/jupiter/blob/master/example/store/mongo/config.toml) +### Mongo +#### 配置项 +| 名称 | 类型 | 描述 | +| :------:| :------: | :------: | +| `dsn` | string | 连接串 | +| `socketTimeout` | string | 超时时间 | +|`poolLimit` | int |资源池限制 | +.... + +#### 示例 +```toml +[jupiter.mongo] +[jupiter.mongo.test] +dsn="mongodb://xxx:xxx@xxx.xxx.xxx.xxx:27027/admin?replicaSet=live" +socketTimeout="3s" +poolLimit=5 +``` + diff --git a/website/docs/jupiter/7.1autologger.md b/website/docs/jupiter/7.1autologger.md new file mode 100644 index 0000000000..dfbccdae62 --- /dev/null +++ b/website/docs/jupiter/7.1autologger.md @@ -0,0 +1,76 @@ +# 7.1 收敛错误 + +日志错误可以通过[程序自动生成](https://github.com/douyu/jupiter/tree/master/tools/ast_codes) + + + +## pkg/client/etcdv3 +| 错误 | 级别 | 行数 | +|:--------------|:-----|:-------------------| +| handle watch update | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/watch.go#L49)| +| handle watch block | Warn|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/watch.go#L57)| +| client etcd endpoints empty | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/client.go#L58)| +| parse CaCert failed | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/client.go#L78)| +| load CertFile or KeyFile failed | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/client.go#L93)| +| client etcd start panic | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/client.go#L106)| +| client etcd parse config panic | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/config.go#L64)| +| dial etcd server | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/etcdv3/client.go#L114)| + + +## pkg/client/grpc +| 错误 | 级别 | 行数 | +|:--------------|:-----|:-------------------| +| start grpc client | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/grpc/client.go#L58)| +| client grpc parse config panic | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/grpc/config.go#L65)| +| dial grpc server | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/grpc/client.go#L53)| +| dial grpc server | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/grpc/client.go#L55)| + + +## pkg/client/redis +| 错误 | 级别 | 行数 | +|:--------------|:-----|:-------------------| +| start cluster redis | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/cluster.go#L50)| +| start redis | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/redis.go#L47)| +| addr empty stub config | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/config.go#L110)| +| cluster addr empty stub config | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/config.go#L133)| +| start cluster redis | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/cluster.go#L52)| +| start redis | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/client/redis/redis.go#L49)| + + +## pkg/server/xecho +| 错误 | 级别 | 行数 | +|:--------------|:-----|:-------------------| +| http server parse config panic | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/server/xecho/config.go#L55)| +| echo add route | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/server/xecho/server.go#L50)| + + +## pkg/server/xgrpc +| 错误 | 级别 | 行数 | +|:--------------|:-----|:-------------------| +| grpc server parse config panic | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/server/xgrpc/config.go#L48)| +| new grpc server err | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/server/xgrpc/server.go#L46)| +| grpc server recover | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/pkg/server/xgrpc/interceptor.go#L119)| + + +## jupiter.go +| 错误 | 级别 | 行数 | +|:--------------|:-----|:-------------------| +| leaving jupiter, bye.... | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L221)| +| start governor | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L225)| +| start servers | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L243)| +| exit server | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L244)| +| load remote config | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L319)| +| load local file | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L326)| +| auto max procs | Info|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L356)| +| start governor | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L228)| +| load remote config | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L317)| +| load local file | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L324)| +| auto max procs | Panic|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L352)| +| no config ... | Warn|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L309)| +| stop register close err | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L172)| +| stop governor close err | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L176)| +| graceful stop register close err | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L198)| +| graceful stop governor close err | Error|[代码地址](https://github.com/douyu/jupiter/blob/master/jupiter.go#L202)| + + + diff --git a/website/docs/jupiter/README.md b/website/docs/jupiter/README.md new file mode 100644 index 0000000000..c8986417ca --- /dev/null +++ b/website/docs/jupiter/README.md @@ -0,0 +1,137 @@ +# Jupiter 介绍 + +[![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/) +[![goproxy.cn](https://goproxy.cn/stats/github.com/douyu/jupiter/badges/download-count.svg)](https://github.com/douyu/jupiter) +[![Build Status](https://travis-ci.org/douyu/jupiter.svg?branch=master)](https://travis-ci.org/douyu/jupiter) +[![codecov](https://codecov.io/gh/douyu/jupiter/branch/master/graph/badge.svg)](https://codecov.io/gh/douyu/jupiter) +[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/douyu/jupiter?tab=doc) +[![Go Report Card](https://goreportcard.com/badge/github.com/douyu/jupiter)](https://goreportcard.com/report/github.com/douyu/jupiter) +![license](https://img.shields.io/badge/license-Apache--2.0-green.svg) + +Jupiter 是斗鱼开源的一套微服务治理框架,提供丰富的后台功能,管理应用的资源、配置,应用的性能、配置等可视化。 + +> Jupiter 是罗马神话的众神之神,在天界掌管诸神,在互联网掌管所有微服务! + +## 架构图 + +![image](../static/jupiter/arch.png) + +## 目标 + +我们致力于将 Go 微服务框架标准化,统一错误码、日志、监控、注册、流控的 Schema。将微服务的各个模块可观测、可治理,管理微服务研发侧的全套生命周期。 + +## 功能点 + +- gRPC:基于官方 gRPC 开发,集成流控和多数据中心方式的服务注册,支持多种 roundrobin,p2c 等负载均衡策略; +- 配置:使用 toml、yaml 方式管理配置,规范化核心配置,结合远程配置中心,实现配置版本管理和更新,查看配置依赖关系; +- 日志:基于 zap 日志类库,实现高性能日志库,并对不同环境和条件,实现日志库的自动降级,并对服务端,客户端的慢日志通过配置条件,实现全部慢日志接入; +- 监控:基于 prometheus go sdk 类库,实现对服务端,客户端的数据监控,并与 prometheus、confd、etcd 数据打通,实现应用自动化数据采集; +- 数据库:基于 gorm 的封装,将数据库的 trace,慢日志,监控进行了采集; +- 缓存:基于 go-redis 的封装,将数据库的 trace,慢日志,监控进行了采集,并实现了单个 redis、多从库 redis,客户端 redis 分片,服务端 redis 分片的 api; +- 系统错误码:区分框架和业务的错误码,将框架错误码文档自动生成,自动化的错误码 SRE 分析工具; +- 工程化:基于服务标准、创建、开发、运行、治理等生命周期,完成了`Jupiter`对项目的工程化; +- 服务治理:基于监控,etcd,配置中心,对服务实现了良好的可观测性,可控制性; + +## 快速开始 + +要求 Go version>=1.16 and GO111MODULE=on + +## 安装 + +```bash +GOPROXY=https://goproxy.cn/,direct go install github.com/douyu/jupiter/cmd/jupiter@latest +cd /path/to/workspace +jupiter new jupiter-demo +``` + +## 理念 + +### 工程化 + +目前大部分框架侧重点大部分在协议和编解码,过度的关注于技术细节,框架在投入生产环节会带来一堆工程问题。 + +因此我们`Jupiter`瞄准于企业级的工程化方案,将服务的标准、创建、开发、运行、治理整个生命周期作为`Jupiter`的一部分,以工程效率、工程质量、工程可靠性等为指标,解决了公司大量的工程化问题,降低了研发人员的开发成本。 + +- 制定标准:制定了服务的配置、链路、监控、header 头等标准; +- 脚手架:能够通过命令行,实现服务的创建,升级等功能; +- 配套设施:实现程序的开发,ci,运行,治理,提升工程效率,质量,可靠性; + +工程化的管理使得我们可以保质保量的对项目进行开发,这种理念正是现在业界所缺少的。 + +### 服务治理 + +衡量一个框架的好坏,除了提供高性能 RPC 通信以外,还要包括提供优质的服务治理能力。 + +我们`Jupiter`经历了多个版本的迭代以后,目前的服务治理能力在业界内是非常出色的。 + +- 更完善的服务监控,从服务指标上,我们依据 Google SRE 文档制定监控指标(延迟、流量、错误和饱和度),并对各个指标进行了服务监控;从应用维度上,我们能够看到应用实例监控、应用大盘监控、全部应用大盘监控、各种不同指标的 top 榜,实时监测服务质量。 +- 更有价值的错误报警。我们对服务进行了错误收敛,规范系统错误码和业务错误码,并且能够自动生成对应的错误码文档,当错误发生时,我们通过文档就能准确找到错误的位置,提升错误排查速度。 +- 更全面的服务控制。我们利用配置中心和 etcd,将服务做到可控制性。 +- 更全面的 SOP。我们通过全链路压测、混沌工程等方式,提前解决掉系统中可能存在的严重问题,做好 SOP 手册,这样当问题真正来临的时候,我们才会从容处理。 + +### 拥抱变化 + +Web 开发和运维技术在不断的发展,短短几年已涌现出了非常多的计算形态,如云计算、边缘计算、容器化、网格化、Serverless 等。服务保障技术方面,异地多活、混沌工程也在不断发展。 + +语言栈方面,很多公司也在从早期单一的 PHP、Java 栈扩大到多语言栈并存的局面,特别是近年来 Golang 因在容器化和运维效率上的优势,越来越多的被应用到 Web 服务开发。但每次技术迭代,享受效率提升的同时,也在不断经历应用改造和迁移的痛苦。 + +以斗鱼为例,从 2016 年底我们开始改造基础设施,启动应用服务化建设。短短三年就经历了公有云、异地多活、容器化部署等阶段,目前也在部分业务中探索边缘计算和 Serverless 等新的计算形态。2017 年开始,我们将语言栈从单一的 PHP 扩展为以 Golang、Java、PHP 为主的多语言栈,随之而来的是多 RPC 协议的混战,http1.1、dubbo、gRPC、私有 RPC 协议纷繁冗杂,联调效率极低。经过一段时间的迭代,目前已基本统一为外部调用以 http1.1 为主、内部调用以 gRPC 为主,减少自定义 RPC 协议的使用。 + +从 Golang 应用的角度来看,面临的是一个在不断变化的运行环境和持续丰富的外部环境,这将不断的产生新的问题,比如: + +1. 容器化有 IP 漂移的问题,传统基于 IP 的服务注册和运维方式需要作出改变。 +2. Serverless 的服务监控问题,指标采集以及链路追踪等如何适配? +3. Service Mesh 相对于传统部署方式,服务注册和发现的方式有很大变化。 +4. 多机房部署中,跨机房调用这种’弱网环境‘ 对服务超时、重试、熔断、负载均衡等可用性策略有更高要求。 + +不同于传统 RPC 框架和微服务治理框架,`Jupiter`从一开始就以应用为中心,定位为一个微服务应用的运行时。在历次技术架构,如: + +- 多机房建设 +- 公有化 +- 容器化 + +中,`Jupiter`有效的降低了应用迁移和升级的成本,期间也积累了许多架构经验。未来也必将在 + +- Service Mesh +- Serverless + +等计算形态中,发挥重要的作用。 + +### 提升开发效率 + +开发效率是基础框架和类库的核心关注点之一,`Jupiter`从一开始就挑选和使用了大量开源类库,但也因此带来了若干问题: + +- 开源类库质量参差不齐。如果不加约束的引用开源类库,类库的缺陷就会不受限的在组织内传导,修复的成本非常高。 +- 许多类库并未遵守版本规范,这将会产生兼容性问题,影响开发效率。 +- 许多功能都有多个类库可供选择,不加约束将增加维护和沟通成本,也带来了一定地风险。 +- 不同类库代码风格差异大,有一定沟通成本 +- 不同类库使用的错误处理和错误码、日志、指标采集、对 Debug 模式的支持不尽相同,这既影响开发效率,也影响服务治理。 + +基于上述原因,我们在基础框架和类库中,对主要应用场景常用的类库都增加了一层封装,尽量减少对第三方类库的直接使用。封装的方法有: + +- 利用 Golang 在语言层面上的一些机制进行简易封装: +- type alias: type T = package2.T +- variable binding: var Func = package2.Func +- 统一 New 方法,以简化创建过程,并达到配置驱动的效果 +- 通过 type embedding 扩展类库功能,为第三方库扩展如动态配置、指标收集、链路追踪、统一日志、统一错误码等治理能力。 +- 通过 interface 抽象限制调用行为。对于未稳定的类库,可以采用这种方式限制用户的调用行为,以便将来进行完善和替换。 + +基于以上方法,`Jupiter`既提高了开发效率,也有效的降低了开发风险。 + +同时,`Jupiter`为封装的第三方类库和自研类库提供了统一的治理能力,包括: + +- 统一的指标采集 +- 链路追踪 +- 日志埋点 +- 统一错误处理 +- 动态配置 +- 安全策略 +- Debug 模式 + 等,可以极大的提高应用开发效率。 + +## 总结 + +Web 后台技术在设计、开发、部署、运维各个阶段都在快速发展,微服务应用架构方法、运行环境和治理环境也都在不断变化。 +基础框架作为沟通业务逻辑和运行环境、治理环境的媒介,是稳定业务的重要手段。 + +`Jupiter`服务于整体技术架构,并紧随业界技术趋势,三年我们对`Jupiter`的研发,其具有超出同行很多优秀的特性,详情请见后文。 diff --git a/website/docs/static/agent/configdown1.png b/website/docs/static/agent/configdown1.png new file mode 100644 index 0000000000..d6e67f82a4 Binary files /dev/null and b/website/docs/static/agent/configdown1.png differ diff --git a/website/docs/static/join/join1.jpg b/website/docs/static/join/join1.jpg new file mode 100644 index 0000000000..99ce4b4b5e Binary files /dev/null and b/website/docs/static/join/join1.jpg differ diff --git a/website/docs/static/join/jupiter-join-dingding.jpg b/website/docs/static/join/jupiter-join-dingding.jpg new file mode 100644 index 0000000000..333f64bea3 Binary files /dev/null and b/website/docs/static/join/jupiter-join-dingding.jpg differ diff --git a/website/docs/static/join/jupiter-join-wechat.png b/website/docs/static/join/jupiter-join-wechat.png new file mode 100644 index 0000000000..451356f796 Binary files /dev/null and b/website/docs/static/join/jupiter-join-wechat.png differ diff --git a/website/docs/static/juno/14.1-1.png b/website/docs/static/juno/14.1-1.png new file mode 100644 index 0000000000..dee1f18962 Binary files /dev/null and b/website/docs/static/juno/14.1-1.png differ diff --git a/website/docs/static/juno/14.1-2.png b/website/docs/static/juno/14.1-2.png new file mode 100644 index 0000000000..0d6f77091b Binary files /dev/null and b/website/docs/static/juno/14.1-2.png differ diff --git a/website/docs/static/juno/7.1-1.png b/website/docs/static/juno/7.1-1.png new file mode 100644 index 0000000000..7c20a627ee Binary files /dev/null and b/website/docs/static/juno/7.1-1.png differ diff --git a/website/docs/static/juno/7.1-2.png b/website/docs/static/juno/7.1-2.png new file mode 100644 index 0000000000..b1878b820b Binary files /dev/null and b/website/docs/static/juno/7.1-2.png differ diff --git a/website/docs/static/juno/7.1-3.png b/website/docs/static/juno/7.1-3.png new file mode 100644 index 0000000000..2e5c0438ec Binary files /dev/null and b/website/docs/static/juno/7.1-3.png differ diff --git a/website/docs/static/juno/7.1-4.png b/website/docs/static/juno/7.1-4.png new file mode 100644 index 0000000000..d54486e226 Binary files /dev/null and b/website/docs/static/juno/7.1-4.png differ diff --git a/website/docs/static/juno/7.2-1.png b/website/docs/static/juno/7.2-1.png new file mode 100644 index 0000000000..f83813e6a3 Binary files /dev/null and b/website/docs/static/juno/7.2-1.png differ diff --git a/website/docs/static/juno/9.1.1-1.png b/website/docs/static/juno/9.1.1-1.png new file mode 100644 index 0000000000..dba7562b21 Binary files /dev/null and b/website/docs/static/juno/9.1.1-1.png differ diff --git a/website/docs/static/juno/9.1.2-1.png b/website/docs/static/juno/9.1.2-1.png new file mode 100644 index 0000000000..13bda58578 Binary files /dev/null and b/website/docs/static/juno/9.1.2-1.png differ diff --git a/website/docs/static/juno/9.1.3-1.png b/website/docs/static/juno/9.1.3-1.png new file mode 100644 index 0000000000..aab1623251 Binary files /dev/null and b/website/docs/static/juno/9.1.3-1.png differ diff --git a/website/docs/static/juno/9.1.3-2.png b/website/docs/static/juno/9.1.3-2.png new file mode 100644 index 0000000000..e8938ef89d Binary files /dev/null and b/website/docs/static/juno/9.1.3-2.png differ diff --git a/website/docs/static/juno/9.1.3-3.png b/website/docs/static/juno/9.1.3-3.png new file mode 100644 index 0000000000..23c21f9b3e Binary files /dev/null and b/website/docs/static/juno/9.1.3-3.png differ diff --git a/website/docs/static/juno/9.1.3-4.png b/website/docs/static/juno/9.1.3-4.png new file mode 100644 index 0000000000..3514a8a257 Binary files /dev/null and b/website/docs/static/juno/9.1.3-4.png differ diff --git a/website/docs/static/juno/config3.1.1.png b/website/docs/static/juno/config3.1.1.png new file mode 100644 index 0000000000..080390a21d Binary files /dev/null and b/website/docs/static/juno/config3.1.1.png differ diff --git a/website/docs/static/juno/config3.1.2.png b/website/docs/static/juno/config3.1.2.png new file mode 100644 index 0000000000..29425ebc9c Binary files /dev/null and b/website/docs/static/juno/config3.1.2.png differ diff --git a/website/docs/static/juno/config3.1.3.png b/website/docs/static/juno/config3.1.3.png new file mode 100644 index 0000000000..1417fe6666 Binary files /dev/null and b/website/docs/static/juno/config3.1.3.png differ diff --git a/website/docs/static/juno/config3.3.1.png b/website/docs/static/juno/config3.3.1.png new file mode 100644 index 0000000000..f8dfcbc225 Binary files /dev/null and b/website/docs/static/juno/config3.3.1.png differ diff --git a/website/docs/static/juno/config3.3.2.png b/website/docs/static/juno/config3.3.2.png new file mode 100644 index 0000000000..f1463f334f Binary files /dev/null and b/website/docs/static/juno/config3.3.2.png differ diff --git a/website/docs/static/juno/config3.3.3.png b/website/docs/static/juno/config3.3.3.png new file mode 100644 index 0000000000..2c8ae21a3c Binary files /dev/null and b/website/docs/static/juno/config3.3.3.png differ diff --git a/website/docs/static/juno/config3.4.1.png b/website/docs/static/juno/config3.4.1.png new file mode 100644 index 0000000000..3b0c050ab2 Binary files /dev/null and b/website/docs/static/juno/config3.4.1.png differ diff --git a/website/docs/static/juno/config3.4.2.png b/website/docs/static/juno/config3.4.2.png new file mode 100644 index 0000000000..780940d187 Binary files /dev/null and b/website/docs/static/juno/config3.4.2.png differ diff --git a/website/docs/static/juno/config3.4.3.png b/website/docs/static/juno/config3.4.3.png new file mode 100644 index 0000000000..7a0fab2a66 Binary files /dev/null and b/website/docs/static/juno/config3.4.3.png differ diff --git a/website/docs/static/juno/config3.4.4.png b/website/docs/static/juno/config3.4.4.png new file mode 100644 index 0000000000..7080adc324 Binary files /dev/null and b/website/docs/static/juno/config3.4.4.png differ diff --git a/website/docs/static/juno/config3.4.5.png b/website/docs/static/juno/config3.4.5.png new file mode 100644 index 0000000000..b7ad1b715e Binary files /dev/null and b/website/docs/static/juno/config3.4.5.png differ diff --git a/website/docs/static/juno/config3.4.6.png b/website/docs/static/juno/config3.4.6.png new file mode 100644 index 0000000000..6d15980848 Binary files /dev/null and b/website/docs/static/juno/config3.4.6.png differ diff --git a/website/docs/static/juno/config3.4.7.png b/website/docs/static/juno/config3.4.7.png new file mode 100644 index 0000000000..fc5bb62a5d Binary files /dev/null and b/website/docs/static/juno/config3.4.7.png differ diff --git a/website/docs/static/juno/image-20200904151850462.png b/website/docs/static/juno/image-20200904151850462.png new file mode 100644 index 0000000000..8440c1cdcb Binary files /dev/null and b/website/docs/static/juno/image-20200904151850462.png differ diff --git a/website/docs/static/juno/monitor-5.1-aaaa.png b/website/docs/static/juno/monitor-5.1-aaaa.png new file mode 100644 index 0000000000..b0a0a65ecc Binary files /dev/null and b/website/docs/static/juno/monitor-5.1-aaaa.png differ diff --git a/website/docs/static/juno/monitor-5.1-aaaaaaaaaaaaaaa.png b/website/docs/static/juno/monitor-5.1-aaaaaaaaaaaaaaa.png new file mode 100644 index 0000000000..6a63f867c0 Binary files /dev/null and b/website/docs/static/juno/monitor-5.1-aaaaaaaaaaaaaaa.png differ diff --git a/website/docs/static/juno/monitor-5.1-x123xdasdas.png b/website/docs/static/juno/monitor-5.1-x123xdasdas.png new file mode 100644 index 0000000000..cd471c6d1e Binary files /dev/null and b/website/docs/static/juno/monitor-5.1-x123xdasdas.png differ diff --git a/website/docs/static/juno/monitor-5.1.5.1.png b/website/docs/static/juno/monitor-5.1.5.1.png new file mode 100644 index 0000000000..785915e2d7 Binary files /dev/null and b/website/docs/static/juno/monitor-5.1.5.1.png differ diff --git a/website/docs/static/juno/monitor-5.1.5.2.png b/website/docs/static/juno/monitor-5.1.5.2.png new file mode 100644 index 0000000000..b756f4d3bf Binary files /dev/null and b/website/docs/static/juno/monitor-5.1.5.2.png differ diff --git a/website/docs/static/juno/monitor-5.1.5.3.png b/website/docs/static/juno/monitor-5.1.5.3.png new file mode 100644 index 0000000000..0b52d12421 Binary files /dev/null and b/website/docs/static/juno/monitor-5.1.5.3.png differ diff --git a/website/docs/static/juno/pprof1.1.png b/website/docs/static/juno/pprof1.1.png new file mode 100644 index 0000000000..d00eddf9d1 Binary files /dev/null and b/website/docs/static/juno/pprof1.1.png differ diff --git a/website/docs/static/juno/pprof1.2.png b/website/docs/static/juno/pprof1.2.png new file mode 100644 index 0000000000..515a09c5b7 Binary files /dev/null and b/website/docs/static/juno/pprof1.2.png differ diff --git a/website/docs/static/juno/pprof2.1.png b/website/docs/static/juno/pprof2.1.png new file mode 100644 index 0000000000..a23da9915f Binary files /dev/null and b/website/docs/static/juno/pprof2.1.png differ diff --git a/website/docs/static/juno/pprof2.2.png b/website/docs/static/juno/pprof2.2.png new file mode 100644 index 0000000000..7813963962 Binary files /dev/null and b/website/docs/static/juno/pprof2.2.png differ diff --git a/website/docs/static/juno/pprof3.1.png b/website/docs/static/juno/pprof3.1.png new file mode 100644 index 0000000000..732ea181ee Binary files /dev/null and b/website/docs/static/juno/pprof3.1.png differ diff --git a/website/docs/static/juno/pprof3.2.png b/website/docs/static/juno/pprof3.2.png new file mode 100644 index 0000000000..a4cc09e31a Binary files /dev/null and b/website/docs/static/juno/pprof3.2.png differ diff --git a/website/docs/static/juno/pprof4.1.png b/website/docs/static/juno/pprof4.1.png new file mode 100644 index 0000000000..c4ffeb6de6 Binary files /dev/null and b/website/docs/static/juno/pprof4.1.png differ diff --git a/website/docs/static/juno/pprof5.1.png b/website/docs/static/juno/pprof5.1.png new file mode 100644 index 0000000000..c55fd938c1 Binary files /dev/null and b/website/docs/static/juno/pprof5.1.png differ diff --git a/website/docs/static/juno/pprof5.2.png b/website/docs/static/juno/pprof5.2.png new file mode 100644 index 0000000000..e89560a831 Binary files /dev/null and b/website/docs/static/juno/pprof5.2.png differ diff --git a/website/docs/static/juno/pprof6.1.png b/website/docs/static/juno/pprof6.1.png new file mode 100644 index 0000000000..6fe3762dec Binary files /dev/null and b/website/docs/static/juno/pprof6.1.png differ diff --git a/website/docs/static/juno/pprof6.2.png b/website/docs/static/juno/pprof6.2.png new file mode 100644 index 0000000000..5ced080218 Binary files /dev/null and b/website/docs/static/juno/pprof6.2.png differ diff --git a/website/docs/static/jupiter/6.10rocketmq.png b/website/docs/static/jupiter/6.10rocketmq.png new file mode 100644 index 0000000000..606d654de7 Binary files /dev/null and b/website/docs/static/jupiter/6.10rocketmq.png differ diff --git a/website/docs/static/jupiter/6.11sentinel.png b/website/docs/static/jupiter/6.11sentinel.png new file mode 100644 index 0000000000..08a0b854a9 Binary files /dev/null and b/website/docs/static/jupiter/6.11sentinel.png differ diff --git a/website/docs/static/jupiter/6.9mongodb.png b/website/docs/static/jupiter/6.9mongodb.png new file mode 100644 index 0000000000..3d5606bd0d Binary files /dev/null and b/website/docs/static/jupiter/6.9mongodb.png differ diff --git a/website/docs/static/jupiter/access_token_create_1.png b/website/docs/static/jupiter/access_token_create_1.png new file mode 100644 index 0000000000..eec6c10d6f Binary files /dev/null and b/website/docs/static/jupiter/access_token_create_1.png differ diff --git a/website/docs/static/jupiter/access_token_create_2.png b/website/docs/static/jupiter/access_token_create_2.png new file mode 100644 index 0000000000..ee810a4a11 Binary files /dev/null and b/website/docs/static/jupiter/access_token_create_2.png differ diff --git a/website/docs/static/jupiter/access_token_create_3.png b/website/docs/static/jupiter/access_token_create_3.png new file mode 100644 index 0000000000..2b47df571b Binary files /dev/null and b/website/docs/static/jupiter/access_token_create_3.png differ diff --git a/website/docs/static/jupiter/arch.png b/website/docs/static/jupiter/arch.png new file mode 100644 index 0000000000..1f41d313d0 Binary files /dev/null and b/website/docs/static/jupiter/arch.png differ diff --git a/website/docs/static/jupiter/client-etcd.png b/website/docs/static/jupiter/client-etcd.png new file mode 100644 index 0000000000..45911e6c41 Binary files /dev/null and b/website/docs/static/jupiter/client-etcd.png differ diff --git a/website/docs/static/jupiter/client-gorm.png b/website/docs/static/jupiter/client-gorm.png new file mode 100644 index 0000000000..b5d4fdf262 Binary files /dev/null and b/website/docs/static/jupiter/client-gorm.png differ diff --git a/website/docs/static/jupiter/client-redis.png b/website/docs/static/jupiter/client-redis.png new file mode 100644 index 0000000000..ff27690957 Binary files /dev/null and b/website/docs/static/jupiter/client-redis.png differ diff --git a/website/docs/static/jupiter/dashboard1.png b/website/docs/static/jupiter/dashboard1.png new file mode 100644 index 0000000000..de44387153 Binary files /dev/null and b/website/docs/static/jupiter/dashboard1.png differ diff --git a/website/docs/static/jupiter/dashboard2.png b/website/docs/static/jupiter/dashboard2.png new file mode 100644 index 0000000000..34955835b7 Binary files /dev/null and b/website/docs/static/jupiter/dashboard2.png differ diff --git a/website/docs/static/jupiter/grpc-direct-client.png b/website/docs/static/jupiter/grpc-direct-client.png new file mode 100644 index 0000000000..35bed4977b Binary files /dev/null and b/website/docs/static/jupiter/grpc-direct-client.png differ diff --git a/website/docs/static/jupiter/grpc-direct-server.png b/website/docs/static/jupiter/grpc-direct-server.png new file mode 100644 index 0000000000..ef8b3e3fff Binary files /dev/null and b/website/docs/static/jupiter/grpc-direct-server.png differ diff --git a/website/docs/static/jupiter/grpc-etcd-client.png b/website/docs/static/jupiter/grpc-etcd-client.png new file mode 100644 index 0000000000..d92c0168d4 Binary files /dev/null and b/website/docs/static/jupiter/grpc-etcd-client.png differ diff --git a/website/docs/static/jupiter/grpc-etcd-server.png b/website/docs/static/jupiter/grpc-etcd-server.png new file mode 100644 index 0000000000..c08276b37d Binary files /dev/null and b/website/docs/static/jupiter/grpc-etcd-server.png differ diff --git a/website/docs/static/jupiter/grpctest-bindapp-1.png b/website/docs/static/jupiter/grpctest-bindapp-1.png new file mode 100644 index 0000000000..b123e7a7aa Binary files /dev/null and b/website/docs/static/jupiter/grpctest-bindapp-1.png differ diff --git a/website/docs/static/jupiter/grpctest-bindapp-2.png b/website/docs/static/jupiter/grpctest-bindapp-2.png new file mode 100644 index 0000000000..150f78cc7a Binary files /dev/null and b/website/docs/static/jupiter/grpctest-bindapp-2.png differ diff --git a/website/docs/static/jupiter/grpctest-usage.png b/website/docs/static/jupiter/grpctest-usage.png new file mode 100644 index 0000000000..28b9b26768 Binary files /dev/null and b/website/docs/static/jupiter/grpctest-usage.png differ diff --git a/website/docs/static/jupiter/helloworld.png b/website/docs/static/jupiter/helloworld.png new file mode 100644 index 0000000000..e10f8f5dbd Binary files /dev/null and b/website/docs/static/jupiter/helloworld.png differ diff --git a/website/docs/static/jupiter/httptest-url.png b/website/docs/static/jupiter/httptest-url.png new file mode 100644 index 0000000000..5bdb0ce4be Binary files /dev/null and b/website/docs/static/jupiter/httptest-url.png differ diff --git a/website/docs/static/jupiter/httptest-usage.png b/website/docs/static/jupiter/httptest-usage.png new file mode 100644 index 0000000000..7d48d06da0 Binary files /dev/null and b/website/docs/static/jupiter/httptest-usage.png differ diff --git a/website/docs/static/jupiter/logger-command.png b/website/docs/static/jupiter/logger-command.png new file mode 100644 index 0000000000..0f1f733924 Binary files /dev/null and b/website/docs/static/jupiter/logger-command.png differ diff --git a/website/docs/static/jupiter/trace2.1.png b/website/docs/static/jupiter/trace2.1.png new file mode 100644 index 0000000000..1ad2c7f781 Binary files /dev/null and b/website/docs/static/jupiter/trace2.1.png differ diff --git a/website/docs/static/jupiter/trace2.2.png b/website/docs/static/jupiter/trace2.2.png new file mode 100644 index 0000000000..33da02dd0d Binary files /dev/null and b/website/docs/static/jupiter/trace2.2.png differ diff --git a/website/docs/static/logo.png b/website/docs/static/logo.png new file mode 100644 index 0000000000..c88482cabb Binary files /dev/null and b/website/docs/static/logo.png differ diff --git a/website/docs/static/minerva/grpcserver1.png b/website/docs/static/minerva/grpcserver1.png new file mode 100644 index 0000000000..48467ec16b Binary files /dev/null and b/website/docs/static/minerva/grpcserver1.png differ diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000000..9888b72f3e --- /dev/null +++ b/website/package.json @@ -0,0 +1,27 @@ +{ + "name": "jupiter-website", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "docs:dev": "vuepress dev docs", + "docs:build": "vuepress build docs" + }, + "repository": { + "type": "git", + "url": "git@github.com:douyu/jupiter.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@vuepress/plugin-active-header-links": "^1.2.0", + "@vuepress/plugin-back-to-top": "^1.2.0", + "@vuepress/plugin-medium-zoom": "^1.2.0", + "@vuepress/plugin-nprogress": "^1.2.0", + "@vuepress/plugin-pwa": "^1.2.0", + "moment": "^2.24.0", + "vuepress": "^1.8.0" + } +} \ No newline at end of file