Git基本概念及工作流介绍

未分类

git介绍

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Torvalds 开始着手开发 Git 来替代 BitKeeper,后者之前一直是 Linux 内核开发人员在全球使用的主要源代码工具。尽管最初 Git 的开发是为了辅助 Linux 内核开发的过程,但是我们已经发现在很多其他自由软件项目中也使用了 Git。例如 很多 Freedesktop 的项目迁移到了 Git 上。

Git基础

Git首先需要掌握的概念

  • 工作区:就是在电脑里能看到的目录
  • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库,版本库里面存了很多东西,其中最重要的就是暂存区(stage或index),Git为我们自动创建的第一个分支master,以及指向master分支的一个指针叫做HEAD
  • 远程库(中央仓库)

结构如下所示:

未分类

工作区内修改的代码提交到远程库需要三步:

  • git add把代码文件添加到暂存区
  • git commit把暂存区的内容提交到当前分支
  • git push把代码推到远程库

Git工作流

掌握工作流能更好的实现团队间通过远程库进行协作。

中心化的工作流

中心化的工作流需要远程库存在一个master分支即可

未分类

A和B同时对项目修改,A和B的本地都有了各自的历史,A先提交代码到远程库,不会发生问题,B再提交的时候就会产生冲突
远程库在这里作为中央仓库代表官方项目,因此它的提交历史应该被视作神圣不可更改的。如果开发者的本地提交和中央仓库分叉,Git会拒绝将他们的修改推送上去,因为这会覆盖官方提交
冲突解决办法:先将代码拉到本地,再执行rebase操作

完整命令

git pull --rebase origin master

合并过程如有冲突,需手动进行修改,可以用git status查看当前工作区状态
合并完成后

git push origin master

Feature分支的工作流

未分类

团队成员在不同的分支上修改不同功能,等待功能模块完成后再合并到主分支。隔离功能开发后,通过pull request合并代码,也可以和其他成员沟通,其他成员对代码查看和提问。

我们项目组中使用这种工作流

GitFlow工作流

GitFlow工作流围绕项目发布定义了一个严格的分支模型,方便管理大型项目。和功能分支相比,这种工作流没有增加任何新的概念或命令。除了功能分支之外,它还为准备发布、维护发布、记录发布分别是用了单独的分支。
它有两个分支来记录项目历史。master分支存储官方发布历史,develop分支整合功能分支,这两个分支不直接交互。
开发分支:如果develop分支的新功能足够发布,可以从develop分支fork一个发布分支,只有和发布相关的任务应该在这个分支进行,如修复bug、生成文档等。完成发布后,发布分支合并会master和develop分支

维护分支,通常有以下约定:

  • 从develop创建
  • 合并进master分支
  • 命名规范release-*

Fork工作流

未分类

Fork工作流与其他工作流不同的是,每个开发者都有一个远程代码库和本地代码库,Fork工作流的主要优点在于贡献可以轻易地整合进项目,而不需要每个人都推送到单一的远程库,开发者将代码推到个人仓库后在告知中央仓库需要合并代码
项目管理员执行合并操作时可以有两步:

直接检查PullRequest中检查代码
将代码拉取到本地仓库然后手动合并

以上对Git使用做了大致总结,欢迎补充。

鲁大师问:Git最常用和最不常用的5个命令分别是什么?
我答:
最常用的

git status
git log --oneline
git commit
git fetch
git merge

最不常用的

git pull
git add
git rebase
git clone
git reflog

CentOS编译安装zabbix 3.2.7

修改/usr/local/apache/
修改php.ini 文件

[root@localhost zabbix-3.2.7]# groupadd zabbix

[root@localhost zabbix-3.2.7]# useradd -g zabbix zabbix
yum安装 net-snmp,net-snmp-devel,mysql(mariadb),mysql-devel(mariadb-devel),curl,curl-devel

进入zabbix安装目录

./configure --prefix=/usr/local/zabbix --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2
make 
make install
systemctl start mariadb
mysql
create database zabbix character set utf8 collate utf8_bin;
grant all privileges on zabbix.* to zabbix@localhost identified by '123456';
---------------------
如果有如下报错
# MariaDB [(none)]> grant all on zabbix.* to zabbix@localhost identified by ‘123456‘;
#ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your #MariaDB server version for the right syntax to use near '‘123456‘' at line 1
修改‘’为英文状态
----------------------
flush privileges;
exit;
mkdir -p /usr/local/apache/htdocs/zabbix

[root@localhost zabbix-3.2.7]# cp -ra frontends/php/* /usr/local/apache/htdocs/zabbix

进入数据库文件目录,将相关数据导入数据库

[root@localhost mysql]# pwd
/usr/src/zabbix-3.2.7/database/mysql
root@localhost mysql]# mysql -uzabbix -p123456 zabbix < schema.sql 
[root@localhost mysql]# mysql -uzabbix -p123456 zabbix < images.sql
[root@localhost mysql]# mysql -uzabbix -p123456 zabbix < data.sql
chown zabbix:zabbix /usr/local/apache/htdocs/zabbix


cp /usr/local/zabbix/sbin/zabbix_server /etc/init.d/

编辑/usr/local/zabbix/etc/zabbix_server.conf

修改DBHost=localhost DBName=zabbix DBUser=zabbix DBPssword=123456

报错:PHP bcmath extension missing (PHP configuration parameter --enable-bcmath).
进入php安装目录 /usr/src/php-7.1.7/ext/bcmath
执行/usr/src/php-7.1.7/ext/bcmath
[root@localhost bcmath]# ./configure --with-php-config=/usr/local/php7/bin/php-config
[root@localhost bcmath]# make  &  make install
Installing shared extensions:     /usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/
[root@localhost bcmath]# cd /usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/

[root@localhost php7]# cp /usr/local/php7/lib/php/extensions/no-debug-non-zts-20160303/bcmath.so /usr/local/php7/include/php/ext(这是默认路径,php.ini中可定义)

