Graphite 之把它装起来

Graphite 是一款时序数据库

初步安装

安装 Graphite 有 n 种方法,在下选用的是 pip 安装的方式,使用默认安装位置 /opt/graphite

十分简单,只需要分别安装三个组件 graphite-webwhispercarbon

1
2
3
4
$ export PYTHONPATH="/opt/graphite/lib/:/opt/graphite/webapp/"
$ pip3 install --no-binary=:all: https://github.com/graphite-project/whisper/tarball/master
$ pip3 install --no-binary=:all: https://github.com/graphite-project/carbon/tarball/master
$ pip3 install --no-binary=:all: https://github.com/graphite-project/graphite-web/tarball/master

如果你希望自己指定安装位置:Installing From Pip

安装过程中可能出现的问题

1
$ pip3 install --no-binary=:all: https://github.com/graphite-project/graphite-web/tarball/master

在执行第三条语句的时候

duang!!!

distutils.errors.CompileError: command ‘x86_64-linux-gnu-gcc’ failed with exit status 1

……

distutils.errors.DistutilsError: Setup script exited with error: command ‘x86_64-linux-gnu-gcc’ failed with exit status 1

执行下面语句方可药到病除

1
$ sudo apt-get install libpq-dev python-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev libffi-dev

初始化配置

修改 webapp 元数据库

Django 元数据默认存储在 SQLite 中,但为了更好的扩展性,在下把它放到 mysql 中

If running multiple Graphite-web instances, a database such as PostgreSQL or MySQL is required so that all instances may share the same data source.

为 Graphite 添加数据库账号

1
2
3
mysql> create database graphite;
mysql> grant all on graphitedb.* to 'graphite'@'%' identified by 'graphitepass';
mysql> grant all on graphitedb.* to 'graphite'@'localhost' identified by 'graphitepass';

添加(修改)database 配置

1
2
3
$ cd /opt/graphite/webapp/graphite
$ cp local_settings.py.example local_settings.py
$ vi local_settings.py

数据库配置的格式可参考 django 文档

1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'NAME': 'graphite',
'ENGINE': 'django.db.backends.mysql',
'USER': 'graphite',
'PASSWORD': 'graphitepass',
'HOST': 'localhost',
'PORT': '3306'
}
}

记得提前建库

重新初始化元数据

修改了数据库配置之后,需要在 Mysql 中重新初始化元数据

1
PYTHONPATH=$GRAPHITE_ROOT/webapp django-admin.py migrate --settings=graphite.settings --run-syncdb

注意:需将 $GRAPHITE_ROOT 替换为你的安装位置,如果是默认安装则为 /opt/graphite

开始配置 Webapp

为了让服务器达到高可用、高性能,我们选用 nginx + wsgi,官方提供了三种方案

  • nginx + gunicorn
  • Apache + mod_wsgi
  • Nginx + uWSGI

此处我们选用第一个方案 nginx + gunicorn

使用这套组合只是为了让 python 下的 web 服务更加健壮,nginx 负责负载均衡、缓存请求等功能,而 gunicorn 负责接收来自 nginx 的动态请求,处理后返回给 nginx,再由 nginx 返回给用户。

安装 Gunicorn

1
$ pip3 install gunicorn

安装 Nginx

1
$ sudo apt install nginx

为 Graphite 配置特定的日志文件

1
2
3
4
$ sudo touch /var/log/nginx/graphite.access.log
$ sudo touch /var/log/nginx/graphite.error.log
$ sudo chmod 640 /var/log/nginx/graphite.*
$ sudo chown user:user /var/log/nginx/graphite.*

定制 Graphite 配置文件

vi /etc/nginx/sites-available/graphite

内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
upstream graphite {
server 127.0.0.1:8080 fail_timeout=0;
}

server {
listen 80;

server_name 127.0.0.1;

root /opt/graphite/webapp;

access_log /var/log/nginx/graphite.access.log;
error_log /var/log/nginx/graphite.error.log;

location = /favicon.ico {
return 204;
}

location /static/ {
alias /opt/graphite/static/;
}

location / {
try_files $uri @graphite;
}

location @graphite {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://graphite;
}
}

部分配置需要按部署策略修改,例如 server_nameroot

启用配置文件

1
2
3
4
$ sudo ln -s /etc/nginx/sites-available/graphite /etc/nginx/sites-enabled
$ sudo rm -f /etc/nginx/sites-enabled/default

$ sudo service nginx reload

启动 Graphite

1
$ PYTHONPATH=/opt/graphite/webapp gunicorn wsgi --workers=4 --bind=127.0.0.1:8080 --log-file=/var/log/gunicorn.log --preload --pythonpath=/opt/graphite/webapp/graphite &

上面的命令会让 graphite 启动在 localhost:8080 ,记录日志在 /var/log/gunicorn.log ,并且使用 /opt/graphite/webapp/graphite 座位 webapp 的路径。

由于我们已经在 nginx 中绑定了 8080 端口,所以进入这个地址就 ok 了:127.0.0.1

其他

修改 Graphite 时区

如果你需要将时区切到北京时间来

1
2
3
$ vi /opt/graphite/webapp/graphite/local_settings.py

TIME_ZONE = 'Asia/Shanghai'

配置过程中可能出现的问题

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.

给python3 装上MySQL

1
pip3 install mysqlclient

小声 bb:mysqlclient 查询比 pymysql 快

进入 graphite web 界面却看见一片空白

两种情况

没有找到 static 目录

注意观察控制台(后台运行则看输出的日志),是否输出类似信息

1
2
3
4
5
6
7
8
9
10
11
12
13
Not Found: /static/img/graphite-logo.png
Not Found: /static/js/ext/adapter/ext/ext-base-debug.js
Not Found: /static/js/ext/resources/css/ext-all.css
Not Found: /static/js/browser.js
Not Found: /static/js/ext/ext-all-debug.js
Not Found: /static/js/composer_widgets.js
Not Found: /static/js/composer.js
Not Found: /static/js/completer.js
Not Found: /static/img/carbon-fiber.png
Not Found: /static/js/browser.js
Not Found: /static/js/composer_widgets.js
Not Found: /static/js/composer.js
Not Found: /static/js/completer.js

如果是,则为寻找不到静态文件

执行下面的命令,注意替换 $GRAPHITE_ROOT 为 graphite 的目录,默认为 /opt/graphite

1
$ PYTHONPATH=$GRAPHITE_ROOT/webapp django-admin.py collectstatic --noinput --settings=graphite.settings

然后在编辑 nginx 配置,并增加如下配置

vi /etc/nginx/sites-available/graphite

1
2
3
location /static/ {
alias /opt/graphite/static/;
}

注意:上面的修改只有在 nginx 的转发下才可寻找到 static 目录,若不想通过 nginx 访问,参阅下面的文档

关于 static 目录,官方文档给出了解释:Filesystem Paths

试试打开 debug 模式

1
2
3
4
5
$ cd /opt/graphite/webapp/graphite
$ vi local_settings.py

# 将 DEBUG 设为 True
DEBUG = True

不明白为啥的同学,可以参考这个 issue:Static Folder Cannot Found