使用Fail2ban保护Linux系统
Unix/LinuxC技术 jackxiang 2015-1-6 16:10
MarkMan – 马克鳗,让设计更有爱!
MarkMan – 马克鳗 是一款方便高效的标注工具,极大节省设计师在设计稿上添加和修改标注的时间,让设计更有爱。
一张标注了间距和长度的设计稿,才是有爱的设计稿。想做有爱的设计师,又想摆脱人肉标注的重体力劳动吗?
MarkMan – 马克鳗 可以很方便的为设计稿添加标记,双击、滚轮、拖动…
新版特性:
增加坐标、颜色、文字标记
优化界面设计和交互方式
加入全局放大镜(快捷键同PS)
MarkMan – 马克鳗 是一款方便高效的标注工具,极大节省设计师在设计稿上添加和修改标注的时间,让设计更有爱。
一张标注了间距和长度的设计稿,才是有爱的设计稿。想做有爱的设计师,又想摆脱人肉标注的重体力劳动吗?
MarkMan – 马克鳗 可以很方便的为设计稿添加标记,双击、滚轮、拖动…
新版特性:
增加坐标、颜色、文字标记
优化界面设计和交互方式
加入全局放大镜(快捷键同PS)
saltstack的安装使用
Unix/LinuxC技术 jackxiang 2015-1-4 22:01
背景:配置仓库结合svn版本控制工具
saltstack的安装使用
centos6.3_x86_64
安装EPEL第三方软件源
wget -c http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm
安装
yum install salt-master -y //master
yum install salt-minion //clients
chkconfig --list|grep salt //master默认监听两个端口, 4505(publish_port)为salt的消息发布系统,4506(ret_port)为salt客户端与服务端通信的端口,所以确保客户端能跟服务端的这2个端口通信
salt-master 0:off 1:off 2:off 3:on 4:on 5:on 6:off
salt-syndic 0:off 1:off 2:off 3:on 4:on 5:on 6:off
chkconfig --list|grep salt //clients 没有端口,只有进程
salt-minion 0:off 1:off 2:off 3:on 4:on 5:on 6:off
配置
/etc/init.d/salt-master start //master直接启动,若也要作为clients,install salt-minino,修改master和id
vi /etc/salt/minion //clients
master: 192.168.2.18 //冒号后面有空格
/etc/init.d/salt-minion start
认证
salt-key -L //all list 详细可salt-key --help
实时管理
salt "localhost.localdomain" cmd.run "df -Th"
localhost.localdomain:
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
ext4 19G 6.5G 11G 38% /
tmpfs tmpfs 244M 0 244M 0% /dev/shm
/dev/sda1 ext4 485M 40M 420M 9% /boot
群发
salt "*" cmd.run "ls -al /opt/io.sh"
localhost.localdomain:
-rwxr-xr-x 1 root root 396 Jun 8 18:22 /opt/io.sh
过滤匹配
salt '192.168.*' cmd.run 'echo hi'
正常我们每台主机的HOSTS都是这样
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
为了区分开来并且MASTER也作为客户端
vi /etc/salt/minion
39 id: 192.168.2.18 //或者修改为自定义名称 比如 id: salt-master,修改id后客户端必须重启,salt-keys -L 才能认得到 然后加入-a 如果修改过ID,最好把旧的删掉 -d
salt-key -D //删除所有KEY
salt-key -d key //删除单个key
salt-key -A //接受所有KEY
salt-key -a key //接受单个key
[root@server1 salt]# salt-key -L
Accepted Keys:
Unaccepted Keys:
192.168.2.18
192.168.2.19
Rejected Keys:
[root@server1 salt]# salt-key -a 192.168.2.18
Key for minion 192.168.2.18 accepted.
[root@server1 salt]# salt-key -a 192.168.2.19
Key for minion 192.168.2.19 accepted.
[root@server1 salt]# salt-key -L
Accepted Keys:
192.168.2.18
192.168.2.19
Unaccepted Keys:
Rejected Keys:
测试服务端和客户端通讯
salt "192.168.2.19" test.ping //单引号也可以
192.168.2.19:
True
salt "*" salt.modules.disk //salt.modules.disk 模块
组
服务端:
vi /etc/salt/master
nodegroups:
mytest1: 'S@192.168.2.0/24'
salt -N mytest1 test.ping
192.168.2.18:
True
client1_2.19:
True
KEYS名字 nodegroups:
test1: 'L@192.168.2.18,client1_2.19' //多个
test2: 'client1_2.19' //单个
来自:http://www.2cto.com/os/201308/238485.html
saltstack的安装使用
centos6.3_x86_64
安装EPEL第三方软件源
wget -c http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm
安装
yum install salt-master -y //master
yum install salt-minion //clients
chkconfig --list|grep salt //master默认监听两个端口, 4505(publish_port)为salt的消息发布系统,4506(ret_port)为salt客户端与服务端通信的端口,所以确保客户端能跟服务端的这2个端口通信
salt-master 0:off 1:off 2:off 3:on 4:on 5:on 6:off
salt-syndic 0:off 1:off 2:off 3:on 4:on 5:on 6:off
chkconfig --list|grep salt //clients 没有端口,只有进程
salt-minion 0:off 1:off 2:off 3:on 4:on 5:on 6:off
配置
/etc/init.d/salt-master start //master直接启动,若也要作为clients,install salt-minino,修改master和id
vi /etc/salt/minion //clients
master: 192.168.2.18 //冒号后面有空格
/etc/init.d/salt-minion start
认证
salt-key -L //all list 详细可salt-key --help
实时管理
salt "localhost.localdomain" cmd.run "df -Th"
localhost.localdomain:
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
ext4 19G 6.5G 11G 38% /
tmpfs tmpfs 244M 0 244M 0% /dev/shm
/dev/sda1 ext4 485M 40M 420M 9% /boot
群发
salt "*" cmd.run "ls -al /opt/io.sh"
localhost.localdomain:
-rwxr-xr-x 1 root root 396 Jun 8 18:22 /opt/io.sh
过滤匹配
salt '192.168.*' cmd.run 'echo hi'
正常我们每台主机的HOSTS都是这样
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
为了区分开来并且MASTER也作为客户端
vi /etc/salt/minion
39 id: 192.168.2.18 //或者修改为自定义名称 比如 id: salt-master,修改id后客户端必须重启,salt-keys -L 才能认得到 然后加入-a 如果修改过ID,最好把旧的删掉 -d
salt-key -D //删除所有KEY
salt-key -d key //删除单个key
salt-key -A //接受所有KEY
salt-key -a key //接受单个key
[root@server1 salt]# salt-key -L
Accepted Keys:
Unaccepted Keys:
192.168.2.18
192.168.2.19
Rejected Keys:
[root@server1 salt]# salt-key -a 192.168.2.18
Key for minion 192.168.2.18 accepted.
[root@server1 salt]# salt-key -a 192.168.2.19
Key for minion 192.168.2.19 accepted.
[root@server1 salt]# salt-key -L
Accepted Keys:
192.168.2.18
192.168.2.19
Unaccepted Keys:
Rejected Keys:
测试服务端和客户端通讯
salt "192.168.2.19" test.ping //单引号也可以
192.168.2.19:
True
salt "*" salt.modules.disk //salt.modules.disk 模块
组
服务端:
vi /etc/salt/master
nodegroups:
mytest1: 'S@192.168.2.0/24'
salt -N mytest1 test.ping
192.168.2.18:
True
client1_2.19:
True
KEYS名字 nodegroups:
test1: 'L@192.168.2.18,client1_2.19' //多个
test2: 'client1_2.19' //单个
来自:http://www.2cto.com/os/201308/238485.html
[实践OK]入门教学之Linux如何解决动态库的版本控制, Linux如何解决动态库的版本控制,C语言HelloWorld示例,readelf -d libhello.so.0.0.0 |grep SONAME,以及动态链接的进程映射之/proc/pid/maps。 分析/proc/[pid]/maps中的各个内存区域的大小。
Unix/LinuxC技术 jackxiang 2014-12-31 16:21
核心中的核心:
gcc -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0 hello.o #在生成可执行文件时就得有:libhello.so.0文件,即使是软链接也成,得有。动态链接版本库的标准用法,不标准用libhello.so 也成:gcc -shared -Wl,-soname,libhello.so -o libhello.so.0.0.0 hello.o
背景:共享库,主版本升级,即接口发生变化。
Linux 系统提供一个命令 ldconifg 专门为生成共享库的soname 文件,以便程序在加载时后通过soname 找到共享库。
1)real name:
咱生成的实体文件是:real name ==>libhello.so.0.0.0
readelf -d libhello.so.0.0.0 |grep SONAME
0x000000000000000e (SONAME) Library soname: [libhello.so.0]
1.1.1234的是共享库的版本号,其主版本号+小版本号+build号。主板号,代表当前动态库的版本,如果动态库的接口有变化,那么这个版本号就要加1;后面的两个版本号(小版本号 和 build 号)是告诉你详细的信息,比如为一个hot-fix 而生成的一个版本,其小版本号加1,build号也应有变化。 这个文件名包含共享库的代码。
2)soname:
动态库的soname( Short for shared object name),其是应用程序加载dll 时候,其寻找共享库用的文件名。ldconfig会自动生成,格式为前面的realname:
lib + math+.so + ( major version number)
3)link name:
共享库的连接名(link name),是专门为build 阶段连接而用的名字。这个名字就是lib + math +.so ,比如libmath.so。其是不带任何版本信息的。
例子,在编译时需要link name ,专门为build 阶段连接而用的名字,否者报错/usr/bin/ld: cannot find -lhello:(共享库的连接名(link name),是专门为build 阶段连接而用的名字。例子叫: libhello.so)
gcc -o main main.o -lhello -L.
/usr/bin/ld: cannot find -lhello
解决办法:
ln -sf libhello.so.0 libhello.so
4)ldconfig自动找SONAME,生成SONAME名的共享库,如下:
最后,ldconfig时,是找那个SONAME,然后自动生成对应的共享库:
inux 系统提供一个命令 ldconifg 专门为生成共享库的soname 文件,以便程序在加载时后通过soname 找到共享库。
实践并证明如下(生成SONAME名:gcc -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0 hello.o ,名字叫:libhello.so.0 ,这块即使-L. 引用了,非软链接是libhello.so.0.0.0, 它会提示:/bin/ld: cannot find -lhello,这个:-soname指定名字后,-L会找它,无论是实体的libhello.so.0还是软链接都得有,否则会提示cannot find -lhello,当然,你可以直接写成:gcc -shared -Wl,-soname,libhello.so -o libhello.so.0.0.0 libhello.o ,gcc -o main main.o -lhello -L. ,它会找libhello.so文件是否存在,当然可以软链接:mv libhello.so libhello.so.0.0.0 ,ln -s libhello.so.0.0.0 libhello.so,再编译就能通过:gcc -o main main.o -lhello -L. ,至于运行还是得找:LD_LIBRARY_PATH和ldconfig进行帮忙。):
readelf -d /home/xiangdong/test/c/libhello.so.0.0.0|grep SONAME
0x000000000000000e (SONAME) Library soname: [libhello.so.0]
cp /home/xiangdong/test/c/libhello.so.0.0.0 /usr/lib64/.
ldconfig -p|grep hello
ldconfig
ldconfig -p|grep hello
libhello.so.0 (libc6,x86-64) => /usr/lib64/libhello.so.0 (这个自动由chkconfig生成的so就是前面生成的SONAME名,这一句:gcc -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0 hello.o)
升级问题:
1)共享库,小版本升级,即接口不变.
当升级小版本时,共享库的soname 是不变的,所以需要重新把soname 的那个连接文件指定新版本就可以。 调用ldconfig命令,系统会帮你做修改那个soname link文件,并把它指向新的版本呢。这时候你的应用程序就自动升级了。
2)共享库,主版本升级,即接口发生变化。
共享库,主版本升级,即接口发生变化。
当升级主版本时,共享库的soname 就会加1.比如libhello.so.0.0.0 变为 libhello.so.1.0.0. 这时候再运行ldconfig 文件,就会发现生成两个连接 文件。
ln -s libhello.so.0---->libhello.so.0.0.0
ln -s libhello.so.1----->libhello.so.1.0.0
尽管共享库升级,但是你的程序依旧用的是旧的共享库,并且两个之间不会相互影响。
问题是如果更新的共享库只是增加一些接口,并没有修改已有的接口,也就是向前兼容。但是这时候它的主版本号却增加1. 如果你的应用程序想调用新的共享库,该怎么办? 简单,只要手工把soname 文件修改,使其指向新的版本就可以。(这时候ldconfig 文件不会帮你做这样的事,因为这时候soname 和real name 的版本号主板本号不一致,只能手动修改)。
比如: ln -s libhello.so.0 ---> libhello.so.1.0.0
但是有时候,主版本号增加,接口发生变化,可能向前不兼容。这时候再这样子修改,就会报错,“xx”方法找不到之类的错误。
总结一下,Linux 系统是通过共享库的三个不同名字,来管理共享库的多个版本。 real name 就是共享库的实际文件名字,soname 就是共享库加载时的用的文件名。在生成共享库的时候,编译器将soname 绑定到共享库的文件头里,二者关联起来。 在应用程序引用共享库时,其通过link name 来完成,link时将按照系统指定的目录去搜索link名字找到共享库,并将共享库的soname写在应用程序的头文件里。当应用程序加载共享库时,就会通过soname在系统指定的目录(path or LD_LIBRARY)去寻找共享库。
当共享库升级时,分为两种。一种是主板本不变,升级小版本和build 号。在这种情况下,系统会通过更新soname( ldconfig 来维护),来使用新的版本号。这中情况下,旧版本就没有用,可以删掉。
另外一种是主版本升级,其意味着库的接口发生变化,当然,这时候不能覆盖已有的soname。系统通过增加一个soname(ldconfig -p 里面增加一项),使得新旧版本同时存在。原有的应用程序在加载时,还是根据自己头文件的旧soname 去寻找老的库文件。
5.如果编译的时候没有指定,共享库的soname,会怎么样?
这是一个trick 的地方。第一系统将会在生成库的时候,就没有soname放到库的头里面。从而应用程序连接时候,就把linkname 放到应用程序依赖库里面。或者换句话说就是,soname这时候不带版本号。 有时候有人直接利用这点来升级应用程序,比如,新版本的库,直接拷贝到系统目录下,就会覆盖掉已经存在的旧的库文件,直接升级。 这个给程序员很大程度的便利性,如果一步小心,就会调到类似windows的Dll hell 陷阱里面。建议不要这样做。
=================================================================================================
Makefile有一句:
DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
编译下看看输出:
[hiredis]# make clean
rm -rf libhiredis.so libhiredis.a hiredis-test examples/hiredis-example* *.o *.gcda *.gcno *.gcov
[hiredis]# make
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb net.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb hiredis.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb sds.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb async.c
cc -shared -Wl,-soname,libhiredis.so.0.11 -o libhiredis.so net.o hiredis.o sds.o async.o
静态编译:
ar rcs libhiredis.a net.o hiredis.o sds.o async.o
一)这个/home/test/rpmbuild/BUILD/ngx_http_monitor_module-2.2.0/hiredis 目录下面也并没有:
ls libhiredis.so.0.11
ls: cannot access libhiredis.so.0.11: No such file or directory
readelf -d libhiredis.so
静态就是纯静态的:
ldd libhiredis.a
ldd: warning: you do not have execution permission for `./libhiredis.a'
not a dynamic executable
Dynamic section at offset 0xa7f0 contains 21 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libhiredis.so.0.11] <===就是这个就是-soname,libhiredis.so.0.11编译进去的。
二)Nginx启动后,并找不到这个:
ldd /usr/local/nginx/sbin/nginx
libhiredis.so.0.11 => not found
Starting nginx: /usr/local/nginx/sbin/nginx: error while loading shared libraries: libhiredis.so.0.11: cannot open shared object file: No such file or directory
=============================================================================================
怎么样实现把共享库的soname 提取出来,写在自己的共享库的头文件里面?
第二个是动态库的soname( Short for shared object name),依赖该shared library的应用程序中记录了它的soname,所以应用程序加载该shared library的时候,其寻找共享库用的soname文件名。其格式为
lib + math+.so + ( major version number)
它是一个指向名字为real name的shared library的软链接。
当升级主版本时,共享库的soname 就会加1.比如libhello.so.0.0.0 变为 libhello.so.1.0.0. 这时候再运行ldconfig 文件,就会发现生成两个连接 文件。
ln -s libhello.so.0---->libhello.so.0.0.0
ln -s libhello.so.1----->libhello.so.1.0.0
尽管共享库升级,但是你的程序依旧用的是旧的共享库,并且两个之间不会相互影响。
问题是如果更新的共享库只是增加一些接口,并没有修改已有的接口,也就是向前兼容。但是这时候它的主版本号却增加1. 如果你的应用程序想调用新的共享库,该怎么办? 简单,只要手工把soname 文件修改,使其指向新的版本就可以。(这时候ldconfig 文件不会帮你做这样的事,因为这时候soname 和real name 的版本号主板本号不一致,只能手动修改)。
比如: ln -s libhello.so.0 ---> libhello.so.1.0.0
但是有时候,主版本号增加,接口发生变化,可能向前不兼容。这时候再这样子修改,就会报错,“xx”方法找不到之类的错误。
这就是接下来要介绍的第三个共享库的名字,link name,顾名思义,就是在编译过程,link 阶段用的文件名。 其将soname 和real name 关联起来。
第三个名字,共享库的连接名(link name),是专门为build 阶段连接而用的名字。这个名字就是lib + math +.so ,比如libmath.so。其是不带任何版本信息的。在共享库编译过程中,连接(link) 阶段,编译器将生成一个共享库及real name,同时将共享库的soname,写在共享库文件里的文件头里面。可以用命令 readelf -d sharelibrary 去查看。
在应用程序引用共享库时,其会用到共享库的link name。在应用程序的link阶段,其通过link名字找到动态库,并且把共享库的soname 提取出来,写在自己的共享库的头文件里面。当应用程序加载时就会通过soname 去给定的路径下寻找该共享库。
参考:
http://blog.163.com/kefeng_1984/blog/static/166615272014714114141296/
http://blog.chinaunix.net/uid-23592843-id-223539.html
阅读全文
gcc -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0 hello.o #在生成可执行文件时就得有:libhello.so.0文件,即使是软链接也成,得有。动态链接版本库的标准用法,不标准用libhello.so 也成:gcc -shared -Wl,-soname,libhello.so -o libhello.so.0.0.0 hello.o
背景:共享库,主版本升级,即接口发生变化。
Linux 系统提供一个命令 ldconifg 专门为生成共享库的soname 文件,以便程序在加载时后通过soname 找到共享库。
1)real name:
咱生成的实体文件是:real name ==>libhello.so.0.0.0
readelf -d libhello.so.0.0.0 |grep SONAME
0x000000000000000e (SONAME) Library soname: [libhello.so.0]
1.1.1234的是共享库的版本号,其主版本号+小版本号+build号。主板号,代表当前动态库的版本,如果动态库的接口有变化,那么这个版本号就要加1;后面的两个版本号(小版本号 和 build 号)是告诉你详细的信息,比如为一个hot-fix 而生成的一个版本,其小版本号加1,build号也应有变化。 这个文件名包含共享库的代码。
2)soname:
动态库的soname( Short for shared object name),其是应用程序加载dll 时候,其寻找共享库用的文件名。ldconfig会自动生成,格式为前面的realname:
lib + math+.so + ( major version number)
3)link name:
共享库的连接名(link name),是专门为build 阶段连接而用的名字。这个名字就是lib + math +.so ,比如libmath.so。其是不带任何版本信息的。
例子,在编译时需要link name ,专门为build 阶段连接而用的名字,否者报错/usr/bin/ld: cannot find -lhello:(共享库的连接名(link name),是专门为build 阶段连接而用的名字。例子叫: libhello.so)
gcc -o main main.o -lhello -L.
/usr/bin/ld: cannot find -lhello
解决办法:
ln -sf libhello.so.0 libhello.so
4)ldconfig自动找SONAME,生成SONAME名的共享库,如下:
最后,ldconfig时,是找那个SONAME,然后自动生成对应的共享库:
inux 系统提供一个命令 ldconifg 专门为生成共享库的soname 文件,以便程序在加载时后通过soname 找到共享库。
实践并证明如下(生成SONAME名:gcc -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0 hello.o ,名字叫:libhello.so.0 ,这块即使-L. 引用了,非软链接是libhello.so.0.0.0, 它会提示:/bin/ld: cannot find -lhello,这个:-soname指定名字后,-L会找它,无论是实体的libhello.so.0还是软链接都得有,否则会提示cannot find -lhello,当然,你可以直接写成:gcc -shared -Wl,-soname,libhello.so -o libhello.so.0.0.0 libhello.o ,gcc -o main main.o -lhello -L. ,它会找libhello.so文件是否存在,当然可以软链接:mv libhello.so libhello.so.0.0.0 ,ln -s libhello.so.0.0.0 libhello.so,再编译就能通过:gcc -o main main.o -lhello -L. ,至于运行还是得找:LD_LIBRARY_PATH和ldconfig进行帮忙。):
readelf -d /home/xiangdong/test/c/libhello.so.0.0.0|grep SONAME
0x000000000000000e (SONAME) Library soname: [libhello.so.0]
cp /home/xiangdong/test/c/libhello.so.0.0.0 /usr/lib64/.
ldconfig -p|grep hello
ldconfig
ldconfig -p|grep hello
libhello.so.0 (libc6,x86-64) => /usr/lib64/libhello.so.0 (这个自动由chkconfig生成的so就是前面生成的SONAME名,这一句:gcc -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.0 hello.o)
升级问题:
1)共享库,小版本升级,即接口不变.
当升级小版本时,共享库的soname 是不变的,所以需要重新把soname 的那个连接文件指定新版本就可以。 调用ldconfig命令,系统会帮你做修改那个soname link文件,并把它指向新的版本呢。这时候你的应用程序就自动升级了。
2)共享库,主版本升级,即接口发生变化。
共享库,主版本升级,即接口发生变化。
当升级主版本时,共享库的soname 就会加1.比如libhello.so.0.0.0 变为 libhello.so.1.0.0. 这时候再运行ldconfig 文件,就会发现生成两个连接 文件。
ln -s libhello.so.0---->libhello.so.0.0.0
ln -s libhello.so.1----->libhello.so.1.0.0
尽管共享库升级,但是你的程序依旧用的是旧的共享库,并且两个之间不会相互影响。
问题是如果更新的共享库只是增加一些接口,并没有修改已有的接口,也就是向前兼容。但是这时候它的主版本号却增加1. 如果你的应用程序想调用新的共享库,该怎么办? 简单,只要手工把soname 文件修改,使其指向新的版本就可以。(这时候ldconfig 文件不会帮你做这样的事,因为这时候soname 和real name 的版本号主板本号不一致,只能手动修改)。
比如: ln -s libhello.so.0 ---> libhello.so.1.0.0
但是有时候,主版本号增加,接口发生变化,可能向前不兼容。这时候再这样子修改,就会报错,“xx”方法找不到之类的错误。
总结一下,Linux 系统是通过共享库的三个不同名字,来管理共享库的多个版本。 real name 就是共享库的实际文件名字,soname 就是共享库加载时的用的文件名。在生成共享库的时候,编译器将soname 绑定到共享库的文件头里,二者关联起来。 在应用程序引用共享库时,其通过link name 来完成,link时将按照系统指定的目录去搜索link名字找到共享库,并将共享库的soname写在应用程序的头文件里。当应用程序加载共享库时,就会通过soname在系统指定的目录(path or LD_LIBRARY)去寻找共享库。
当共享库升级时,分为两种。一种是主板本不变,升级小版本和build 号。在这种情况下,系统会通过更新soname( ldconfig 来维护),来使用新的版本号。这中情况下,旧版本就没有用,可以删掉。
另外一种是主版本升级,其意味着库的接口发生变化,当然,这时候不能覆盖已有的soname。系统通过增加一个soname(ldconfig -p 里面增加一项),使得新旧版本同时存在。原有的应用程序在加载时,还是根据自己头文件的旧soname 去寻找老的库文件。
5.如果编译的时候没有指定,共享库的soname,会怎么样?
这是一个trick 的地方。第一系统将会在生成库的时候,就没有soname放到库的头里面。从而应用程序连接时候,就把linkname 放到应用程序依赖库里面。或者换句话说就是,soname这时候不带版本号。 有时候有人直接利用这点来升级应用程序,比如,新版本的库,直接拷贝到系统目录下,就会覆盖掉已经存在的旧的库文件,直接升级。 这个给程序员很大程度的便利性,如果一步小心,就会调到类似windows的Dll hell 陷阱里面。建议不要这样做。
=================================================================================================
Makefile有一句:
DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
编译下看看输出:
[hiredis]# make clean
rm -rf libhiredis.so libhiredis.a hiredis-test examples/hiredis-example* *.o *.gcda *.gcno *.gcov
[hiredis]# make
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb net.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb hiredis.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb sds.c
cc -std=c99 -pedantic -c -O3 -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings -g -ggdb async.c
cc -shared -Wl,-soname,libhiredis.so.0.11 -o libhiredis.so net.o hiredis.o sds.o async.o
静态编译:
ar rcs libhiredis.a net.o hiredis.o sds.o async.o
一)这个/home/test/rpmbuild/BUILD/ngx_http_monitor_module-2.2.0/hiredis 目录下面也并没有:
ls libhiredis.so.0.11
ls: cannot access libhiredis.so.0.11: No such file or directory
readelf -d libhiredis.so
静态就是纯静态的:
ldd libhiredis.a
ldd: warning: you do not have execution permission for `./libhiredis.a'
not a dynamic executable
Dynamic section at offset 0xa7f0 contains 21 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libhiredis.so.0.11] <===就是这个就是-soname,libhiredis.so.0.11编译进去的。
二)Nginx启动后,并找不到这个:
ldd /usr/local/nginx/sbin/nginx
libhiredis.so.0.11 => not found
Starting nginx: /usr/local/nginx/sbin/nginx: error while loading shared libraries: libhiredis.so.0.11: cannot open shared object file: No such file or directory
=============================================================================================
怎么样实现把共享库的soname 提取出来,写在自己的共享库的头文件里面?
第二个是动态库的soname( Short for shared object name),依赖该shared library的应用程序中记录了它的soname,所以应用程序加载该shared library的时候,其寻找共享库用的soname文件名。其格式为
lib + math+.so + ( major version number)
它是一个指向名字为real name的shared library的软链接。
当升级主版本时,共享库的soname 就会加1.比如libhello.so.0.0.0 变为 libhello.so.1.0.0. 这时候再运行ldconfig 文件,就会发现生成两个连接 文件。
ln -s libhello.so.0---->libhello.so.0.0.0
ln -s libhello.so.1----->libhello.so.1.0.0
尽管共享库升级,但是你的程序依旧用的是旧的共享库,并且两个之间不会相互影响。
问题是如果更新的共享库只是增加一些接口,并没有修改已有的接口,也就是向前兼容。但是这时候它的主版本号却增加1. 如果你的应用程序想调用新的共享库,该怎么办? 简单,只要手工把soname 文件修改,使其指向新的版本就可以。(这时候ldconfig 文件不会帮你做这样的事,因为这时候soname 和real name 的版本号主板本号不一致,只能手动修改)。
比如: ln -s libhello.so.0 ---> libhello.so.1.0.0
但是有时候,主版本号增加,接口发生变化,可能向前不兼容。这时候再这样子修改,就会报错,“xx”方法找不到之类的错误。
这就是接下来要介绍的第三个共享库的名字,link name,顾名思义,就是在编译过程,link 阶段用的文件名。 其将soname 和real name 关联起来。
第三个名字,共享库的连接名(link name),是专门为build 阶段连接而用的名字。这个名字就是lib + math +.so ,比如libmath.so。其是不带任何版本信息的。在共享库编译过程中,连接(link) 阶段,编译器将生成一个共享库及real name,同时将共享库的soname,写在共享库文件里的文件头里面。可以用命令 readelf -d sharelibrary 去查看。
在应用程序引用共享库时,其会用到共享库的link name。在应用程序的link阶段,其通过link名字找到动态库,并且把共享库的soname 提取出来,写在自己的共享库的头文件里面。当应用程序加载时就会通过soname 去给定的路径下寻找该共享库。
参考:
http://blog.163.com/kefeng_1984/blog/static/166615272014714114141296/
http://blog.chinaunix.net/uid-23592843-id-223539.html
阅读全文
背景:奶奶的,回重庆的票没着落,回的来票倒是搞了,难不成真得坐高铁?有没有必要拉一100M带宽靠近点服务器好,呵呵。
重庆至北京高铁元旦首发 商务座票价2383...
6小时前 重庆至北京高铁元旦首发 票价767.5元...
12小时前 重庆至北京高铁元旦首发 票价767.5元...
重庆至北京高铁元旦首发 商务座票价2383...
6小时前 重庆至北京高铁元旦首发 票价767.5元...
12小时前 重庆至北京高铁元旦首发 票价767.5元...
背景:当今中国,对知识产权的保护,我扯下淡吧,还是不够,但目前来说,中国人民的确是没钱,买点便宜的,也就罢了,人们已经很艰难,就不要拆穿,这位仁兄非要这样写,于是就写出了这样的文章了,真是....叫好。
作者:水木然
其实,拉动中国经济增长的三驾马车是这样的:
一、抄袭
阅读全文
作者:水木然
其实,拉动中国经济增长的三驾马车是这样的:
一、抄袭
阅读全文
怎样在Linux下从源代码安装SQLite3,在redhat安装gearman,在make的时候,报错,怎么解决的办法?
Unix/LinuxC技术 jackxiang 2014-12-26 16:37
SQLite3是一个极轻型的独立的无服务器的SQL数据库引擎。
你不需要做任何的配置来使其工作。所有你需要的就是安装它并开始使用它。
既然是无服务器的,它被用在很多你所使用的著名的软件中,甚至你可能并不知道那些软件正在使用它。看看下面的例子所有的大公司正在使用SQLiete.PUP编程语言内嵌了SQLite数据库于其中。
如果你从来没有使用过SQLite,按照下面的文章中所提到的步骤安装在Linux上,并且创建了一个例子数据库。
下载SQLite3源代码
去SQLite下载页面,并点击“sqlite-autoconf-3070603.tar.gz”(在源代码部分),并下载到你的系统中。或者使用wget直接从服务器下载就像下面。
安装 SQLite3
Uncompress the tar.gz file and install SQLite3 as shown below.
解压tar.gz文件并像下面所示安装
tar xvfz sqlite-autoconf-3080704.tar.gz
cd sqlite-autoconf-3080704
./configure
make
make install
make安装命令后会有以下的输出。
test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"
./libtool --mode=install /usr/bin/install -c sqlite3 /usr/local/bin/sqlite3
/usr/bin/install -c .libs/sqlite3 /usr/local/bin/sqlite3
test -z "/usr/local/include" || mkdir -p -- "/usr/local/include"
/usr/bin/install -c -m 644 'sqlite3.h' '/usr/local/include/sqlite3.h'
/usr/bin/install -c -m 644 'sqlite3ext.h' '/usr/local/include/sqlite3ext.h'
test -z "/usr/local/share/man/man1" || mkdir -p -- "/usr/local/share/man/man1"
/usr/bin/install -c -m 644 './sqlite3.1' '/usr/local/share/man/man1/sqlite3.1'
test -z "/usr/local/lib/pkgconfig" || mkdir -p -- "/usr/local/lib/pkgconfig"
/usr/bin/install -c -m 644 'sqlite3.pc' '/usr/local/lib/pkgconfig/sqlite3.pc'
提示:如果你对mysql数据库有兴趣,你也可以安装在你的系统中。
摘自:http://blog.csdn.net/qianguozheng/article/details/6731928
在redhat安装gearman,在make的时候,报错,怎么解决的办法:
[root@test gearmand-1.1.12]# make
make -j9 all-am
make[1]: Entering directory `/home/xiangdong/software/gearmand-1.1.12'
CXX libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'bool gearmand::queue::Instance::_sqlite_prepare(const std::string&, sqlite3_stmt**)':
libgearman-server/plugins/queue/sqlite/instance.cc:125: error: 'sqlite3_prepare_v2' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'gearmand_error_t gearmand::queue::Instance::init()':
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_READWRITE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_CREATE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'sqlite3_open_v2' was not declared in this scope
make[1]: *** [libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo] Error 1
make[1]: Leaving directory `/home/xiangdong/software/gearmand-1.1.12'
make: *** [all] Error 2
删除了系统原带的sqlite3 ,到官网上下一个源码,重新编译安装sqlite3。
如:
把sqlite3安装到 /usr/local/sqlite3
tar zxf sqlite3.xxxx.tar.gz
cd sqlite.3.xxxx
./configura --prefix=/usr/local/sqlite3
make && make install
cd ..
最后在编译Gearman时带上 --with-sqlite3=/usr/local/sqlite3,告诉编译器应该使用这个新的sqlite即可。
实践如下:
来自:http://zhidao.baidu.com/question/531552126.html
你不需要做任何的配置来使其工作。所有你需要的就是安装它并开始使用它。
既然是无服务器的,它被用在很多你所使用的著名的软件中,甚至你可能并不知道那些软件正在使用它。看看下面的例子所有的大公司正在使用SQLiete.PUP编程语言内嵌了SQLite数据库于其中。
如果你从来没有使用过SQLite,按照下面的文章中所提到的步骤安装在Linux上,并且创建了一个例子数据库。
下载SQLite3源代码
去SQLite下载页面,并点击“sqlite-autoconf-3070603.tar.gz”(在源代码部分),并下载到你的系统中。或者使用wget直接从服务器下载就像下面。
安装 SQLite3
Uncompress the tar.gz file and install SQLite3 as shown below.
解压tar.gz文件并像下面所示安装
tar xvfz sqlite-autoconf-3080704.tar.gz
cd sqlite-autoconf-3080704
./configure
make
make install
make安装命令后会有以下的输出。
test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"
./libtool --mode=install /usr/bin/install -c sqlite3 /usr/local/bin/sqlite3
/usr/bin/install -c .libs/sqlite3 /usr/local/bin/sqlite3
test -z "/usr/local/include" || mkdir -p -- "/usr/local/include"
/usr/bin/install -c -m 644 'sqlite3.h' '/usr/local/include/sqlite3.h'
/usr/bin/install -c -m 644 'sqlite3ext.h' '/usr/local/include/sqlite3ext.h'
test -z "/usr/local/share/man/man1" || mkdir -p -- "/usr/local/share/man/man1"
/usr/bin/install -c -m 644 './sqlite3.1' '/usr/local/share/man/man1/sqlite3.1'
test -z "/usr/local/lib/pkgconfig" || mkdir -p -- "/usr/local/lib/pkgconfig"
/usr/bin/install -c -m 644 'sqlite3.pc' '/usr/local/lib/pkgconfig/sqlite3.pc'
提示:如果你对mysql数据库有兴趣,你也可以安装在你的系统中。
摘自:http://blog.csdn.net/qianguozheng/article/details/6731928
在redhat安装gearman,在make的时候,报错,怎么解决的办法:
[root@test gearmand-1.1.12]# make
make -j9 all-am
make[1]: Entering directory `/home/xiangdong/software/gearmand-1.1.12'
CXX libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'bool gearmand::queue::Instance::_sqlite_prepare(const std::string&, sqlite3_stmt**)':
libgearman-server/plugins/queue/sqlite/instance.cc:125: error: 'sqlite3_prepare_v2' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'gearmand_error_t gearmand::queue::Instance::init()':
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_READWRITE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_CREATE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'sqlite3_open_v2' was not declared in this scope
make[1]: *** [libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo] Error 1
make[1]: Leaving directory `/home/xiangdong/software/gearmand-1.1.12'
make: *** [all] Error 2
删除了系统原带的sqlite3 ,到官网上下一个源码,重新编译安装sqlite3。
如:
把sqlite3安装到 /usr/local/sqlite3
tar zxf sqlite3.xxxx.tar.gz
cd sqlite.3.xxxx
./configura --prefix=/usr/local/sqlite3
make && make install
cd ..
最后在编译Gearman时带上 --with-sqlite3=/usr/local/sqlite3,告诉编译器应该使用这个新的sqlite即可。
实践如下:
来自:http://zhidao.baidu.com/question/531552126.html
[实践OK]linux平台上编译安装boost库
Unix/LinuxC技术 jackxiang 2014-12-26 13:56
背景:PHP的gearman需要这Lib库,才能编译得过,做一些多任务分发时需要gearman的PHP扩展。
Download: http://sourceforge.net/projects/boost/?source=typ_redirect
阅读全文
Download: http://sourceforge.net/projects/boost/?source=typ_redirect
阅读全文
背景:自己整个T60P的电脑一直想折腾到4G,各种折腾硬是没有折腾上得去。啥ReadyFor4GB 突破 32 位 Windows 7 Vista 内存 4G 限制,啥利用富裕RAM提高系统运行速度的两种途径——RAMDRIVE和SMARTDRV。都无效果,最后一查,还是硬件没有支持,啥软件方法都白扯,
前一段时间T60p里面有条1G的内存坏了,机器总蓝屏,于是买了一条2G的换上,本子有3G内存了,上周同事从美国又给我带来一条2G的,于是把另一条1G的也换下来了,就有了4G,可是Vista系统只认到3G,于是升级BIOS,换操作系统为2003,2008,强行启用PAE,都没用,只能认到3G,到网上搜索,各种说法不一。最后还是在联想官网找到了答案,T60p不支持4G内存,主板决定的,安装什么操作系统都没戏,痛苦啊。。。。。
Memory 256M,512MB,1GB or 2GB and supports up to 4GB maximum memory
Note:Only 64-bit operating systems support more than 3GB of system memory(RAM).Inter Chipsets 945GM and945PM do not support more than 3GB system memory(RAM),even when a 64-bit operatiing system is installed.
来自:http://simon.blog.51cto.com/80/83561/
②关于T60p能不能支持4G以上内存的问题
我谷歌到的大部分答案,都是简单的“可以”。
导致了内存价钱便宜时,伤害了那些8G/16G用户……
理论状态32位的CPU,寻址2的32次方=4,294,967,296=4,294,967K=4,294M=4G
因此,以T2700为首T2字头的32位CPU群,4G是极限!且系统里见到3.5之类也是正常的。
而T7字头为64位的CPU,4G以上(128G以下)自然就木问题了!
当然,操作系统也的用64位的,否则还是那个“32位限制”的根本问题。
UPDATE: 多谢手握真相的网友,官方答复因945PM无法支持Memory Remapping!
因此T60p 硬件可以上4G,但实际最多只能用3G!
摘自:http://blog.sina.com.cn/s/blog_5921fa08010170yq.html
T60p安装SSD后出现windows7 卡(死)现象,与AHCI关系不大!
(后面会详述解决方案):
http://blog.sina.com.cn/s/blog_5921fa08010170yq.html
终于忍不住将t60p的风扇换成T500的风扇了:
http://www.nb591.com/thread-102982-1-1.html
http://www.wendangdaquan.com/Wdshow.asp?id=879ee2294b73f242336c5fe0
购买地址:https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-3869566946.40.1UnP1i&id=8524574266
安装地址:http://www.docin.com/p-394979668.html
前一段时间T60p里面有条1G的内存坏了,机器总蓝屏,于是买了一条2G的换上,本子有3G内存了,上周同事从美国又给我带来一条2G的,于是把另一条1G的也换下来了,就有了4G,可是Vista系统只认到3G,于是升级BIOS,换操作系统为2003,2008,强行启用PAE,都没用,只能认到3G,到网上搜索,各种说法不一。最后还是在联想官网找到了答案,T60p不支持4G内存,主板决定的,安装什么操作系统都没戏,痛苦啊。。。。。
Memory 256M,512MB,1GB or 2GB and supports up to 4GB maximum memory
Note:Only 64-bit operating systems support more than 3GB of system memory(RAM).Inter Chipsets 945GM and945PM do not support more than 3GB system memory(RAM),even when a 64-bit operatiing system is installed.
来自:http://simon.blog.51cto.com/80/83561/
②关于T60p能不能支持4G以上内存的问题
我谷歌到的大部分答案,都是简单的“可以”。
导致了内存价钱便宜时,伤害了那些8G/16G用户……
理论状态32位的CPU,寻址2的32次方=4,294,967,296=4,294,967K=4,294M=4G
因此,以T2700为首T2字头的32位CPU群,4G是极限!且系统里见到3.5之类也是正常的。
而T7字头为64位的CPU,4G以上(128G以下)自然就木问题了!
当然,操作系统也的用64位的,否则还是那个“32位限制”的根本问题。
UPDATE: 多谢手握真相的网友,官方答复因945PM无法支持Memory Remapping!
因此T60p 硬件可以上4G,但实际最多只能用3G!
摘自:http://blog.sina.com.cn/s/blog_5921fa08010170yq.html
T60p安装SSD后出现windows7 卡(死)现象,与AHCI关系不大!
(后面会详述解决方案):
http://blog.sina.com.cn/s/blog_5921fa08010170yq.html
终于忍不住将t60p的风扇换成T500的风扇了:
http://www.nb591.com/thread-102982-1-1.html
http://www.wendangdaquan.com/Wdshow.asp?id=879ee2294b73f242336c5fe0
购买地址:https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-3869566946.40.1UnP1i&id=8524574266
安装地址:http://www.docin.com/p-394979668.html
每个人都知道,肥从口出。减肥的根本就是要控制食量。控制食量不是叫你不食,而是少吃。同时要从你吃的东西,改变你的饮食习惯和体内代谢。 促进代谢怎么做健康?
下面是我一天的食谱
早上:2杯温开水(可以清肠,调理代谢作用)豆浆2杯(一定是无糖新鲜豆浆),麦片1大碗(普通超市买的即食原味麦片就好。一定在吃完豆浆后才吃)如果感觉还饿可以多吃个苹果 中午:正常吃饭(宁可吃多点菜也别多吃点饭吗,饭一小碗就好。最好选鸡肉,鱼吃。)吃完后一定记得喝杯茶。晚餐:正常吃饭(宁可吃多点菜也别多吃点饭吗,饭一小碗就好。最好选鸡肉,鱼吃。)吃完后喝杯普洱。记得8点后一定不要进食。 除此还要多运动。
节食没有减下来的,不仅效果慢,而且肯定会反弹。那我到底是怎么瘦的呢?呵呵,其实重点在我每天午饭后喝的茶上,其实那不是一般的绿茶或是潽尔茶,而是一款具有更强、更专业的瘦身效果的饮料,名字叫做大肚子减肥茶。我就是靠着喝这款饮料来为身体补充瘦素和清除自由基,所以才健健康康瘦下来一年不反弹的。 大肚子减肥茶都合适什么人群呢?>>>
减肥小贴士
(1)饭后一定要养成喝茶的习惯(茶可以减肥可以养生,也可以去油脂)
(2)能站别坐,能坐别躺。多运动
(3)早睡早起,最好12点前睡,早上一定要养成喝两杯水的习惯。喝水可以调节代谢,代谢好一定会廋,何为代谢好--每天起来都可以拉一坨漂亮的便便!
下面是我一天的食谱
早上:2杯温开水(可以清肠,调理代谢作用)豆浆2杯(一定是无糖新鲜豆浆),麦片1大碗(普通超市买的即食原味麦片就好。一定在吃完豆浆后才吃)如果感觉还饿可以多吃个苹果 中午:正常吃饭(宁可吃多点菜也别多吃点饭吗,饭一小碗就好。最好选鸡肉,鱼吃。)吃完后一定记得喝杯茶。晚餐:正常吃饭(宁可吃多点菜也别多吃点饭吗,饭一小碗就好。最好选鸡肉,鱼吃。)吃完后喝杯普洱。记得8点后一定不要进食。 除此还要多运动。
节食没有减下来的,不仅效果慢,而且肯定会反弹。那我到底是怎么瘦的呢?呵呵,其实重点在我每天午饭后喝的茶上,其实那不是一般的绿茶或是潽尔茶,而是一款具有更强、更专业的瘦身效果的饮料,名字叫做大肚子减肥茶。我就是靠着喝这款饮料来为身体补充瘦素和清除自由基,所以才健健康康瘦下来一年不反弹的。 大肚子减肥茶都合适什么人群呢?>>>
减肥小贴士
(1)饭后一定要养成喝茶的习惯(茶可以减肥可以养生,也可以去油脂)
(2)能站别坐,能坐别躺。多运动
(3)早睡早起,最好12点前睡,早上一定要养成喝两杯水的习惯。喝水可以调节代谢,代谢好一定会廋,何为代谢好--每天起来都可以拉一坨漂亮的便便!
一个关于i++和++i的问题。
Php/Js/Shell/Go jackxiang 2014-12-19 16:10
背景:i++还是++i这个问题,我为什么记下了,又忘记了,我觉得这是一个哲学问题。
这是一个医学问题,这是一个物理问题:
Firefox下,打开一个空白页面,按下:Shift+F4,调出Js调试工具:
先后是:
1
2
2
2
原因如下:
a= i++;
则相当于 a=i;i=i+1; //alert i++ 时:相当于a=i,还是原值1。后面再alerti时相当于i=i+1了等于2.
a=++i;
则相当于 i=i+1;a=i;// alert ++i 时,相当于前面的i=i+1,所以就等于2了,而接着再alert i 时还是2.
________________________________________________________
都是i=i+1的意思,区别在于i++是i先不自加,在语句完后自加,++i先自加;
列如a=1+i++;i本来为1的话,这里a=1+1;语句完后i才加1为2;
a=1+++i的话就先i=i+1;i=2.然后a=i+1,a=3
直接使用看不出区别,都是变量i加1
在赋值时才能进行区别,
如:
y=i++ // y的值为i (先引用,后运算)
y=++i // y的值为i+1的结果 (先运算,后引用)
++i是在使用i之前先使i的值加1
i++是在使用i之后,使i的值加1
这是一个医学问题,这是一个物理问题:
Firefox下,打开一个空白页面,按下:Shift+F4,调出Js调试工具:
先后是:
1
2
2
2
原因如下:
a= i++;
则相当于 a=i;i=i+1; //alert i++ 时:相当于a=i,还是原值1。后面再alerti时相当于i=i+1了等于2.
a=++i;
则相当于 i=i+1;a=i;// alert ++i 时,相当于前面的i=i+1,所以就等于2了,而接着再alert i 时还是2.
________________________________________________________
都是i=i+1的意思,区别在于i++是i先不自加,在语句完后自加,++i先自加;
列如a=1+i++;i本来为1的话,这里a=1+1;语句完后i才加1为2;
a=1+++i的话就先i=i+1;i=2.然后a=i+1,a=3
直接使用看不出区别,都是变量i加1
在赋值时才能进行区别,
如:
y=i++ // y的值为i (先引用,后运算)
y=++i // y的值为i+1的结果 (先运算,后引用)
++i是在使用i之前先使i的值加1
i++是在使用i之后,使i的值加1
[实践OK]CentOS的Gearman安装与使用无错版,包含PHP的gearmand扩展,包括安装Gearmand及其PHP扩展,及简单task/worker,相当不容易。
Php/Js/Shell/Go jackxiang 2014-12-18 15:22
背景:用PHP做一些简单的上传是没有任何的问题,但是要做断点上传好像也是没有大问题,但要是并发的切片加断点上传可能就会有问题了哟。
第一个问题是合并问题:如果一上传就合并,PHP老半天不返回是一个方面(是PHP超时还是Nginx超时?),这样势必会造成客户端因没返回,没法再启动新的上传进程,如果用php的追加写文件内存太大还会退出的可能,用上gearmand后出现异步同时写,可能加快了传输效率的同时IO可能会比较密集(假如同一时间并发上传的人多的情况。)。
第二个问题是先后问题:如果并发时出现了传一半时最后一片先上传上来了怎么办?如果直接追加进文件是会不按顺序出错的,如果放在那儿不管,那啥时候管,这也是一个问题。
第三个问题是锁的问题:并发时如果同时两片到了,像PHP这种如何去结合锁的功能呢?据我所知有memcache的add函数是原子操作,可以利用,那就设计到锁多久,是不是又回到第一个问题,返回时间得浪费多长时间呢。
基于上面三点,看来PHP做这活不是太靠谱,于是引出了gearman这个模型,相当于异步处理,再集合PHP的memcache锁(memcache放内存,可能得用ttserver才行,协议一样的。),PHP上传逻辑处理,Nginx上传插件,才有可能做一个较为靠谱且稳定的分片,断点加多进程(多线程)上传服务搭建。
一、从源码安装gearmand遇到的各种外部代码版本及yum版本太低的导致各种编译不过的问题,历程相当的麻烦,特别是boost和这个libevent默认的yum install非常低,都给编译了,把rpm所强制删除了,最后才成功,再就是g++编译版本,得export后才能编译,否则一堆问题,都在下面有描写。
出现第一个问题及处理办法:
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'bool gearmand::queue::Instance::_sqlite_prepare(const std::string&, sqlite3_stmt**)':
libgearman-server/plugins/queue/sqlite/instance.cc:125: error: 'sqlite3_prepare_v2' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'gearmand_error_t gearmand::queue::Instance::init()':
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_READWRITE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_CREATE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'sqlite3_open_v2' was not declared in this scope
make[1]: *** [libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo] Error 1
将队列存放在sqlite3或postgresql。这货是用的sqlite存队列啊:
yum search sqlite
yum install sqlite.x86_64 sqlite-devel.x86_64
还是不行,参考:
安装:https://jackxiang.com/post/7709/ 后,
最后在编译Gearman时带上 --with-sqlite3=/usr/local/sqlite3,告诉编译器应该使用这个新的sqlite即可。
出现第二个问题及处理办法:
./libgearman-1.0/gearman.h:53:23: error: cinttypes: No such file or directory
命令:
yum install gcc44 gcc44-c++ libstdc++44-devel -y
然后在环境变量里加入:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc
export CXX=/usr/bin/g++44
保存退出后执行:
source /etc/profile
删除gearmand-0.34文件夹重新进行编译.
重新进行编译后执行make这步......
看来还得重新export一次新的编译器,因为昨天的关了终端,今天的又没了:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc //这行有问题~
export CXX=/usr/bin/g++44
g++ -o testmemcached testmemcached.cpp -lmemcached
为何还是不行?
echo $CC
/usr/bin/gcc //没变,这儿有问题,再重新设置一次,查到上面这个or有问题:export CC=/usr/bin/gcc44。
# echo $CXX
/usr/bin/g++44 //变了
重新设置,好了:
export CC=/usr/bin/gcc44
/usr/bin/gcc44
在后面有详细的说明,可以不source直接设置环境变量,因为编译后也不一定要这个版本的gcc的。
出现第三个问题的处理办法:
ibgearman-server/plugins/queue/mysql/queue.cc:430: error: 'mysql_error' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc: In function 'gearmand_error_t _mysql_queue_replay(gearman_server_st*, void*, gearmand_error_t (*)(gearman_server_st*, void*, const char*, size_t, const char*, size_t, const void*, size_t, gearman_job_priority_t, int64_t), void*)':
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'MYSQL_RES' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'result' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:447: error: 'MYSQL_ROW' was not declared in this scope
[root@test gearmand-1.1.12]# ./configure --help|grep mysql
--with-mysql=[ARG] use MySQL client library [default=yes], optionally
specify path to mysql_config
Full path to mysql_config program
看样子是想用mysql做队列queue的:
加上还是报错,去了得了,不用mysql做队列,有sqlite足够了,
--without-mysql就好了,来自:
https://bugs.launchpad.net/gearmand/+bug/1327038 说的:
出现第四个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::m_default_line_length'
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::options_description(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::run()':
/usr/local/include/boost/program_options/detail/parsers.hpp:107: undefined reference to `boost::program_options::detail::cmdline::get_canonical_option_prefix()'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::extra_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)':
/usr/local/include/boost/program_options/detail/parsers.hpp:77: undefined reference to `boost::program_options::detail::cmdline::set_additional_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)'
collect2: ld returned 1 exit status
make[1]: *** [bin/gearadmin] Error 1
make[1]: Leaving directory `/home/xiangdong/software/gearmand-1.1.12'
[root@test gearmand-1.1.12]# ./configure --help|grep boost
--with-boost[=ARG] use Boost library from a standard location
--with-boost-libdir=LIB_DIR
Force given directory for boost libraries. Note that
fails and you know exactly where your boost
--with-boost-program-options[=special-lib]
use the program options library from boost - it is
--with-boost-program-options=boost_program_options-gcc-mt-1_33_1
指定boost的库:
从这儿得知在这儿呢: http://jackxiang.com/post/7706/
系统默认会将include拷贝到/usr/local/include/boost/中
将lib拷贝到/usr/local/lib下
yum install boost-devel [实践失败]
回头了解下boost的结构,rpm包是啥样的,如下所示,版本号1.33,有可能是因为lddconfig里默认配置指向这个旧版本了,如下:
vi /etc/ld.so.conf
[root@test ~]# rpm -ql boost-1.33.1-16.el5_9
/usr/lib64/*.so.* //各种so文件
/usr/lib/*.so.* //各种so文件
rpm -ql boost-devel-1.33.1-16.el5_9
/usr/include/boost 里面是各种分类目录,里面是hpp头文件
algorithm/
archive/
assign/
bind/
compatibility
config/
devel包里还有静态a文件及动态so文件:
/usr/lib/libboost_test_exec_monitor.a
/usr/lib/libboost_test_exec_monitor.so
如下实践试试:
cd /home/xiangdong/software/boost_1_57_0
./bootstrap.sh --prefix=/usr/local/boost-1.57
vi tools/build/v2/user-config.jam
文件尾部增加(没找到,直接./b2 ./b2 install 即可!):
using mpi
./b2
./b2 install
Boost headers version >= 1.39.0
[root@localdomain gearmand-1.1.12]# yum search boost
[root@localdomain gearmand-1.1.12]# yum install boost.x86_64
[root@localdomain gearmand-1.1.12]# yum install yum install boost-devel.x86_64
旧的yum源,直接干死,用源码装个试试:
出现第五个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/libgearman-server/gearmand_con.cc:677: undefined reference to `event_initialized'
collect2: ld returned 1 exit status
libevent版本太老了,更新新的版本:
安装最新版本的libevent,并执行以下操作:(备份老版本的/usr/lib64/libevent.so)
ln -s /usr/lib64/libevent-2.0.so.5 /usr/lib64/libevent.so
删除老旧的libevent的rpm包后,安装最新的方法实践如下:
[root@test software]# cp /usr/lib64/libevent.so /usr/lib64/libevent.so.bak.old
[root@test libevent-2.0.21-stable]# tar -zxvf libevent-2.0.21-stable.tar.gz
[root@test libevent-2.0.21-stable]# cd libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr/local/libevent-2.0.21-stable
ls -al /usr/lib | grep libevent
rpm -qa|grep libevent
libevent-1.4.13-1
libevent-devel-1.4.13-1
libevent-devel-1.4.13-1
libevent-1.4.13-1
rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]# rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]#
卸载后看还有没:
[root@test libevent-2.0.21-stable]# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 31 Dec 30 17:17 libevent-1.1a.so.1 -> /usr/lib/libevent-1.1a.so.1.0.2
-rw-r--r-- 1 root root 31596 Jan 7 2007 libevent-1.1a.so.1.0.2
rm -Rf /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1 //删除干净
[root@test libevent-2.0.21-stable]# rm -Rf /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1
[root@test libevent-2.0.21-stable]#
cd /home/xiangdong/software/libevent-2.0.21-stable //最新安装包
./configure --prefix=/usr //libevent会安装到 /usr/lib 或 /usr/local/lib 下
#./configure --prefix=/usr/local/libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr && make && make install
测试libevent是否安装成功:ls -al /usr/lib | grep libevent(或 ls -al /usr/local/lib | grep libevent)
ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 Dec 31 09:44 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x 1 root root 1065819 Dec 31 09:44 libevent-2.0.so.5.1.9
-rw-r--r-- 1 root root 1678970 Dec 31 09:44 libevent.a
lrwxrwxrwx 1 root root 26 Dec 31 09:44 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9
如果libevent的安装目录为/usr/local/lib下,则还需要建立 libevent-1.4.so.2 到 /usr/lib 的软连接,这样其他程序运行时才能找到libevent库:ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib/libevent-1.4.so.2
ls /usr/lib/libevent-2.0.so.5
/usr/lib/libevent-2.0.so.5
干掉旧的libevent的残留的动态so文件:
ls -al /usr/lib64 | grep libevent
lrwxrwxrwx 1 root root 19 Dec 31 09:40 libevent-1.4.so.2 -> libevent.so.bak.old
-rwxr-xr-x 1 root root 104296 Dec 31 09:22 libevent.so.bak.old
[root@test libevent-2.0.21-stable]# rm -Rf /usr/lib64/libevent-1.4.so.2
参考来自:http://blog.sina.com.cn/s/blog_4b93170a0100mbm9.html
编译成功结果如下:
启动gearmand的方法:
[root@test gearmand-1.1.12]# whereis gearmand
gearmand: /usr/local/sbin/gearmand
[root@test ~]# mkdir -p /usr/local/gearman/log
ls /usr/local/sqlite3/bin/
sqlite3
*特别提醒,(mysql性能上可能在做队列上并不比sqlite强到哪儿去)
使用sqlite更加简单方便 :
/usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
很遗憾,我到现在也没能编译出对MySQL的持久化
[root@test ~]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
/usr/local/sbin/gearmand: Error while initializing the queue : libsqlite3
原来是sqlite的位置不对,修改路径后就OK了:
启动成功:
[root@test sqlite3]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite3/bin/gearman --libsqlite3-table gearman_queue -d
[root@test sqlite3]#
端口存在了,说明是真的启动成功了:
[root@test sqlite3]# netstat -atlunp|grep 4830
tcp 0 0 0.0.0.0:4830 0.0.0.0:* LISTEN 17820/gearmand
tcp 0 0 :::4830 :::* LISTEN 17820/gearmand
也就是说gearmand启动时候自己建立一个sqlite的表,如下:
[root@test sqlite3]# cat /usr/local/sqlite3/bin/gearman
SQLite format 3@ ''blegearman_queuegearman_queueCREATE TABLE gearman_queue ( unique_key TEXT, function_name TEXT, priority INTEGER, data BLOB, when_to_run INTEGER, PRIMARY KEY (unique_key, function_name))9M'indexsqlite_autoindex_gearman_queue_1gearman_queue
经过一陈折腾,说明这个gearmand对boost库的要求高,对libevent的版本也要求高,不是能经过yum install能解决得了的,得自己安装后指定,再就是对编译器的版本也是有要求的,也就是说相对来说其安装比较苛刻一些,如Lamp架构相比较的话,难度要高一些。
——————————————————————————————————————————————————————————————
总之,一大堆问题,这货居然还这么流行听说Gearman最初用于LiveJournal的图片resize功能,由于图片resize需要消耗大量计算资 源,因此需要调度到后端多台服务器执行,完成任务之后返回前端再呈现到界面。,看来广大分发系统还真得靠它啊,其它各种小问题不断,参考:
http://www.111cn.net/sys/CentOS/65334.htm
二、PHP的gearmand扩展编译及遇到问题解决实践如下:
PHP的gearmand折腾扩展,这块试了好几个版本的扩展要么configure不过去,要么是lib里却啥,但最后还是以当前最新的版本gearman-1.1.2.tgz给解决了:
./configure --with-php-config=/usr/local/php/bin/php-config
出现如下所示的配置错误:
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable gearman support... yes, shared
found in /usr/local
checking for gearman_create in -lgearman... no
configure: error: wrong libgearman version or lib not found
问题一:
gearman的PHP扩展时出现configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.警告信息。
警告信息说明需要安装 re2c
执行下面命令安装:
wget http://sourceforge.net/projects/re2c/files/re2c/0.13.5/re2c-0.13.5.tar.gz/download
2014-12-31 11:01:59 (999 KB/s) - `re2c-0.13.5.tar.gz' saved [782725/782725]
tar -zxvf re2c-0.13.5.tar.gz
cd re2c-0.13.5
./configure && make && make install //安装成功,警告得到了解决,第二个依旧存在。
它的意思是好像没有找到lib,不对是找到了没有找到里面的某个叫gearman_create的函数,这个就奇怪了,找下:
[root@test /]# find . -name "*gearman*.so*"
./usr/local/lib/libgearman.so.8.0.0
./usr/local/lib/libgearman.so
./usr/local/lib/libgearman.so.8
[root@test /]# vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/lib
/lib64
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib
有这个位置的啊。
[root@test /]# ldconfig //重新lib的位置载入。
[root@test gearman-0.4.0]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@test gearman-0.4.0]# ./configure --with-php-config=/usr/local/php/bin/php-config
问题依旧,去官网看一下呗,http://gearman.org/download/:
文字摘录:PHP
There are two PHP client/worker libraries, one which is a pure PHP extension and one which wraps the libgearman C library.
Gearman Extension
A PHP extension that wraps the libgearman C library.
Gearman PHP Extension (1.0.2) (Source)
官方的PHP扩展高V1.0.2,我这个是gearman-0.4.0太旧了,好像还有更高的gearman-1.1.2.tgz,http://pecl.php.net/package/gearman,放上官网这个上去重新试下了:
tar -zxvf gearman-1.0.2.tgz
cd gearman-1.0.2
[root@test gearman-1.0.2]# phpize
./configure --with-php-config=/usr/local/php/bin/php-config //这个没有问题
[root@test gearman-1.0.2]# make && make install
/home/xiangdong/software/gearman-1.0.2/php_gearman.c: In function ‘zm_startup_gearman’:
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: ‘GEARMAN_MAGIC_TEXT’ undeclared (first use in this function)
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: (Each undeclared identifier is reported only once
还是差啥么子玩意,换个更新的看下,gearman-1.1.2.tgz 实践OK了,如下:
Libraries have been installed in:
/home/xiangdong/software/gearman-1.1.2/modules
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
Build complete.
Don't forget to run 'make test'.
[root@test gearman-1.1.2]# make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
真在的:
ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
在php.ini里加上这个扩展就成了。Successful....EOF
[root@test gearman-1.1.2]# php -v
PHP 5.3.10 (cli) (built: Feb 3 2012 14:04:56)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator
[root@test gearman-1.1.2]# vi /usr/local/php/etc/php.ini
extension = "gearman.so"
[root@test gearman-1.1.2]# php -m|grep gearman
gearman
三、代码编写task的分发及client的及简单代码实践OK及其情况实践Ok:
cd /usr/local/gearman/
[root@test gearman]# mkdir codesTest
[root@test gearman]# cd codesTest/
[root@test codesTest]# vi myworker.php
以守护进程方式启动worker:
# nohup php myworker.php >/dev/null 2>&1 &
[root@test codesTest]# nohup php myworker.php >/dev/null 2>&1 &
[1] 31238
一个发送任务处理请求的client:
vi myclient.php
[root@test codesTest]# vi myclient.php
运行myclient.php:
[root@test codesTest]# php myclient.php "Jose"
hello, Jose
H:test.local:2
一个发出并行处理任务请求的例子tasksclient:
[root@test codesTest]# vi tasksclient.php
运行tasksclient:
[root@test codesTest]# php tasksclient.php
Completed task:: id :2 , handled result:hello, John
Completed task:: id :1 , handled result:hello, Jose
查看worker及队列情况:
(echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]# (echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
34 192.168.109.8 - : sayhello logMsg
35 192.168.109.8 - :
.
查看当前队列情况(显示格式FUNCTION\tTOTAL\tRUNNING\tAVAILABLE_WORKERS):
(echo "status"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]# (echo "status"; sleep 0.1) | nc 192.168.109.8 4830
sayhello 0 0 1
logMsg 0 0 1
.
监控php的守护进程(没实践), 可以开多个,并同时监控:
关于Worker守护进程的启动和监控
上面例子中直接启动worker脚本作为守护进程,无法监控到worker进程是否存活.
使用Unix进程监控supervisord则可轻松解决这个问题.
将如下配置添加到supervisord的配置中,即可实现由supervisord来启动和监控myworker.
编辑配置文件 vi /etc/supervisord.conf
[program:myworker]
command=/usr/local/php5415/bin/php myworker.php
process_name=%(program_name)s_%(process_num)02d
;修改numprocs即可同时开启多个worker进程
numprocs=1
directory=/usr/local/gearman/codesTest
autostart=true
autorestart=true
user=gearmand
stopsignal=KILL
Posted in Daemon / Worker, Gearman.
Tagged gearman.
监控这块看:
http://jingyan.baidu.com/article/375c8e198d1b1425f2a2290c.html
上面这块的PHP扩展代码及实践来自:
http://www.51itstudy.com/30114.html
http://codego.net/384693/
_________下面是摘录别的文章不一定自己配置时可完全过得过,得按自己环境作配置安装,只是用作参考!_______
Gearman的目的在于用PHP扩展分发,于是PHP扩展如何安装:
tar zxvf gearman-1.1.1.tgz
cd gearman-1.1.1
/opt/local/php/bin/phpize
./configure --with-php-config=/opt/local/php/bin/php-config --with-gearman
make
make install
编辑 php.ini
vi php.ini
增加
extension = "gearman.so"
重启php
启动gearmand 服务
gearmand -L 10.6.0.6 -p 4730 -u root -l /var/log/gearmand.log -d
其他参数请 gearmand --help
摘自:http://jicki.blog.51cto.com/1323993/1177487
阅读全文
第一个问题是合并问题:如果一上传就合并,PHP老半天不返回是一个方面(是PHP超时还是Nginx超时?),这样势必会造成客户端因没返回,没法再启动新的上传进程,如果用php的追加写文件内存太大还会退出的可能,用上gearmand后出现异步同时写,可能加快了传输效率的同时IO可能会比较密集(假如同一时间并发上传的人多的情况。)。
第二个问题是先后问题:如果并发时出现了传一半时最后一片先上传上来了怎么办?如果直接追加进文件是会不按顺序出错的,如果放在那儿不管,那啥时候管,这也是一个问题。
第三个问题是锁的问题:并发时如果同时两片到了,像PHP这种如何去结合锁的功能呢?据我所知有memcache的add函数是原子操作,可以利用,那就设计到锁多久,是不是又回到第一个问题,返回时间得浪费多长时间呢。
基于上面三点,看来PHP做这活不是太靠谱,于是引出了gearman这个模型,相当于异步处理,再集合PHP的memcache锁(memcache放内存,可能得用ttserver才行,协议一样的。),PHP上传逻辑处理,Nginx上传插件,才有可能做一个较为靠谱且稳定的分片,断点加多进程(多线程)上传服务搭建。
一、从源码安装gearmand遇到的各种外部代码版本及yum版本太低的导致各种编译不过的问题,历程相当的麻烦,特别是boost和这个libevent默认的yum install非常低,都给编译了,把rpm所强制删除了,最后才成功,再就是g++编译版本,得export后才能编译,否则一堆问题,都在下面有描写。
出现第一个问题及处理办法:
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'bool gearmand::queue::Instance::_sqlite_prepare(const std::string&, sqlite3_stmt**)':
libgearman-server/plugins/queue/sqlite/instance.cc:125: error: 'sqlite3_prepare_v2' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc: In member function 'gearmand_error_t gearmand::queue::Instance::init()':
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_READWRITE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'SQLITE_OPEN_CREATE' was not declared in this scope
libgearman-server/plugins/queue/sqlite/instance.cc:224: error: 'sqlite3_open_v2' was not declared in this scope
make[1]: *** [libgearman-server/plugins/queue/sqlite/libgearman_server_libgearman_server_la-instance.lo] Error 1
将队列存放在sqlite3或postgresql。这货是用的sqlite存队列啊:
yum search sqlite
yum install sqlite.x86_64 sqlite-devel.x86_64
还是不行,参考:
安装:https://jackxiang.com/post/7709/ 后,
最后在编译Gearman时带上 --with-sqlite3=/usr/local/sqlite3,告诉编译器应该使用这个新的sqlite即可。
出现第二个问题及处理办法:
./libgearman-1.0/gearman.h:53:23: error: cinttypes: No such file or directory
命令:
yum install gcc44 gcc44-c++ libstdc++44-devel -y
然后在环境变量里加入:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc
export CXX=/usr/bin/g++44
保存退出后执行:
source /etc/profile
删除gearmand-0.34文件夹重新进行编译.
重新进行编译后执行make这步......
看来还得重新export一次新的编译器,因为昨天的关了终端,今天的又没了:
export CC=/usr/bin/gcc44 or export CC=/usr/bin/gcc //这行有问题~
export CXX=/usr/bin/g++44
g++ -o testmemcached testmemcached.cpp -lmemcached
为何还是不行?
echo $CC
/usr/bin/gcc //没变,这儿有问题,再重新设置一次,查到上面这个or有问题:export CC=/usr/bin/gcc44。
# echo $CXX
/usr/bin/g++44 //变了
重新设置,好了:
export CC=/usr/bin/gcc44
/usr/bin/gcc44
在后面有详细的说明,可以不source直接设置环境变量,因为编译后也不一定要这个版本的gcc的。
出现第三个问题的处理办法:
ibgearman-server/plugins/queue/mysql/queue.cc:430: error: 'mysql_error' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc: In function 'gearmand_error_t _mysql_queue_replay(gearman_server_st*, void*, gearmand_error_t (*)(gearman_server_st*, void*, const char*, size_t, const char*, size_t, const void*, size_t, gearman_job_priority_t, int64_t), void*)':
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'MYSQL_RES' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:446: error: 'result' was not declared in this scope
libgearman-server/plugins/queue/mysql/queue.cc:447: error: 'MYSQL_ROW' was not declared in this scope
[root@test gearmand-1.1.12]# ./configure --help|grep mysql
--with-mysql=[ARG] use MySQL client library [default=yes], optionally
specify path to mysql_config
Full path to mysql_config program
看样子是想用mysql做队列queue的:
加上还是报错,去了得了,不用mysql做队列,有sqlite足够了,
--without-mysql就好了,来自:
https://bugs.launchpad.net/gearmand/+bug/1327038 说的:
出现第四个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::m_default_line_length'
/home/xiangdong/software/gearmand-1.1.12/bin/gearadmin.cc:129: undefined reference to `boost::program_options::options_description::options_description(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::run()':
/usr/local/include/boost/program_options/detail/parsers.hpp:107: undefined reference to `boost::program_options::detail::cmdline::get_canonical_option_prefix()'
bin/gearadmin.o: In function `boost::program_options::basic_command_line_parser<char>::extra_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)':
/usr/local/include/boost/program_options/detail/parsers.hpp:77: undefined reference to `boost::program_options::detail::cmdline::set_additional_parser(boost::function1<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>)'
collect2: ld returned 1 exit status
make[1]: *** [bin/gearadmin] Error 1
make[1]: Leaving directory `/home/xiangdong/software/gearmand-1.1.12'
[root@test gearmand-1.1.12]# ./configure --help|grep boost
--with-boost[=ARG] use Boost library from a standard location
--with-boost-libdir=LIB_DIR
Force given directory for boost libraries. Note that
fails and you know exactly where your boost
--with-boost-program-options[=special-lib]
use the program options library from boost - it is
--with-boost-program-options=boost_program_options-gcc-mt-1_33_1
指定boost的库:
从这儿得知在这儿呢: http://jackxiang.com/post/7706/
系统默认会将include拷贝到/usr/local/include/boost/中
将lib拷贝到/usr/local/lib下
yum install boost-devel [实践失败]
回头了解下boost的结构,rpm包是啥样的,如下所示,版本号1.33,有可能是因为lddconfig里默认配置指向这个旧版本了,如下:
vi /etc/ld.so.conf
[root@test ~]# rpm -ql boost-1.33.1-16.el5_9
/usr/lib64/*.so.* //各种so文件
/usr/lib/*.so.* //各种so文件
rpm -ql boost-devel-1.33.1-16.el5_9
/usr/include/boost 里面是各种分类目录,里面是hpp头文件
algorithm/
archive/
assign/
bind/
compatibility
config/
devel包里还有静态a文件及动态so文件:
/usr/lib/libboost_test_exec_monitor.a
/usr/lib/libboost_test_exec_monitor.so
如下实践试试:
cd /home/xiangdong/software/boost_1_57_0
./bootstrap.sh --prefix=/usr/local/boost-1.57
vi tools/build/v2/user-config.jam
文件尾部增加(没找到,直接./b2 ./b2 install 即可!):
using mpi
./b2
./b2 install
Boost headers version >= 1.39.0
[root@localdomain gearmand-1.1.12]# yum search boost
[root@localdomain gearmand-1.1.12]# yum install boost.x86_64
[root@localdomain gearmand-1.1.12]# yum install yum install boost-devel.x86_64
旧的yum源,直接干死,用源码装个试试:
出现第五个问题的解决办法:
/home/xiangdong/software/gearmand-1.1.12/libgearman-server/gearmand_con.cc:677: undefined reference to `event_initialized'
collect2: ld returned 1 exit status
libevent版本太老了,更新新的版本:
安装最新版本的libevent,并执行以下操作:(备份老版本的/usr/lib64/libevent.so)
ln -s /usr/lib64/libevent-2.0.so.5 /usr/lib64/libevent.so
删除老旧的libevent的rpm包后,安装最新的方法实践如下:
[root@test software]# cp /usr/lib64/libevent.so /usr/lib64/libevent.so.bak.old
[root@test libevent-2.0.21-stable]# tar -zxvf libevent-2.0.21-stable.tar.gz
[root@test libevent-2.0.21-stable]# cd libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr/local/libevent-2.0.21-stable
ls -al /usr/lib | grep libevent
rpm -qa|grep libevent
libevent-1.4.13-1
libevent-devel-1.4.13-1
libevent-devel-1.4.13-1
libevent-1.4.13-1
rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]# rpm -e --allmatches --nodeps libevent-1.4.13-1 libevent-devel-1.4.13-1
[root@test libevent-2.0.21-stable]#
卸载后看还有没:
[root@test libevent-2.0.21-stable]# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 31 Dec 30 17:17 libevent-1.1a.so.1 -> /usr/lib/libevent-1.1a.so.1.0.2
-rw-r--r-- 1 root root 31596 Jan 7 2007 libevent-1.1a.so.1.0.2
rm -Rf /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1 //删除干净
[root@test libevent-2.0.21-stable]# rm -Rf /usr/lib/libevent-1.1a.so.1.0.2 /usr/lib/libevent-1.1a.so.1
[root@test libevent-2.0.21-stable]#
cd /home/xiangdong/software/libevent-2.0.21-stable //最新安装包
./configure --prefix=/usr //libevent会安装到 /usr/lib 或 /usr/local/lib 下
#./configure --prefix=/usr/local/libevent-2.0.21-stable
[root@test libevent-2.0.21-stable]# ./configure --prefix=/usr && make && make install
测试libevent是否安装成功:ls -al /usr/lib | grep libevent(或 ls -al /usr/local/lib | grep libevent)
ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 Dec 31 09:44 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x 1 root root 1065819 Dec 31 09:44 libevent-2.0.so.5.1.9
-rw-r--r-- 1 root root 1678970 Dec 31 09:44 libevent.a
lrwxrwxrwx 1 root root 26 Dec 31 09:44 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9
如果libevent的安装目录为/usr/local/lib下,则还需要建立 libevent-1.4.so.2 到 /usr/lib 的软连接,这样其他程序运行时才能找到libevent库:ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib/libevent-1.4.so.2
ls /usr/lib/libevent-2.0.so.5
/usr/lib/libevent-2.0.so.5
干掉旧的libevent的残留的动态so文件:
ls -al /usr/lib64 | grep libevent
lrwxrwxrwx 1 root root 19 Dec 31 09:40 libevent-1.4.so.2 -> libevent.so.bak.old
-rwxr-xr-x 1 root root 104296 Dec 31 09:22 libevent.so.bak.old
[root@test libevent-2.0.21-stable]# rm -Rf /usr/lib64/libevent-1.4.so.2
参考来自:http://blog.sina.com.cn/s/blog_4b93170a0100mbm9.html
编译成功结果如下:
启动gearmand的方法:
[root@test gearmand-1.1.12]# whereis gearmand
gearmand: /usr/local/sbin/gearmand
[root@test ~]# mkdir -p /usr/local/gearman/log
ls /usr/local/sqlite3/bin/
sqlite3
*特别提醒,(mysql性能上可能在做队列上并不比sqlite强到哪儿去)
使用sqlite更加简单方便 :
/usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
很遗憾,我到现在也没能编译出对MySQL的持久化
[root@test ~]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite/bin/gearman --libsqlite3-table gearman_queue -d
/usr/local/sbin/gearmand: Error while initializing the queue : libsqlite3
原来是sqlite的位置不对,修改路径后就OK了:
启动成功:
[root@test sqlite3]# /usr/local/sbin/gearmand -l /usr/local/gearman/log/trace2.log --verbose INFO -p 4830 -q libsqlite3 --libsqlite3-db /usr/local/sqlite3/bin/gearman --libsqlite3-table gearman_queue -d
[root@test sqlite3]#
端口存在了,说明是真的启动成功了:
[root@test sqlite3]# netstat -atlunp|grep 4830
tcp 0 0 0.0.0.0:4830 0.0.0.0:* LISTEN 17820/gearmand
tcp 0 0 :::4830 :::* LISTEN 17820/gearmand
也就是说gearmand启动时候自己建立一个sqlite的表,如下:
[root@test sqlite3]# cat /usr/local/sqlite3/bin/gearman
SQLite format 3@ ''blegearman_queuegearman_queueCREATE TABLE gearman_queue ( unique_key TEXT, function_name TEXT, priority INTEGER, data BLOB, when_to_run INTEGER, PRIMARY KEY (unique_key, function_name))9M'indexsqlite_autoindex_gearman_queue_1gearman_queue
经过一陈折腾,说明这个gearmand对boost库的要求高,对libevent的版本也要求高,不是能经过yum install能解决得了的,得自己安装后指定,再就是对编译器的版本也是有要求的,也就是说相对来说其安装比较苛刻一些,如Lamp架构相比较的话,难度要高一些。
——————————————————————————————————————————————————————————————
总之,一大堆问题,这货居然还这么流行听说Gearman最初用于LiveJournal的图片resize功能,由于图片resize需要消耗大量计算资 源,因此需要调度到后端多台服务器执行,完成任务之后返回前端再呈现到界面。,看来广大分发系统还真得靠它啊,其它各种小问题不断,参考:
http://www.111cn.net/sys/CentOS/65334.htm
二、PHP的gearmand扩展编译及遇到问题解决实践如下:
PHP的gearmand折腾扩展,这块试了好几个版本的扩展要么configure不过去,要么是lib里却啥,但最后还是以当前最新的版本gearman-1.1.2.tgz给解决了:
./configure --with-php-config=/usr/local/php/bin/php-config
出现如下所示的配置错误:
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable gearman support... yes, shared
found in /usr/local
checking for gearman_create in -lgearman... no
configure: error: wrong libgearman version or lib not found
问题一:
gearman的PHP扩展时出现configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.警告信息。
警告信息说明需要安装 re2c
执行下面命令安装:
wget http://sourceforge.net/projects/re2c/files/re2c/0.13.5/re2c-0.13.5.tar.gz/download
2014-12-31 11:01:59 (999 KB/s) - `re2c-0.13.5.tar.gz' saved [782725/782725]
tar -zxvf re2c-0.13.5.tar.gz
cd re2c-0.13.5
./configure && make && make install //安装成功,警告得到了解决,第二个依旧存在。
它的意思是好像没有找到lib,不对是找到了没有找到里面的某个叫gearman_create的函数,这个就奇怪了,找下:
[root@test /]# find . -name "*gearman*.so*"
./usr/local/lib/libgearman.so.8.0.0
./usr/local/lib/libgearman.so
./usr/local/lib/libgearman.so.8
[root@test /]# vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/lib
/lib64
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib
有这个位置的啊。
[root@test /]# ldconfig //重新lib的位置载入。
[root@test gearman-0.4.0]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@test gearman-0.4.0]# ./configure --with-php-config=/usr/local/php/bin/php-config
问题依旧,去官网看一下呗,http://gearman.org/download/:
文字摘录:PHP
There are two PHP client/worker libraries, one which is a pure PHP extension and one which wraps the libgearman C library.
Gearman Extension
A PHP extension that wraps the libgearman C library.
Gearman PHP Extension (1.0.2) (Source)
官方的PHP扩展高V1.0.2,我这个是gearman-0.4.0太旧了,好像还有更高的gearman-1.1.2.tgz,http://pecl.php.net/package/gearman,放上官网这个上去重新试下了:
tar -zxvf gearman-1.0.2.tgz
cd gearman-1.0.2
[root@test gearman-1.0.2]# phpize
./configure --with-php-config=/usr/local/php/bin/php-config //这个没有问题
[root@test gearman-1.0.2]# make && make install
/home/xiangdong/software/gearman-1.0.2/php_gearman.c: In function ‘zm_startup_gearman’:
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: ‘GEARMAN_MAGIC_TEXT’ undeclared (first use in this function)
/home/xiangdong/software/gearman-1.0.2/php_gearman.c:4638: error: (Each undeclared identifier is reported only once
还是差啥么子玩意,换个更新的看下,gearman-1.1.2.tgz 实践OK了,如下:
Libraries have been installed in:
/home/xiangdong/software/gearman-1.1.2/modules
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
Build complete.
Don't forget to run 'make test'.
[root@test gearman-1.1.2]# make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
真在的:
ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/gearman.so
在php.ini里加上这个扩展就成了。Successful....EOF
[root@test gearman-1.1.2]# php -v
PHP 5.3.10 (cli) (built: Feb 3 2012 14:04:56)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
with eAccelerator v0.9.6.1, Copyright (c) 2004-2010 eAccelerator, by eAccelerator
[root@test gearman-1.1.2]# vi /usr/local/php/etc/php.ini
extension = "gearman.so"
[root@test gearman-1.1.2]# php -m|grep gearman
gearman
三、代码编写task的分发及client的及简单代码实践OK及其情况实践Ok:
cd /usr/local/gearman/
[root@test gearman]# mkdir codesTest
[root@test gearman]# cd codesTest/
[root@test codesTest]# vi myworker.php
以守护进程方式启动worker:
# nohup php myworker.php >/dev/null 2>&1 &
[root@test codesTest]# nohup php myworker.php >/dev/null 2>&1 &
[1] 31238
一个发送任务处理请求的client:
vi myclient.php
[root@test codesTest]# vi myclient.php
运行myclient.php:
[root@test codesTest]# php myclient.php "Jose"
hello, Jose
H:test.local:2
一个发出并行处理任务请求的例子tasksclient:
[root@test codesTest]# vi tasksclient.php
运行tasksclient:
[root@test codesTest]# php tasksclient.php
Completed task:: id :2 , handled result:hello, John
Completed task:: id :1 , handled result:hello, Jose
查看worker及队列情况:
(echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]# (echo "workers"; sleep 0.1) | nc 192.168.109.8 4830
34 192.168.109.8 - : sayhello logMsg
35 192.168.109.8 - :
.
查看当前队列情况(显示格式FUNCTION\tTOTAL\tRUNNING\tAVAILABLE_WORKERS):
(echo "status"; sleep 0.1) | nc 192.168.109.8 4830
[root@test codesTest]# (echo "status"; sleep 0.1) | nc 192.168.109.8 4830
sayhello 0 0 1
logMsg 0 0 1
.
监控php的守护进程(没实践), 可以开多个,并同时监控:
关于Worker守护进程的启动和监控
上面例子中直接启动worker脚本作为守护进程,无法监控到worker进程是否存活.
使用Unix进程监控supervisord则可轻松解决这个问题.
将如下配置添加到supervisord的配置中,即可实现由supervisord来启动和监控myworker.
编辑配置文件 vi /etc/supervisord.conf
[program:myworker]
command=/usr/local/php5415/bin/php myworker.php
process_name=%(program_name)s_%(process_num)02d
;修改numprocs即可同时开启多个worker进程
numprocs=1
directory=/usr/local/gearman/codesTest
autostart=true
autorestart=true
user=gearmand
stopsignal=KILL
Posted in Daemon / Worker, Gearman.
Tagged gearman.
监控这块看:
http://jingyan.baidu.com/article/375c8e198d1b1425f2a2290c.html
上面这块的PHP扩展代码及实践来自:
http://www.51itstudy.com/30114.html
http://codego.net/384693/
_________下面是摘录别的文章不一定自己配置时可完全过得过,得按自己环境作配置安装,只是用作参考!_______
Gearman的目的在于用PHP扩展分发,于是PHP扩展如何安装:
tar zxvf gearman-1.1.1.tgz
cd gearman-1.1.1
/opt/local/php/bin/phpize
./configure --with-php-config=/opt/local/php/bin/php-config --with-gearman
make
make install
编辑 php.ini
vi php.ini
增加
extension = "gearman.so"
重启php
启动gearmand 服务
gearmand -L 10.6.0.6 -p 4730 -u root -l /var/log/gearmand.log -d
其他参数请 gearmand --help
摘自:http://jicki.blog.51cto.com/1323993/1177487
阅读全文
[实践OK] 百度云解析之vps安装centOS7 系统下利用iptables配置IP地址白名单放行百度云CDN加速(百度云加速)IP地址群。
Unix/LinuxC技术 jackxiang 2014-12-17 21:42
背景:使用vps性能不是太好,于是否有恶意的访问增加流量,而此时呢,想用云加速,但一加速就被iptables分析日志干成黑名单了,有时一访问太快了给nginx拒绝了,实现方法见Url:http://jackxiang.com/post/7671/ 。如何防止误伤到去加速呢,百度提供出了他们的IP地址,我们可以用白名单写入到iptables里于是就好了。
把NS指向百度的:修改DNS地址到 ns1.bdydns.cnns2.bdydns.cn
nslookup用法:怎么查看一个网站域名的NS服务器地址
nslookup,然后空格,加上一个“/”斜杠,再加上一个问号,就能出现对应指令的所有参数和使用方法。
我们如果想看一个域名的NS值,最简便的方法是在nslookup后面直接跟上域名,注意不要带http://,就会出现这个域名对应的NS记录值。
nslookup www.jackxiang.com
服务器: dnscache33
Address: 127.0.0.1
非权威应答:
名称: ns1.bdydns.cn
Addresses: 180.97.36.63
111.206.223.119
Aliases: www.jackxiang.com
后面有兄弟邮件询问这个,我作了下简单回复:
Dear:
一般不建议网络使用白名单,因为有很多位置的IP你没法判定完全,如来自美国、法国
一般使用黑名单的较多,谁ddos,就拉黑谁,百度的所谓cdn也就是他从一些自己的IP
机器下面来抓你服务器的页面,后存起来,如果是最新的用户就不用访问你的服务器。
在 2015-09-02 15:32:16,"木秀于林" <8047105XX@qq.com> 写道:
你好向东!
[实践OK] 云vps安装centOS7 系统下利用iptables配置IP地址白名单放行百度云CDN加速(百度云加速)IP地址群
看到你发布的这篇文章很不错,就是研究了半天没搞定,
我用了百度云加速,现在网站访问除了问题,百度客服说服务器拦截了百度IP,空间商说没有防火墙,空间商让我在AMH面板安装AMNetwork试试,安装后在面板添加代码怎么也搞不定,显示AMNetwork : 防火墙配置失败,请检查更改规则是否正确。
我的QQ号8047105XX
在您有空的时候希望帮一下,谢谢了!
————————————————————————————————————————————————————————————————
实践证明:
https://jackxiang.com 没法加速Https(不加速透传也成),不想加速,只加速:http://jackxiang.com 和http://www.jackxiang.com都是没有问题,但我要管理用https,经过加速后没法访问,这块暂时不用云加速。
关于iptable如何在开机启动和crontab里放入自动把某些IP及端口打开或扔进防火墙的链接如下:
http://jackxiang.com/post/7782/
编辑iptables配置文件,将文件内容更改为如下,则具备了ip地址白名单功能
#vim /etc/sysconfig/iptables
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-N whitelist
-A whitelist -s 1.2.3.0/24 -j ACCEPT
-A whitelist -s 4.5.6.7 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j whitelist
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j whitelist
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j whitelist
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
6~8 行是添加白名单列表,可以是ip段或者单个ip地址
10~12行 注意的是“-j whitelist”而不是“-j ACCEPT”,前者将该端口访问权限限制在白名单内,后者为不限制
13行 任何ip地址都能ping通该主机,因为“-j ACCEPT”没有做相应限制
配置完毕后,运行命令重启防火墙使规则生效
#systemctl restart iptables.service
上述摘自:http://blog.chinaunix.net/uid-13344516-id-4573922.html
实践如下:
百度云加速列表写成iptables白名单如下,这样就可以防止iptables分析Http请求日志时把它过滤掉:
好像会报254错,但写成24就没错了:
百度去加速的白名单来源:
http://yunjiasu.baidu.com/website/node/#domain=jackxiang.com
jackxiang.com 分配到的节点
地点 线路 IP
济南 联通 119.188.132.68
济南 联通 119.188.132.67
石家庄 联通 61.182.137.6
西安 电信 117.34.28.77
西安 电信 117.34.28.78
苏州 电信 61.155.149.78
苏州 电信 61.155.149.79
南宁 电信 222.216.190.62
南宁 电信 222.216.190.63
百度云加速所有的节点IP
地点 线路 IP段
佛山 电信 183.60.235.0 ~ 183.60.235.254
石家庄 联通 61.182.137.0 ~ 61.182.137.254
南宁 电信 222.216.190.0 ~ 222.216.190.254
济南 联通 119.188.14.0 ~ 119.188.14.254
苏州 电信 61.155.149.0 ~ 61.155.149.254
济南 联通 119.188.132.0 ~ 119.188.132.254
西安 电信 117.34.28.0 ~ 117.34.28.254
郑州 联通 42.236.7.0 ~ 42.236.7.254
关于ssl免费版本不支持的问题回复 AddTime:2015-02-03:
我问题:
https://jackxiang.com 没法加速Https(不加速透传也成),不想加速,只加速:http://jackxiang.com 是没有问题,但我要管理用https,你们没有给我转过支。
回复如下:
您好,目前的免费版本是不支持https的,后续收费版才会支持。
————————————EOF———————————————
把NS指向百度的:修改DNS地址到 ns1.bdydns.cnns2.bdydns.cn
nslookup用法:怎么查看一个网站域名的NS服务器地址
nslookup,然后空格,加上一个“/”斜杠,再加上一个问号,就能出现对应指令的所有参数和使用方法。
我们如果想看一个域名的NS值,最简便的方法是在nslookup后面直接跟上域名,注意不要带http://,就会出现这个域名对应的NS记录值。
nslookup www.jackxiang.com
服务器: dnscache33
Address: 127.0.0.1
非权威应答:
名称: ns1.bdydns.cn
Addresses: 180.97.36.63
111.206.223.119
Aliases: www.jackxiang.com
后面有兄弟邮件询问这个,我作了下简单回复:
Dear:
一般不建议网络使用白名单,因为有很多位置的IP你没法判定完全,如来自美国、法国
一般使用黑名单的较多,谁ddos,就拉黑谁,百度的所谓cdn也就是他从一些自己的IP
机器下面来抓你服务器的页面,后存起来,如果是最新的用户就不用访问你的服务器。
在 2015-09-02 15:32:16,"木秀于林" <8047105XX@qq.com> 写道:
你好向东!
[实践OK] 云vps安装centOS7 系统下利用iptables配置IP地址白名单放行百度云CDN加速(百度云加速)IP地址群
看到你发布的这篇文章很不错,就是研究了半天没搞定,
我用了百度云加速,现在网站访问除了问题,百度客服说服务器拦截了百度IP,空间商说没有防火墙,空间商让我在AMH面板安装AMNetwork试试,安装后在面板添加代码怎么也搞不定,显示AMNetwork : 防火墙配置失败,请检查更改规则是否正确。
我的QQ号8047105XX
在您有空的时候希望帮一下,谢谢了!
————————————————————————————————————————————————————————————————
实践证明:
https://jackxiang.com 没法加速Https(不加速透传也成),不想加速,只加速:http://jackxiang.com 和http://www.jackxiang.com都是没有问题,但我要管理用https,经过加速后没法访问,这块暂时不用云加速。
关于iptable如何在开机启动和crontab里放入自动把某些IP及端口打开或扔进防火墙的链接如下:
http://jackxiang.com/post/7782/
编辑iptables配置文件,将文件内容更改为如下,则具备了ip地址白名单功能
#vim /etc/sysconfig/iptables
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-N whitelist
-A whitelist -s 1.2.3.0/24 -j ACCEPT
-A whitelist -s 4.5.6.7 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j whitelist
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j whitelist
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j whitelist
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
6~8 行是添加白名单列表,可以是ip段或者单个ip地址
10~12行 注意的是“-j whitelist”而不是“-j ACCEPT”,前者将该端口访问权限限制在白名单内,后者为不限制
13行 任何ip地址都能ping通该主机,因为“-j ACCEPT”没有做相应限制
配置完毕后,运行命令重启防火墙使规则生效
#systemctl restart iptables.service
上述摘自:http://blog.chinaunix.net/uid-13344516-id-4573922.html
实践如下:
百度云加速列表写成iptables白名单如下,这样就可以防止iptables分析Http请求日志时把它过滤掉:
好像会报254错,但写成24就没错了:
百度去加速的白名单来源:
http://yunjiasu.baidu.com/website/node/#domain=jackxiang.com
jackxiang.com 分配到的节点
地点 线路 IP
济南 联通 119.188.132.68
济南 联通 119.188.132.67
石家庄 联通 61.182.137.6
西安 电信 117.34.28.77
西安 电信 117.34.28.78
苏州 电信 61.155.149.78
苏州 电信 61.155.149.79
南宁 电信 222.216.190.62
南宁 电信 222.216.190.63
百度云加速所有的节点IP
地点 线路 IP段
佛山 电信 183.60.235.0 ~ 183.60.235.254
石家庄 联通 61.182.137.0 ~ 61.182.137.254
南宁 电信 222.216.190.0 ~ 222.216.190.254
济南 联通 119.188.14.0 ~ 119.188.14.254
苏州 电信 61.155.149.0 ~ 61.155.149.254
济南 联通 119.188.132.0 ~ 119.188.132.254
西安 电信 117.34.28.0 ~ 117.34.28.254
郑州 联通 42.236.7.0 ~ 42.236.7.254
关于ssl免费版本不支持的问题回复 AddTime:2015-02-03:
我问题:
https://jackxiang.com 没法加速Https(不加速透传也成),不想加速,只加速:http://jackxiang.com 是没有问题,但我要管理用https,你们没有给我转过支。
回复如下:
您好,目前的免费版本是不支持https的,后续收费版才会支持。
————————————EOF———————————————