修改php.ini ,最后一行加

extension=bcmath.so

重启httpd zabbix服务

docker部署zabbix监控系统(nginx mysql)

本次使用docker搭建zabbix的组合是mysql+docker+zabix-server

1. 先安装数据库mysql

docker run --name zabbix-mysql-server --hostname zabbix-mysql-server 
-e MYSQL_ROOT_PASSWORD="123456" 
-e MYSQL_USER="zabbix" 
-e MYSQL_PASSWORD="123456" 
-e MYSQL_DATABASE="zabbix" 
-p 3306:3306  
-d 
mysql

2. 创建zabbix-server

docker run  --name zabbix-server-mysql --hostname zabbix-server-mysql 
--link zabbix-mysql-server:mysql 
-e DB_SERVER_HOST="mysql" 
-e MYSQL_USER="zabbix" 
-e MYSQL_DATABASE="zabbix" 
-e MYSQL_PASSWORD="123456" 
-v /etc/localtime:/etc/localtime:ro 
-v /data/docker/zabbix/alertscripts:/usr/lib/zabbix/alertscripts 
-v /data/docker/zabbix/externalscripts:/usr/lib/zabbix/externalscripts 
-p 10051:10051 
-d 
zabbix/zabbix-server-mysql

3. 最后web-nginx

最后安装zabbix-web-nginx
docker run --name zabbix-web-nginx-mysql --hostname zabbix-web-nginx-mysql 
--link zabbix-mysql-server:mysql 
--link zabbix-server-mysql:zabbix-server 
-e DB_SERVER_HOST="mysql" 
-e MYSQL_USER="zabbix" 
-e MYSQL_PASSWORD="123456" 
-e MYSQL_DATABASE="zabbix" 
-e ZBX_SERVER_HOST="zabbix-server" 
-e PHP_TZ="Asia/Shanghai" 
-p 8000:80 
-p 8443:443 
-d 
zabbix/zabbix-web-nginx-mysql

登录访问测试

浏览器访问ip:8000查看
默认登录
username:Admin
password:zabbix

这里说明下,mysql没做数据卷的映射,nginx也没做数据卷的映射,在实际生产环境下,最好做数据映射。防止数据丢失。

docker-zabbbix-agent的安装以及链接zabbix-server

docker run --name zabbix-agent --link zabbix-server-mysql:zabbix-server -d zabbix/zabbix-agent:latest

最后需要在web端将,zabbix-agent添加到zabbix-server的host列表里面。

监控

zabbix主动发现并监控磁盘IO性能

一. 基本概念

1. 读/写IO

最为常见说法,读IO,就是发指令,从磁盘读取某段扇区的内容。指令一般是通知磁盘开始扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区个数,同时给出动作是读,还是写。磁盘收到这条指令,就会按照指令的要求,读或者写数据。控制器发出的这种指令+数据,就是一次IO,读或者写。

2. 大/小块IO

指控制器的指令中给出的连续读取扇区数目的多少,如果数目很大,比如128,64等等,就应该算是大块IO,如果很小,比如1, 4,8等等,就应该算是小块IO,大块和小块之间,没有明确的界限。

3. 连续/随机IO

连续和随机,是指本次IO给出的初始扇区地址,和上一次IO的结束扇区地址,是不是完全连续的,或者相隔不多的,如果是,则本次IO应该算是一个连续IO,如果相差太大,则算一次随机IO。连续IO,因为本次初始扇区和上次结束扇区相隔很近,则磁头几乎不用换道或换道时间极短;如果相差太大,则磁头需要很长的换道时间,如果随机IO很多,导致磁头不停换道,效率大大降底。

4. 顺序/并发IO

这个的意思是,磁盘控制器每一次对磁盘组发出的指令套(指完成一个事物所需要的指令或者数据),是一条还是多条。如果是一条,则控制器缓存中的IO队列,只能一个一个的来,此时是顺序IO;如果控制器可以同时对磁盘组中的多块磁盘,同时发出指令套,则每次就可以执行多个IO,此时就是并发IO模式。并发IO模式提高了效率和速度。

5. IO并发几率

单盘,IO并发几率为0,因为一块磁盘同时只可以进行一次IO。对于raid0,2块盘情况下,条带深度比较大的时候(条带太小不能并发IO,下面会讲到),并发2个IO的几率为1/2。其他情况请自行运算。

6. IOPS

即每秒进行读写(I/O)操作的次数,一个IO所用的时间=寻道时间+数据传输时间。 IOPS=IO并发系数/(寻道时间+数据传输时间),由于寻道时间相对传输时间,大几个数量级,所以影响IOPS的关键因素,就是降底寻道时间,而在连续IO的情况下,寻道时间很短,仅在换磁道时候需要寻道。在这个前提下,传输时间越少,IOPS就越高。

7. 每秒IO吞吐量

显然,每秒IO吞吐量=IOPS乘以平均IO SIZE。 Io size越大,IOPS越高,每秒IO吞吐量就越高。

8. 设磁头每秒读写数据速度为V,V为定值

则IOPS=IO并发系数/(寻道时间+IO SIZE/V),代入,得每秒IO吞吐量=IO并发系数乘IO SIZE乘V/(V乘寻道时间+IO SIZE)。我们可以看出影响每秒IO吞吐量的最大因素,就是IO SIZE和寻道时间,IO SIZE越大,寻道时间越小,吞吐量越高。相比能显著影响IOPS的因素,只有一个,就是寻道时间。

二. 监控磁盘IO的基本原理:通过分析/proc/diskstats文件,来对IO的性能进行监控。

1. 第一至第三个域

分别是主设备号,次设备号,设备名称

2. 第4个域

读完成次数 —– 读磁盘的次数,成功完成读的总次数。(number of issued reads. This is the total number of reads completed successfully.)

