Git 更安全的强制推送,–force-with-lease

由于 git rebase 命令的存在,强制将提交推送到远端仓库似乎也有些必要。不过都知道 git push –force 是不安全的,这让 git rebase 命令显得有些鸡肋。

本文将推荐 –force-with-lease 参数,让我们可以更安全地进行强制推送。

–force-with-lease 参数自 Git 的 1.8.5 版本开始提供,只在解决 git push –force 命令造成的安全问题。

那么 git push –force 命令有什么安全问题?

–force 会使用本地分支的提交覆盖远端推送分支的提交。也就是说,如果其他人在相同的分支推送了新的提交,你的这一举动将“删除”他的那些提交!就算在强制推送之前先 fetch 并且 merge 或 rebase 了也是不安全的,因为这些操作到推送之间依然存在时间差,别人的提交可能发生在这个时间差之内。

–force-with-lease 将解决这种安全问题

使用了 –force-with-lease 参数之后,上面那种安全问题就没有那么危险了。

使用此参数推送,如果远端有其他人推送了新的提交,那么推送将被拒绝,这种拒绝和没有加 –force 参数时的拒绝是一样的。

walterlv$ git push --force-with-lease
To https://github.com/walterlv/walterlv.github.io.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/walterlv/walterlv.github.io.git'

请特别注意——如果你 fetch 之后在本地的 origin 相关分支上已经看到了别人的提交,依然进行强制推送,你还是会覆盖别人的提交。也就是说,–force-with-lease 解决的是本地仓库不够新时,依然覆盖了远端新仓库的问题,如果你执意想要覆盖远端提交,只需要先 fetch 再推送,它也不会拒绝的。

在使用 git push –force-with-lease 命令被拒绝时,你需要 fetch 仓库,然后确认其他人是否对此分支有新的修改,如果没有,你才可以继续强制推送。

walterlv$ git fetch
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 46 (delta 21), reused 40 (delta 15), pack-reused 0
Unpacking objects: 100% (46/46), done.
From https://github.com/walterlv/walterlv.github.io
   e75edf0..217a49d  master     -> origin/master

在 fetch 完毕之后,请一定检查此分支是否已经被其他人修改,如果有新的提交,你应该进行一次 merge 或者 rebase。

walterlv$ git rebase
First, rewinding head to replay your work on top of it...
Applying: Add post "safe push using force with lease".

此后,再次进行推送或强制推送即可。

walterlv$ git push --force-with-lease
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 363 bytes | 363.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/walterlv/walterlv.github.io.git
   219a6d5..dff94a5  master -> master

额外的问题:为什么推送到远端的提交还依然要用 rebase?

Git 官方文档对 rebase 有如下描述:

未分类

▲ 如果你想吐槽那段中文翻译,我只想说——那是 Git 的官方中文文档

既然已经推送的提交不应该再进行 rebase,那本不应该会遇到本文提到的问题。但是——GitHub 的工作流或者 GitLab 的工作流中,都有一种行为是 rebase 自己的分支到 origin/master 上,以保证 master 分支上的提交是纯粹的干净的。也就是说,本意是禁止对合并到 master 或 develop 分支上的提交进行 rebase;但对于自己的 temp 分支或者 feature 分支,因为提交还没有合并到主干中,随时删除掉或者将历史进行美化也不会造成太大的问题。

未分类

▲ 这是 GitLab 上的设置,可以要求提交者必须进行 rebase 才允许合并。

Git 在不同的项目使用不同的author

安装好 Git 的时候,每个人都会设置全局的账户:

git config --global user.name "laixintao"
git config --global user.email "[email protected]"

公司的 Git 账户和个人的 Git 账户不一样,可以在项目中设置此项目的 Author :

git config user.name "laixintao"
git config user.email "[email protected]"

这样私人账户每次都要设置,可以设置一条 Git 的 alias ,这样每次都用这一条命令就可以了。

git config --global alias.private 'config user.email "[email protected]"'

其实 git config –global 命令是修改的一个文件,$HOME/.gitconfig 例如我的文件如下:

[core]
        editer = "/usr/local/bin/vim"
        editor = vim
        excludesfile = ~/.gitignore_global
[user]
        name = laixintao
        email = [email protected]
        username = laixintao
[alias]
        pr = pullrequest
        ck = checkout
        br = branch
        lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
[merge]
        tool = vimdiff
        conflictstyle = diff3
[pull]
    rebase = true
[mergetool]
        prompt = false
[github]
        user = [email protected]
[filter "lfs"]
        process = git-lfs filter-process
        required = true
        clean = git-lfs clean -- %f
        smudge = git-lfs smudge -- %f

同之前提到的 myrc 项目一样,gitconfig 这个文件我也是用 git 来追踪的,去一个新环境只要安装好这个项目就可以回到自己熟悉的 git 了。

zabbix 监控 Resin

一、环境介绍

服务器信息:
zabbix-server:172.16.4.6
zabbix-java-gateway:172.16.0.7
Resin:172.16.0.6

软件环境:
 zabbix版本:Zabbix server v2.4.6
 zabbix-java-gateway:zabbix-java-gateway-2.4.6-1.el6.x86_64.rpm
 测试jar:cmdline-jmxclient-0.10.3.jar

二、安装zabbix

zabbix安装可以参考zabbix官网介绍,这里就不在详细说明了,参考如下网址:

https://www.zabbix.com/documentation/2.4/manual/installation/install_from_packages

zabbix-java-gateway下载地址:

http://www.zabbix.com/download.php

zabbix-java-gateway官网安装介绍:

https://www.zabbix.com/documentation/2.4/ru/manual/concepts/java?s[]=java

测试jar下载地址:(需要翻。。。)

http://crawler.archive.org/cmdline-jmxclient/cmdline-jmxclient-0.10.3.jar

三、安装zabbix-java-gateway网关

安装

# rpm -ihv zabbix-java-gateway-2.4.6-1.el6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:zabbix-java-gateway    ########################################### [100%]

修改配置文件:

# grep  -Ev "(^#|^$)" /etc/zabbix/zabbix_java_gateway.conf 
LISTEN_IP="172.16.0.7"   \zabbix-java-gateway 网关监听地址
LISTEN_PORT=10052        \zabbix-java-gateway  网关监听端口
PID_FILE="/var/run/zabbix/zabbix_java.pid" \zabbix-java-gateway 的pid文件路径
START_POLLERS=5    \启动5个线程
TIMEOUT=10        \超时时长

