squid安装与反向代理的配置

目前两台服务器,IP地址分别为
192.168.1.120
192.168.2.50
其中192.168.2.50提供web服务,可直接通过192.168.2.50访问该站点,现在要在192.168.1.120上安装squid来做192.168.2.50的反向代理,当用户访问192.168.1.120时,120服务器将用户的请求转给50,50响应后将响应内容转给120,然后再由120返回给用户。
1. 安装squid
继续阅读

发表在 系统架构 | 标签为 , , | 11 条评论

访客动态 —— 站点必配小工具

对于经常写博客(当然,也包括个人网站)的朋友来说,非常关心博客的访问情况,为了清楚的知道自己网站的访问动态,会安装一些流量统计的代码,然后通过统计后台查看网站最新的访问情况,极端点的话,比如我吧,可能一、两个小时就会查看一次,看看又有谁访问了我的网站,他们都是通过什么方式找到我的博客的——通过搜索引擎呢?还是直接访问,还是从别的网站链接过来的。

所以每次都得首先打开统计代码网站,然后通过注册的账号和密码登录后台,最后点击后台最新访客动态,查看访客的情况,这样的操作虽然管用,但显得比较繁锁,挺麻烦的。
继续阅读

发表在 mylife | 标签为 | 4 条评论

http协议中,url最大长度是多少?

相信很我朋友都有这个疑问,或者当有人问起时,可能会临时的去网站搜索一下,答案就多了,我搜到的答案就有好几个,1024个字符啊、4096个字符啊,反正什么样的结果都有,那么究竟url的最大长度是多少呢?今天下午为了解决这个疑问,查了一些资料,并做了一些测试,基本上可能得出结论。

在http协议中,其实并没有对url长度作出限制,往往url的最大长度和用户浏览器和Web服务器有关,不一样的浏览器,能接受的最大长度往往是不一样的,当然,不一样的Web服务器能够处理的最大长度的URL的能力也是不一样的。
继续阅读

发表在 linux/server | 标签为 , | 12 条评论

mysql表快速制造测试数据

帖子表只有20多W的数据,快添加测试数据至400W
执行以下语句。

INSERT INTO posts(
	bar_id,thread_id,FIRST,author,authorid,
	subject,dateline,message,useip,haveattach
	) 
SELECT 
	bar_id,thread_id,FIRST,author,authorid,
	subject,dateline,message,useip,haveattach 
FROM posts;

继续阅读

发表在 mysql | 标签为 | 留下评论

Memcached安装

软件列表

memcached-1.4.4.tar.gz
libevent-1.4.13-stable .tar.gz

1. libevnet安装
继续阅读

发表在 linux/server | 标签为 , | 14 条评论

php中,怎么对大文件进行读取操作

在php中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。

需求

有一个800M的日志文件,大约有500多万行, 用php返回最后几行的内容。

实现方法

1. 直接采用file函数来操作

注:由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不 继续阅读

发表在 LAMP | 标签为 , | 一条评论

rsync: Failed to exec /home/hqlong/xxx/: Permission denied (13)的问题

上周发布新版本时,发布程序死活用不了,出现以下信息。

rsync: Failed to exec /home/hqlong/xxx/: Permission denied (13)
rsync error: error in IPC code (code 14) at pipe.c(84) [receiver=3.0.6]
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: error in IPC code (code 14) at io.c(600) [receiver=3.0.6]

继续阅读

发表在 linux/server | 标签为 | 5 条评论

apt-get安装apache,怎么开启模块

通过

sudo apt-get install apache2

安装apache时,除了开启了一些基本的模块外,很多模块都没有开启。
所有和apache相关的配置文件都会放在/etc/apache2这个目录下,其中mods-available这个目录存放了所有可用的模块,mods-enabled这个目录则放了所有已开启的模块。在这些目录中,一般情况下,每个模块都对应着两个文件,一个xx.conf文件,即该模块的配置文件,一个xx.load文件,即加载模块相关库的文件,有些模块可能只有一个xx.load文件。

当要开启一个模块时,只需要从mods-avalilable中将和该模块相关的两个文件拷贝到mods-enabled目录,然后重启apache即可。 继续阅读

发表在 linux/server | 一条评论

怎么将foxmail导入到Evolution