3. 第5个域

合并读完成次数, 第9个域:合并写完成次数。为了效率可能会合并相邻的读和写。从而两次4K的读在它最终被处理到磁盘上之前可能会变成一次8K的读,才被计数(和排队),因此只有一次I/O操作。这个域使你知道这样的操作有多频繁。(number of reads merged)

4. 第6个域

读扇区的次数,成功读过的扇区总次数。(number of sectors read. This is the total number of sectors read successfully.)

5. 第7个域

读花费的毫秒数,这是所有读操作所花费的毫秒数(用__make_request()到end_that_request_last()测量)。(number of milliseconds spent reading. This is the total number of milliseconds spent by all reads (as measured from __make_request() to end_that_request_last()).)

6. 第8个域

写完成次数 —-写完成的次数,成功写完成的总次数。(number of writes completed. This is the total number of writes completed successfully.)

7. 第9个域

合并写完成次数 —–合并写次数。(number of writes merged Reads and writes which are adjacent to each other may be merged for efficiency. Thus two 4K reads may become one 8K read before it is ultimately handed to the disk, and so it will be counted (and queued) as only one I/O. This field lets you know how often this was done.)

8. 第10个域

写扇区次数 —- 写扇区的次数,成功写扇区总次数。(number of sectors written. This is the total number of sectors written successfully.)

9. 第11个域

写操作花费的毫秒数 — 写花费的毫秒数,这是所有写操作所花费的毫秒数(用__make_request()到end_that_request_last()测量)。(number of milliseconds spent writing This is the total number of milliseconds spent by all writes (as measured from __make_request() to end_that_request_last()).)

10. 第12个域

正在处理的输入/输出请求数 — -I/O的当前进度,只有这个域应该是0。当请求被交给适当的request_queue_t时增加和请求完成时减小。(number of I/Os currently in progress. The only field that should go to zero. Incremented as requests are given to appropriate request_queue_t and decremented as they finish.)

11. 第13个域

输入/输出操作花费的毫秒数 —-花在I/O操作上的毫秒数,这个域会增长只要field 9不为0。(number of milliseconds spent doing I/Os. This field is increased so long as field 9 is nonzero.)

12. 第14个域

输入/输出操作花费的加权毫秒数 —– 加权, 花在I/O操作上的毫秒数,在每次I/O开始,I/O结束,I/O合并时这个域都会增加。这可以给I/O完成时间和存储那些可以累积的提供一个便利的测量标准。(number of milliseconds spent doing I/Os. This field is incremented at each I/O start, I/O completion, I/O merge, or read of these stats by the number of I/Os in progress (field 9) times the number of milliseconds spent doing I/O since the last update of this field. This can provide an easy measure of both I/O completion time and the backlog that may be accumulating.)

三. zabbix监控主动发现磁盘并监控其吞吐量与iops

1. 监控内容的json化脚本partition_low_discovery.sh