启动zabbix-java-gateway网关

# /etc/init.d/zabbix-java-gateway start

检查zabbix-java-gateway网关是否启动成功

# netstat -tpln | grep 10052
tcp        0      0 172.16.0.7:10052            0.0.0.0:*                   LISTEN      6976/java

四、配置Resin,启用JMX

在Resin家目录下的conf/目录中,修改resin.conf配置文件,添加一下信息:

可以参考官网介绍:http://caucho.com/resin-4.0/admin/advanced-jmx.xtp

      <jvm-arg>-Dcom.sun.management.jmxremote</jvm-arg>
      <jvm-arg>-Dcom.sun.management.jmxremote.port=12345</jvm-arg>
      <jvm-arg>-Dcom.sun.management.jmxremote.ssl=false</jvm-arg>
      <jvm-arg>-Dcom.sun.management.jmxremote.authenticate=false</jvm-arg>
      <jvm-arg>-Djava.rmi.server.hostname=172.16.0.6</jvm-arg> \此项可选

在resin中添加完Resin后,重启启动resin

# /etc/init.d/resin stop
# /etc/init.d/resin start

在zabbix-server端启用zabbix-java-gateway选项:

# grep -Ev "(^#|^$)" /etc/zabbix/zabbix_server.conf | grep -i java
JavaGateway=172.16.0.7 \zabbix-java-gateway的地址
JavaGatewayPort=10052   \zabbix-java-gateway的端口号
StartJavaPollers=5       \启动5个线程

五、在zabbix-java-gateway服务器上,利用cmdline-jmxclient-0.10.3.jar获取resin服务器的key

获取key

# java -jar cmdline-jmxclient-0.10.3.jar  - 172.16.0.6:12345 | sort
com.alibaba.druid:id=1924372698,type=DruidDataSource
com.alibaba.druid:type=DruidDataSourceStat
com.alibaba.druid:type=DruidDriver
com.alibaba.druid:type=DruidStatService
com.alibaba.druid:type=MockDriver
com.sun.management:type=HotSpotDiagnostic
java.lang:name=CMS Old Gen,type=MemoryPool
java.lang:name=CMS Perm Gen,type=MemoryPool
java.lang:name=CodeCacheManager,type=MemoryManager
java.lang:name=Code Cache,type=MemoryPool
java.lang:name=ConcurrentMarkSweep,type=GarbageCollector
java.lang:name=Par Eden Space,type=MemoryPool
java.lang:name=ParNew,type=GarbageCollector
java.lang:name=Par Survivor Space,type=MemoryPool
java.lang:type=ClassLoading
java.lang:type=Compilation
java.lang:type=Memory
java.lang:type=OperatingSystem
java.lang:type=Runtime
java.lang:type=Threading
java.util.logging:type=Logging
JMImplementation:type=MBeanServerDelegate
resin:Host=www.magedu.com,name=deploy,type=EarDeploy
resin:Host=www.magedu.com,name=deploy,type=ResourceDeploy
resin:Host=www.magedu.com,name=/resin-doc,type=WebApp
resin:Host=www.magedu.com,name=/solr,type=WebApp
resin:Host=www.magedu.com,name=/,type=WebApp
resin:Host=www.magedu.com,name=webapps,type=WebAppDeploy
resin:Host=www.magedu.com,WebApp=/,name=/data/web/www.magedu.com/WEB-INF/rewrite.xml,type=RewriteImport
resin:Host=www.magedu.com,WebApp=/resin-doc,name=jdbc/resin,type=ConnectionPool
resin:Host=www.magedu.com,WebApp=/resin-doc,name=jdbc/resin,type=JdbcDriver
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-basic-field,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-basic,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-create,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-inherit,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-many2many,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-many2one,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-one2many,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-query,type=WebApp
resin:Host=www.magedu.com,WebApp=/resin-doc,name=/resin-doc/examples/amber-session,type=WebApp
。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。\此处省略一些信息
resin:name=127.0.0.1-6800,type=Port
resin:name=app-tier,type=Cluster
resin:name=hosts,type=HostDeploy
resin:name=INADDR_ANY-8002,type=Port
resin:name=www.magedu.com,type=Host
resin:type=BlockManager
resin:type=PersistentStore
resin:type=ProxyCache
resin:type=Resin
resin:type=Server
resin:type=ThreadPool

获取value

# java -jar cmdline-jmxclient-0.10.3.jar  - 172.16.0.6:12345  "resin:type=ThreadPool" \利用此key可以获取此key中的多个属性,然后利用属性获取值
Attributes:
 Name: The name property of the JMX ObjectName (type=java.lang.String)
 ObjectName: The JMX ObjectName for the MBean (type=javax.management.ObjectName)
 ThreadActiveCount: The current number of active threads (type=int)
 ThreadCount: The current number of managed threads (type=int)
 ThreadIdleCount: The current number of idle threads (type=int)
 ThreadIdleMax: The configured maximum number of idle threads (type=int)
 ThreadIdleMin: The configured minimum number of idle threads (type=int)
 ThreadMax: The configured maximum number of threads (type=int)
 Type: The type property of the JMX ObjectName (type=java.lang.String)
# java -jar cmdline-jmxclient-0.10.3.jar  - 172.16.0.6:12345  "resin:type=ThreadPool"  ThreadMax  \利用"resin:type=ThreadPool" 获取ThreadMax的值
04/01/2016 18:29:58 +0800 org.archive.jmx.Client ThreadMax: 15000

六、作为zabbix使用的key、value都获取到以后,我们接下来制作zabbix模板

创建一个名为Resin的模板

未分类

添加Applications;以下是我自己添加的;大家可以根据自己的需求添加:

未分类

添加完Applications以后,在添加item,在这里以MemoryPool_Eden为例,添加item

未分类

添加完item以后,在添加图形;以下是我自己添加的绘图信息:

未分类

到此模板制作完成,现在开始在主机中关联模板:

未分类

添加完后,可以看到此主机的JMX变为绿色:

未分类

到此我们可以静心心来,查看绘制的图形信息了

未分类

到此,监控已经完成,如有做的不好的地方,请大家帮忙指正,O(∩_∩)O谢谢

使用vsftpd搭建显式SSL/TLS加密的FTP服务器(FTPS)

最近在Hostens购买了立陶宛的大硬盘小鸡,用于存放备份数据,因此需要在服务器上搭建FTP,而通过普通FTP协议在公网传输数据具有一定的安全隐患,因此需要为FTP服务器配置SSL来对传输的数据进行加密。

