VFS: Unable to mount root fs on unknown-block(0,0).

由于内核脏牛漏洞,可以从本地普通用户很容易就提权到root。是一个及其危险的漏洞,故在官方发布漏洞补丁第一时间进行升级内核,但CentOS的系统的内核补丁,需要重启服务器后生效。

其中一台服务器升级重启后,出现错误”VFS: Unable to mount root fs on unknown-block(0,0).” 导致启动不了,分析了下,应该是到了grub阶段就挂了。
但在使用修复模式选择原来老的内核grub菜单,可以引导进入系统。

仔细排查后发现在/boot 分区下initramfs-2.6.32-642.6.2.el6.x86_64.img 这个新的内核的镜像文件没有生成。并且在/boot/grub/grub.conf 文件中也少了一行

initrd /initramfs-2.6.32-642.6.2.el6.x86_64.img

用dracut 生成img文件
dracut -f /boot/initramfs-2.6.32-642.6.2.el6.x86_64.img 2.6.32-642.6.2.el6.x86_64

然后手工修改grub.conf 文件,重启就可以了。

原先的服务器boot 分区设置只有100M,导致在升级内核空间不够。没有生成img文件并增加grub文件配置引起错误。

在升级了内核后,两个内核空间占用了98M的空间。但此时还空间还没有满。

在启动过程中,同时会产生一个initrd-2.6.32-642.6.2.el6.x86_64kdump.img 也会占用空间。在启动新内核的时候生成这个文件的时候空间不足,导致启动失败。而在切回到原来旧内核的时候,会继续使用原先老的dump文件的空间。空间就不会扩展。能成功启动。

》》》

以后尽量将boot分区空间设置大一点,至少保留500M的样子,可以同时并行保持2,3个内核,出现问题,也可以回滚到上一个内核进行处理。

title: logstsh-if-conf.d
date: 2016-05-28 14:57:55

tags:logstash

一般情况下,logstash 测试和运行环境存在区别的。
为了方便,logstash 测试的时候会使用如下命令:

1
/opt/logstash/bin/logstash -f /opt/logstash/conf.d/test.conf

测试没有问题。然后就会使用如下方式:

1
service logstash restart

让logstash 程序读取conf.d 目录下所有conf文件,然后启动程序。
这样就会带来一个问题,conf.d的文件 会被加载一个logstash 进程运行,多个conf 文件没有相互隔离。会出现测试时候不存在的问题。
解决方法:

1 使用 测试方法,将多个conf文件分开运行,写到脚本中

1
2
/opt/logstash/bin/logstash -f /opt/logstash/conf.d/test1.conf
/opt/logstash/bin/logstash -f /opt/logstash/conf.d/test2.conf

2 在配置文件中增加tag并做好if判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
input
file {
type => "app-log"
path => [ "/data/*.log" ]
start_position => "beginning"
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601} "
negate => true
what => previous
}
}
file {
type => "app-access-log"
path => [ "/data/*.log" ]
}
}
output {
if ([type] in ["app-log", "app-access-log"]) {
}
}

logstash 在生产环境,一般是用service方式运行,或者使用supervisord来运行。

es-immense-term

es集群在运行过程中,收到告警说两个几点CPU load告警,上去看了日志发现如下错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
java.lang.IllegalArgumentException: Document contains at least one immense term in field="msg" (whose UTF8 encoding is longer than the max length 32766), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: '[123, 34, 98, 114, 111, 97, 100, 99, 97, 115, 116, 73, 100, 34, 58, 49, 52, 48, 56, 49, 57, 57, 57, 56, 56, 44, 34, 116, 121, 112]...', original message: bytes can be at most 32766 in length; got 40283
at org.apache.lucene.index.DefaultIndexingChain$PerField.invert(DefaultIndexingChain.java:685)
at org.apache.lucene.index.DefaultIndexingChain.processField(DefaultIndexingChain.java:359)
at org.apache.lucene.index.DefaultIndexingChain.processDocument(DefaultIndexingChain.java:318)
at org.apache.lucene.index.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:239)
at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:454)
at org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1511)
at org.apache.lucene.index.IndexWriter.addDocument(IndexWriter.java:1246)
at org.elasticsearch.index.engine.internal.InternalEngine.innerCreateNoLock(InternalEngine.java:482)
at org.elasticsearch.index.engine.internal.InternalEngine.innerCreate(InternalEngine.java:435)
at org.elasticsearch.index.engine.internal.InternalEngine.create(InternalEngine.java:404)
at org.elasticsearch.index.shard.service.InternalIndexShard.create(InternalIndexShard.java:403)
at org.elasticsearch.action.bulk.TransportShardBulkAction.shardIndexOperation(TransportShardBulkAction.java:449)
at org.elasticsearch.action.bulk.TransportShardBulkAction.shardUpdateOperation(TransportShardBulkAction.java:541)
at org.elasticsearch.action.bulk.TransportShardBulkAction.shardOperationOnPrimary(TransportShardBulkAction.java:240)
at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction.performOnPrimary(TransportShardReplicationOperationAction.java:511)
at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction$1.run(TransportShardReplicationOperationAction.java:419)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.lucene.util.BytesRefHash$MaxBytesLengthExceededException: bytes can be at most 32766 in length; got 40283
at org.apache.lucene.util.BytesRefHash.add(BytesRefHash.java:284)
at org.apache.lucene.index.TermsHashPerField.add(TermsHashPerField.java:151)
at org.apache.lucene.index.DefaultIndexingChain$PerField.invert(DefaultIndexingChain.java:659)
... 18 more