#!/bin/bash
# Author: guoxiangfu
# Email: [email protected]
#script name:partition_low_discovery.sh
#Fucation:zabbix low-level discovery
partition() {
            port=($(grep -E "(vd[a-z]$|sd[a-z]$)" /proc/partitions|awk '{print $4}'))
            printf '{n'
            printf 't"data":[n'
               for key in ${!port[@]}
                   do
                       if [[ "${#port[@]}" -gt 1 && "${key}" -ne "$((${#port[@]}-1))" ]];then
                          printf 't {n'
                          printf "ttt"{#PARTITIONNAME}":"${port[${key}]}"},n"
                     else [[ "${key}" -eq "((${#port[@]}-1))" ]]
                          printf 't {n'
                          printf "ttt"{#PARTITIONNAME}":"${port[${key}]}"}n"
                       fi
               done
                          printf 't ]n'
                          printf '}n'
}
$1

把此文件存放到scripts里,然后给与755权限,并修改用户与组为zabbix

2. 可运行脚本检测是否能成功运行,运行的结果类似如下:

监控

3. 同时允许zabbix用户无密码运行netstat

echo "zabbix ALL=(root) NOPASSWD:/bin/netstat">>/etc/sudoers
#Disable requiretty
sed -i 's/^Defaults.*.requiretty/#Defaults    requiretty/' /etc/sudoers

四. 修改zabbix_agentd配置

1. 在zabbix_agentd.conf中添加以下内容

#monitor process
UserParameter=process.nginx.memory,/etc/zabbix/scripts/processstatus.sh nginx
UserParameter=process.nginx.cpu,/etc/zabbix/scripts/processstatus.sh nginxcpu
UserParameter=custom.vfs.dev.read.ms[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$7}'
UserParameter=custom.vfs.dev.write.ops[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$8}'
UserParameter=custom.vfs.dev.write.ms[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$11}'
UserParameter=custom.vfs.dev.io.active[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$12}'
UserParameter=custom.vfs.dev.io.ms[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$13}'
UserParameter=custom.vfs.dev.read.sectors[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$6}'
UserParameter=custom.vfs.dev.write.sectors[*],cat /proc/diskstats | grep $1 | head -1 | awk '{print $$10}'
UserParameter=zabbix_partition_discovery[*],/bin/bash /etc/zabbix/scripts/partition_low_discovery.sh $1

2. 重启zabbix服务

/etc/init.d/zabbix-agent restart

五. 主机关联模板

1. 导入监控模板文件,

下载Template_partition_Auto_Discovery:
https://www.guoxiangfu.com/zb_users/upload/2017/07/201707141500004488508687.zip

1.1 导入模板

监控

监控

1.2 关联zabbix客户端主机

监控

监控

监控

2. 因为要监控特有的分区

需要使用zabbix正则表达式过滤,管理->一般->右侧下来条选择“正则表达式”->创建

3. 正则表达式:

名称:Partition regex
表达式:^(vda|vdb|vdc|vdd|vde|vdf|vdg|sda|sdb|sdc|sdd|sde|sdf|sdg|xvda|xvdb|xvdc|xvdd|xvde|xvdf|
xvdg|xvdh|xvdi|xvdj|xvdk|xvdq|xvdl)$
期望的结果:结果为真

监控

监控

监控

3.1 打开主机监控的图形

监控

Zabbix 3.2.6配置ODBC监控MySQL和Oracle

一、总览

ODBC的监控和在Zabbix前端配置数据库监控条目类型基本一致。

ODBC是用C语言编写的用于连接数据库管理系统的一个中间件,最初有微软公司研发,后来发展到各大平台。

有了ODBC的支持,Zabbix可以查询很多种数据库,因为Zabbix自己不直接去连接数据库,而是通过ODBC的接口和驱动,因此可以更加高效的去监控不同的数据库。

二、安装配置

1、编译Zabbix server

要支持ODBC功能,在编译的时候需要加上--with-unixodbc,解决依赖需要安装如下软件包,
yum -y install unixODBC unixODBC-devel

2、安装unixODBC驱动

驱动是用于ODBC连接数据库用的,他可以支持各式各样的驱动,在大部分的Linux发行版中的仓库中,都有这些驱动,我们安装一个MySQL的驱动,用来监控MySQL数据库。
yum install mysql-connector-odbc

3、配置unixODBC

ODBC的配置主要是通过修改odbcinst.ini和odbc.ini两个文件,可以通过下面的命令去指定配置文件的位置。

# odbcinst -j
unixODBC 2.2.14
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

odbcinst.ini主要是配置安装的ODBC数据库驱动,如MySQL,oracle,各字段含义我不再介绍。

[MySQL]                      # 驱动名称,在数据库文件中需要
Description     = ODBC for MySQL
Driver          = /usr/lib/libmyodbc5.so
Setup           = /usr/lib/libodbcmyS.so
Driver64        = /usr/lib64/libmyodbc5.so
Setup64         = /usr/lib64/libodbcmyS.so
FileUsage       = 1

odbc.ini主要是配置数据源。

[test]                        # 数据源名称Data source name,在zabbix前端配置需要
Description = MySQL test database
Driver      = mysql           # 从驱动文件odbcinst.ini获取
Server      = 127.0.0.1
User        = zabbix
Password    = zabbix
Port        = 3306
Database    = zabbix

我们可以通过在安装unixODBC的时候附带安装的一个命令isql来判断我们是否可以成功的连接数据库。

# isql test
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

4、配置Zabbix前端web

首先创建一个监控条目。

监控

这几个条目是必填的,具体解释如下:

  • Type 这里我们选择Database monitor
  • Key 选择db.odbc.select[unique_description,data_source_name]
    unique_description将会用于触发器中的条目
    data_source_name填写在odbc.ini中的test
  • User name 输入在odbc.ini中的用户名
  • Password 输入在odbc.ini中的密码
  • SQL query 输入SQL查询语句
  • Type of information 需要我们之前查询的返回值是什么,正确的选择才会被支持

5、注意事项

  • 查询语句执行时间不能超过配置的超时时间

  • 查询只允许返回一个值.

  • 如果查询语句返回了多个列,它只读取第一列

  • 如果查询语句返回了多行,它读取第一条

  • SQL语句必须是 select开头,只能是查询语句.

  • SQL语句不能包含换行符

6、错误消息

从zabbix 2.08开始ODBC提供如下详细的错误信息:
Cannot execute ODBC query:[SQL_ERROR]:[42601][7][ERROR: syntax error at or near ";"; Error while executing the query]|
-------------------------  ---------   -----  |  ------------------------------------------------------------------- |
            |                  |         |    `- Native error code            `- error message.                      `- Record separator
            |                  |         `-SQLState
            `- Zabbix message  `- ODBC return code
错误消息最长不能超过128字节,因此错误消息太长会被截断。

三、验证

因为我们没有创建图像,可以从最新数据库里面查看我们创建的条目。

监控

你可以写更加复杂的SQL查询语句,以及制作触发器来对数据库更加详细的监控。

附录:

以上是对监控MySQL做的监控,下面我主要简要对Oracle的监控做下介绍。

1、下载oracle客户端

http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

官网下载速度比较慢,也可以到我上传到51CTO下载中心的地方下载。

http://down.51cto.com/data/2328882

oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-odbc-11.2.0.3.0-1.x86_64.rpm
oracle-instantclient11.2-sqlplus-11.2.0.3.0-1.x86_64.rpm

2、安装

yum localinstall oracle-instantclient11.2-*

3、创建本地监控

安装的默认位置分别在
/usr/share/oracle/11.2/client64
/usr/include/oracle/11.2/client64
/usr/lib/oracle/11.2/client64
 设置环境变量之前,在/usr/lib/oracle/11.2/client64下创建network/admin文件夹,
mkdir  -p  /usr/lib/oracle/11.2/client64/network/admin
在此文件夹下创建tnsnames.ora,其内容入下:
test_oracle=
   (DESCRIPTION =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.1.14)(PORT = 1521))
     (CONNECT_DATA =
        (SERVER = DEDICATED)
        (SERVICE_NAME = basicdb)
     )
    )

    在/usr/lib/oracle/11.2/client64/network/admin文件下创建sqlnet.ora,输入:

NAME_DIRECTORY_PATH=(TNSNAMES,EZCONNECT)

4、配置环境变量

export ORACLE_HOME=/usr/lib/oracle/11.2/client64
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib64:$LD_LIBRARY_PATH
export TNS_ADMIN=$ORACLE_HOME/network/admin
export PATH=$PATH:$ORACLE_HOME/bin:$HOME/bin

5、配置需要的库

chmod +x /usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1
cd /usr/lib64/
ln -s libodbcinst.so.2.0.0  libodbcinst.so.1

6、添加oracle驱动