服务端软件:vsftpd

以下是/etc/vsftpd/vsftpd.conf文件的SSL配置部分

vsftpd的基础及虚拟用户配置:

https://lonelyboy.org/post/34.html

使用FTP over SSL必须拥有SSL证书,证书获取方法可以使用openssl自签署或者通过letsencrypt的certbot获取证书。

#SSL配置部分

ssl_enable=YES

allow_anon_ssl=NO

force_local_data_ssl=YES

force_local_logins_ssl=YES

force_anon_logins_ssl=YES

force_anon_data_ssl=YES

ssl_tlsv1=YES

ssl_sslv2=NO

ssl_sslv3=NO

require_ssl_reuse=NO

ssl_ciphers=HIGH

rsa_cert_file=服务器证书存放目录

rsa_private_key_file=服务器证书对应的私钥存放目录

使用Docker Compose部署python应用

这篇文章我们通过Docker Compose来运行部署一个简单的Python web应用,我们将使用Flask框架和Redis。

预备的东西

  • 安装好Docker
  • 安装好Docker Compose

定义应用的依赖

1、创建项目目录

mkdir composetest
cd composetest

2、创建应用文件app.py

在项目根目录composetest下创建并打开app.py文件,编写如下代码:

import time

import redis
from flask import Flask


app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)


@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

这里,redis是应用网络上edis容器的主机名,我们使用Redis的默认端口:6379。

3、创建应用requirements.txt文件

在项目根目录composetest下创建requirements.txt文件,编辑文件:

flask
redis

创建Dockerfile文件

我们写个Dockerfile文件来构建Docker镜像,该镜像会包含该Python应用的所有依赖,包括Python本身。

在项目根目录composetest下创建Dockerfile文件并编辑文件:

FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

该文件告诉Docker完成以下工作:

  • 构建一个以Python 3.4镜像为基础镜像的镜像.
  • 把当前目录 . 复制到镜像的 /code 路径下.
  • 设置工作目录为 /code .
  • 安装Python依赖.
  • 设置容器的默认命令.

在Compose文件定义服务

在项目根目录composetest下创建docker-compose.yml文件并编辑:

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

该Compose文件定义两个服务:web和redis。该web服务将

  • 使用从Dockerfile文件构建的镜像.
  • 暴露容器的5000端口映射到宿主机的5000端口。我们使用Flask的web服务器默认端口 5000.

redis服务使用从Docker Hub registry仓库拉取的公有Redis镜像。

使用Compose构建和运行app

在项目根目录composetest下启动运行应用:

$ docker-compose up
Starting composetest_web_1   ... done
Starting composetest_redis_1 ... done
Attaching to composetest_redis_1, composetest_web_1
redis_1  | 1:C 05 May 02:38:07.354 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 05 May 02:38:07.354 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 05 May 02:38:07.354 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1  | 1:M 05 May 02:38:07.355 * Running mode=standalone, port=6379.
redis_1  | 1:M 05 May 02:38:07.355 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1  | 1:M 05 May 02:38:07.355 # Server initialized
redis_1  | 1:M 05 May 02:38:07.355 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1  | 1:M 05 May 02:38:07.355 * DB loaded from disk: 0.000 seconds
redis_1  | 1:M 05 May 02:38:07.355 * Ready to accept connections
web_1    |  * Serving Flask app "app" (lazy loading)
web_1    |  * Environment: production
web_1    |    WARNING: Do not use the development server in a production environment.
web_1    |    Use a production WSGI server instead.
web_1    |  * Debug mode: on
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1    |  * Restarting with stat
web_1    |  * Debugger is active!
web_1    |  * Debugger PIN: 320-444-115
web_1    | 172.18.0.1 - - [05/May/2018 02:38:11] "GET / HTTP/1.1" 200 -

Compose拉取Redis镜像,为我们的应用构建一个镜像,并开始我们定义的服务。这种情况,代码在构建时是被静态地复制到镜像里。

打开浏览器,输入http://0.0.0.0:5000/, 会看到页面输出:

Hello World! I have been seen 1 times.

刷新页面,这里的数字会顺序递增

Hello World! I have been seen 2 times.

打开另一个terminal窗口,输入docker image ls可以看到本地的镜像列表,列表中会看到redis和web:

$ docker image ls
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
composetest_web                  latest              88cd35029579        12 hours ago        94.9MB
springio/gs-spring-boot-docker   latest              6c173fe17a59        26 hours ago        118MB
python                           3.4-alpine          42756b6e26a0        2 weeks ago         83.6MB
hello-world                      latest              e38bc07ac18e        3 weeks ago         1.85kB
redis                            alpine              98bd7cfc43b8        5 weeks ago         27.8MB
openjdk                          8-jdk-alpine        224765a6bdbe        3 months ago        102MB

要停止应用,可以输入docker-compose down命令或者按CTRL + C。

修改Compose文件

编辑docker-compose.yml,为web服务添加一个bind mount:

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
    volumes:
     - .:/code
  redis:
    image: "redis:alpine"

新添加的 volume 键将宿主机的项目目录挂载到容器里的 /code 目录,这样我们可以即时地修改代码,而不用重新构建镜像。

重新构建和运行应用

项目根目录下输入 docker-compose up 重新构建并运行修改Compose文件后的应用

$ docker-compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
...

刷新浏览器,会看到计数依然会递增。

更新应用

现在项目代码已经通过 volume 被挂载到容器,我们可以修改代码并即时看到变化,而不用重新构建镜像。我们编辑修改下 app.py文件,比如将 Hello World! 修改为 Hello from Docker!:

return 'Hello from Docker! I have been seen {} times.n'.format(count)

刷新浏览器,页面会相应地更新

未分类

docke-compose其他命令

在后台运行服务:

$ docker-compose up -d

查看当前运行服务:

$ docker-compose ps

查看web服务在使用的环境变量:

$ docker-compose run web env

停止服务:

$ docker-compose stop

停止并删除容器、网络、镜像和volumes卷

$ docker-compose down --volumes

Centos-7安装zabbix

本例环境使用Centos7.3 64位

安装zabbix需要mysql的支持,下面是快速安装LNMP的方法(使用EZHTTP安装)

安装LNMP

首先创建一个目录存放下载文件:

[root@localhost ~]# mkdir /software
[root@localhost software]# cd /software/

安装wget工具:

[root@localhost software]# yum -y install wget

下载EZHTTP安装脚本:

[root@localhost software]# wget --no-check-certificate https://github.com/centos-bz/ezhttp/archive/master.zip?time=$(date +%s) -O ezhttp.zip

启动脚本:

[root@localhost software]# unzip ezhttp.zip
[root@localhost software]# cd ezhttp-master
[root@localhost ezhttp-master]# chmod +x start.sh
[root@localhost ezhttp-master]# ./start.sh

进去选择页面

除了数字选择项需要确认输入,其他的的按回车默认就行:

nginx 和 apache 都行,个人比较喜欢nginx
php版本5.5-7.1
mysql版本5.6

[root@localhost ezhttp-master]# ./start.sh
#############################################################################

You are welcome to use this script to deploy your linux,hope you like.
The script is written by Zhu Maohai.
If you have any question.
please visit http://devops.webres.wang/ezhttp/ and submit your issue.thank you.

############################################################################

1) LAMP LNMP LANMP Installation.
2) Some Useful Tools.
3) Upgrade Software
4) Exit.

please select: 1
you select LAMP LNMP LANMP Installation.
1) LNMP(Nginx MySQL PHP)
2) LAMP(Apache MySQL PHP)
3) LNAMP(Nginx Apache MySQL PHP)
4) back to main menu

please input the package you like to install: 1
#################### nginx setting ####################


1) nginx-1.8.0
2) tengine-2.1.0
3) openresty-1.9.7.3
4) custom_version
5) do_not_install

which nginx you do select(default do_not_install): 1
your selection: nginx-1.8.0
nginx-1.8.0 install location(default:/usr/local/nginx,leave blank for default): 
nginx-1.8.0 install location: /usr/local/nginx
the nginx-1.8.0 configure parameter is:
--prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/software/ezhttp-master/soft/openssl-1.0.2h  --with-http_sub_module --with-http_stub_status_module --with-pcre --with-pcre=/software/ezhttp-master/soft/pcre-8.33 --with-zlib=/software/ezhttp-master/soft/zlib-1.2.8 --with-http_secure_link_module


Would you like to change it?[N/y](default n): 
you select no,configure parameter will not be changed.

Do you need to install nginx module?[N/y](default n): 
#################### mysql setting ####################


1) mysql-5.1.73
2) mysql-5.5.54
3) mysql-5.6.35
4) mysql-5.7.17 (need about 2GB RAM when building,try mysql-5.6 if failed)
5) libmysqlclient18
6) custom_version
7) do_not_install

which mysql you'd select(default do_not_install): 3
your selection: mysql-5.6.35
mysql-5.6.35 install location(default:/usr/local/mysql,leave blank for default): 
mysql-5.6.35 install location: /usr/local/mysql
mysql data location(default:/usr/local/mysql/data,leave blank for default): 
mysql-5.6.35 data location: /usr/local/mysql/data
mysql port number(default:3306,leave blank for default): 
mysql port number: 3306
mysql server root password (default:root,leave blank for default): 123456
mysql-5.6.35 root password: 123456
the mysql-5.6.35 configure parameter is:
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/usr/local/mysql/etc -DMYSQL_UNIX_ADDR=/usr/local/mysql/data/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=complex -DENABLED_LOCAL_INFILE=1 


Would you like to change it?[N/y](default n): 
you select no,configure parameter will not be changed.
#################### php setting ####################


1) php-5.2.17
2) php-5.3.29
3) php-5.4.43
4) php-5.5.27
5) php-5.6.15
6) php-7.1.0
7) custom_version
8) do_not_install

which php you'd select(default do_not_install): 6
your selection: php-7.1.0
php-7.1.0 install location(default:/usr/local/php,leave blank for default): 
php-7.1.0 install location: /usr/local/php
the php-7.1.0 configure parameter is:
--prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --enable-bcmath=shared --with-pdo_sqlite --with-gettext=shared --with-iconv --enable-ftp=shared --with-sqlite --with-sqlite3 --enable-mbstring=shared --enable-sockets=shared --enable-zip --enable-soap=shared --with-openssl --with-zlib --with-curl=shared --with-gd=shared --with-jpeg-dir --with-png-dir --with-freetype-dir --with-mcrypt=shared,/opt/ezhttp/libmcrypt-2.5.8 --with-mhash=shared,/opt/ezhttp/mhash-0.9.9.9 --enable-opcache --with-mysql=mysqlnd --with-mysqli=shared,mysqlnd --with-pdo-mysql=shared,mysqlnd --without-pear --with-libdir=lib64 --disable-fileinfo


Would you like to change it?[N/y](default n): 
you select no,configure parameter will not be changed.
#################### PHP modules install ####################
php-7.1.0 version available modules:

#################### php_modules install ####################

1) fileinfo
2) php-gmp
3) php-swoole-1.7.20
4) do_not_install

please input one or more number between 1 and 4(default do_not_install)(ie.1 2 3): 
your selection do_not_install
#################### other_soft install ####################

1) memcached-1.4.24
2) pure-ftpd-1.0.41
3) phpMyAdmin-4.4.12-all-languages
4) redis-3.0.3
5) mongodb-linux-x86_64-2.4.9
6) phpRedisAdmin-1.1.0
7) memadmin-1.0.12
8) rockmongo-1.1.6-fix-auth
9) jdk1.7.0_79
10) jdk1.8.0_66
11) apache-tomcat-7.0.68
12) apache-tomcat-8.0.39
13) do_not_install

please input one or more number between 1 and 13(default do_not_install)(ie.1 2 3): 1 2 3 4 6 10 12
your selection memcached-1.4.24 pure-ftpd-1.0.41 phpMyAdmin-4.4.12-all-languages redis-3.0.3 phpRedisAdmin-1.1.0 jdk1.8.0_66 apache-tomcat-8.0.39
input memcached-1.4.24 location(default:/usr/local/memcached): 
memcached location: /usr/local/memcached
input pure-ftpd-1.0.41 location(default:/usr/local/pureftpd): 
pureftpd location: /usr/local/pureftpd
Would you like to install web user manager for pureftpd?[N/y](default n): 
you select not install web manager
input phpMyAdmin-4.4.12-all-languages location(default:/home/wwwroot/phpmyadmin): 
phpmyadmin location: /home/wwwroot/phpmyadmin
input redis-3.0.3 location(default:/usr/local/redis): 
redis location: /usr/local/redis
please input the max memory allowed for redis(ie.128M,512m,2G,4g): 128M
128M
input phpRedisAdmin-1.1.0 location(default:/home/wwwroot/redisadmin): 
phpRedisAdmin location: /home/wwwroot/redisadmin
input jdk1.8.0_66 location(default:/usr/local/jdk1.8.0_66): 
jdk8 location: /usr/local/jdk1.8.0_66
input apache-tomcat-8.0.39 location(default:/usr/local/tomcat8): 
tomcat8 location: /usr/local/tomcat8
#################### your choice overview ####################