这两天将ubuntu彻底重装,装上了ubuntu9.10,但这次的代价也不少,由于以前随意调过分区,整个分区表乱了,导致在装ubuntu时,不能显示硬盘的分区表信息,然后去window里,一个很小的误操作,将整个盘给弄没有,最后整个硬盘进行了重新分区。先不说这个了,进入正题吧!
ubuntu9.10默认用的是Evolution这个客户端,先前我用的是thunderbird,硬盘分区了,邮件全掉了,还好台式机上还有个到9月份foxmail格式的备份,当然10月份的邮件就没了。
foxmail 的备份格式为.eml格式,而Evolution 能多识别的格式比较多,最常用的是通用mbox格式,所以只需要将.eml格式转成mbox格式。 继续阅读

发表在 linux/server | 标签为 , , | 留下评论

ubuntu9.10 flash 出现方块字的解决方法

环境 ubuntu9.10

sudo vim /etc/fonts/conf.d/49-sansserif.conf


< string >sans-serif< /string >
换成 继续阅读

发表在 linux/server | 标签为 , , | 7 条评论

安装jabberd时,出现Libidn >= 0.3.0 not found 问题

安装jabberd时,出现:

checking for stringprep_check_version in -lidn... yes
checking for Libidn version >= 0.3.0... no
configure: error: Libidn >= 0.3.0 not found

这样的问题呢?libidn这个库已经存在。

[~@serv_1 jabberd-2.2.9]# rpm -qa | grep libidn
libidn-0.6.5-1.1
libidn-devel-0.6.5-1.1

libidn这个库我确实也已经安装了,为什么还是会出现这样的问题呢?不明白?
查了资料说,要么没有libidn这个库,要么就是库的路径不对,但我的库都是装在系统默认的环境变量所指的目录里的。/usr/include /usr/lib。没有理由找不到啊!!
不解!!

机器人 2009-10-30 17:10 于 北京 阴

发表在 linux/server | 标签为 , | 3 条评论

开启iPhone写博功能

用手机写博客的好处是在任何有手机信号的地方都可以进行,大大降低了 写博客的限制。有时想写博客时,偏偏又没有上网条件。但当有上网条件的时候,翩翩又没什么好写的。现在这一切都不是问题。
wordpress只要安装一个叫WPhone的插件,就可以很方便的通过iPhone来使用wp。

机器人 2009年10月27日 11:04 发自 iPhone

发表在 mylife | 标签为 | 2 条评论

期待ubuntu9.10的正式发布

一直用的是去年装的ubuntu8.10,一算,用了一年多了,期待ubuntu9.10的正式发布,准备彻底重装新系统。

机器人 2009年10月10日 14:27 于 北京 阴

发表在 mylife | 标签为 | 5 条评论

Linux命令行下svn常用命令

1、Linux命令行下将文件checkout到本地目录

svn checkout path(path是服务器上的目录)

例如:svn checkout svn://192.168.1.1/pro/domain

简写:svn co
继续阅读

发表在 linux/server | 标签为 | 留下评论

GDB怎么调试运行着的程序

对于GDB这里就不作介绍了,随便找个搜索引擎一搜GDB,介绍就已经是很详细了,这篇文章主要是来谈怎么使用GDB来调试一个运行着的程序,或者说怎么调试一个进程,似乎标题有些拗口,其次也会对fork()分离出现的多子进程的调试加以说明。
下面是一段测试代码。
test.c

#include < stdio.h >
#include < unistd.h >
 
static void PrintMessage(int i);
static void GoToSleep(void);
 
 
int main(void)
{
	int i = 100000;
 
	while ( 1 )
	{
		PrintMessage( i );
		GoToSleep();
		i -= 1;
	}
 
	return 0;
}
 
 
 
void PrintMessage(int i)
{
		char buf[1024];
		sprintf(buf,"%d bottles of beer on the wall.\n", i);
		printf("%s",buf);
 
}
 
 
 
static void GoToSleep(void)
{
	sleep(3);
}

接下来是编译时使用的Makefile文件.

TARGET = test
SRC    =  $(TARGET).c
OBJ    =  $(TARGET).o
CC     =  gcc
CFLAGS = -g3 -W -Wall -std=c99
 
$(TARGET): $(OBJS)
 
 
.PHONY: clean
 
clean:
	$(RM) $(TARGET) $(OBJS)