# vim  /etc/odbcinst.ini
[oracle]
Description     = Oracle ODBC driver for Oracle 11g
Driver          = /usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1

7、添加oracle数据源

# vim  /etc/odbc.ini  
[test1]
Driver= oracle
DSN= test_oracle
ServerName= yourname
UserID= basicdb
Password= yourpasswd

8、sqlplus测试连接

# sqlplus yourname/yourpasswd@test_oracle

SQL*Plus: Release 11.2.0.3.0 Production on Wed Jul 19 11:39:18 2017

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL&gt; exit

9、配置zabbix前端

参考文档:https://www.zabbix.com/documentation/3.2/manual/config/items/itemtypes/odbc_checks

配置zabbix使用mailx实现邮件报警

说明:

Zabbix监控服务端、客户端都已经部署完成,被监控主机已经添加,Zabiix监控运行正常。

实现目的:

在Zabbix服务端设置邮件报警,当被监控主机宕机或者达到触发器预设值时,会自动发送报警邮件到指定邮箱。

具体操作:

以下操作在Zabbix监控服务端进行

备注:Zabbix监控服务端

操作系统:CentOS

使用外部邮箱账号发送报警邮件设置:

一、关闭sendmail或者postfix

service sendmail stop #关闭

chkconfig sendmail off #禁止开机启动

service postfix stop

chkconfig postfix off

备注:

使用外部邮箱账号时,不需要启动sendmail或者postfix

如果在sendmail或者postfix启动的同时使用外部邮箱发送报警邮件,首先会读取外部邮箱

配置信息。

二、安装邮件发送工具mailx

yum install mailx #安装

CentOS 5.x 编译安装mailx,直接yum安装的mailx版本太旧,使用外部邮件发送会有问题。

yum remove mailx #卸载系统自带的旧版mailx

下载mailx:

http://nchc.dl.sourceforge.net/project/heirloom/heirloom-mailx/12.4/mailx-12.4.tar.bz2

tar jxvf mailx-12.4.tar.bz2 #解压

cd mailx-12.4 #进入目录

make #编译

make install UCBINSTALL=/usr/bin/install #安装

ln -s /usr/local/bin/mailx /bin/mail #创建mailx到mail的软连接

ln -s /etc/nail.rc /etc/mail.rc #创建mailx配置文件软连接

三、配置Zabbix服务端外部邮箱

vi /etc/mail.rc #编辑,添加以下信息

set [email protected]

smtp=smtp.163.com   //添加发送人、发送服务器

set [email protected]

smtp-auth-password=123456   //添加发送人的邮箱和登录密码。

set smtp-auth=login  

:wq! #保存退出

echo "zabbix test mail" |mail -s "zabbix" [email protected]

#测试发送邮件,标题zabbix,邮件内容:zabbix test mail,发送到的邮箱:[email protected]或者[email protected],发送短信的时候要在139邮箱上面开启短信提醒。这里我就不说了,自己百度去。

#这时候,邮箱[email protected]会收到来自[email protected]的测试邮件

四、配置Zabbix服务端邮件报警

1、打开Zabbix

管理-示警媒介类型-创建媒体类型

监控

名称:Sendmail

类型:脚本

脚本名称:sendmail.sh

已启用:勾选

2、设置Zabbix用户报警邮箱地址

可以添加163邮箱也可以添加139邮箱。

监控

监控

类型:Sendmail

收件人:[email protected]

其他默认即可,也可
以根据需要设置

状态:已启用

存档

3、设置Zabbix触发报警的动作

组态-动作-创建动作

监控

名称:Action-Email

默认接收人:故障{TRIGGER.STATUS},服务器:{HOSTNAME1}发生: {TRIGGER.NAME}故障!

默认信息:

  • 告警主机:{HOSTNAME1}

  • 告警时间:{EVENT.DATE} {EVENT.TIME}

  • 告警等级:{TRIGGER.SEVERITY}

  • 告警信息: {TRIGGER.NAME}

  • 告警项目:{TRIGGER.KEY1}

  • 问题详情:{ITEM.NAME}:{ITEM.VALUE}

  • 当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}

  • 事件ID:{EVENT.ID}

  • 恢复信息:打钩

  • 恢复主旨:恢复{TRIGGER.STATUS}, 服务器:{HOSTNAME1}: {TRIGGER.NAME}已恢复!

  • 恢复信息:

  • 告警主机:{HOSTNAME1}

  • 告警时间:{EVENT.DATE} {EVENT.TIME}

  • 告警等级:{TRIGGER.SEVERITY}

  • 告警信息: {TRIGGER.NAME}

  • 告警项目:{TRIGGER.KEY1}

  • 问题详情:{ITEM.NAME}:{ITEM.VALUE}

  • 当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}

  • 事件ID:{EVENT.ID}

  • 已启用:打钩

监控

切换到操作选项

新的

操作类型:送出信息

送到用户:添加

默认信息:打钩

选择用户:Admin

选择

仅送到:Sendmail

存档

4、添加Zabbix服务端邮件发送脚本

cd /usr/local/zabbix/share/zabbix/alertscripts #进入脚本存放目录

vi sendmail.sh #编辑,添加以下代码

#!/bin/sh

echo "$3" | mail -s "$2" $1

:wq! #保存退出