意思就是消息的中的某个字段msg 的字段长度 超过了最大设置的值 32766字节。es系统不处理这个消息并抛出异常。 一般是这个字段设置成了not_anayzed,然后长度超出限制了。term 是一个搜索的最小单位,一般不会太大。

网上找了下解决方案,就是超出的部分就ignore。

1
2
3
4
5
6
7
8
9
10
11
curl -XPUT 'http://localhost:9200/twitter' -d '
{
"mappings":{
"tweet" : {
"properties" : {
"message" : {"type" : "string", "index":"not_analyzed","ignore_above":256 }
}
}
}
}
'

如果这个字段是 index:analyzed的情况就不会出现这个问题。具体要查看你es中设置的mapping。我默认是设置了动态 mapping。将没有指定的filed 设置成了not anaylzed。然后就出来这个长度的限制,修改mapping 搞定。

Linux 双网卡绑定bonding

环境:

CentOS 5系列 + Xen

1 双网卡绑定 ,产生bond0 接口

脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
cp /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/sysconfig/network-scripts/ifcfg-eth1.bak
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 <<EOF
DEVICE=eth1
USERCTL=no
BOOTPROTO=none
ONBOOT=yes
MASTER=bond0
SLAVE=yes
TYPE=Ethernet
EOF
cp /etc/sysconfig/network-scripts/ifcfg-eth2 /etc/sysconfig/network-scripts/ifcfg-eth2.bak
cat > /etc/sysconfig/network-scripts/ifcfg-eth2 <<EOF
DEVICE=eth2
USERCTL=no
BOOTPROTO=none
ONBOOT=yes
MASTER=bond0
SLAVE=yes
TYPE=Ethernet
EOF
cat >/etc/sysconfig/network-scripts/ifcfg-bond0 << EOF
DEVICE=bond0
BOOTPROTO=none
IPADDR=192.168.10.xx
NETMASK=255.255.255.0
NETWORK=192.168.10.254
USERCTL=no
ONBOOT=yes
TYPE=Ethernet
EOF

2 修改xen配置文件

/etc/xen/xend-config.sxp

(network-script ‘network-bridge netdev=bond0’)

使xen使用bond0 接口,默认生成xenbr0 的接口
或者

(network-script ‘network-bridge bridge=xenbr1 netdev=bond0’)

指定桥接的接口

原来的虚拟机是使用了多网卡 桥接的脚本
/etc/xen/xend-config.sxp

(network-script multi_bridge)

/etc/xen/scripts/multi_bridge

1
2
3
4
5
6
#!/bin/bash
dir=$(dirname "$0")
"$dir/network-bridge" "$@" vifnum=0 netdev=eth0 bridge=xenbr0
"$dir/network-bridge" "$@" vifnum=1 netdev=eth1 bridge=xenbr1
"$dir/network-bridge" "$@" vifnum=2 netdev=eth2 bridge=xenbr2
"$dir/network-bridge" "$@" vifnum=3 netdev=eth3 bridge=xenbr3

修改使用bond0

sed -i ‘s/eth1/bond0/g’ /etc/xen/scripts/multi_bridge sed -i ‘5,6s/^/#/‘ /etc/xen/scripts/multi_bridge

3 domainU 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
name = "domain-1"
uuid = "a5b43314-cd35-74e3-a357-4290768b7599"
maxmem = 8192
memory = 8192
vcpus = 6
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [ "type=vnc,vncunused=1,keymap=en-us" ]
disk = [ "tap:aio:/data/xenserver/domain-1/domain-1.img,xvda,w" ]
vif = [ "mac=00:16:3e:37:02:c7,bridge=xenbr0,script=vif-bridge", "mac=00:16:36:18:22:f1,bridge=xenbr1,script=vif-bridge" ]

4 修改内核加载参数,使之生效