此程序是一个服务程序,程序一旦启动,将作为一个进程永驻内存,可以通过

~@hqlong ps -ef | grep "test"

来查看该进程的信息。
此程序主要实现每3秒钟向墙上打印一瓶啤酒。对于这样的一个启动就作为一个进程进驻内存的程序应该怎么来进行调试呢?接下来的事情就是要来回来这个问题,
通过make来对源文件进行编译。

~@hqlong make

这里会在当前目录下产生一个test的可执行文件。
在对程序进行正式调试之前来回忆一个使用GDB调试一个非服务程序的步骤。假设test这个可执行文件是一个非服务程序,那么一般是通过如下几步方式来进行调试的。

hqlong@ubuntu:/tmp$ gdb test
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http ://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) b 1
Breakpoint 1 at 0x80483f4: file beer-process.c, line 1.
(gdb) r
Starting program: /tmp/test 
 
Breakpoint 1, main () at beer-process.c:9
warning: Source file is more recent than executable.
9	{
(gdb) n
main () at beer-process.c:10
10		int i = 100000;
(gdb) q
The program is running.  Exit anyway? (y or n) y
</http>

首先是通过gdb test来调试程序。然后使用b(break) 1在第一行设置断点,然后使用r(run) 来运行程序,最后使用n来单步运行程序,如果想要查看运行中某变量的值,可能通过p(print)来打印。如查看i的值,就可以通过p i。最后使用q(quit)来退出程序。

由于服务程序一旦启动,就以进程的方式进驻内存,不退出,所以和非服务程序的调试方式有一些区别。
服务一旦启动后,系统会分配一个pid,然后使用gdb绑定上这个pid,最后就可以通过通用方式进行调试了。
绑定进程的方式有下几种。

hqlong@ubuntu:/tmp$ ./test &
100000 bottles of beer on the wall.
[1] 25292

方式一
通过–pid参数来绑定指定的进程程序。

~@hqlong gdb --pid 25552

方式二
通过程序和进程号来绑定。

~@hqlong gdb test 25552

方式二
先启动gdb后,通过attach来绑定pid

~@hqlong gdb
gdb) attach 25552

将pid和gdb绑定后,就可以来对每一段代码进行调试。
下面是对上面例子的完整调试过程。
1. 启动进程

hqlong@ubuntu:/tmp$ ./test &
[1] 25615
hqlong@ubuntu:/tmp$ 100000 bottles of beer on the wall.
99999 bottles of beer on the wall.
99998 bottles of beer on the wall.

可以看见,启动test后,系统所分配的pid(进程号)为25615,然后每隔3秒钟就打印出一条信息。
2.使用gdb来绑定test进程。
这里需要重新启动一个新的shell来进行调试,也就是新开一个窗口,然后使用

hqlong@ubuntu:/tmp$ gdb --pid 25615
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http ://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
Attaching to process 25615
Reading symbols from /tmp/test...done.
Reading symbols from /lib/tls/i686/cmov/libc.so.6...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
0xb7ffb430 in __kernel_vsyscall ()
(gdb) 
</http>

来将gdb与已启动的test进行绑定,从而进入调试状态,这里会发现,当进入gdb调试状态后,先前启动程序的窗口就不再每隔3秒钟打印信息了,而是将控制权将给了gdb.
3.使用bt来显示当前程序的函数调用栈结构(也就是函数的调用顺序)。

(gdb) bt
#0  0xb7ffb430 in __kernel_vsyscall ()
#1  0xb7f23780 in nanosleep () from /lib/tls/i686/cmov/libc.so.6
#2  0xb7f235be in sleep () from /lib/tls/i686/cmov/libc.so.6
#3  0x0804851e in GoToSleep () at beer-process.c:35
#4  0x080484ac in main () at beer-process.c:15
(gdb)

可知函数的调用过程为:main调用GoToSleep,GoToSleep调用sleep等。
使用frame来选择程序的调试起点,也可以使用break来选择指定的行或者函数来作为断点。

(gdb) frame 4
#4  0x080484ac in main () at beer-process.c:15
15			GoToSleep();
(gdb)

这里我们选择最底层的栈,也就是整个程序的入口main函数来作为起点。
4. 调试跟踪过程
使用n(next)来一步一步的跟踪。