chown -R zabbix.zabbix /usr/local/zabbix/share/zabbix/alertscripts/*

zabbix_server.conf 文件中加入脚本的相对路径

AlertScriptsPath=/usr/local/zabbix/share/zabbix/alertscripts

#设置脚本所有者为zabbix用户

chmod +x /usr/local/zabbix/share/zabbix/alertscripts/sendmail.sh

#设置脚本执行权限

五、测试Zabbix报警

关闭Zabbix客户端服务

service zabbix_agentd stop

查看你的[email protected]邮箱,会收到报警邮件

再开启Zabbix客户端服务

service zabbix_agentd start

查看你的[email protected]邮箱,会收到恢复邮件

使用外部邮箱账号发送报警邮件设置完成。

至此,Zabbix邮件报警设置完成。

使用zabbix自动发现自动监控多tomcat实例

说明

何为自动发现?首先我们监控多tomcat实例,如果一个个实例地添加或许可以完成当前需求。但是日后随着实例的增多,再手动一个个去添加就十分不方便了。这时候需要自动发现这个功能,来帮助我们自动添加监控tomcat实例。本文就以监控tomcat线程为例,来实现这个自动发现的功能。这里zabbix版本为3.0。

监控

创建自动发现脚本

可以理解为这个脚本能够打印出当前服务器上所有的tomcat实例名称。zabbix会定期执行这个脚本,做到自动发现当前所有的tomcat实例,脚本放在zabbix-agent安装路径的scripts目录下。而下一步就是给找到的tomcat实例添加所需要监控的值。下面先看脚本:

# cat discover_jvm.py
#!/usr/bin/python2.7 
#Usage: discover tomcat_app
#Last Modified:

import subprocess
import json

#args为自己定义查找项目名字的方式,由于各自部署方式的不同,这里需要根据实际情况来写命令。
args="find /opt/app/applications -name 'catalina.properties' | sort -n | uniq | awk -F'/' '{print $5}'"
t=subprocess.Popen(args,shell=True,stdout=subprocess.PIPE).communicate()[0]

apps=[]

for app in t.split('n'):
    if len(app) != 0:
        apps.append({'{#APP_NAME}':app})

打印出zabbix可识别的json格式

print json.dumps({'data':apps},indent=4,separators=(',',':'))

执行打印结果如下所示:

# chmod a+x discover_jvm.py 赋予执行权限
# chown zabbix:zabbix discover_jvm.py 添加属主为zabbix用户
# ./discover_jvm.py 
{
    "data":[
        {
            "{#APP_NAME}":"app1"
        },
        {
            "{#APP_NAME}":"app2"
        }
    ]
}
这里打印出app1、app2两个实例,以后要是有其他实例,也能够同样打印出来。

创建监控项脚本

这个脚本的作用是打印出tomcat实例需要监控的项,本例为线程数。该脚本执行需要两个参数,$1为实例名,$2为监控项名。打印的结果为一个整型的数字。记得跟上面的脚本放在同样的位置,并赋予执行权限和正确的属主。

# cat app_status.sh 
#!/bin/bash
#Usage: tomcat_app status
#Last Modified:

app=$1
status=$2
pid=`ps -ef | grep "$app" | grep -v grep | grep -v "$0"| awk '{print $2}'`

case $status in
    thread.num)
        /opt/programs/jdk1.7.0_67/bin/jstack "$pid" | grep http | wc -l
        ;;
    *)
        echo "Usage:$0 {app_name status[thread.num]}" 
        exit 1
        ;;
esac

#执行
#./app_status.sh app_name thread.num

日后如果需要添加新的监控项,只需修改上面的脚本,改变$2的选择即可。

zabbix客户端配置

在客户端配置文件中添加自定义监控的key,其实就是给我们监控选项取个名字,然后如何获取这个值。示例如下:

#变量1的key为custom.discover.jvm_app,为自动发现的tomcat实例名,获取方式即为执行dicover_jvm脚本
UserParameter=custom.discover.jvm_app,/opt/programs/bd-zabbix-agentd_3.0.4/scripts/discover_jvm.py
#变量2的key为custom.app.thread_num,[*]表示需要变量支持,这里即为$1、$2(本例中$2的意义不同,监控项就不同)获取方式为执行app_status.sh脚本
UserParameter=custom.app.thread_num[*],/opt/programs/bd-zabbix-agentd_3.0.4/scripts/app_status.sh $1 $2

修改完后重启zabbix客户端。然后在服务端进行验证:

#验证获取custom.discover.jvm_app的key值
zabbix-server_3.0.4/bin/zabbix_get -s 10.205.51.22 -p 20050 -k custom.discover.jvm_app
#验证获取custom.app.thread_num的key值
./zabbix_get -s 10.205.51.22 -p 20050 -k custom.app.thread_num[app1,thread_num]
如果正确的话,就会返回在客户端执行脚本一样的结果。

zabbix界面添加自动发现模版

为了便于后面更多的主机添加此监控,这里就创建一个模板来进行配置。首先创建一个发现规则,该规则就是用来自动发现tomcat实例的:

监控

取一个名字,并填上我们之前定义的key,然后保存即可:

监控

然后创建一个监控项:

监控

取一个名字,也填上我们之前定义的key,注意这里的#APP_NAME为之前脚本输出的变量,要填写一致:

监控

然后我们创建一个图像来观察数据:

监控

同样取名字的变量要跟之前一致,并添加数据源为刚刚我们定义的监控项:

监控

最后可以观察到图像:

监控

当然我们还可以定义一个触发器,比如大于多少线程就告警,这里就不一一赘述了。

Ansible安装配置zabbix-agent

Ansible Role: zabbix-agent

安装zabbix客户端

介绍

zabbix(音同 z?bix)是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。
zabbix agent需要安装在被监视的目标服务器上,它主要完成对硬件信息或与操作系统有关的内存,CPU等信息的收集。zabbix agent可以运行在Linux,Solaris,HP-UX,AIX,Free BSD,Open BSD, OS X, Tru64/OSF1, Windows NT4.0, Windows (2000/2003/XP/Vista)等系统之上。

官方地址: https://www.zabbix.com
官方文档地址:https://www.zabbix.com/documentation/3.2/manual

要求

此角色仅在RHEL及其衍生产品上运行。

测试环境

ansible 2.3.0.0
os Centos 6.7 X64
python 2.6.6

角色变量

software_files_path: "/opt/software"
software_install_path: "/usr/local"

zabbix_agent_version: "3.2.6"

zabbix_agent_file: "zabbix-{{ zabbix_agent_version }}.tar.gz"
zabbix_agent_file_path: "{{ software_files_path }}/{{ zabbix_agent_file }}"
zabbix_agent_file_url: "https://jaist.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/{{ zabbix_agent_version }}/{{ zabbix_agent_file }}"

zabbix_agent_repo_url: "http://repo.zabbix.com/zabbix/3.2/rhel/6/x86_64/zabbix-release-3.2-1.el6.noarch.rpm"
zabbix_agent_packages:
  - "zabbix-agent-{{ zabbix_agent_version }}-1.el6"

zabbix_agent_user: zabbix
zabbix_agent_group: zabbix

zabbix_agent_install_from_source: false

zabbix_agent_source_dir: "/tmp/{{ zabbix_agent_file | replace('.tar.gz','') }}"
zabbix_agent_source_configure_command: >
  ./configure
  --prefix={{ software_install_path }}/zabbix-{{ zabbix_agent_version }}
  --enable-agent

zabbix_agent_conf_path: "/etc/zabbix" 
zabbix_agent_logs_path: "/var/log/zabbix"

zabbix_agent_hostname: "{{ ansible_hostname | d() }}"
zabbix_agent_server_host: "127.0.0.1"

依赖

None

github地址

https://github.com/kuailemy123/Ansible-roles/tree/master/zabbix-agent

Example Playbook

---
# 源码安装
- hosts: node2
  roles:
   - { role: zabbix-agent, zabbix_agent_install_from_source: true, zabbix_agent_server_host: "192.168.77.130" }

# rpm包安装
- hosts: node3
  roles:
   - { role: zabbix-agent, zabbix_agent_server_host: "192.168.77.130" }

使用

~]# /etc/init.d/zabbix-agent 
Usage: /etc/init.d/zabbix-agent {start|stop|status|restart|help}

    start        - start zabbix_agentd
    stop        - stop zabbix_agentd
    status        - show current status of zabbix_agentd
    restart        - restart zabbix_agentd if running by sending a SIGHUP or start if not running
    help        - this screen

Xtrabackup定时备份mysql数据库脚本

定时备份MySQL数据库

脚本内容:

#!/bin/bash

## 备份计划任务
## 
## 每天凌晨1:30一次全量备份
## 每天间隔1小时一次增量备份
## 30 1 * * * backup.sh full
## 00 * * * * backup.sh inc
##
##  恢复数据步骤:
##  (1)、查看备份日志,找到全量备份和增量备份的关系(注意增量备份的顺序)
##
##  cat ${BACKUP_BASE_DIR}/${INC_BASE_LIST}
##  (2)、全量备份
##  innobackupex --defaults-file=/etc/my.cnf --apply-log ${BACKUP_BASE_DIR}/full_dir
##
##  (3)、第一个增量
##  innobackupex --defaults-file=/etc/my.cnf --apply-log ${BACKUP_BASE_DIR}/full_dir 
##  --incremental-dir=${BACKUP_BASE_DIR}/one_inc_dir
##
##  (4)、第二个增量
##  innobackupex --defaults-file=/etc/my.cnf --apply-log ${BACKUP_BASE_DIR}/full_dir 
##  --incremental-dir=${BACKUP_BASE_DIR}/two_inc_dir
##
##  (5)、恢复数据
##  innobackupex --defaults-file=/etc/my.cnf --copy-back ${BACKUP_BASE_DIR}/full_dir

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

BACKUP_BASE_DIR="/backup/xtrabackup"
INC_BASE_LIST="${BACKUP_BASE_DIR}/inc_list.txt"
XTRABACKUP_PATH="/usr/local/xtrabackup/bin/innobackupex"

MYSQL_CNF="/etc/my.cnf"
MYSQL_HOSTNAME=127.0.0.1
MYSQL_USERNAME=root
MYSQL_PASSWORD=w7tQ5NNWWRk

LOCK_FILE=/tmp/innobackupex.lock
THREAD=3

mkdir -p ${BACKUP_BASE_DIR}
CURRENT_BACKUP_PATH="${BACKUP_BASE_DIR}/$(date +%F_%H-%M)"
[[ -d ${CURRENT_BACKUP_PATH} ]] && CURRENT_BACKUP_PATH="${BACKUP_BASE_DIR}/$(date +%F_%H-%M-%S)"

print_help(){
    echo "--------------------------------------------------------------"
    echo "Usage: $0 full | inc | help               "
    echo "--------------------------------------------------------------"
    exit 1
}

[[ $# -lt 1 || "$1" == "help" ]] && print_help

[[ -f "$LOCK_FILE" ]] && echo -e "Usage: rm -f $LOCK_FILEnUsage: chattr -i $LOCK_FILE && rm -f $LOCK_FILE" && exit 1

FullBackup(){
    touch $LOCK_FILE
    chattr +i $LOCK_FILE
    local rc=0
    ${XTRABACKUP_PATH} 
    --defaults-file=${MYSQL_CNF} 
    --user=${MYSQL_USERNAME} 
    --password=${MYSQL_PASSWORD} 
    --host=${MYSQL_HOSTNAME} 
    --parallel=${THREAD} 
    --no-timestamp ${CURRENT_BACKUP_PATH} > ${CURRENT_BACKUP_PATH}_full.log 2>&1
    grep ".* completed OK!" ${CURRENT_BACKUP_PATH}_full.log > /dev/null 2>&1
    if [ $? -ne 0 ];then
        rc=1
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && rm -rf ${CURRENT_BACKUP_PATH}
    else
        echo "NULL|${CURRENT_BACKUP_PATH}|full" >> ${INC_BASE_LIST}
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && chattr +i ${CURRENT_BACKUP_PATH} || rc=1
    fi
    chattr -i ${LOCK_FILE}
    rm -f $LOCK_FILE
    chattr +a ${INC_BASE_LIST}
    return $rc
}

IncBackup(){
    touch $LOCK_FILE
    chattr +i $LOCK_FILE
    local rc=0
    PREV_BACKUP_DIR=$(sed '/^$/d' ${INC_BASE_LIST} | tail -1 | awk -F '|' '{print $2}')
    ${XTRABACKUP_PATH} 
    --defaults-file=${MYSQL_CNF} 
    --user=${MYSQL_USERNAME} 
    --password=${MYSQL_PASSWORD} 
    --host=${MYSQL_HOSTNAME} 
    --no-timestamp --incremental ${CURRENT_BACKUP_PATH} 
    --incremental-basedir=${PREV_BACKUP_DIR} > ${CURRENT_BACKUP_PATH}_inc.log 2>&1
    grep ".* completed OK!" ${CURRENT_BACKUP_PATH}_inc.log > /dev/null 2>&1
    if [ $? -ne 0 ];then
        rc=1
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && rm -rf ${CURRENT_BACKUP_PATH}
    else
        echo "${PREV_BACKUP_DIR}|${CURRENT_BACKUP_PATH}|inc" >> ${INC_BASE_LIST}
        [[ -d ${CURRENT_BACKUP_PATH} && $(pwd) != "/" ]] && chattr +i ${CURRENT_BACKUP_PATH} || rc=1
    fi
    chattr -i ${LOCK_FILE}
    rm -f $LOCK_FILE
    chattr +a ${INC_BASE_LIST}
    return $rc
}

## 全量备份
if [ "$1" == "full" ];then
    FullBackup
fi

## 增量备份
if [ "$1" == "inc" ];then
    ## 判断上一次备份是否存在,无则进行全量备份
    if [[ ! -f ${INC_BASE_LIST} || $(sed '/^$/d' ${INC_BASE_LIST} | wc -l) -eq 0 ]];then
        FullBackup
    else
        IncBackup
    fi
fi

## 删除14天前的备份
if [[ -d ${BACKUP_BASE_DIR} && $(pwd) != "/" ]];then
    find ${BACKUP_BASE_DIR} -name "$(date -d '14 days ago' +'%F')_*" | xargs chattr -i
    find ${BACKUP_BASE_DIR} -name "$(date -d '14 days ago' +'%F')_*" | xargs rm -rf
fi

加入计划任务

crontab -e
30 1 * * * /home/sh/backup.sh full
00 */6 * * * /home/sh/backup.sh inc
# mysql 