1
2
3
4
5
6
cp /etc/modprobe.conf /etc/modprobe.conf.bak
cat >> /etc/modprobe.conf << EOF
alias bond0 bonding
options bond0 miimon=100 mode=0
EOF

xen方式需要重启机器,才能保证双网卡绑定正常
加载绑定模块
modprobe bonding

xen 在重启完后,会生成一个pbond0 的接口

cat /proc/net/bonding/pbond0

CentOS 6系列 + KVM

ifcfg-bond0

1
2
3
4
5
DEVICE=bond0
BOOTPROTO=static
BRIDGE=br0
NM_CONTROLLED=no
ONBOOT=yes

ifcfg-br0

1
2
3
4
5
6
7
8
9
10
11
DEVICE=br0
TYPE=Bridge
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.11.110
NETMASK=255.255.255.0
GATEWAY=192.168.11.254
MTU=1500
SLAVE=bond0
NM_CONTROLLED=no
PEERDNS=no

vi /etc/libvirt/qemu/domain-1.xml

1
2
3
4
5
6
<interface type='bridge'>
<mac address='52:54:31:b3:73:31'/>
<source bridge='br0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

多个bonding

修改内核模块

1
2
3
4
5
6
7
cat >> /etc/modprobe.conf << EOF
alias bond0 bonding
options bond0 miimon=100 mode=0
alias bond1 bonding
options bond1 miimon=100 mode=0
EOF

modprobe bonding

SaltStack

saltstack

安装配置测试

salt-master

1
yum install -y salt-master

修改配置文件 /etc/salt/master

默认不用修改(KISS)

1
#interface: 0.0.0.0

启动

1
service salt-master restart

查看端口

1
netstat -lntp|grep 4505

salt-minion

安装

1
yum install -y salt-minion

配置

/etc/salt/minion

1
master: 192.168.4.201

启动minion

1
service salt-minion start

查看端口

1
netstnt -lntp|grep 4506

salt master 为salt minion 授权

1
2
#salt-key -L
salt-key -a test.*.com

测试

1
salt test.*.com test.ping

防火墙 master

1
2
-A INPUT -m state --state new -m tcp -p tcp --dport 4505 -j ACCEPT
-A INPUT -m state --state new -m tcp -p tcp --dport 4506 -j ACCEPT

规范

主机名

1
2
3
4
<app>-<001>-<sjc|fd|inner>-<11|12|201|204>-<ip>.*.com
kvmguest-002-inner-2-32.*.com
kvmguest-inner-192-168-2-32.*.com

/etc/hosts

1
2
127.0.0.1 localhost
<ip> hostname

例子:

1
2
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.2.32 kvmguest-002-inner-2-32.*.com kvmguest-002-inner-2-32

远程命令 remote command

minon

1
2
3
4
5
6
salt '*' test.ping
salt 'myminion' sys.list_functions test
salt '*' sys.doc test.fib
salt '*' test.fib 30
salt '*' sys.doc test
salt '*' sys.list_functions sys
1
2
3
4
5
6
sudo salt '*' cmd.run_all 'echo HELLO'
sudo salt --out=nested '*' cmd.run_all 'echo HELLO'
salt --out=raw '*' cmd.run_all 'echo HELLO'
salt --out=json '*' cmd.run_all 'echo HELLO'
--out=yaml
--out=quiet

Targeting strings

1
2
3
4
5
6
salt '*' test.ping
sudo salt 'myminion' test.ping
sudo salt 'my*' test.ping
sudo salt 'my*mini*' test.ping
sudo salt '??minion' test.ping
sudo salt '[a-m]yminion' test.ping

Perl-compatible regular expression matching PCRE

1
2
3
4
5
6
7
salt -E 'myminion' test.ping
salt -E 'my' test.ping
salt -E 'my.*n' test.ping
salt -E '^myminion$' test.ping
salt -E '((my)|(your))minion' test.ping
salt -E 'myminion(s)?' test.ping
salt -E '(my)?minion' test.ping

List matching

1
2
salt -L 'myminion' test.ping
salt -L 'myminion,yourminion,theirminion' test.ping

Grains
Grains represent static data describing a minion.
Pillars
Pillar data is similar to grains except that it can be defined more dynamically and is
a secure store for data.

Grain and pillar matching

1
2
3
4
5
6
7
salt '*' grains.item os_family
salt '*' grains.item os
salt '*' grains.item osfinger
salt --grain 'os_family:RedHat' test.ping
salt -G 'os:Ubuntu' test.ping
salt -G 'os:u*' test.ping
salt '*' grains.items

设置变量