Package: lnmp

*****Nginx Setting*****
Nginx: nginx-1.8.0
Nginx Location: /usr/local/nginx
Nginx Configure Parameter: --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/software/ezhttp-master/soft/openssl-1.0.2h  --with-http_sub_module --with-http_stub_status_module --with-pcre --with-pcre=/software/ezhttp-master/soft/pcre-8.33 --with-zlib=/software/ezhttp-master/soft/zlib-1.2.8 --with-http_secure_link_module
Nginx Modules: 


*****MySQL Setting*****
MySQL Server: mysql-5.6.35
MySQL Location: /usr/local/mysql
MySQL Data Location: /usr/local/mysql/data
MySQL Port Number: 3306
MySQL Root Password: 123456
MySQL Configure Parameter: -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/usr/local/mysql/etc -DMYSQL_UNIX_ADDR=/usr/local/mysql/data/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=complex -DENABLED_LOCAL_INFILE=1 

*****PHP Setting*****
PHP: php-7.1.0
PHP Location: /usr/local/php
PHP Configure Parameter: --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --enable-bcmath=shared --with-pdo_sqlite --with-gettext=shared --with-iconv --enable-ftp=shared --with-sqlite --with-sqlite3 --enable-mbstring=shared --enable-sockets=shared --enable-zip --enable-soap=shared --with-openssl --with-zlib --with-curl=shared --with-gd=shared --with-jpeg-dir --with-png-dir --with-freetype-dir --with-mcrypt=shared,/opt/ezhttp/libmcrypt-2.5.8 --with-mhash=shared,/opt/ezhttp/mhash-0.9.9.9 --enable-opcache --with-mysql=mysqlnd --with-mysqli=shared,mysqlnd --with-pdo-mysql=shared,mysqlnd --without-pear --with-libdir=lib64 --disable-fileinfo

*****Other Software Setting*****
Other Software:  memcached-1.4.24 pure-ftpd-1.0.41 phpMyAdmin-4.4.12-all-languages redis-3.0.3 phpRedisAdmin-1.1.0 jdk1.8.0_66 apache-tomcat-8.0.39
memcached location: /usr/local/memcached
pureftpd location: /usr/local/pureftpd
phpmyadmin_location: /home/wwwroot/phpmyadmin
redis_location: /usr/local/redis
phpRedisAdmin_location: /home/wwwroot/redisadmin
jdk8_location: /usr/local/jdk1.8.0_66
tomcat8_location: /usr/local/tomcat8
JAVA_HOME: /usr/local/jdk1.8.0_66

##############################################################

Are you ready to configure your Linux?[Y/n](default y):

安装过程等待即可:

..............................
..............................

安装成功:

start programs...
Starting nginx daemon: .
Starting MySQL.. SUCCESS! 
Warning: Using a password on the command line interface can be insecure.
Starting php-fpm  done
Starting memcached: 
Start pureftpd....  [OK] 
Starting Redis server...

使用EZHTTP安装成功后各服务已经打开,输入Linxu 机器IP 访问即可:

未分类

恭喜,安装成功了!

开始安装zabbix

配置源

Zabbix在CentOS基本源里不可获得,因此必须配置EPEL 和Zabbix 官方repository,因为需要一款名叫fping的软件(这款软件你下载源码编译安装貌似行不通!),然后其他的yum源将mysql全部识别为mariadb了,所以想yum安装mysql,请安装mysql社区版官方源,或者编译安装,上面的EZHTTP安装脚本就是编译安装

安装EPEL repository

[root@localhost software]# pwd
/software
[root@localhost software]# yum -y install epel-release

配置ZabbixZone package repository and GPG key

[root@localhost software]# rpm --import http://repo.zabbix.com/RPM-GPG-KEY-ZABBIX
[root@localhost software]# rpm --import http://repo.zabbix.com/RPM-GPG-KEY-ZABBIX-A14FE591
[root@localhost software]# yum -y install fping
[root@localhost software]# rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm

安装Zabbix server and agent(agent是可选的)

安装Zabbix server and agent:(配置自己监控自己,所以安装了zabbix-agent)

yum -y install zabbix-server-mysql zabbix-web-mysql zabbix-agent

可以上zabbix rpm包官网查看或下载相应包

http://repo.zabbix.com/

创建MySQL 数据库和用户

登录Mysql:

[root@localhost software]# mysql -uroot -p123456

创建一个数据库zabbix和数据库用户zabbix:

mysql> create database zabbix character set utf8;

mysql> grant all privileges on zabbix.* to 'zabbix'@'localhost' identified by 'zabbix';

mysql> flush privileges;

数据库导入zabbix template

看yum安装的zabbix-server-mysql-3.x.x 这个文件的版本是多少就改成多少

[root@localhost software]# zcat /usr/share/doc/zabbix-server-mysql-3.2.4/create.sql.gz |mysql -uzabbix -pzabbix -b zabbix

配置Zabbix server

vi /etc/zabbix/zabbix_server.conf

配置下面的几个参数
带#号的就去掉#号,并修改其值

ListenPort=10051
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=zabbix
DBSocket=/usr/local/mysql/data/mysql.sock
DBPort=3306

配置zabbix-agent

vi /etc/zabbix/zabbix_agentd.conf

配置zabbix server的ip

## Line 95 - Specify Zabbix server ##

Server=127.0.0.1

## Line 136 - Specify Zabbix server ##

ServerActive=127.0.0.1

## Line 147 - Specify Zabbix server Hostname or IP address

Hostname=127.0.0.1

修改PHP 设置

修改php.ini为zabbix 建议的设置
编辑文件 php.ini,

[root@localhost software]# vi /usr/local/php/etc/php.ini

设置下面的参数:

max_execution_time = 300

max_input_time = 300

memory_limit = 128M

post_max_size = 32M

upload_max_filesize = 2M

date.timezone = Asia/Shanghai

安装时可能缺少下面扩展,把下面内容添加到php.ini

extension=bcmath.so
extension=gettext.so
extension=sockets.so

安装扩展

