有时在工作中往github上提交代码或者clone别人的代码,总是特别慢!小一点的项目源代码还好,大的项目就要急死人了,差一点的速度经常是个位数,真的很耽误事!有个修改hosts的方法大家可以试试,我这边亲测有效,别的我不敢保证,大家可以试试!
1.打开hosts文件
sudo vim /etc/hosts
2.在该文件末尾空一行填入
151.101.72.249 github.global.ssl.fastly.net
大家可以先试试看,有效果的话最好!
有时在工作中往github上提交代码或者clone别人的代码,总是特别慢!小一点的项目源代码还好,大的项目就要急死人了,差一点的速度经常是个位数,真的很耽误事!有个修改hosts的方法大家可以试试,我这边亲测有效,别的我不敢保证,大家可以试试!
1.打开hosts文件
sudo vim /etc/hosts
2.在该文件末尾空一行填入
151.101.72.249 github.global.ssl.fastly.net
大家可以先试试看,有效果的话最好!
1、创建企业微信并创建一应用:


2、微信报警工具安装配置:
mkdir –p /usr/local/zabbix/alertscripts
rz(本地上传zabbix_weixin.x86_64.tar.gz)
tar –zxvf zabbix_weixin.x86_64.tar.gz
mv zabbix_weixin /weixin /usr/local/zabbix/alertscripts/weixin
chmod o+x /usr/local/zabbix/alertscripts/weixin
mv zabbix_weixin/weixincfg.json /etc/
修改:vi /etc/weixincfg.json



那个测试试了很多微信账号才成功,原来这个账号在这里可以查看得到:

测试格式:/usr/local/zabbix/ alertscripts /weixin contact(微信账号) subject(报警标题) body(报警内容)
4、添加脚本到zabbix_server.conf
AlertScriptsPath=/usr/local/zabbix/alertscripts

5、zabbix-web端设置:Actions动作,并设置触发微信报警:
脚本加入三个参数:{ALERT.SENDTO}、{ALERT.SUBJECT}、{ALERT.MESSAGE}







解决办法:后来才发现,原来是直接添加了此“微信警报”,而应该先添加操作里的小“Add”,再添加后面的大环境“Add”.如下图操作:



测试:


解决方法:

![]()

问题:发现给微信发送了两次警报:如图

解决方法:原来是因为在做邮件发送警报时,默认发送选择了“ALL”:


后来重新一次遇到的问题:
解决方法:发现所提示的目录与实际的不符。原来是由于在zabbix_server.conf配置文件中添加了脚本,没重启服务,需要重启才会生效。要不然会默认读一个目录。
/etc/zabbix_server restart
自使用Zabbix监控系统以来,一直想用JMX来监控Tomcat,但是一直都没配置成功,总有一些问题,监控端的报错又很抽象,搜索网上大都是复制粘贴之产物,或者是缺斤短两之网文,但是一直都没放弃,至今终于配置成功,并且成功获取数据,形成图形,现在把自己解决问题的过程和配置的一些心得整理成文.
环境介绍:
监控JMX配置步骤
1.在zabbix服务器上安装配置zabbix-java-gateway,并且配置相关参数。
2.配置tomcat服务器,JMX服务相关参数,上传依赖包
3.zabbix web端添加监控
4.启动tomcat服务,查看zabbix web端监控运行状态,排错.
5.自定义图形和监控项
1.安装zabbix-java-gateway
yum -y install zabbix-java-gateway
2.配置zabbix-java-gateway
grep "^[A-Z]" /etc/zabbix/zabbix_java_gateway.conf
LISTEN_IP="0.0.0.0" #监听本机所有ip
LISTEN_PORT=10052 #在10052端口提供服务
PID_FILE="/var/run/zabbix/zabbix_java.pid"
START_POLLERS=5
3.启动服务
service zabbix-java-gateway start
4.配置zabbix-server
grep "^[A-Z]" /etc/zabbix/zabbix_server.conf|grep Java
JavaGateway=127.0.0.1 #JavaGateway所在服务器的IP
JavaGatewayPort=10052 #JavaGateway的默认端口
StartJavaPollers=5 #JVM进行监控轮询实例数,默认是0
5.重启zabbix-server
service zabbix-server restart
6.查看监听端口
![]()
1.配置catalina.sh
vim /apache-tomcat-7.0.68/bin/catalina.sh
CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=utf-8
-Dcom.sun.management.jmxremote #开启远程
-Dcom.sun.management.jmxremote.authenticate=false #免密认证
# -Dcom.sun.management.jmxremote.port=12345 #这里不需要这行,一会儿说明原因
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=192.168.66.22" #要监控的tomcat主机ip
2.配置server.xml
vim /m.aaa.com/conf/server.xml (注意,这里是实例里面的配置文件)
在任意位置添加如下文字,意思是远程连接端口是12345,获取数据端口是123456,如果有多实例,全部都要加这行文字,端口数字不同即可
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="12345" rmiServerPortPlatform="12346"/>
3.开放指定端口
iptables -I INPUT -p tcp -m multiport –dports 12345,12346 -j ACCEPT
4.下载支持的jar包
链接:http://down.51cto.com/data/2448735
里面包含两个jar包,catalina-jmx-remote.jar和cmdline-jmxclient-0.10.3.jar 还有一个监控模板
catalina-jmx-remote.jar存放位置:/apache-tomcat-7.0.68/lib/
cmdline-jmxclient-0.10.3.jar 这个jar是用来测试连通情况的,zabbix和tomcat服务器上都要放一个
1.添加JMX介面,这里添加的端口号是远程连接端口号