1
2
3
4
salt '*' grains.setval foo bar
salt '*' grains.item foo
salt '*' grains.setval baz '["larry", "moe", "curly"]'
salt '*' grains.delval baz
1
2
3
4
5
6
# cat /etc/salt/grains
baz:
- larry
- moe
- curly
foo: bar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
salt '*.baz.com' test.ping
salt -E 'web-(prod|dev)' test.ping
salt -L 'web-jonh, dborac-ether' test.ping
# By grains, target the RedHat and Debian systems
salt -G 'os:(RedHat|Debian)' test.ping
# By Pillar data, target human resources
salt -I 'deparment:HR' test.ping
# By IP/subnet, target the local network
salt -S '192.16.0.0/24' test.ping

Compound matching

1
2
3
4
5
6
7
8
9
10
11
12
# By minion ID and grains
salt -C 'web-* and G@os:Ubuntu' test.ping
# By grains and Pillar data
salt -C 'G@cpuarch:x86_64 and I@office:32D' test.ping
salt -C '*minion and G@os:Ubuntu and not L@yourminion,theirminion'
test.ping
salt -C '* and not G@os_family:RedHat' test.ping
salt -C 'G@os:Ubuntu or G@os:Fedora' test.ping

组合

Letter Match Type Example
G Grains glob G@os:Ubuntu
E PCRE minion ID E@web\d+.(dev\ qa\ prod).loc
P Grains PCRE P@os:(RedHat\ Fedora\ CentOS)
L List of minions L@minion1.example.com, minion3.domain.com
I Pillar glob I@pdata:foobar
S Subnet/IP address S@192.168.1.0/24 or S@192.168.1.100
R Range cluster R@%foo.bar

Remote execution modules and functions

1
2
<module>.<function>
test.ping
1
salt '*' sys.list_modules

常用模块

用户管理

1
2
3
4
salt '*' sys.doc user.add
salt '*' user.add name <uid> <gid> <groups> <home> <shell>
salt '*' user.add larry
salt '*' user.info larry

安装包

1
2
3
4
5
salt '*' sys.doc pkg.install
salt '*' pkg.install httpd
salt '*' pkg.version nano
salt '*' pkg.list_pkgs --out=json
salt '*' pkg.remove htop

管理服务

1
2
salt '*' service.status httpd
salt '*' service.stop apache2

监控minion状态

1
2
3
4
salt '*' status.diskusage
salt '*' status.loadavg
salt '*' status.meminfo
salt '*' status.uptime

运行命令

1
2
3
4
5
salt '*' cmd.run 'echo Hello!'
salt '*' cmd.run_stderr 'echo Hello!'
salt '*' cmd.retcode 'echo Hello!'
salt '*' cmd.run_all 'echo Hello!'
cmd.script sh脚本

state

对基础服务的管理包括配置管理系统、用户账号管理、yum配置管理、hosts文件管理、时间同步管理、DNS配置管理。

配置管理系统

配置管理系统使用模块化设计,

每个服务一个模块,
将多个模块组织到一起形成角色(/srv/salt/roles/)。

所有模块放置到:/srv/salt下,
入口配置文件为:/srv/salt/top.sls。

模块使用的变量放置到:/srv/pillar,
入口配置文件:/srv/pillar/top.sls。

针对变量的作用域不同,将变量分为三级:

一级应用于模块(/srv/pillar/模块名),

一级应用于角色(/srv/pillar/roles/),

一级应用于主机节点(/srv/pillar/nodes)。

入口配置/srv/salt/top.sls,直接引用各种角色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
base:
'*':
- roles.common
'admin.grid.mall.com':
- roles.admin
'ha.grid.mall.com':
- roles.ha
'web*.grid.mall.com':
- roles.web
'cache*.grid.mall.com':
- roles.cache
'mc*.grid.mall.com':
- roles.mc
'db*.grid.mall.com':
- roles.db
'search*.grid.mall.com':
- roles.search
'storage*'.grid.mall.com':
- roles.storage

变量入口配置文件/srv/pillar/top.sls:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
base:
'*':
- roles.common
# 引用角色级变量
# 模块级变量在角色级变量中引用
'admin.grid.mall.com':
- roles.admin
'ha.grid.mall.com':
- roles.ha
'web*.grid.mall.com':
- roles.web
'cache*.grid.mall.com':
- roles.cache
'mc*.grid.mall.com':
- roles.mc
'db*.grid.mall.com':
- roles.db
'search*.grid.mall.com':
- roles.search
'storage*'.grid.mall.com':
- roles.storage
# 引用节点级变量
'ha1.grid.mall.com':
- nodes.ha1
'ha2.grid.mall.com':
- nodes.ha2
'mc1.grid.mall.com':
- nodes.mc1
'mc2.grid.mall.com':
- nodes.mc2
'db1.grid.mall.com':
- nodes.db1
'db2.grid.mall.com':
- nodes.db2