CentOS 6.5安装XtraBackup 还原RDS Mysql备份文件到本地Mysql服务器

有个网站的数据库用了下RDS,本文记录将RDS备份文件backup.gz还原到本地Mysql服务器中的流程。

顺便解决了innobackupex_55: command not found报错的问题。

MySQL

安装XtraBackup工具,去官网根据对应系统版本,安装XtraBackup,我安装的是比较经典稳定的2.1.5版

wget https://www.percona.com/downloads/XtraBackup/XtraBackup-2.1.5/RPM/rhel6/x86_64/percona-xtrabackup-2.1.5-680.rhel6.x86_64.rpm

安装依赖包

yum install -y perl-DBD-MySQL perl-DBI  perl-Time-HiRes libaio*

安装

rpm -ivh percona-xtrabackup-2.1.5-680.rhel6.x86_64.rpm

查看安装成功没有

rpm -qa |grep  xtrabackup

显示

percona-xtrabackup-2.1.5-680.rhel6.x86_64

rpm -ql percona-xtrabackup-2.1.5-680.rhel6.x86_64

显示

/usr/bin/innobackupex
/usr/bin/innobackupex-1.5.1
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup
/usr/bin/xtrabackup_55
/usr/bin/xtrabackup_56
/usr/share/doc/percona-xtrabackup-2.1.5
/usr/share/doc/percona-xtrabackup-2.1.5/COPYING