2.添加监控模板

3.监控项添加完后,JMX图标显示红色,因为tomcat服务还没有起
4.多实例监控,进入主机-项目进行配置,在server.xml中指定的什么端口,这里就选什么端口

在zabbix服务器端尝试获取数据,显示如下数据连接正确
java -jar cmdline-jmxclient-0.10.3.jar - 192.168.66.22:12345 java.lang:type=Memory NonHeapMemoryUsage

在tomcat服务器端显示使用12346进行连接

如果看者严格按照上面的配置操作,这时zabbix服务web端JMX图标已经显示绿色,如果还是红色,请参考下面的提示排错
**1. java.rmi.ConnectException: Connection refused to host: 192.168.66.22; nested exception is: **
java.net.ConnectException: Connecti
错误原因:只在catalina.sh中配置了一个远程端口
还记得上面我在/apache-tomcat-7.0.68/bin/catalina.sh有一行注释掉了么,在这个文件中不能指定端口号,否则就会报如上错误
2. java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.ServiceUnavailableException [Root exception is java.rmi.Con
错误原因:没有配置远程端口
光删除掉上面的端口号还不够,还需要在/m.aaa.com/conf/server.xml中添加相应的端口配置
3.java.lang.ClassNotFoundException: org.apache.catalina.mbeans.JmxRemoteLifecycleListener
错误原因:这是tomcat报错,缺少支持的jar包catalina-jmx-remote.jar
请往上翻,找51cto的下载链接,下载相关jar包
4. Catalina:type=ThreadPool,name=http-8080
![]()
错误原因:支持的name里没有http-8080
查看支持哪些类型和调用
java -jar cmdline-jmxclient-0.10.3.jar – 192.168.66.22:12345
上面报错的解决方法是:
1.java -jar cmdline-jmxclient-0.10.3.jar – 192.168.66.22:12347|grep Thread

2.配置模板
![]()
3.点击进入修改键值

4.改完后是这样的
![]()
5.目标是全绿

Zabbix是一款开源并且完全免费的企业级系统监控软件,它拥有强大无比的各种监控功能,可以全方位监控你的服务器或是VPS系统运行状态。
首先各位别被企业级这几个字眼给唬住了,很多朋友可能一看到这种字眼就觉得,哇,这玩意儿不会特别难装吧!?其实我说句实在话,Zabbix安装还是挺简单的,倒是配置使用起来需要花一些时间,因为它有太多的功能,所以显的操作界面乱七八糟,初次使用的朋友可能会有点摸不着头脑。所以,我决定写一篇文章来描述如何安装zabbix
因为博主的主机的性能实在不怎么样,所以我用虚拟机来演示如何安装。有些不一样的地方我会注释说明
[root@heroyf ~]# yum update
[root@heroyf ~]# INSTALL_AGENT=1 INSTALL_APPS=sitemgr INIT_SWAPFILE=1 INSTALL_PKGS='nginx-stable,php56,php71,mysql56' bash -c "$(curl -sS http://dl.appnode.com/install.sh)"
为什么我不选择用宝塔呢,因为宝塔的lnmp镜像源实在的慢的不能接受了
安装完成登录之后,请安装网站所需的lnmp环境
环境安装完成后,我们回到Xshell内,新建一个用户:
[root@heroyf ~]# groupadd zabbix
[root@heroyf ~]# useradd zabbix -g zabbix -s /sbin/nologin
安装EPEL源:
[root@heroyf ~]# yum -y install epel-release
安装编译Zabbix需要的各种依赖和组件:
[root@heroyf ~]# yum -y install net-snmp-devel fping
在root目录内下载Zabbix源码(在你的本地电脑也提前下载一份,待会会用到):
[root@heroyf ~]# cd /root
[root@heroyf ~]# wget https://excellmedia.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/3.4.7/zabbix-3.4.7.tar.gz
解压并进入到Zabbix目录内:
[root@heroyf ~]# tar -zxvf zabbix-3.4.7.tar.gz
[root@heroyf ~]# cd zabbix-3.4.7
编译:
[root@heroyf ~]# ./configure --enable-server --enable-agent --with-mysql --enable-ipv6 --with-net-snmp --with-libcurl --with-libxml2
如果出现如下错误
configure: error: Not found mysqlclient library
configure: error: LIBXML2 library not found
configure: error: Unable to use libevent (libevent check failed)
configure: error: Curl library not found
解决办法:
[root@heroyf ~]# yum install mysql-devel
[root@heroyf ~]# yum install libxml2 libxml2-devel
[root@heroyf ~]# yum install libevent-devel -y
[root@heroyf ~]# yum install curl-devel
完成后如图所示:

安装:
[root@heroyf ~]# make install
通过phpmyadmin,将一个数据库的排序规则改成utf8_general_ci,如图所示:

接着我们导入zabbix-3.4.7/database/mysql目录下的数据库文件:
schema.sql
images.sql
data.sql
在phpMyAdmin内导入我们的数据库文件,如图所示:

编辑Zabbix的服务端配置文件:
[root@heroyf ~]# vim /usr/local/etc/zabbix_server.conf
修改数据库名、数据库用户名、数据库用户对应的root密码,如图所示:

接着修改Zabbix的客户端配置文件:
[root@heroyf ~]# vim /usr/local/etc/zabbix_agentd.conf
将Server=127.0.0.1后面的IP修改成你的服务器或是VPS的公网IP,如图所示:

关闭CentOS7的防火墙:
[root@heroyf ~]# systemctl stop firewalld.service
[root@heroyf ~]# systemctl disable firewalld.service
启动Zabbix的服务端和客户端:
[root@heroyf ~]# zabbix_server
[root@heroyf ~]# zabbix_agentd
确保进程处于启动状态,可用命令ps -ef查看
添加网站节点

修改php.ini中的参数max_input_time为300:
[root@heroyf ~]# find / -name php.ini

回到Xshell内,复制Zabbix的前端程序文件到你的站点目录内:
[root@heroyf ~]# cp -r /root/zabbix-3.4.7/frontends/php/* 你的站点目录
此时通过浏览器,访问你的站点,不出意外的话可以看到Zabbix的安装界面了:

检测环境组件,这里需要注意的是往下拉会有一个PHPLDAP的Warning,PHP的LDAP扩展非必须安装,所以我们无视掉即可:

填写MySQL的数据库连接信息,这里和之前我们在zabbix_server.conf配置文件内填写的内容要一致,这一步细心就好,我就不展示了
填写站点名字,请注意上面的Host和Port不要做更改
再次确认你之前填写的这些信息是否无误,没问题就点击Next step
不出意外这里会报一个错误,所以这里我们将配置文件下载到本地:

只需要将配置文件上传到我们的站点根目录下的conf目录内即可
可用工具FileZilla
回到浏览器中,再次点击Finish,就安装完成了。
默认的管理员账号:Admin
密码:zabbix
登录进去后,第一件事情就是把密码改了,然后把站点语言修改成中文:

接着Zabbix默认会给我们启用一个没密码的Guest,为了安全起见,我们需要把这个账号停用掉:

至此,Zabbix的安装和基本配置就完成了。
总的来说,有四台机器,各自的功能如下:
a. 假设有一个机器在运行web应用,容器是tomcat,这个应用有个接口http://localhost:8080/zabbixcustomitemdemo/count,可以返回最近一分钟的某个业务量(例如网站访问次数);
b. 有一台机器安装了zabbix agent,作为自定义监控项的载体;
c. 有一台机器安装了zabbix server;
d. 有一台机器安装了mysql,作为zabbix系统的数据库;
整体部署如下图所示:

这是个基于maven的java web应用,里面有个spring mvc的controller,提供一个http服务,范围某个业务每分钟的业务量,代码如下图所示:
@Controller
public class CountController {
@RequestMapping("/count")
@ResponseBody
public int count(String model, String type) {
int base;
int max;
int min;
if("a".equals(model)){
base = 50000;
}else{
base =10000;
}
if("0".equals(type)){
max = 9000;
min = 1000;
}else{
max = 1000;
min = 0;
}
return base + new Random().nextInt(max)%(max-min+1);
}
}
从以上代码我们可以看出,http服务会返回随机数,此服务接受两个参数model和type,当model等于”a”时返回的随机数从50000开始,model不等于”a”时返回的随机数从10000开始,当type等于”0”时,在base的基础上增加的值是1000到9000之间,当type不等于”0”时,在base的基础上增加的值是0到1000之间;
整个工程的代码已经上传到git上,地址是[email protected]:zq2599/blog_demos.git,这个目录下由多个工程,本次实战的工程是zabbixcustomitemdemo,如下图:

上面我们已经把四台机器的功能和关系梳理清楚了,现在就来制定docker-compose.yml文件吧:
version: '2'
services:
zabbix-mysql-service:
image: daocloud.io/library/mysql:8
container_name: zabbix-mysql-service
environment:
- MYSQL_ROOT_PASSWORD=888888
restart: always
zabbix-server-service:
image: monitoringartist/zabbix-xxl:3.2.6
links:
- zabbix-mysql-service:mysqlhost
container_name: zabbix-server-service
restart: always
depends_on:
- zabbix-mysql-service
ports:
- "8888:80"
environment:
- ZS_DBHost=mysqlhost
- ZS_DBUser=root
- ZS_DBPassword=888888
zabbix-agent-a:
image: zabbix/zabbix-agent:ubuntu-3.2.6
links:
- zabbix-server-service:zabbixserverhost
container_name: zabbix-agent-a
restart: always
depends_on:
- zabbix-server-service
environment:
- ZBX_HOSTNAME=zabbix-agent-service-a
- ZBX_SERVER_HOST=zabbixserverhost
tomcat-server-service:
image: bolingcavalry/bolingcavalrytomcat:0.0.1
container_name: tomcat-server
restart: always
ports:
- "8080:8080"
yml文件的内容如上所示,其中mysql、zabbix server,zabbix agent的配置和上一章《Docker下实战zabbix三部曲之二:监控其他机器》是一样的,新增的是一个tomcat的镜像,这个镜像是我在tomcat官方镜像的基础上做了点小改动,使得这个tomcat支持在线部署web应用,关于tomcat在线部署应用,请看文章《实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》: https://blog.csdn.net/boling_cavalry/article/details/70184605
准备好yml文件之后,打开终端,在yml文件所在目录下执行docker-compose up -d可以将yml文件中所有的容器都启动;
注意,如果您的电脑之前已经运行过上一章《Docker下实战zabbix三部曲之二:监控其他机器》中的docker-compose.yml文件,那么本次执行docker-compose up -d会提示启动失败,已有同样名称的容器存在,这时候可以去上一章的docker-compose.yml文件所在目录执行docker-compose down,也可以通过docker ps -a将所有容器列出,再通过docker stop命令依次停止所有容器,再执行docker-compose rm命令依次删除;
打开终端,进入web工程zabbixcustomitemdemo的目录下,执行命令mvn clean package -U -Dmaven.test.skip=true tomcat7:redeplo y,即可将web工程部署到tomcat容器上,关于在线部署的细节请参照文章《实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》;
部署成功后,打开浏览器,访问http://localhost:8080/zabbixcustomitemdemo/count,web server会返回一个数字,如下图所示:

接下来我们要在zabbix agent上做一个shell脚本,此脚本的功能时发起http请求http://localhost:8080/zabbixcustomitemdemo/count?model=a&type=0,就能得到web服务响应的数字,如果此脚本每分钟被调用一次,就能得到完整的监控曲线图了;
a. 首先,执行docker exec -it zabbix-agent-a /bin/bash登录zabbix agent的容器;
b. 登录后,执行apt-get update更新apt;
c. 先后执行apt-get install wget和apt-get install vim,安装wget和vi工具;
d. 新建目录/usr/work/,在此目录下用vi创建一个shell文件biz_count.sh,内容如下:
#"!/bin/bash
wget -qO- http://tomcathost:8080/zabbixcustomitemdemo/count?model=$1&type=$2
echo ""
上面代码的功能是访问http服务获取一个数字,其中model和type用的是shell的入参;
注意两个细节:
第一个:最后一行代码echo “”,实践证明这一行是很有用的,有了这一行就会在输出http返回的数字后进行换行,有了换行数据才能成功上报到zabbix server;
第二个:wget命令后面的url参数中,”&”符号前面要加转义的斜杠””;
e. 执行chmod a+x biz_count.sh,给shell赋予可执行权限;
继续在zabbix agent容器上,我们要添加一个自定义监控项,这样后面在zabbix server上就能使用该监控项了:
a. 在/etc/zabbix/zabbix_agentd.d目录下,新增一个biz.conf文件,内容如下:
UserParameter=get_total_num[*],/usr/work/biz_count.sh $1 $2
以上代码配置了一个自定义监控项,名称是get_total_num,可以接受两个入参,该监控项会调用biz_count.sh这个脚本,并且把外部传来的两个入参直接传递给biz_count.sh;
b. 执行chmod a+r biz.conf使得该文件可读;
在zabbix agent上测试
继续在zabbix agent容器上,执行以下命令来测试刚刚新加的监控项:
/usr/sbin/zabbix_agentd -t get_total_num[a,0]
中括号中的a,0表示两个入参分别是”a”和”0”,我们执行四次,入参分别用[a,0]、[b,0]、[a,1]、[b,1],得到的结果如下图所示:

四个返回值分别是54741、17097、50564、10919,结合前面的java代码可以发现两个参数都生效了,数字的大小范围因入参而变化;
为了让监控项生效,需要重启zabbix agent,不过这里有个更快捷的方法可以试试:
a. 执行exit退出zabbix agent容器;
b. 执行docker restart zabbix-agent-a重启zambia agent容器;
到了这里,自定义监控项已经准备好了,接下来在zabbix server上把它配置成功,我们就能看到监控数据和曲线图了,不过在配置前,我们可以在zabbix server上测试一下能否成功调用zabbix agent上的监控项;
首先我们要搞清楚zabbix agent机器的ip,有两种方法:
第一种,执行docker exec -it zabbix-agent-a /bin/bash登录zabbix agent的容器,在容器中执行ip addr命令可以得到ip;
第二种,直接执行docker exec -it zabbix-agent-a ip addr命令得到ip;
不论哪种,都能得到zabbix-agent的ip是172.31.0.5;
现在我们登录zabbix server容器,执行命令docker exec -it zabbix-server-service /bin/bash即可登录,登录后执行以下命令:
zabbix_get -s 172.31.0.5 -k get_total_num[a,0]
如下图所示,测试成功,调用agent的监控项返回了符合预期的数据:

还记得我们刚才在zabbix agent上配置好之后,需要重启agent服务或者重启zabbix agent容器,如果您忘了这一步,现在zabbix server上测试会得到如下错误提示:

这时候去重启一下,再回来测试就可以成功了。
在浏览器上输入”http://localhost:8888/“登录管理页面,先添加agent机器,如下图:

添加之后,点击下图红框位置,进入监控项页面:

如下图,点击右上角的“Create item”即可开始添加监控项:

新增的监控项,我们只要填写Name,Key,Update interval(更新频率)这几个字段,其他的保持不变,每个要更新的字段的内容如下图:

填写并保存后,我们可以在Monitoring -> Latest data中看到最新的监控项数据,如下图:

接下来我们添加一个监控图形,操作如下图所示,可以进入图形管理页面:

如下图,点击右上角的“Create graph”创建一个图形:

新建图形的时候,名称随意,只要Items选中刚刚创建的监控项即可,如下图:

创建成功,现在要看看效果了,操作如下图所示:

点击”add”之后,在弹出的页面上选择刚刚我们新建的图形选项,操作完毕后,点击下图红框位置,就能看见曲线图了:

曲线图如下:

以上就是自定义监控项开发和设置的所有过程,基于监控项的操作,除了图形还能添加tirgger用来告警,在添加action用来确定告警的动作
假设实际项目中我们有两台应用服务器,为了监控它们,我们要在上面分别安装zabbix-agent服务,然后通过配置让它们与zabbix server连接,所有监控数据和监控配置数据都被zabbix server保存在mysql中,部署情况如下图:

真实场景中是在应用服务器上安装zabbix agent服务,但是安装agent的过程和步骤不是本次实践的重点,为了快速体验服务本文使用了zabbix官方的agent镜像,这个镜像实际上就是在ubuntu14上安装了zabbix agent(在服务器上安装zabbix agent的过程就不在本文中详述了,对安装有兴趣的读者们可以去网上搜索相关资料)
docker-compose.yml文件
按照前面图片所示的部署情况,我们的docker-compose.yml内容如下,mysql和zabbix server是必须的,再新增了两个zabbix agent容器,名称分别是zabbix-agent-a和zabbix-agent-b:
version: '2'
services:
zabbix-mysql-service:
image: daocloud.io/library/mysql:8
container_name: zabbix-mysql-service
environment:
- MYSQL_ROOT_PASSWORD=888888
restart: always
zabbix-server-service:
image: monitoringartist/zabbix-xxl:3.2.6
links:
- zabbix-mysql-service:mysqlhost
container_name: zabbix-server-service
restart: always
depends_on:
- zabbix-mysql-service
ports:
- "8888:80"
environment:
- ZS_DBHost=mysqlhost
- ZS_DBUser=root
- ZS_DBPassword=888888
zabbix-agent-a:
image: zabbix/zabbix-agent:ubuntu-3.2.6
links:
- zabbix-server-service:zabbixserverhost
container_name: zabbix-agent-a
restart: always
depends_on:
- zabbix-server-service
environment:
- ZBX_HOSTNAME=zabbix-agent-service-a
- ZBX_SERVER_HOST=zabbixserverhost
zabbix-agent-b:
image: zabbix/zabbix-agent:ubuntu-3.2.6
links:
- zabbix-server-service:zabbixserverhost
container_name: zabbix-agent-b
restart: always
depends_on:
- zabbix-server-service
environment:
- ZBX_HOSTNAME=zabbix-agent-service-b
- ZBX_SERVER_HOST=zabbixserverhost
如上所示,zabbix agent在配置过程中要用到zabbix server的ip信息,这里我们通过links参数,在zabbix agent的host文件中加入了zabbix server的ip信息,host name是zabbixserverhost;
另外,ZBX_HOSTNAME和ZBX_SERVER_HOST这两个环境变量,在zabbix agent镜像的官方文档中已经说明,如下图,ZBX_HOSTNAME用来表示自己的身份,ZBX_SERVER_HOST是用来标明zabbix server的ip信息的,这里直接用link参数中的alias来表示,就能通过host直接找到zabbix server的ip了:

打开控制台,在docker-compose.yml文件所在的目录下执行命令docker-compose up -d,如图:

等待大约1分钟,让zabbix server完成初始化,然后就能登录管理页面了,详情请参照《Docker下实战zabbix三部曲之一:极速体验》一文,登录后进入hosts页面,如下图:

按照前面的部署描述图上的部署,有两台机器装了zabbix agent服务,然后想要加入监控,第一步我们要把机器的ip确定下来,在控制台执行docker exec -it zabbix-agent-a ip addr命令,可以看到如下输出,第一台机器的ip是172.31.0.4:

在控制台执行docker exec -it zabbix-agent-b ip addr命令,可以看到如第二台机器的ip是172.31.0.5;
点击hosts页面右上角的Create host按钮,可以添加监控机器,如下图:

在添加机器的页面,主要参数填写如下:
a. Host name :机器的环境变量ZBX_HOSTNAME的值:zabbix-agent-service-a;
b. Visible name :和Host name的值相同;
c. Groups : 机器分组,这里选择Linux servers;
d. Agent interfaces:这里面只需要填写IP address,就是刚才我们通过命令docker exec -it zabbix-agent-a ip addr得到的ip:172.31.0.4;
这个页面只需要填写以上四点内容,其他的都保持默认值,填写完毕后点击底部的”Add”按钮,如下图:

增加成功后,在列表中可以看到新增的机器,如下图:

在机器列表页面中,点击机器名称,如下图红框中位置:

在打开的页面点击”Templates”,如下图红框所示:

再点击”Select”按钮,如下图红框所示:

在弹出的页面中,勾选“Template OS Linux”,然后再点击底部的“Select”按钮,这样就把linux服务的常用监控项给批量添加了,如下图:

注意,返回的页面中,一定要点击“Add”才能让把刚才的选择加上,如下图:

然后点击“Update”,完成监控项的批量添加,如下图:

按照同样的方法把另一台机器的监控也加上;
等待大约1-2分钟后,再刷新hosts页面,就能看到列表中的”ZBX”图标已经变为绿色,表示监控已经生效;
我们来看看监控曲线图吧,点击下图红框中的“Graphs”:

可以看到有5个曲线图可以查看,如下图,我们看一下cpu load:

在跳转的页面中,点击“Previdew”,就能看到cpu load的曲线图了,如下图:

至此,我们添加监控机器的实战已经完成了,但是在真实场景中,我们除了cpu、磁盘等基础信息的监控,还要监控一些业务有关的数据,例如某个http服务每分钟的访问量。
首先创建一份docker-compose.yml文件,内容如下:
version: '2'
services:
zabbix-mysql:
image: daocloud.io/library/mysql:8
container_name: zabbix-mysql
environment:
- MYSQL_ROOT_PASSWORD=888888
restart: always
zabbix-server:
image: monitoringartist/zabbix-xxl
links:
- zabbix-mysql:mysqlhost
container_name: zabbix-server
restart: always
depends_on:
- zabbix-mysql
ports:
- "8888:80"
environment:
- ZS_DBHost=mysqlhost
- ZS_DBUser=root
- ZS_DBPassword=888888
打开命令行,在刚才创建的docker-compose.yml目录下,执行docker-compose up -d,这样就会先后启动mysql和zabbix server两个服务的容器,如下图:

在命令行输入命令docker logs -f zabbix-server-service,查看zabbix server的日志输出,下图是部分日志的截图,可以看到有数据库初始化的操作:

等待大约一分钟之后,zabbix server的日志不再滚动,表示初始化已经完成,打开浏览器输入http://localhost:8888,可以看到zabbix的管理系统的登录页面,如下图:

输入用户名admin,密码zabbix
登录后即可看到管理系统了,如下图:

按照下图的操作,查看已经监控的主机情况,如图,目前只能看到一台机器的信息,就是zabbix server自己这台机器,从列表的几列信息中可以看到有64个监控项,43个触发器,10个图形:

上图右侧的红框中显示的status是”Disabled”,表示这个host的监控还没有启动,点击这个”Disabled”就能启动监控,将状态变为”Enabled”,大约1分钟后再刷新页面,可以看到展示如下图:

除了状态变为”Enabled”,右侧原本灰色的”ZBX”也变成了绿色,表示该机器的监控状态是正常的;
按照下图的红框和箭头操作,可以看到zabbix server所在机器的cpu load的曲线图:

按照下图的箭头依次点击红框中的内容:

在打开后的页面中按照下图的箭头依次选择和点击:

这时候再点击右上角的”注销”按钮,退出重现登录,如下图红框所示:

再重新登录后,就能看见页面已经全部中文显示了,如下图:

以上就是Docker下实战zabbix的第一部分,快速体验zabbix系统和服务,但只有一个zabbix server服务器意义不大,毕竟实际场景是要通过zabbix系统去监控其他机器和服务,下一章我们尝试把zabbix agent加入进来,以更接近实际场景的方式来继续学习zabbix。
如今服务器的配置提升明显,单一主机上部署单一网站会对主机造成大量的性能损失,因此web服务虚拟主机的技术应运而生。所谓虚拟主机指的是在一台机器上运行多个网站(如company1.example.com和company2.example.com)的做法 。虚拟主机可以是“ 基于IP的 ”,这意味着每个网站都有不同的IP地址,或者“ 基于名称 ”,这意味着每个IP地址上都有多个名称,或者“基于端口”,这意味着在同一ip的不同端口上提供不同的网站,通过这些方法使得他们在同一台物理服务器上运行的事实对最终用户来说并不明显。
Apache是第一批支持基于IP的虚拟主机的服务器之一。Apache的版本1.1及更高版本支持基于IP和基于名称的虚拟主机(虚拟主机)。虚拟主机的后一种变型有时也被称为基于主机的或非IP虚拟主机。
FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)。它还支持分布式的运算, 即 FastCGI 程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。
FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail- Over特性等等。
3台主机用于分别部署httpd,php和mysql,实现分离
软件版本