用户账号管理
用户管理模块:/srv/salt/users

pillar和grains都可以用来获取变量

grains偏向于获取客户端相关信息,比如客户端硬件架构、cpu核数、操作系统版本等信息,相当于puppet的facter;

pillar用于定义用户变量,通过pillar变量的传递,使salt state模块易于重用,相当于puppet的hiera。

使用pillar变量之前需要执行salt ‘*’ saltutil.refresh_pillar命令使变量生效。

使用命令salt ‘admin.grid.mall.com’ pillar.item users获取users变量:

/srv/salt/users/user.sls用于管理用户

Saltstack:服务部署

API (http restful)

salt —versions-report

Specify an sls file

We can also specify an sls file. Sls files don’t normally use execution modules, and instead use state modules that are called automagically by Salt when it processes the state, although there is a special state module to call execution modules from within sls files. More on writing states in a minute:

Apply the states from the ssh.sls file on all minions.

Notice how we omit the .sls extension in the command line.

salt ‘*’ state.sls ssh

salt -N ‘logs_wpk’ state.highstate
salt kvmguest-001-sjc-13-33..com state.highstate
salt kvmguest-001-sjc-13-33.
.com state.sls base.zabbix

zabbix api

简介

zabbix api 为批量操作,第三方软件集成及其他作用提供可编程接口。

zabbix api 在1.8版本以后开始提供,zabbix移动客户端和原生的web前端部分都是建立在zabbix api上。zabbix api中间件使得架构更加模块化并避免对数据库进行操作。允许你使用JSON RPC协议来创建、更新和获取zabbix 对象并操作(认证你的账户)。

zabbix api 提供两项功能:

  1. 远程管理zabbix 配置
  2. 远程检索配置和历史数据

zabbix API开发库

zabbix API请求和响应都是json,并且还提供了各种语法的lib库,http://zabbix.org/wiki/Docs/api/libraries,包含php、c#、Python、Perl、go等等语言

使用JSON

采用JSON RPC协议实现。调用任何函数,都要发送POST请求,输入输出都是JSON格式。
工作方式如下:

  1. 准备JSON对象,描述你想要做什么(创建主机,获取图像,更新监控项)
  2. 采用POST方式 http://zabbix.*.info/zabbix/api_jsonrpc.php发送此JSON对象. http://example.com/zabbix/是Zabbix前端地址。api_jsonrpc.php是调用API的PHP脚本。可在安装可视化前端的目录下找到。
  3. 获取json响应格式

请求方法必须是POST方法,HTTP Header Content-Type 必须为【application/jsonrequest,application/json-rpc,application/json】其中之一

基本请求格式

JSON 请求如下:

1
2
3
4
5
6
7
8
9
10
{
"jsonrpc": "2.0",
"method": "method.name",
"params": {
"param_1_name": "param_1_value",
"param_2_name": "param_2_value"
},
"id": 1,
"auth": "159121b60d19a9b4b55d49e30cf12b81",
}
  1. json rpc协议版本
  2. 具体执行的操作 如:host.create item.update
  3. 传递json对象来作为参数,如创建监控项 ,name 和key是必须的。
  4. id 1 绑定json请求和响应
  5. auth 认证令牌

API 使用

1 登录

1
2
curl -i -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"user.login","params":{"user":"***","password":"***"},"auth":null,"id":0}' http://zabbix.***.info/api_jsonrpc.php

2 获取主机

1
curl -i -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"host.get","params":{"output":["hostid","name"],"filter":{"host":""}},"auth":"22ad296ae1ac36a07d16ea91d7af7227","id":1}' http://zabbix.***.info/api_jsonrpc.php

3 获取监控主机的hostids

1
2
curl -i -X POST -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0","method":"host.get","params":{"output":["hostid"],"filter": {"host":"192.168.11.1"}},"auth": "22ad296ae1ac36a07d16ea91d7af7227","id": 0}' http://x.x.x.x/api_jsonrpc.php
#"hostid":"10243"

(3)获得监控项itemids

1
2
3
curl -i -X POST -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0","method":"item.get","params":{"output":"itemids","hostids":"10243","search":{"key_":"system.cpu.util
[,idle,avg1]"}},"auth": "a826fca79a0795ccc1224dc76329972f","id": 0}' http://x.x.x.x/api_jsonrpc.php
#“item”:"24526"

(4)获取监控项”system.cpu.util[,idle,avg1] “在2014.2.19 14:00~14:20的值