[root@localhost ext]# cd /software/ezhttp-master/soft/php-7.1.0/ext
[root@localhost ext]# pwd
/software/ezhttp-master/soft/php-7.1.0/ext
[root@localhost ext]# cd sockets/
[root@localhost sockets]# /usr/local/php/bin/phpize
[root@localhost sockets]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost sockets]# cd ..
[root@localhost ext]# cd bcmath/
[root@localhost bcmath]# /usr/local/php/bin/phpize
[root@localhost bcmath]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@localhost bcmath]# cd ..
[root@localhost ext]# cd gettext/
[root@localhost gettext]# /usr/local/php/bin/phpize
[root@localhost gettext]# ./configure --with-php-config=/usr/local/php/bin/php-config

使用下面命令可以看到有一个扩展存放的目录,我们需要的扩展模块在其中即安装成功

[root@localhost gettext]# make && make install

修改php-fpm运行的用户和组

[root@localhost software]# vi /usr/local/php/etc/php-fpm.d/www.conf
user = www
group = www

方法一:使用 apache 服务器

apache配置zabbix-web站点文件

[root@localhost etc]# cd /etc/httpd/

vi conf/httpd.conf
修改下面内容:

Listen 80

User www
Group wwww

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

vi conf.d/zabbix.conf
修改内容如下:

<IfModule mod_php5.c>
    php_value max_execution_time 300
    php_value memory_limit 128M
    php_value post_max_size 32M
    php_value upload_max_filesize 8M
    php_value max_input_time 300
    php_value always_populate_raw_post_data -1
    php_value date.timezone Asia/Shanghai
</IfModule>

然后重启apache、mysql、php、zabbix-server
浏览器输入ip/setup.php 即可进入zabbix初次web安装界面

方法二:使用 Nginx 服务器

配置zabbix-web站点文件

把zabbix程序文件拷贝到我们指定的目录,并修改属主和属组

[root@localhost software]# cp -r /usr/share/zabbix /var/www/
[root@localhost software]# chown -R www:www /var/www/zabbix
[root@localhost software]# chown -R www:www /etc/zabbix
[root@localhost software]# chown -R www:www /usr/share/zabbix
[root@localhost software]# chown -R www:www /usr/lib/zabbix
[root@localhost software]# chmod -R 755 /etc/zabbix/web

创建存放web站点配置文件的目录