这里我们需要编译的软件为httpd和php,mysql可以考虑使用二进制包或者直接官方yum安装
1.安装centos开发工具包
yum groupinstall "development tools" -y
2.安装编译httpd和php需要的包
#部分包需要epel源
#yum install epel-release -y
yum install pcre-devel openssl-devel expat-devel libxml2-devel bzip2-devel libmcrypt-devel -y
这里在192.168.99.130机器上编译httpd2.4
1.创建apache用户
useradd -r apache -s /sbin/nologin
2.解压httpd,apr,apr-util源码包,这里需要的包均可在httpd官网下到
tar xvf httpd-2.4.33.tar.bz2
tar xvf apr-1.6.2.tar.gz
tar xvf apr-util-1.6.1.tar.gz
3.编译httpd
#移动解压的apr和apr-util到指定的httpd源码目录可以省去分别编译3个程序
mv apr-1.6.2 httpd-2.4.33/srclib/apr
mv apr-util-1.6.1 httpd-2.4.33/srclib/apr-util
#编译参数,具体含义可以参考./configure的帮助文档或者官方文档
./configure
--prefix=/app/httpd24
--enable-so
--enable-ssl
--enable-cgi
--enable-rewrite
--with-zlib
--with-pcre
--with-included-apr
--enable-modules=most
--enable-mpms-shared=all
--with-mpm=prefork
make && make install
4.配置环境变量
vim /etc/profile.d/httpd.sh
PATH=/app/httpd24/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
source /etc/profile.d/httpd.sh
由于这里为了实现多机分离,因此在192.168.99.131主机上进行编译
1.解压PHP源码
tar xvf php-7.1.18.tar.bz2
2.进入目录
#编译参数
./configure
--prefix=/app/php
--enable-mysqlnd
--with-mysqli=mysqlnd
--with-openssl
--with-pdo-mysql=mysqlnd
--enable-mbstring
--with-freetype-dir
--with-jpeg-dir
--with-png-dir
--with-zlib
--with-libxml-dir=/usr
--enable-xml
--enable-sockets
--enable-fpm
--with-config-file-path=/etc
--with-config-file-scan-dir=/etc/php.d
--enable-maintainer-zts
--disable-fileinfo
make && make install
3.配置文件设置
cd php-7.1.18/
cp php.ini-production /etc/php.ini
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
#给予执行权限
chmod +x /etc/init.d/php-fpm
#添加到服务中
chkconfig --add php-fpm
#设置开机启动
chkconfig php-fpm on
cd /app/php/etc
cp php-fpm.conf.default php-fpm.conf
cp php-fpm.d/www.conf.default php-fpm.d/www.conf
service php-fpm start
这里不再多谈maraidb安装,之前的博客有很详细的mariadb部署细节。这里推荐直接yum安装就好。
1.支持代理模块
vim /app/httpd24/conf/httpd.conf
#取消下面两行的注释
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
#修改下面行
<IfModule dir_module>
DirectoryIndex index.php index.html
2.编辑虚拟主机配置
<VirtualHost *:80>
DocumentRoot "/data/web1/wp"
ServerName www.douma.com
ErrorLog "logs/a.com.error_log"
TransferLog "logs/a.com-access_log"
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
ProxyRequests Off
ProxyPassMatch ^/(.*.php)$ fcgi://192.168.99.131:9000/app/web1/wp/$1
<directory "/data/web1/wp">
require all granted
</directory>
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/data/web2/dz"
ServerName www.fansity.com
ErrorLog "logs/b.com.error_log"
TransferLog "logs/b.com-access_log"
<directory "/data/web2/dz">
require all granted
</directory>
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
ProxyRequests Off
ProxyPassMatch ^/(.*.php)$ fcgi://192.168.99.131:9000/app/web2/dz/$1
</VirtualHost>
3.创建站点目录
# httpd主机
mkdir -pv /data/web{1,2}
#wordpress
tar xvf wordpress-4.9.4-zh_CN.tar.gz
mv wordpress web1/
cd web1
ln -sv wordpress wp
#修改配置文件
vim web1/wp/wp-config-sample.php
mv wp-config-sample.php wp-config.php

wordpress基本配置完成,之后复制到fast-cgi机器的对应目录(要先在对应主机创建好目录)
scp -pr wordpress 192.168.99.131:/app/web1/
安装Discuzx
cd /data/web2/
git clone https://gitee.com/ComsenzDiscuz/DiscuzX.git
cp -a DiscuzX/upload web2/
ln -sv upload dz
复制文件到fast-cgi主机(要在另一台主机创建好对应目录)
scp -pr upload 192.168.99.131:/app/web2/
4.启动httpd服务
apachectl start
1.站点目录修改
#创建对应目录,要在httpd主机复制文件到fast-cgi之前
mkdir -pv /app/web{1,2}
#创建软连接
cd /app/web1
ln -sv wordpress wp
#复制配置文件并且修改
mv wordpress/wp-config-simple.php wordpress/wp-config.php
vim wordpress/wp-config.php
cd /app/web2
ln -sv upload dz

2.php修改,并添加apache用户
useradd -r apache -s /sbin/nologin
vim /app/php/etc/php-fpm.d/www.conf
#修改运行用户为apache
#修改监听ip
#注释掉仅仅允许本机访问
#重新启动php-fpm
service php-fpm restart
#由于论坛安装时候会修改文件所以要给upload目录添加apache的权限
setfacl -R -m u:apache:rwx /app/web2/upload/


1.创建账号
MariaDB [(none)]> grant all on *.* to admin identified by 'admin';
#刷新权限
MariaDB [(none)]> flush privileges;
2.创建wp数据库,论坛会在安装时候自动创建
MariaDB [(none)]> create database wp;
由于是基于域名的虚拟主机,所以在没有DNS的情况下,要想正常访问,就要在宿主机上修稿hosts文件
#win
C:WindowsSystem32driversetchosts
#linux
/etc/hosts
#添加如下信息
192.168.99.130 www.douma.com
192.168.99.130 www.fansity.com
1.安装wordpress
在宿主机浏览器上打开www.douma.com
会自动跳转到安装页面
配置好对应信息点击安装wordpress



2.安装Discuzx
在宿主机浏览器上打开www.fansity.com
自动跳转到安装页面

点击同意

点击下一步

继续下一步

填写完成后点击下一步进行自动安装

安装完成

点击右下角的跳转到论坛

正常访问,这里论坛基本配置完成。
使用 Samba 来共享 ChromeBook 上挂载的硬盘文件,这样一来,Mac、Win 和 Android 都可以共享文件。
我使用的 Linux 系统是 ArchLinux,安装方法很简单,其他平台自行查找。
pacman -S samba
Samba 的配置文件在 /etc/samba/smb.conf。首先我把硬盘挂载到 /data01 目录,然后新建了文件夹 share,并且把文件夹权限改成了 777。
[global]
workgroup = WORKGROUP
server string = Media Server
security = user
log file = /var/log/samba/log.%m
max log size = 50
hosts allow = 127., 172., 192.168.1., 192.168.3., 10.
[share]
comment = To share
path = /data01/share
valid users = ouyangsong
read only = No
browseable = No
然后检查配置的语法。
testparm
常用的选项:

Samba 需要 Linux 账号才可以使用,用户名可以共享,但是密码不共享。我就直接使用本来就有的账号 ouyangsong,只需要把它设置一个 Samba 密码即可。
smbpasswd -a ouyangsong
如果是专门创建来登陆 Samba 服务,最好禁用其他登陆选项。
禁用 Shell
usermod --shell /user/bin/nologin --lock ouyangsong
禁用 SSH
修改 /etc/ssh/sshd_conf 中的 AllowUsers 字段。
网上有些教程这里过时了,因为这个服务名字已经修改了。
systemctl restart smb nmb
Mac 打开 finder,然后 command + k 就可以打开远程连接。填入对应的 IP,就会提示输入用户名和密码就可以登陆了。

安卓我使用的文件管理器是 Solid Explorer,添加远程连接找到 LAN/SMB 方式即可。

saltstack的master上minion连接较多,下面这个程序可以分析哪些minion任务执行成功,哪些执行失败以及哪些没有返回。
脚本说明:
一、最先打印出本次任务的job id、command name以及其它相关信息,然后是本次任务的执行流程和结果,这和我们单独执行这个命令是一致的。最后程序会打印出所有未成功的任务和未返回的任务,并且重新执行一遍。 这里要说明的是,因为没有查看对应的情景,对于失败任务的排判断做的不好,另外minion未连接我也归为任务未返回,并且会再执行一遍,实际上如果是minion未连接,则不应该执行。
二、 程序我们先派生子进程去执行salt命令,再salt命令执行完毕后,我们的程序会对其中失败的和未返回的minion任务二次执行
三、编写脚本
import salt.utils.event
import re
import signal, time
import sys
import os
def single_handler(target):
os.execl('/usr/bin/salt', 'salt', target, 'state.sls', 'os')
def handler(num1, num2):
#signal.signal(signal.SIGCLD,signal.SIG_IGN)
print 'We are in signal handler'
print 'Job Not Ret: '+str(record[jid])
print ' Job Failed: '+str(failedrecord[jid])
print 'all done...'
for item in failedrecord[jid]:
#print item
try:
pid = os.fork()
if pid == 0:
single_handler(item)
except OSError:
print 'we exec. '+ item +' error!'
for item in record[jid]:
#print item
try:
print 'fork ok ' + item
pid = os.fork()
if pid == 0 :
single_handler(item)
except OSError:
print 'we exec. '+item + ' error!'
sys.stdout.flush()
os._exit(0)
fd = open('/tmp/record', 'w+')
#sys.stdout = fd
#sys.stderr = fd
signal.signal(signal.SIGCLD, handler)
#fd = open('/var/log/record', 'w+')
os.dup2(fd.fileno(), sys.stdout.fileno())
os.dup2(fd.fileno(), sys.stderr.fileno())
#sys.stdout = fd
#sys.stderr = fd
try:
pid = os.fork()
if pid == 0:
time.sleep(2)
try:
os.execl('/usr/bin/salt', 'salt', '*', 'state.sls', 'os')
except OSError:
print 'exec error!'
os._exit(1)
except OSError:
print 'first fork error!'
os._exit(1)
event = salt.utils.event.MasterEvent('/var/run/salt/master')
flag=False
reg=re.compile('salt/job/([0-9]+)/new')
reg1=reg
#a process to exec. command, but will sleep some time
#another process listen the event
#if we use this method, we can filter the event through func. name
record={}
failedrecord={}
jid = 0
#try:
for eachevent in event.iter_events(tag='salt/job',full=True):
eachevent=dict(eachevent)
result = reg.findall(eachevent['tag'])
if not flag and result:
flag = True
jid = result[0]
print " job_id: " + jid
print " Command: " + dict(eachevent['data'])['fun'] + ' ' + str(dict(eachevent['data'])['arg'])
print " RunAs: " + dict(eachevent['data'])['user']
print "exec_time: " + dict(eachevent['data'])['_stamp']
print "host_list: " + str(dict(eachevent['data'])['minions'])
sys.stdout.flush()
record[jid]=eachevent['data']['minions']
failedrecord[jid]=[]
reg1 = re.compile('salt/job/'+jid+'/ret/([0-9.]+)')
else:
result = reg1.findall(eachevent['tag'])
if result:
record[jid].remove(result[0])
if not dict(eachevent['data'])['success']:
failedrecord[jid].append(result[0])
#except:
# print 'we in except'
"""
print 'Job Not Ret: '+str(record[jid])
print ' Job Failed: '+str(failedrecord[jid])
for item in failedrecord[jid]:
os.system('salt '+ str(item) + ' state.sls os')
for item in record[jid]:
os.system('salt '+ str(item) + ' state.sls os')
os._exit(0)
"""
执行结果:
job_id: 20151208025319005896
Command: state.sls ['os']
RunAs: root
exec_time: 2015-12-08T02:53:19.006284
host_list: ['172.18.1.212', '172.18.1.214', '172.18.1.213', '172.18.1.211']
172.18.1.213:
----------
ID: configfilecopy
Function: file.managed
Name: /root/node3
Result: True
Comment: File /root/node3 is in the correct state
Started: 02:53:19.314015
Duration: 13.033 ms
Changes:
----------
ID: commonfile
Function: file.managed
Name: /root/commonfile
Result: True
Comment: File /root/commonfile is in the correct state
Started: 02:53:19.327173
Duration: 1.993 ms
Changes:
Summary
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
172.18.1.212:
----------
ID: configfilecopy
Function: file.managed
Name: /root/node2
Result: True
Comment: File /root/node2 is in the correct state
Started: 02:53:19.337325
Duration: 8.327 ms
Changes:
----------
ID: commonfile
Function: file.managed
Name: /root/commonfile
Result: True
Comment: File /root/commonfile is in the correct state
Started: 02:53:19.345787
Duration: 1.996 ms
Changes:
Summary
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
172.18.1.211:
----------
ID: configfilecopy
Function: file.managed
Name: /root/node1
Result: True
Comment: File /root/node1 is in the correct state
Started: 02:53:19.345017
Duration: 12.741 ms
Changes:
----------
ID: commonfile
Function: file.managed
Name: /root/commonfile
Result: True
Comment: File /root/commonfile is in the correct state
Started: 02:53:19.357873
Duration: 1.948 ms
Changes:
Summary
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
172.18.1.214:
Minion did not return. [Not connected]
We are in signal handler
Job Not Ret: ['172.18.1.214']
Job Failed: []
all done...
fork ok 172.18.1.214
172.18.1.214:
Minion did not return. [Not connected]