1
curl -i -X POST -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0","method":"history.get","params":{"history":0,"itemids":["24526"],"time_from":"1392789600","time_till":"1392790200","output":"extend"},"auth": "a826fca79a0795ccc1224dc76329972f","id": 0}' http://x.x.x.x/api_jsonrpc.php

参考地址

https://www.zabbix.com/documentation/2.4/manual/api

使用MegaCli工具查看Raid磁盘阵列状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#MegaCli -LDInfo -Lall -aALL 查raid级别
#MegaCli -AdpAllInfo -aALL 查raid卡信息
#MegaCli -AdpBbuCmd -aAll 查看电池信息
#MegaCli -FwTermLog -Dsply -aALL 查看raid卡日志
#MegaCli -adpCount 【显示适配器个数】
#MegaCli -AdpGetTime –aALL 【显示适配器时间】
#MegaCli -AdpAllInfo -aAll 【显示所有适配器信息】
#MegaCli -LDInfo -LALL -aAll 【显示所有逻辑磁盘组信息】
#MegaCli -PDList -aAll 【显示所有的物理信息】
#MegaCli -AdpBbuCmd -GetBbuStatus -aALL |grep 'Charger Status' 【查看充电状态】
#MegaCli -AdpBbuCmd -GetBbuStatus -aALL【显示BBU状态信息】
#MegaCli -AdpBbuCmd -GetBbuCapacityInfo -aALL【显示BBU容量信息】
#MegaCli -AdpBbuCmd -GetBbuDesignInfo -aALL 【显示BBU设计参数】
#MegaCli -AdpBbuCmd -GetBbuProperties -aALL 【显示当前BBU属性】
#MegaCli -cfgdsply -aALL 【显示Raid卡型号,Raid设置,Disk相关信息】

3.磁带状态的变化,从拔盘,到插盘的过程中。

Device |Normal|Damage|Rebuild|Normal

Virtual Drive |Optimal|Degraded|Degraded|Optimal

Physical Drive |Online|Failed –> Unconfigured|Rebuild|Online

4.查看磁盘缓存策略

1
2
3
4
5
#MegaCli -LDGetProp -Cache -L0 -a0
#MegaCli -LDGetProp -Cache -L1 -a0
#MegaCli -LDGetProp -Cache -LALL -a0
#MegaCli -LDGetProp -Cache -LALL -aALL
#MegaCli -LDGetProp -DskCache -LALL -aALL

5.设置磁盘缓存策略
缓存策略解释:
WT (Write through)

WB (Write back)

NORA (No read ahead)

RA (Read ahead)

ADRA (Adaptive read ahead)

Cached

Direct

例子:

1
2
3
4
5
6
#MegaCli -LDSetProp WT|WB|NORA|RA|ADRA -L0 -a0
or
#MegaCli -LDSetProp -Cached|-Direct -L0 -a0
or
enable / disable disk cache
#MegaCli -LDSetProp -EnDskCache|-DisDskCache -L0 -a0

6.创建一个 raid5 阵列,由物理盘 2,3,4 构成,该阵列的热备盘是物理盘 5

1
#/opt/MegaCli -CfgLdAdd -r5 [1:2,1:3,1:4] WB Direct -Hsp[1:5] -a0

7.创建阵列,不指定热备

1
#/opt/MegaCli -CfgLdAdd -r5 [1:2,1:3,1:4] WB Direct -a0

8.删除阵列

1
#/opt/MegaCli -CfgLdDel -L1 -a0

9.在线添加磁盘

1
#/opt/MegaCli -LDRecon -Start -r5 -Add -PhysDrv[1:4] -L1 -a0

10.阵列创建完后,会有一个初始化同步块的过程,可以看看其进度。

1
#/opt/MegaCli -LDInit -ShowProg -LALL -aALL

或者以动态可视化文字界面显示

1
#/opt/MegaCli -LDInit -ProgDsply -LALL -aALL

11.查看阵列后台初始化进度

1
#/opt/MegaCli -LDBI -ShowProg -LALL -aALL

或者以动态可视化文字界面显示

1
#/opt/MegaCli -LDBI -ProgDsply -LALL -aALL

12.指定第 5 块盘作为全局热备

1
#/opt/MegaCli -PDHSP -Set [-EnclAffinity] [-nonRevertible] -PhysDrv[1:5] -a0

13.指定为某个阵列的专用热备

1
#/opt/MegaCli -PDHSP -Set [-Dedicated [-Array1]] [-EnclAffinity] [-nonRevertible] -PhysDrv[1:5] -a0

14.删除全局热备

1
#/opt/MegaCli -PDHSP -Rmv -PhysDrv[1:5] -a0

15.将某块物理盘下线/上线