[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# mkdir conf.d/

配置nginx.conf,把新建的目录包含进去

[root@localhost conf]# vi nginx.conf

listen 80 default_server;      ===> 改为 listen 90 default_server;
root /home/wwwroot/;      ===> 改为 # root /home/wwwroot/;
include vhost/*.conf;    ===> 改为 include /usr/local/nginx/conf/conf.d/*.conf;

配置zabbix.conf(zabiix站点的配置文件)

[root@localhost conf]# cd conf.d/
[root@localhost conf.d]# vi zabbix.conf

zabbix.conf 内容如下:

    server {
        listen 80;
        server_name localhost;
        root /var/www/zabbix;
        index index.php index.html index.htm;
        access_log  logs/zabbix.access.log;
        error_log   logs/zabbix.error.log;

        location / {
            try_files $uri $uri/ /index.php?$args;
        }

        location ~ .*.(php)?$ {
            expires -1s;
            try_files $uri =404;
            fastcgi_split_path_info ^(.+.php)(/.+)$;
            include        fastcgi_params;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PHP_VALUE        open_basedir=$document_root:/tmp/:/proc/:/usr/share/zabbix/:/etc/zabbix/web/:/etc/zabbix/;
        }

    }

启动zabbix 和 各服务

启动zabbix-server 和zabbix-agent。并设置zabbix-server和zabbix-agent开机自动启动

systemctl start zabbix-server

systemctl start zabbix-agent

/etc/init.d/nginx restart

chkconfig nginx on

/etc/init.d/mysqld restart

chkconfig mysqld on

/etc/init.d/php-fpm restart

chkconfig php-fpm on

systemctl enable zabbix-server

systemctl enable zabbix-agent

修改Firewall 和SELinux 设置

开放zabbix端口10050 and 10051

firewall-cmd --permanent --add-port=10050/tcp

firewall-cmd --permanent --add-port=10051/tcp

重启firewall

systemctl restart firewalld

如果使用 SELinux, 运行以下命令使 Apache 可以和 Zabbix通信

setsebool -P httpd_can_connect_zabbix=1

如果是测试环境可以直接关闭防火墙和selinux

[root@localhost software]# systemctl stop firewalld
[root@localhost local]# chkconfig firewalld off

修改配置文件,禁用selinux

[root@localhost software]# setenforce 0
[root@localhost software]# vi /etc/selinux/config

SELINUX=disabled

输入ip/setup.php进入zabbix-web界面进行后续安装操作

未分类

确认状态都是ok

未分类

配置数据库信息(填写上面我们设置的数据库账户和密码:zabbix,zabbix,测试环境可以直接用root)

未分类

进入下一步,默认即可

未分类

如果出现下面错误

未分类

解决方法:

sed -i 's#cgi.fix_pathinfo=0#cgi.fix_pathinfo=1#' /usr/local/php/etc/php.ini
/etc/init.d/php-fpm restart

刷新浏览器, 一直下一步

登录,默认用户名: Admin , 默认密码:zabbix

未分类

使用php7.0版本初始化完成后页面有如下的报错:

未分类

这个是因为PHP 7.1.0类型强化,处理方法也很简单找到Zabbix WEB目录下include/func.inc.php文件,执行下面命令,并重启php服务:

sed -i ‘/$last = strtolower(substr($val, -1));/a$val = substr($val,0,-1);’ /var/www/zabbix/include/func.inc.php
/etc/init.d/php-fpm reload
然后刷新页面可以看到已经正常。

ok,初始化完毕。。。

解决图形中文乱码

未分类

这个问题是由于zabbix的web端没有中文字库,我们最需要把中文字库加上即可
解决办法如下
1.从windows下控制面板->字体->选择一种中文字库例如“楷体”

未分类

2.把它拷贝到zabbix的web端的fonts目录下例如:/var/www/html/zabbix/fonts,确认后缀为ttf

未分类

3.修改zabbix的web端/include/defines.inc.php
点击(此处)折叠或打开

//define('ZBX_FONT_NAME', 'graphfont');
define('ZBX_FONT_NAME', 'simkai');

//define('ZBX_GRAPH_FONT_NAME',     'graphfont'); // font file name
define('ZBX_GRAPH_FONT_NAME',       'simkai'); // font file name

其中simkai为字库名字,不包含ttf后缀
测试结果:

未分类

Zabbix通过SNMPv2监控DELL服务器的硬件信息

(一)zabbix监控DELL服务器

(1)简述

监控DELL服务器硬件一般有两种途径:

1、操作系统上安装OMSA,编写脚本调用omreport命令进行监控(需要在操作系统上安装比较麻烦);
2、使用iDRAC(Integrated Dell Remote Access Controller,是一款dell专门用于远程访问控制接口),可以不用在操作系统上安装OMSA,只需要在iDRAC上开启SNMP,zabbix通过SNMP进行监控。对于不支持OMSA的操作系统和要求不能安装额外软件的情况下,推荐使用SNMP监控,配置简单方便(推荐使用)。

(2)步骤

1、登陆iDRAC,直接在浏览器输入访问的ip即可

未分类

2、通过iDRAC开启snmp服务:iDRAC设置—>网络—>服务—>snmp代理,启用snmp并设置团体名(community),不推荐使用默认的public。建议所有服务器设置统一的团体名。

未分类

3、在zabbix_server或代理端通过snmpwalk(snmpwalk -v 2c -c public IP)查看是否能获取到数据。如果获取不到数据,查看失败的原因。

未分类

4、在zabbix官网下下载改监控的相应的模板(https://share.zabbix.com/cat-server-hardware/dell/dell-idrac-chinese) https://share.zabbix.com/
其他的模板都可以在这进行下载

未分类

5、把下载的模板导入到zabbix_server中。配置—>模板—>选择文件—>导入

未分类

6、添加监控服务器。配置—>主机—>创建主机,填写相关信息。

未分类

未分类

未分类

7、修改收集数据的时间,查看获取的数据

未分类

未分类

最后可以查看下监控项看是否有不支持的,不支持的查看原因进行优化。

实现Zabbix通过邮件发送图形报表

在使用Zabbix的过程中,我们通常会建立一些需要图形报表来汇总需要监控的Graph。
而下面的两个脚本,则是通过从Zabbix数据库中获取所有的图形数据,提供Zabbix的WEB接口将所有图形保存到本地,然后通过脚本以Email形式发送过来,作为每天的自动报表。

在本地创建/data/cscript 和 /data/graph 目录

save_graph.pl

#!/usr/bin/perl
use File::Path;
use DBI;
use Net::FTP;
#
#定义graph路径,判断graph目录是否存在,不存在则自动新建
my $path = '/data/graph';
if(-e $path) { rmtree($path); }
mkdir($path);
#
my $stime = `date +%Y%m%d`; chop($stime); $stime .= '1000';
if( length($stime) != 12 ) { print "Error get date"; exit; }
#
#指定截图图形的时间轴周期
my $period = 21600;    # 6 hours
#
#定义Web的登陆名及密码
my $login = 'admin';   # Zabbix Web User
my $pass = 'password'; # Zabbix Web User Password, must be URL Encoded
#
#定义FTP账号密码
my $ftp_site = 'ftp.corp.intra';
my $ftp_user_name = 'zabbix';
my $ftp_password = 'zabbix';
#
#定义cookie的路径
my $cook = "/tmp/cookie";
#
#指定链接数据库
my $dsn = 'DBI:mysql:zabbix:localhost'; # Connect MySQL DB "zabbix" on localhost
my $db_user_name = 'zabbix'; # MySQL DB user
my $db_password = 'dbpassword'; # MySQL DB user password
my $dbh = DBI->connect($dsn, $db_user_name, $db_password);
#
#查询存在哪些screen
my $sth = $dbh->prepare(qq{select a.name,a.hsize,a.vsize, b.resourceid, b.width, b.height,b.x,b.y from screens a,screens_items as b where a.screenid=b.screenid and a.templateid<=>NULL order by a.name});
$sth->execute();
my %screens;
#
# Get all graphs by using curl
while (my ($name,$hsize,$vsize, $id,$width,$height,$x,$y) = $sth->fetchrow_array())
{
#
#长度大于2位的是graph,小于2位的表示是MAP
if(length($id) > 2)
{
#print "$id => $idsn";
#
#定义导出的文件路径及文件名
my $p = "$path/$name.$hsize.$vsize.$y.$x.$id.png";
#
#获取cookie,免除访问实际数据时需要认证
my $strcomm  = `curl  -D $cook -b $cook -d "request=&name=$login&password=$pass&autologin=1&enter=Sign+in"  localhost/zabbix/index.php`;
#
#获取图形文件
$strcomm  = `curl  -b $cook -F  "graphid=$id" -F "period=$period" -F "stime=$stime" -F "width=$width" -F "height=$height" localhost/zabbix/chart2.php > $p`;
}
#
#否则,小于2位的表示是MAP
else {
my $p = "$path/map.$name.$id.png";
my $strcomm  = `curl  -b $cook -F  "sysmapid=$id" localhost/zabbix/map.php > $p`;

#
#ftp到服务器上
my $ftp = Net::FTP->new
(
$FTP_Site,
Timeout => 30
) or die "could not connect.n";
$ftp->login($ftp_user_name,$ftp_password) or die "Could not login.n";
$ftp->binary,$ftp->message;
#$remotefile = "Lync.png";
#$localfile = "$path/$p";
$ftp->put($p) or die "put $remotefile fail.n",$ftp->message;
$ftp->quit;
}
}
exit ;

email-pic.py

#! /usr/bin/env python
import os
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
# 定义函数 _sendmail
def _sendmail(smtp_server,port,account,password,str_from,list_to,msg):
    smtp = smtplib.SMTP(smtp_server,port)
    smtp.ehlo()
    smtp.starttls()
    smtp.ehlo()
#    smtp.login(account, password)
    smtp.sendmail(str_from, list_to,msg)
    smtp.close()

# 定义函数 _get_pictures
def _get_pictures(image_dir):
#建立空列表Pictures
    pictures = []
#os.listdir 返回指定目录下的所有文件和目录名
    for f in os.listdir(image_dir):
# append 是在列表最后增加内容,这里是将list出来的信息f增加到Picture列表中
        pictures.append(f)
    return pictures
# 定义函数 _create_msg
def _create_msg(screen_name,screens,image_dir,str_from,list_to):
    msgRoot = MIMEMultipart('related')

# 定义邮件主题
    msgRoot['Subject'] = 'Zabbix Screen Report: %s' % screen_name

#定义发件人、收件人
    msgRoot['From'] = str_from
    msgRoot['To'] = ",".join(list_to)
    msgRoot.preamble = 'This is a multi-part message in MIME format.'
    # Encapsulate the plain and HTML versions of the message body in an
    # 'alternative' part, so message agents can decide which they want to display.
    msgAlternative = MIMEMultipart('alternative')
    msgRoot.attach(msgAlternative)
# 定义邮件正文内容
    msgText = MIMEText('This is the alternative plain text message.')
    msgAlternative.attach(msgText)
    contents = ""
# tuple 元组 定义hsize,vsize变量  
    contents += "<h1>Screen %s</h1><br>" % screen_name
    _,hsize,vsize,_,_,_,_,= tuple(screens[0].split('.'))

    contents +="<table>"

# sorted()是产生一个新的列表并排序   
    screens = sorted(screens)
    y= -1
    for f in screens:
# 将文件名以为.分割点
        items = f.split('.')

# 原文件名格式:$path/$name.$hsize.$vsize.$y.$x.$id.png
# 经过切片后取 image_Y,Image_x,image_ID
        # tuple 元组
        _,_,_,image_y,image_x,image_id,_ = tuple(items)
        #定义邮件中的图片文件名:image-screen_name-image_id
        image_name = "image-%s-%s" % (screen_name, image_id)
        #fp = open("test.txt",w)     直接打开一个文件,如果文件不存在则创建文件
        #关于open 模式:
        #w     以写方式打开,
        #a     以追加模式打开 (从 EOF 开始, 必要时创建新文件)
        #r+     以读写模式打开
        #w+     以读写模式打开 (参见 w )
        #a+     以读写模式打开 (参见 a )
        #rb     以二进制读模式打开
        #wb     以二进制写模式打开 (参见 w )
        #ab     以二进制追加模式打开 (参见 a )
        #rb+    以二进制读写模式打开 (参见 r+ )
        #wb+    以二进制读写模式打开 (参见 w+ )
        #ab+    以二进制读写模式打开 (参见 a+ )
        fp = open('%s/%s' % (image_dir,f), 'rb')

        #fp.read([size])                     #size为读取的长度,以byte为单位
        msgImage = MIMEImage(fp.read())

        #fp.close()  #关闭文件。python会在一个文件不用后自动关闭文件,不过这一功能没有保证,最好还是养成自己关闭的习惯。 
        #如果一个文件在关闭后还对其进行操作会产生ValueError
        fp.close()

        msgImage.add_header('Content-ID', "<%s>" % image_name)
        msgRoot.attach(msgImage)
#定义循环
        if y != image_y:
            if y!= -1:
                contents +="</tr>"
            y = image_y
            contents +="<tr>"

# 定义td中嵌套图片文件
        contents +="<td><img src='cid:%s'></td>" % image_name

# table结束   
    contents += "</table>"
# 定义邮件格式为HTML
    msgText = MIMEText(contents, 'html')

    msgAlternative.attach(msgText)
#    msgRoot.attach(msgAlternative)
    return msgRoot
# Create the root message and fill in the from, to, and subject headers
def main(str_from,list_to,image_dir):
    pictures = _get_pictures(image_dir)
# 定义screen name,如:  Citrix_APP_Server_Loading
    for screen_name in list(set([x.split('.')[0] for x in pictures ])):
# startswith 判断字串开始
# screens 是一组 相同前缀的文件,如: screens ['Zabbix_server.2.2.1.1.525.png', 'Zabbix_server.2.2.1.0.524.png']
        screens = [x for x in pictures if x.startswith(str(screen_name) + '.') ]

        msgRoot = _create_msg(screen_name,screens,image_dir,str_from,list_to)

#定义邮件服务器地址、端口
        _sendmail(smtp_server,port,'','',str_from,list_to,msgRoot.as_string())
# 定义发送邮件信息,发件人,收件人,图片目录
if __name__ == '__main__':
   smtp_server = '10.210.1.16'
   port = 25
   str_from = '[email protected]'
   list_to = [
                "[email protected]"
             ]
   image_dir = '/data/graph/maps'
   main(str_from,list_to,image_dir)

源代码参考地址:http://heylinux.com/archives/2081.html

centos下使用yum 安装percona xtrabackup

配置percona的yum仓库

一、先安装依赖

yum install perl-DBI

yum install perl-DBD-MySQL

yum install perl-Time-HiRes

yum install perl-IO-Socket-SSL

二、配置yum源

方法1、自动安装percona的yum仓库(以下分别为x86_64和i386平台)

#rpm -ivh http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
#rpm -ivh http://www.percona.com/redir/downloads/percona-release/percona-release-0.0-1.i386.rpm

方法2、手动yum仓库

创建文件/etc/yum.repos.d/Percona.repo内容如下:

[percona]
name = CentOS $releasever - Percona
baseurl=http://repo.percona.com/centos/$releasever/os/$basearch/
enabled = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-percona
gpgcheck = 1

获取和保存key

#wget http://www.percona.com/redir/downloads/percona-release/RPM-GPG-KEY-percona

#cp RPM-GPG-KEY-percona /etc/pki/rpm-gpg/RPM-GPG-KEY-percona

安装 percona xtrabackup
下面我们就可以安装percona一系列工具了:

安装xtrabackup    
#yum -y install percona-xtrabackup    
安装toolkit
#yum -y install percona-toolkit

wordpress删除文章时自动删除文章图片

wordpress删除文章时候文章的图片和略缩图源文件并不会从服务器删除,对于强迫症来说这太难受了,去网上搜索了一下,有相关的教程,下面的代码放到主题的functions.php文件中就可以

/* 删除文章时删除图片附件 */ 
function delete_post_and_attachments($post_ID) { 
 global $wpdb; 
 //删除特色图片 
 $thumbnails = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id' AND post_id = $post_ID" ); 
 foreach ( $thumbnails as $thumbnail ) { 
 wp_delete_attachment( $thumbnail->meta_value, true ); 
 } 
 //删除图片附件 
 $attachments = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE post_parent = $post_ID AND post_type = 'attachment'" ); 
 foreach ( $attachments as $attachment ) { 
 wp_delete_attachment( $attachment->ID, true ); 
 } 
 $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_thumbnail_id' AND post_id = $post_ID" ); 
} 
add_action('before_delete_post', 'delete_post_and_attachments'); 
/* 删除文章时删除图片附件over */

ps:这些小功能是我在建站过程中的一些需求,所以记录下来,方便下次使用