(gdb) n
Single stepping until exit from function sleep, 
which has no line number information.
GoToSleep () at beer-process.c:36
36	}
(gdb) 
main () at beer-process.c:16
16			i -= 1;
(gdb) 
14			PrintMessage( i );
(gdb)

这里有个技巧,如果要重复执行上一次执行的操作,可以直接回车。
通过上面的调试,发现程序运行到了14行,也就是PrintMessage函数处,如果这个时候我们继续n(next),程序就直接跳过函数,运行到函数的下一行,但如果想进入函数内部去调试,可以使用s(step),来进入函数体内进行调试。
进入函数体

(gdb) 
14			PrintMessage( i );
(gdb) s
PrintMessage (i=99897) at beer-process.c:25
25	{
(gdb) n
27	    sprintf(buf,"%d bottles of beer on the wall.\n", i);
(gdb) n
28		printf("%s",buf);
(gdb)

以上是进入PrintMessage体内,然后继续使用n(next)来一步一步的运行。进行到了28行,发现有两个变量,一个为i,另一个为buf,可以通过p(print)来打印该变量的值。

(gdb) p i
$1 = 99897
(gdb) p buf
$2 = "99897 bottles of beer on the wall.\n\000\000R\000�0u������$u���\227\001�\000\000\000\000p���\000\000\000\000\000\000\000\000\001\000\000\000��DB�x��8���\000\000\000\000�\217\001�p\226\001�0u��$u���\226\000�\001\000\000\000\000\000\000\000�v���\222\001�\205���", '\0' <repeats 12 times>, "�\226\000��\217\001�\000\000\000\000\000u���t���\020\001�\b\000\000\000\f\000\000\000\000����v��b\221\000�\000���\020���\f\000\000\000�\217"...
(gdb) 
</repeats>

发现通过p i 来打印i的值,结果是正确的,但通过p buf来打印buf 的值,却显示了很多不可读的乱码。这里因为buf代表这个变量在内存中的首地址,所以p不知道变量在什么时候结束,而i则不同,因为i是整型,在内存中一般占4个字节,所以p直接从首地址向后数4位就行了。所以这里打印字符指针或者数组时,需要指定一个长度。语法为 p *buf@len. 这里的len可以通过strlen(buf)来取得。

(gdb) p *buf@strlen(buf)
$3 = "99897 bottles of beer on the wall.\n"
(gdb)

这一下子就对了。
接下来继续使用n(next)来单步运行。

(gdb) 
28		printf("%s",buf);

发现运行到这一步时,启动程序的那个窗口打印出了一条信息。

99897 bottles of beer on the wall.

这说明,程序正好运行到了打印字符的地方。
如果这个时候想退出函数,直接返回,可能通过 finish.

(gdb) finish 
Run till exit from #0  PrintMessage (i=99895) at beer-process.c:28
main () at beer-process.c:15
15			GoToSleep();
(gdb)
退出PrintMessage函数,接着运行下一行代码GoToSleep.
如果调试完毕,或能通过q(quit)来退出GDB。
(gdb) q
The program is running.  Quit anyway (and detach it)? (y or n) y
Detaching from program: /tmp/test, process 25615

以上是调试一个进程的过程。

下面附带说明一下怎么调试一个需要通过fork()分离进程的程序。下面是一段一个Web服务器的在接受请求时的代码片断。

for (;;) {
	if ((connfd = accept(listenfd, (struct sockaddr *) &clientaddr,
					&clientaddrlen)) == -1) {
		perror("http server: accept error");
		continue;
	}
	if (fork() == 0)
		accept_request(connfd);
	else close(connfd);
 
	int statloc;
	waitpid(-1, &statloc, WNOHANG);
}

当单步运行到if(fork() == 0)这一步时,那怕是分离进程成功,也不会运行accept_request(connfd);而是直接跳到跳过,运行下面的代码。在调试这样的程序里,需要在进入gdb控制台时,需要将follow-fork-mode的值设成child.

(gdb) set follow-fork-mode child

本文主要是体验一下使用GDB的调试过程,对一些指令和俗语没有作过多的解释,如果有不明白可直接留言,或者参考相关资料。
参数资料
http://www.gnu.org/software/gdb/
http://dirac.org/linux/gdb/06-Debugging_A_Running_Process.php

结束!

机器人 2009-09-10 19:00 于 北京 晴

发表在 c/c++, linux/server | 标签为 | 15 条评论