1
2
#/opt/MegaCli -PDOffline -PhysDrv [1:4] -a0
#/opt/MegaCli -PDOnline -PhysDrv [1:4] -a0

16.查看物理磁盘重建进度

1
#/opt/MegaCli -PDRbld -ShowProg -PhysDrv [1:5] -a0

或者以动态可视化文字界面显示

1
#/opt/MegaCli -PDRbld -ProgDsply -PhysDrv [1:5] -a0

Nginx PHP 整合

yum install tar unzip

现在流行用LNMP的组合框架了。整理了一小篇。
常规的做法是将数据库和Web 应用分两台进行部署。网上的文章,基本上都是在一台Linux服务器上部署Nginx + PHP + MySQL。
在编译PHP的时候都需要安装MySQL 的软件,然后带上—with-mysql的参数。但我们在这台服务器上根本就用不上MySQL的服务。
后来在PHP官网找到一个文档说明,说PHP 默认已经在某个版本后,可以实现不用MySQL 既可以编译具有MySQL连接的PHP。

本次使用的PHP版本是5.5.20

1
2
3
4
5
6
7
yum install -y php-mysql
wget http://cn2.php.net/get/php-5.5.20.tar.gz/from/this/mirror
tar zxvf php-5.5.20.tar.gz
cd php-5.5.20
./configure --prefix=/usr/local/php5 --enable-fpm --with-mysql
make
make install

还额外提供了很多的编译参数,当然还需要安装一些软件依赖包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
./configure --prefix=/data/program/php_5.5 --enable-fpm --with-mysql \
--with-config-file-path=/usr/local/php5/etc \
--enable-mbstring \
--enable-ftp \
--with-gd \
--with-jpeg-dir=/usr \
--with-png-dir=/usr \
--enable-sockets \
--with-freetype-dir=/usr \
--enable-gd-native-ttf \
--with-zlib \
--enable-sysvsem \
--enable-exif \
--enable-sysvshm \
--with-libxml-dir=/usr \
--with-xmlrpc \
--enable-xml \
--enable-shmop \
--enable-zip \
--with-mhash \
--enable-bcmath \
--enable-inline-optimization \
--with-curl \
--enable-mbregex \
--with-openssl \
--enable-opcache=no

软件包

1
2
3
4
yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel
glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel
curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel
yum install -y zlib zlib-devel libxml2 libxml2-devel

拷贝php配置文件和php-fpm的配置。

1
2
3
cp /usr/local/src/php-5.5.20/php.ini-development /usr/local/php5/php.ini
cp /usr/local/php5/etc/php-fpm.conf.default /usr/local/php5/etc/php-fpm.conf
cp sapi/fpm/php-fpm /usr/local/bin

vim /usr/local/php5/php.ini

1
cgi.fix_pathinfo=0

vim /usr/local/php5/etc/php-fpm.conf

1
2
3
4
user = www-data
group = www-data
pid = run/php-fpm.pid
security.limit_extensions = .php .php3 .php4 .php5 .css .js .jpg .jpeg .gif .png .html .htm

然后启动 php-fpm 服务:

1
2
/usr/local/bin/php-fpm
netstat -ant|grep 9000
1
2
3
4
#关闭php-fpm
kill -INT `cat /usr/local/php5/var/run/php-fpm.pid`
#重启php-fpm
kill -USR2 `cat /usr/local/php5/var/run/php-fpm.pid`

安装Nginx

1
2
3
4
5
6
7
groupadd -r -g 5000 nginx
useradd -r -g nginx -u 5000 nginx
yum -y install pcre pcre-devel
wget http://nginx.org/download/nginx-1.2.9.tar.gz
tar zxvf nginx-1.2.9.tar.gz
cd nginx-1.2.9
./configure --prefix=/usr/local/nginx

配置文件

1
2
3
4
5
6
7
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}

其他的一个版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
location ~* \.(php[3-9]?|phtm[l]?)(\/.*)*$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
set $path_info "";
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
}
location ~* \.(php[3-9]?|phtm[l]?)(\/.*)*$ {
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;#这里指定了fastcgi进程侦听的端口,nginx就是通过这里与php交互的
include fastcgi_params;
set $path_info "";
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
}

fastcgi_param 参数

1
2
3
4
5
6
7
8
9
10
11
12
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_cache TEST;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;