使用wget从下载备份文件,下载下来的文件需要重新命名 使用mv命令重命名为backu.gz

下载xtrabackup程序完成后,首先解压backup.gz,再使用xtrabackup中附带的解包工具进行解包。
执行命令:

mkdir -p /home/mysql/data_dir && gzip -d -c backup.gz | xbstream -x -C /home/mysql/data_dir

完成解压及解包后应用innodb的redo-log,执行命令(注意百度教程中是错的)

以下是百度教程中的错误命令:

innobackupex_55 --defaults-file=/home/mysql/data_dir/backup-my.cnf --apply-log /home/mysql/data_dir

但是,innobackupex_55命令执行后报错,如下:

# innobackupex_55 --defaults-file=/home/mysql/data_dir/backup-my.cnf --apply-log /home/mysql/data_dir
-bash: innobackupex_55: command not found

发百度工单瞎耽误工夫,最后自己搞定了,正确的命令为:

innobackupex --defaults-file=/home/mysql/data_dir/backup-my.cnf --apply-log /home/mysql/data_dir

执行后出现以下信息则说明成功了

命令执行完毕后,参考/home/mysql/data_dir/backup-my.cnf文件修改mysql数据库配置中的innodb_log_file_size参数;
使用/home/mysql/data_dir文件夹作为数据目录启动mysql即可。

vi /etc/my.cnf

将原来的datadir = /usr/local/mysql/var注释掉(怎么注释?语句前面加一个#号)
然后将以下的配置加入my.cnf文件中,注意加在原my.cnf文件中的[mysqld]下面,:wq命令保存

[mysqld]
innodb_checksum_algorithm=innodb
innodb_log_checksum_algorithm=innodb
innodb_data_file_path=ibdata1:32M:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=268435456
innodb_fast_checksum=0
innodb_page_size=16384
innodb_log_block_size=512
innodb_undo_tablespaces=0

然后重启Mysql服务

/etc/init.d/mysql restart