下面是对上述代码的含义进行介绍。
第一行代码是为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间。
fastcgi_connect_timeout:指定连接到后端FastCGI的超时时间。
fastcgi_send_timeout:指定向FastCGI传送请求的超时时间,这个值是已经完成两次握手后向FastCGI传送请求的超时时间。
fastcgi_read_timeout:指定接收FastCGI应答的超时时间,这个值是已经完成两次握手后接收FastCGI应答的超时时间。
fastcgi_buffer_size:用于指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小。
fastcgi_buffers:指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等。
fastcgi_busy_buffers_size:的默认值是fastcgi_buffers的两倍。
fastcgi_temp_file_write_size:表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍。
fastcgi_cache:表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也会引起很多问题,要视具体情况而定。
fastcgi_cache_valid:fastcgi用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一个小时,将301应答缓存1天,其他应答均缓存1分钟。

rm /usr/local/nginx/html/index.html
echo “<?php phpinfo(); ?>” >> /usr/local/nginx/html/index.php

下载最新版本的Discuz论坛

1
2
3
4
5
6
7
8
9
10
yum install unzip
mkdir temp
cd temp
wget http://download.comsenz.com/DiscuzX/3.2/Discuz_X3.2_SC_UTF8.zip
unzip Discuz_X3.2_SC_UTF8.zip
cp -r upload /data/bbs
chmod -R 777 /data/bbs/config
chmod -R 777 /data/bbs/data
chmod -R 777 /data/bbs/uc_client
chmod -R 777 /data/bbs/uc_server

Flask extensions 汇总

Flask 的扩张结构是在诞生的时候就确定了的。存在各种各样好用的扩张。
这里整理了一些常用的扩张:
1 Flask-script
给flask提供命令行选项,可以在shell里进行调试,测试工作。
pip install flask-scripts
from flask.ext.script import Manager
manager = Manager(app)
manager.run()

python test.py —help
python test.py shell
python test.py runserver -h 0.0.0.0 -p 5000

2 Flask-Bootstrap
pip install flask-bootstrap

from flask.ext.bootstrap import Bootstrap

bootstrap = Bootstrap(app)

user.html

3 Flask-Moment 时间日期本地格式化
pip install flask-moment

from flask.ext.moment import Moment
moment = Moment(app)

index.html

4 Flask-WTF Form表单
pip install falsk-wtf

Form Classes 继承自Form
from flask.ext.wtf import Form
from wtforms import StringField,SubmitField
from wtform.validators import Rrquired

class NameForm(Form):
name = StringField(‘What is your name?’,validators=[Required()])
submit = SubmitField(‘Submit’)

StringField
TextAreaField
PasswordField
HiddenField
DateField
DateTimeField
IntegerField
DecimalField
FloatField
BooleanField
RadioField
SelectField
SelectMultipleField
FielField
SubmitField
FormField
FieldList

5 数据库
pip install flask-sqlalchemy
MySQL mysql://username:password@hostname/database

2 Login
3 Form

Flask 开发环境设置

Python web框架 Flask开发环境设置,引入venv虚拟环境,能很好的避免各程序版本冲突。

1
2
3
4
5
6
cd ~
mdkir weatherapp
cd weatherapp
mkdir templates
touch index.py
touch templates/index.html

安装虚拟环境virtualenv,Mac OS X 下:

1
2
3
4
5
6
7
$sudo easy_install virtualenv
$cd weatherapp
$virtualenv venv
New python executable in venv/bin/python2.7
lso creating executable in venv/bin/python
Installing setuptools............done.
Installing pip...............done.

应用根目录会生成一个venv目录
激活venv

1
2
$source venv/bin/activate
(venv)$

在venv下安装相关的软件包

1
2
3
4
(venv)$pip install flask
(venv)$python
>>>import falsk
>>>

没有错误,就说明你的flask装好了

1
2
3
4
5
6
7
8
9
10
$vim index.py
from flask import Flask
import os
app = Flask(__name__)
@app.route("/")
def index():
return "Hello,World!"
if __name__ == '__main__':
port = int(os.environ.get('PORT',5000))
app.run(host='0.0.0.0',port=port,debug=True)

运行flaskweb服务

1
2
3
(venv)$python index.py
* Running on http://0.0.0.0:5000/
* Restarting with reloader

浏览器输入http://localhost:5000 就可以看到你的helloworld页面了。

所有的Flask应用程序都需要创建一个app实例。服务响应客户端请求使用WSGI(Web Server Gateway Interace)。
路由和视图函数:
路由就是用来保持URL地址和函数的关系。可以使用装饰器@app.route 来暴露路由。URL 可以有静态和动态的方式声明。
/user/ ,/user/

模板
from flask import render_template

变量:
变量
undefined 字典
undefined 列表
undefined 带变量的列表
对象的方法
管道: safe ,lower,upper,title,trim,striptags

控制:
判断:

Hello,Stranger!

循环

‘’’bash
macro

‘’’



支持在外部文件定义:
‘’’bash
{ macros.render_ct(comment) }
‘’’
支持将重复的内容抽象,然后include

支持继承: