显示标签为“apache”的博文。显示所有博文
显示标签为“apache”的博文。显示所有博文

2013年7月22日星期一

Apache SSL安装与配置教程(Linux系统)--转自http://www.bootf.com/563.html

互联网的线路侦听无处不在,明文传输的数据一不留神就可能被窃取。而Apache的SSL加密连接可以帮助浏览者更加安全可靠的传输数据。通常来说,普通的HTTP协议URL是以 http:// 开头,而SSL加密协议则是以 https:// 开头。本文将介绍CentOS系统下通过仓库(yum、apt-get)配置apache中SSL加密模块的方法。
实验环境:
CentOS release 5.7 (Final)
Apache/2.2.3

首先安装Apache

[root@www ~]# yum install httpd
部署好Apache环境后,开始安装SSL模块

[root@www ~]# yum install mod_ssl
安装完成,直接重启Apache服务:

[root@www ~]# /etc/init.d/httpd restart
由于安装mod_ssl会创建一个默认的SSL证书,路径位于 /etc/pki/tls ,此时可以立即通过https访问服务器了:
https://IP/
如果不使用默认的证书,也可以使用OPENSSL手动创建证书。

使用OPENSSL手动创建证书
先执行以下命令安装OPENSSL:
1
[root@www ~]# yum install openssl
完成后即可按照以下步骤生成证书文件:
1、创建私钥
1
[root@www ~]# openssl genrsa -out server.key 1024
2、用私钥 server.key 文件生成证书签署请求 CSR
1
[root@www ~]# openssl req -new -key server.key -out server.csr
此步骤需要输入一些证书信息,解释如下:
Country Name (2 letter code) [GB]:【在此输入两个字符的国家名。中国的为 CN 】
State or Province Name (full name) [Berkshire]:【省份名称,如北京为 beijing 】
Locality Name (eg, city) [Newbury]:【城市名称,如 beijing】
Organization Name (eg, company) [My Company Ltd]:【公司名称】
Organizational Unit Name (eg, section) []:【部门名称】
Common Name (eg, your name or your server’s hostname) []:【姓名,通常即证书名】
Email Address []:【电子邮箱地址】
随后会要求输入一个challenge password(密码),无需输入,后面一律直接回车即可。
3、生成证书CRT文件
1
[root@www ~]# openssl x509 -days 3650 -req -in server.csr -signkey server.key -out server.crt
上面生成的证书有效期为10年(呵呵太长了点,一般三年就行了)
这时证书的相关文件就都已经生成好了。当前文件夹下应该有server.crt、server.csr、server.key这三个文件。
如果你是个完美论者,理所当然应该把这三个文件丢到证书的“官方目录”中去,省的把文件胡乱放置以后找不着:
1
[root@www ~]# mkdir /etc/pki/tls/mycert
2
[root@www ~]# mv server.* /etc/pki/tls/mycert
最后仅仅需要修改配置文件来指定证书路径:
4、指定证书路径
打开Apache的SSL配置文件 /etc/httpd/conf.d/ssl.conf :
1
[root@www ~]# vi /etc/httpd/conf.d/ssl.conf
找到如下一节:
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/mycert/server.crt
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you’ve both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/mycert/server.key
注意红色的文字修改的部分。保证其路径分别指向刚刚创建的server.crt与server.key即可。
5、重启Apache2
1
[root@www ~]# /etc/init.d/httpd restart
这时新的证书便已经生效了。刷新浏览器,点击浏览器中的证书标志,便可以看到刚刚制作的证书信息:

2013年6月5日星期三

查看apache的版本号

高手谁能告诉我,如何查看apache的版本号?谢谢!

# apachectl -v

2013年4月2日星期二

linux下apache+php安全设置:apache虚拟主机间隔离


1、实现虚拟主机笼环境

a.upl.com /wwwroot/a.upl.com/
b.upl.com /wwwroot/b.upl.com/

<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot “/wwwroot/a.upl.com/”
ServerName a.upl.com
ErrorLog “logs/a.upl.com-error_log”
CustomLog “logs/a.upl.com.com-access_log” common

<IfModule mod_php5.c>
php_admin_value open_basedir “/wwwroot/a.upl.com/:/tmp:/var/lib/php/session”
</IfModule>
(本节配置中间一行是重点!)

<IfModule suexec.c>
SuexecUserGroup daemon daemon
</IfModule>
(以上三行似乎没有用?)

</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot “/www”
ServerName b.upl.com
ErrorLog “logs/b.upl.com-error_log”
CustomLog “logs/b.upl.com-access_log” common

<Directory “/wwwroot/b.upl.com/”>
Order deny,allow
allow from all
</Directory>

<IfModule mod_php5.c>
php_admin_value open_basedir “/wwwroot/b.upl.com/:/tmp:/var/lib/php/session”
</IfModule>

<IfModule suexec.c>
SuexecUserGroup daemon daemon
</IfModule>
</VirtualHost>

实例测试:

www.abc.com与www.def.com两个站点,站点根目录分别是/var/www/html/vhost/www.abc.com/html、/var/www/html/vhost/www.def.com/html

在www.abc.com站点下建一个php文件,读取www.def.com的一个文件输出到浏览器(严格的说php是把它输出到web服务器的output buffer)



<?php
readfile('../../www.def.com/html/index.html');
?>

执行时报错,错误消息大致如下:

Warning: readfile(): open_basedir restriction in effect. File(../../www.def.com/html/index.html) is not within the allowed path(s): (/var/www/html/vhosts/www.def.com/html/:/tmp) in /var/www/html/vhosts/abc/html/test.php on line 2

Warning: readfile(../../www.def.com/html/index.html): failed to open stream: Operation not permitted in /var/www/html/vhosts/www.abc.com/html/test.php on line 2
2、实现禁止php后门执行系统指令

# vim /usr/local/lib/php.ini

disable_functions = phpinfo,gzcompress,apache_note,apache_setenv,proc_get_status,exec,passthru,proc_nice,proc_open,proc_terminate,shell_exec,system,popen,ini_restore,syslog,define_syslog_variables,symlink,link,error_log,leak,dbmopen,openlog,closelog,popen,pclose,stream_socket_server

关健是passthru函数,是它使后门可以执行系统指令
3、隐藏掉php信息
expose_php = On

4、关闭错误提示(如果经常在线调试就算了)
display_errors = Off

5、使用php过滤单引号等特殊字符(此设置不推荐,容易造成问题;仅供参考)
; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
magic_quotes_runtime = On

; Use Sybase-style magic quotes (escape ‘ with ” instead of \’).
magic_quotes_sybase = On
如果打开了,有些php应用工作不正常,所以不推荐

6、让php工作在安全模式(一般不用,设定很严格;亦不推荐)
safe_mode = On

from http://www.tanpao.com/archives/17 (有小幅改动及标注)

2013年3月14日星期四

CentOS 6.2编译安装Apache2.4.1+MySQL5.5.21+PHP5.4


 操作系统:CentOS 6.2 32位
  准备篇:一、配置好IP、DNS 、网关,确保使用远程连接工具能够连接服务器二、配置防火墙,开启80端口、22、21端口

  三、关闭SELINUX

  vi /etc/selinux/config

  #SELINUX=enforcing #注释掉

  #SELINUXTYPE=targeted #注释掉

  SELINUX=disabled #增加

  :wq 保存,关闭

  shutdown -r now #重启系统

  四 、系统约定

  软件源代码包存放位置:/usr/local/src

  源码包编译安装位置:/usr/local/软件名字

  五、下载软件包

  1、下载apache

  http://www.apache.org/dist/httpd/httpd-2.4.1.tar.gz

  2、下载MySQL

  http://mysql.mirror.kangaroot.net/Downloads/MySQL-5.5/mysql-5.5.21.tar.gz

  3、下载php 5.4

  4、下载cmake(MySQL编译工具)

  http://www.cmake.org/files/v2.8/cmake-2.8.7.tar.gz

  5、下载libmcrypt(PHPlibmcrypt模块)

  ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt/libmcrypt-2.5.7.tar.gz

  6、下载apr(Apache库文件)

  http://mirror.bit.edu.cn/apache/apr/apr-1.4.6.tar.gz

  7、下载apr-util(Apache库文件)

  http://mirror.bit.edu.cn/apache/apr/apr-util-1.4.1.tar.gz

  用WinSCP远程连接到服务器,把下载好的软件上传到服务器/usr/local/src下面

  六、安装编译工具及库文件(使用CentOS yum命令安装)yum install make apr* autoconf automake gcc gcc-c++ zlib-devel openssl openssl-devel pcre-devel gd kernel keyutils patch perl kernel-headers compat* mpfr cpp glibc libgomp libstdc++-devel ppl cloog-ppl keyutils-libs-devel libcom_err-devel libsepol-devel libselinux-devel krb5-devel zlib-devel libXpm* freetype libjpeg* libpng* php-common php-gd ncurses* libtool* libxml2 libxml2-devel patch

  安装篇

  以下是用putty工具远程登录到服务器,在命令行下面操作的

  1、安装libmcrypt

  cd /usr/local/src

  tar zxvf libmcrypt-2.5.7.tar.gz #解压

  cd libmcrypt-2.5.7 #进入目录

  ./configure #配置

  make #编译

  make install #安装

  2、安装cmake

  cd /usr/local/src

  tar zxvf cmake-2.8.7.tar.gz

  cd cmake-2.8.7

  ./configure

  make #编译

  make install #安装

  3、安装apr

  cd /usr/local/src

  tar zxvf apr-1.4.6.tar.gz

  cd apr-1.4.6

  ./configure --prefix=/usr/local/apr

  make

  make install

  4、安装apr-util

  tar zxvf apr-util-1.4.1.tar.gz

  cd apr-util-1.4.1

  ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/bin/apr-1-config

  make

  make install

  5、安装mysql

  groupadd mysql #添加mysql组

  useradd -g mysql mysql -s /bin/false #创建用户mysql并加入到mysql组,不允许mysql用户直接登录系统

  mkdir -p /data/mysql #创建MySQL数据库存放目录

  chown -R mysql:mysql /data/mysql #设置MySQL数据库目录权限

  mkdir -p /usr/local/mysql #创建MySQL安装目录

  cd /usr/local/src

  tar zxvf mysql-5.5.21.tar.gz #解压

  cd mysql-5.5.21

  回到cmake目录,删除cmakecache.txt文件

  rm -f CMakeCache.txt

  cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql -DSYSCONFDIR=/etc #配置

  make #编译

  make install #安装

  cd /usr/local/mysql

  cp ./support-files/my-huge.cnf /etc/my.cnf #拷贝配置文件(注意:/etc目录下面默认有一个my.cnf,直接覆盖即可)

  vi /etc/my.cnf #编辑配置文件,在 [mysqld] 部分增加

  datadir = /data/mysql #添加MySQL数据库路径

  ./scripts/mysql_install_db --user=mysql #生成mysql系统数据库

  cp ./support-files/mysql.server /etc/rc.d/init.d/mysqld #把Mysql加入系统启动

  chmod 755 /etc/init.d/mysqld #增加执行权限

  chkconfig mysqld on #加入开机启动

  vi /etc/rc.d/init.d/mysqld #编辑

  basedir = /usr/local/mysql #MySQL程序安装路径

  datadir = /data/mysql #MySQl数据库存放目录

  service mysqld start #启动

  vi /etc/profile #把mysql服务加入系统环境变量:在最后添加下面这一行

  export PATH=$PATH:/usr/local/mysql/bin

  下面这两行把myslq的库文件链接到系统默认的位置,这样你在编译类似PHP等软件时可以不用指定mysql的库文件地址。

  ln -s /usr/local/mysql/lib/mysql /usr/lib/mysql

  ln -s /usr/local/mysql/include/mysql /usr/include/mysql

  shutdown -r now #需要重启系统,等待系统重新启动之后继续在终端命令行下面操作

  mysql_secure_installation #设置Mysql密码

  根据提示按Y 回车输入2次密码

  或者直接修改密码/usr/local/mysql/bin/mysqladmin -u root -p password "123456" #修改密码

  service mysqld restart #重启

  到此,mysql安装完成!

  6、安装apache2cd /usr/local/src

  tar -zvxf httpd-2.4.1.tar.gz

  cd httpd-2.4.1

  mkdir -p /usr/local/apache2 #创建安装目录

  ./configure --prefix=/usr/local/apache2 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-ssl --enable-ssl --enable-module=so --enable-rewrite --enable-cgid --enable-cgi #配置

  make #编译

  make install #安装

  /usr/local/apache2/bin/apachectl -k start #启动

  vi /usr/local/apache2/conf/httpd.conf #编辑配置文件

  找到:#ServerName www.example.com:80

  修改为:ServerName www.osyunwei.com:80

  找到:DirectoryIndex index.html

  修改为:DirectoryIndex index.html index.php

  找到:Options Indexes FollowSymLinks

  修改为:Options FollowSymLinks #不显示目录结构

  找到AllowOverride None

  修改为:AllowOverride All #开启apache支持伪静态,有两处都做修改

  LoadModule rewrite_module modules/mod_rewrite.so #取消前面的注释,开启apache支持伪静态

  vi /etc/profile #添加apache服务系统环境变量

  在最后添加下面这一行

  export PATH=$PATH:/usr/local/apache2/bin

  cp /usr/local/apache2/bin/apachectl /etc/rc.d/init.d/httpd #把apache加入到系统启动

  vi /etc/init.d/httpd #编辑文件

  在#!/bin/sh下面添加以下两行

  #chkconfig:2345 10 90

  #descrption:Activates/Deactivates Apache Web Server

  chown daemon.daemon -R /usr/local/apache2/htdocs #更改目录所有者

  chmod 700 /usr/local/apache2/htdocs -R #更改apache网站目录权限

  chkconfig httpd on #设置开机启动

  /etc/init.d/httpd start

  service httpd restart

  7、安装php

  cd /usr/local/src

  tar -zvxf php-5.3.10.tar.gz

  cd php-5.3.10

  mkdir -p /usr/local/php5 #建立php安装目录

  ./configure --prefix=/usr/local/php5 --with-config-file-path=/usr/local/php5/etc --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-mysql-sock=/tmp/mysql.sock --with-gd --with-iconv --with-freetype --with-jpeg --with-png --with-zlib --with-libxml --enable-xml --enable-discard-path --enable-magic-quotes --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-force-cgi-redirect --enable-mbstring --enable-ftp --enable-gd-native-ttf --with-openssl --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --without-pear --with-gettext --with-mime-magic --enable-suhosin --enable-session --with-mcrypt --with-jpeg    #配置

  make #编译

  make install #安装

  mkdir /usr/local/php5/etc

  cp php.ini-production /usr/local/php5/etc/php.ini #复制php配置文件到安装目录

  rm -rf /etc/php.ini #删除系统自带的配置文件

  ln -s /usr/local/php5/etc/php.ini /etc/php.ini #创建配置文件软链接

  vi /usr/local/php5/etc/php.ini #编辑

  找到:;open_basedir =

  修改为:open_basedir = .:/tmp/ #防止php木马跨站,重要!!

  找到:disable_functions =

  修改为:disable_functions = passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,
ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,escapeshellcmd,dll,popen,
disk_free_space,checkdnsrr,checkdnsrr,getservbyname,getservbyport,disk_total_space,posix_ctermid,
posix_get_last_error,posix_getcwd, posix_getegid,posix_geteuid,posix_getgid,
posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid, posix_getppid,posix_getpwnam,posix_getpwuid, posix_getrlimit, posix_getsid,posix_getuid,posix_isatty, posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid, posix_setpgid,posix_setsid,posix_setuid,posix_strerror,posix_times,posix_ttyname,posix_uname

  #列出PHP可以禁用的函数,如果某些程序需要用到这个函数,可以删除,取消禁用。

  找到:;date.timezone =

  修改为:date.timezone = PRC

  找到:expose_php = On

  修改为:expose_php = OFF #禁止显示php版本的信息

  找到:display_errors = On

  修改为:display_errors = OFF #关闭错误提示

  8、配置apache支持phpvi /usr/local/apache2/conf/httpd.conf #编辑apache配置文件

  在LoadModule php5_module modules/libphp5.so这一行下面添加、

  AddType application/x-httpd-php .php (注意:php .php这个点前面有一个空格)

  service httpd restart #重启apache

  service mysqld restart #重启mysql

  测试篇cd /usr/local/apache2/htdocsvi index.php #输入下面内容

  
  phpinfo();

  ?>

  :wq! #保存

  在客户端浏览器输入服务器IP地址,可以看到相关的配置信息!

  网站程序上传到/usr/local/apache2/htdocs目录里面,如果安装有问题,请检查目录权限

  确保改目录为以下权限

  chown daemon.daemon -R /usr/local/apache2/htdocs

  chmod -R 700 /usr/local/apache2/htdocs

  至此,CentOS 6.2编译安装Apache2.4.1+MySQL5.5.21+PHP5.4配置完成。

CentOS 6.2 Minimal 编译安装LAMP实录



花了两天的时间来实践编译安装LAMP最新版,过程十分顺利……

安装好Centos 6.2 Minimal后,第一件事导入Fedora EPEL repo安装源、安装yum优先级控制软件并升级内核:


rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-7.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
yum -y install yum-priorities
yum update
---------------------------------------------------------------------------

編譯前準備工作

卸载yum或rpm安装的amp软件(CentOS Minimal不需要)

rpm -e httpd
rpm -e mysql
rpm -e php
yum -y remove httpd
yum -y remove php
yum -y remove mysql-server mysql
yum -y remove php-mysql
安裝編譯工具

安装编译工具gcc gcc-c++make automake autoconf kernel-devel
安装PHP所需依赖,如libxml2-devel openssl-devel curl-devel libjpeg-devel libpng-devel等

yum -y install gcc gcc-c++ make automake autoconf kernel-devel ncurses-devel libxml2-devel openssl-devel curl-devel libjpeg-devel libpng-devel pcre-devel libtool-libs freetype-devel gd zlib-devel file bison patch mlocate flex diffutils readline-devel glibc-devel glib2-devel bzip2-devel gettext-devel libcap-devel libmcrypt-devel
安裝下載工具

yum -y install wget
下载所需的源码
下载apache(http://httpd.apache.org)

wget http://labs.renren.com/apache-mirror//httpd/httpd-2.4.2.tar.gz

下载MySQL(http://mysql.mirror.kangaroot.net/Downloads/MySQL-5.5/)

wget http://mysql.mirror.kangaroot.net/Downloads/MySQL-5.5/mysql-5.5.25.tar.gz

下载php(http://www.php.net)

wget http://cn.php.net/get/php-5.4.4.tar.gz/from/this/mirror

下载cmake(MySQL编译工具)

wget http://www.cmake.org/files/v2.8/cmake-2.8.8.tar.gz

下载libmcrypt(PHPlibmcrypt模块)

wget ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt/libmcrypt-2.5.7.tar.gz

下载apr(Apache库文件)

wget http://mirror.bit.edu.cn/apache//apr/apr-1.4.6.tar.gz

下载apr-util(Apache库文件)

wget http://labs.mop.com/apache-mirror//apr/apr-util-1.4.1.tar.gz

下載APR iconv(Apache库文件)

wget http://labs.mop.com/apache-mirror//apr/apr-iconv-1.2.1.tar.gz
開始編譯安裝

安装libmcrypt

cd /usr/local/src
tar zxf libmcrypt-2.5.7.tar.gz
cd libmcrypt-2.5.7
./configure && make && make install
安装cmake

cd /usr/local/src
tar zxf cmake-2.8.8.tar.gz
cd cmake-2.8.8
./configure && make && make install
安装Apr

cd /usr/local/src
tar zxf apr-1.4.6.tar.gz
cd apr-1.4.6
./configure --prefix=/usr/local/apr && make && make install
安装Apr-util

cd /usr/local/src
tar zxf apr-util-1.4.1.tar.gz
cd apr-util-1.4.1
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/bin/apr-1-config && make && make install
安装Apr-iconv

cd /usr/local/src
tar zxf apr-iconv-1.2.1.tar.gz
cd apr-iconv-1.2.1
./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr/bin/apr-1-config && make && make install
安装Mysql

(準備工作)
#添加mysql组并创建用户mysql并加入到mysql组,不允许mysql用户直接登录系统
groupadd mysql && useradd -g mysql mysql -s /bin/false
#创建MySQL数据库存放目录并设置MySQL数据库目录权限
mkdir -p /var/data/mysql && chown -R mysql:mysql /var/data/mysql
#创建MySQL安装目录
mkdir -p /usr/local/mysql
#進入源碼目錄解壓mysql源代碼并進入源碼目錄
cd /usr/local/src && tar zxvf mysql-5.5.25.tar.gz && cd mysql-5.5.25
#配置、編譯和安裝
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/var/data/mysql -DSYSCONFDIR=/etc && make && make install

(配置工作)

cd /usr/local/mysql
cp ./support-files/my-huge.cnf /etc/my.cnf #拷贝配置文件(注意:/etc目录下面默认有一个my.cnf,直接覆盖即可)
vi /etc/my.cnf #编辑配置文件,在 [mysqld] 部分增加

datadir = /var/data/mysql #添加MySQL数据库路径
./scripts/mysql_install_db --user=mysql #生成mysql系统数据库
cp ./support-files/mysql.server /etc/rc.d/init.d/mysqld #把Mysql加入系统服務
chmod 755 /etc/init.d/mysqld #增加执行权限
(開啟自啟動)

chkconfig mysqld on #加入开机启动
vi /etc/rc.d/init.d/mysqld #编辑Mysql服务参数

basedir = /usr/local/mysql #MySQL程序安装路径
datadir = /var/data/mysql #MySQl数据库存放目录

service mysqld start #启动Mysql服务
vi /etc/profile #把mysql服务加入系统环境变量:在最后添加下面这一行

export PATH=$PATH:/usr/local/mysql/bin

#下面这两行把myslq的库文件链接到系统默认的位置,这样你在编译类似PHP等软件时可以不用指定mysql的库文件地址
ln -s /usr/local/mysql/lib/mysql /usr/lib/mysql && ln -s /usr/local/mysql/include/mysql /usr/include/mysql

shutdown -r now #需要重启系统,等待系统重新启动之后继续在终端命令行下面操作

mysql_secure_installation #设置Mysql密码

根据提示按Y,回车输入2次密码
或者直接修改密码

/usr/local/mysql/bin/mysqladmin -u root -p password "123456" #修改密码

service mysqld restart #重启
安装Apache2


cd /usr/local/src && tar -zvxf httpd-2.4.2.tar.gz
cd httpd-2.4.2
mkdir -p /usr/local/apache2 #创建安装目录
./configure --prefix=/usr/local/apache2 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-apr-iconv=/usr/local/apr-iconv --with-ssl --enable-ssl --enable-so --enable-deflate=shared --enable-expires=shared --enable-headers=shared --enable-rewrite=shared --enable-static-support #配置、編譯和安装

编译参数解释:
--prefix=/usr/local/apache:指定安装目录
--with-apr=/usr/local/apr #指定apr目錄
--with-apr-util=/usr/local/apr-util #指定apr-util目錄
--with-apr-iconv=/usr/local/apr-iconv #指定apr-iconv目錄
--enable-so:允许运行时加载DSO模块
--enable-deflate=shared:将deflate模块编译为DSO
--enable-expires=shared:将expires模块编译为DSO
--enable-headers=shared:将headers模块编译为DSO
--enable-rewrite=shared:将rewrite模块编译为DSO
--enable-static-support:使用静态连接(默认为动态连接)编译所有二进制支持程序
更详细的编译参数解释:http://lamp.linux.gov.cn/Apache/ApacheMenu/programs/configure.html
1
/usr/local/apache2/bin/apachectl -k start #启动
(配置工作)
vi /usr/local/apache2/conf/httpd.conf #编辑配置文件
找到:#ServerName www.example.com:80
修改为:ServerName www.localhost.com.cn:80
找到:DirectoryIndex index.html
修改为:DirectoryIndex index.html index.php
找到:Options Indexes FollowSymLinks
修改为:Options FollowSymLinks #不显示目录结构
找到:AllowOverride None
修改为:AllowOverride All #开启apache支持伪静态,有两处都做修改
LoadModule rewrite_module modules/mod_rewrite.so #取消前面的注释,开启apache支持伪静态


vi /etc/profile #添加apache服务系统环境变量
#在最后添加下面这一行

export PATH=$PATH:/usr/local/apache2/bin

cp /usr/local/apache2/bin/apachectl /etc/rc.d/init.d/httpd #把apache加入到系统服務
vi /etc/init.d/httpd

在#!/bin/sh下面添加以下两行
#chkconfig:2345 10 90
#descrption:Activates/Deactivates Apache Web Server

chown daemon.daemon -R /var/www #更改目录所有者
chmod 700 /var/www -R #更改apache网站目录权限
chkconfig httpd on #设置开机启动
service httpd restart
安装php

cd /usr/local/src
tar -zvxf php-5.4.4.tar.gz
cd php-5.4.4
mkdir -p /usr/local/php5 #建立php安装目录
./configure --prefix=/usr/local/php5 --with-config-file-path=/usr/local/php5/etc --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-mysql-sock=/tmp/mysql.sock --with-gd --with-iconv --with-freetype --with-jpeg --with-png --with-zlib--with-libxml --enable-xml --enable-discard-path --enable-magic-quotes --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-force-cgi-redirect --enable-mbstring --enable-ftp --enable-gd-native-ttf --with-openssl --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --without-pear --with-gettext --with-mime-magic --enable-suhosin --enable-session --with-mcrypt && make && make install #配置、编译和安装
mkdir /usr/local/php5/etc
cp php.ini-production /usr/local/php5/etc/php.ini #复制php配置文件到安装目录
rm -rf /etc/php.ini #删除系统自带的配置文件
ln -s /usr/local/php5/etc/php.ini /etc/php.ini #创建配置文件软链接
(配置工作)

vi /usr/local/php5/etc/php.ini #编辑

disable_functions = passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popep,assthru,stream_socket_server,escapeshellcmd,dll,popen,disk_free_space,checkdnsrr,checkdnsrr,getservbyname,getservbyport,disk_total_space,posix_ctermid,posix_get_last_error,posix_getcwd, posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid, posix_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit, posix_getsid,posix_getuid,posix_isatty, posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_strerror,posix_times,posix_ttyname,posix_uname #列出PHP可以禁用的函数,如果某些程序需要用到这个函数,可以删除,取消禁用。
date.timezone = PRC
expose_php = OFF #禁止显示php版本的信息
display_errors = OFF #关闭错误提示
配置apache支持php

vi /usr/local/apache2/conf/httpd.conf #编辑apache配置文件
在LoadModule php5_module modules/libphp5.so这一行下面添加:
AddType application/x-httpd-php .php (注意:php .php这个点前面有一个空格)
1
service httpd restart && service mysqld restart #重启apache和mysql
----------------------------------------------------------------------------------------

配置防火牆,允許防火牆通過21(FTP)、80(WEB)、3306(MYSQL)端口

vi /etc/sysconfig/iptables

#########################################################
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
 -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
#########################################################

service iptables restart //最后重启防火墙使配置生效

2013年3月9日星期六

Linux下Apache中PHP无法解析终结办法


在httpd.conf 里加入如下几句
AddType application/x-httpd-php .php
LoadModule php5_module modules/libphp5.so
<IfModule mod_php5.c>
        AddType application/x-httpd-php .php
        AddType application/x-httpd-php-source .phps
    </IfModule>

怎么说呢,我反正都加了,完美启动,如果少了最后的ifmodule,可能php启动不起来,不知道神码情况,留个笔记,以后研究

2013年2月17日星期日

我的apache php mysql libmemcached memcached 安装实践


参考http://www.hao32.com/webserver/313.html
/sbin/ldconfig 这个命令在安装了新的动态链接库后运行一下,避免依赖此链接库的程序找不到它。
安装apache
wget "http://apache.freelamp.com/httpd/httpd-2.2.15.tar.gz"
tar -xzf httpd-2.2.15.tar.gz
cd httpd-2.2.15
./configure --prefix=/home/zhaigy/apache_n --enable-so
make
make install
安装php
wget "http://cn.php.net/distributions/php-5.3.2.tar.gz"
tar -xzf php-5.3.2.tar.gz
cd php-5.3.2
./configure --prefix=/home/zhaigy/php_n --with-apxs2=/home/webadm/bin/apxs
make
make install
修改httpd.conf
user zhaigy
group zhaigy
LoadModule php4_module modules/libphp4.so (这一项在装完php后会自动添加)
AddType application/x-httpd-php .php (这一项手工添加)
chown -R zhaigy.zhaigy /home/zhaigy/apache_n
启动apache
cd /home/zhaigy/apache_n
./bin/apachectl start
测试
netstat -npl
浏览器打开首页测试
查看phpinfo信息 (可获知:Configuration File (php.ini) Path /home/zhaigy/php_n/lib )
给php添加mysql扩展
cd /home/zhaigy/php-5.3.2/ext/mysql
/home/zhaigy/php_n/bin/phpize
./configure --help
./configure --with-php-config=/home/zhaigy/php_n/bin/php-config --with-mysql="/home/zhaigy/mysql-5.1.22-rc-linux-x86_64-glibc23"
或者./configure --with-php-config=/home/zhaigy/php_n/bin/php-config --with-mysql="mysqlnd"
make
make install 显示 Installing shared extensions:     /home/zhaigy/php_n/lib/php/extensions/no-debug-non-zts-20090626/
cd /home/zhaigy/php_n/
mkdir modules
cp /home/zhaigy/php_n/lib/php/extensions/no-debug-non-zts-20090626/mysql.so ./modules
编写php.ini 参考 http://lamp.linux.gov.cn/PHP/php-5_2-ini.html
修改extension_dir = "/home/zhaigy/php_n/modules"
extension = mysql.so
chown -R zhaigy.zhaigy /home/zhaigy/php_n
重启apache
cd /home/zhaigy/apache_n
./bin/apachectl restart
netstat -npl|grep httpd
php安装源码中不包含的其它扩展,例如 memcached
################################
这个可以不安装
安装 memcached
wget "http://memcached.googlecode.com/files/memcached-1.4.5.tar.gz"
tar -xzvf memcached-1.4.5.tar.gz
cd memcached-1.4.5
./configure --prefix=/home/zhaigy/memcached_n --enable-64bit
make
make install
################################
需要先安装libmemcached
cd /home/zhaigy
wget "http://launchpad.net/libmemcached/1.0/0.42/+download/libmemcached-0.42.tar.gz"
tar -xzf libmemcached-0.42.tar.gz
cd libmemcached-0.42
./configure --prefix=/home/zhaigy/libmemcached_n --without-memcached
--非常的痛苦啊,编译安装在这里总是失败,从网上找的解决方法也不能用
痛苦的3小时
--
无意中使用了旧的版本,发现编译错误少了几个,嗯,找更旧的
cd /home/zhaigy
wget "http://launchpadlibrarian.net/33299675/libmemcached-0.28.tar.gz"
tar xzvf libmemcached-0.28.tar.gz
cd libmemcached-0.28
./configure --prefix=/home/zhaigy/libmemcached_n --without-memcached
make
make install
--这次比较顺利,估计是因为机器上的gcc版本低吧

cp /home/zhaigy/php_n
./bin/pecl -h
./bin/pecl download memcached
tar -xf memcached-1.0.2.tar
cd memcached-1.0.2
/home/zhaigy/php_n/bin/phpize
./configure --with-php-config=/home/zhaigy/php_n/bin/php-config --with-libmemcached-dir="/home/zhaigy/libmemcached_n"
make 这里也遇到编译错误
降低版本
/home/zhaigy/php_n/bin/pecl download memcached-1.0.0
tar -xvf memcached-1.0.0.tar
cd memcached-1.0.0
/home/zhaigy/php_n/bin/phpize
./configure --with-php-config=/home/zhaigy/php_n/bin/php-config --with-libmemcached-dir="/home/zhaigy/libmemcached_n"
make
make install
--顺利
安装到php
cd /home/zhaigy/php_n/
mkdir modules
cp /home/zhaigy/php_n/lib/php/extensions/no-debug-non-zts-20090626/memcached.so ./modules
php.ini中添加
extension = memcached.so
cd /home/zhaigy/apache_n
./bin/apachectl restart
从phpinfo中查看,正常

ActiveMQ:JMS开源框架入门介绍


JMS是为企业级的应用提供一种智能的消息系统,JMS定义了一整套的企业级的消息概念与工具,尽可能最小化的Java语言概念去构建最大化企业消息应用。统一已经存在的企业级消息系统功能。下面我们来学习JMS开源框架入门介绍。介绍基本的JMS概念与开源的JMS框架ActiveMQ应用,内容涵盖一下几点:

基本的JMS概念
JMS的消息模式
介绍ActiveMQ
一个基于ActiveMQ的JMS例子程序


一:JMS基本概念

1. JMS的目标

为企业级的应用提供一种智能的消息系统,JMS定义了一整套的企业级的消息概念与工具,尽可能最小化的Java语言概念去构建最大化企业消息应用。统一已经存在的企业级消息系统功能。

2. 提供者

JMS提供者是指那些完全完成JMS功能与管理功能的JMS消息厂商,理论上JMS提供者完成。JMS消息产品必须是100%的纯Java语言实现,可以运行在跨平台的架构与操作系统上,当前一些JMS厂商包括IBM,Oracle, JBoss社区 (JBoss Community), Apache 社区(ApacheCommunity)。

3. JMS应用程序, 一个完整的JMS应用应该实现以下功能:

JMS 客户端 – Java语言开发的接受与发送消息的程序
非JMS客户端 – 基于消息系统的本地API实现而不是JMS
消息 – 应用程序用来相互交流信息的载体
被管理对象–预先配置的JMS对象,JMS管理员创建,被客户端运用。如链接工厂,主题等
JMS提供者–完成JMS功能与管理功能的消息系统
二:JMS的消息模式

1.点对点的消息模式(Point to Point Messaging)




下面的JMS对象在点对点消息模式中是必须的:

a.队列(Queue) – 一个提供者命名的队列对象,客户端将会使用这个命名的队列对象

b.队列链接工厂(QueueConnectionFactory) – 客户端使用队列链接工厂创建链接队列

ConnectionQueue来取得与JMS点对点消息提供者的链接。

c. 链接队列(ConnectionQueue) – 一个活动的链接队列存在在客户端与点对点消息提供者之间,客户用它创建一个或者多个JMS队列会话(QueueSession)

d.     队列会话(QueueSession) – 用来创建队列消息的发送者与接受者(QueueSenderand QueueReceiver)

e.消息发送者(QueueSender 或者MessageProducer)– 发送消息到已经声明的队列

f.消息接受者(QueueReceiver或者MessageConsumer) – 接受已经被发送到指定队列的消息

2.发布订阅模式(publish – subscribe Mode)




a.主题Topic(Destination) – 一个提供者命名的主题对象,客户端将会使用这个命名的主题对象

b.主题链接工厂(TopciConnectionFactory) – 客户端使用主题链接工厂创建链接主题

ConnectionTopic来取得与JMS消息Pub/Sub提供者的链接。

c.链接主题(ConnectionTopic) – 一个活动的链接主题存在发布者与订阅者之间

d.会话(TopicSession) – 用来创建主题消息的发布者与订阅者 (TopicPublisher  and TopicSubscribers)

e.消息发送者MessageProducer) – 发送消息到已经声明的主题

f.消息接受者(MessageConsumer) – 接受已经被发送到指定主题的消息

三:介绍ActiveMQ

ActiveMQ是apache社区完成的JMS开源消息组件,客户端支持多种语言调用,包括Java,C++, C#,Perl, Python等。支持Spring配置集成等。更多信息访问这里:http://activemq.apache.org/index.html

四:基于ActiveMQ的Publish/subscribe模式Demo程序

消息Broker,JMSprovider

import java.net.URI;
import java.net.URISyntaxException;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * refer to http://activemq.apache.org/jndi-support.html
 * http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html
 * @author gloomyfish
 *
 */
public class PureJMSProducer {
     
    private static final Log LOG = LogFactory.getLog(PureJMSProducer.class);

    private PureJMSProducer() {
    }

    /**
     * @param args the destination name to send to and optionally, the number of
     *                messages to send
     */
    public static void main(String[] args) {
        Context jndiContext = null;
        ConnectionFactory connectionFactory = null;
        Connection connection = null;
        Session session = null;
        Destination destination = null;
        MessageProducer producer = null;
        BrokerService broker = null;
        final int numMsgs = 10;

        /*
         * Create a JNDI API InitialContext object
         */
        try {
            jndiContext = new InitialContext();
        } catch (NamingException e) {
            LOG.info("Could not create JNDI API context: " + e.toString());
            System.exit(1);
        }
         
        // create external TCP broker
        try {
            broker = BrokerFactory.createBroker(new URI("broker:tcp://localhost:61616"));
            broker.start();  
        } catch (URISyntaxException e) {
            LOG.info("Could not create broker: " + e.toString());
        } catch (Exception e) {
            LOG.info("Could not create broker: " + e.toString());
        }
//        try {
//          
//        }

        /*
         * Look up connection factory and destination.
         */
        try {
            connectionFactory = (ConnectionFactory)jndiContext.lookup("ConnectionFactory");
            destination = (Destination)jndiContext.lookup("MyTopic");
        } catch (NamingException e) {
            LOG.info("JNDI API lookup failed: " + e);
            System.exit(1);
        }
         
        /*
         * Create connection. Create session from connection; false means
         * session is not transacted. Create sender and text message. Send
         * messages, varying text slightly. Send end-of-messages message.
         * Finally, close connection.
         */
        try {
            connection = connectionFactory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            producer = session.createProducer(destination);
            TextMessage message = session.createTextMessage();
            Thread.sleep(3000);
            for (int i = 0; i < numMsgs; i++) {
                message.setText("This is message " + (i + 1));
                LOG.info("Sending message: " + message.getText());
                producer.send(message);
                Thread.sleep(3000);
            }

            /*
             * Send a non-text control message indicating end of messages.
             */
            producer.send(session.createMessage());
        } catch (JMSException e) {
            LOG.info("Exception occurred: " + e);
        } catch (InterruptedException e) {
            LOG.info("Exception occurred: " + e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                }
            }
        }
         
        // stop the TCP broker
        try {
            broker.stop();
        } catch (Exception e) {
            LOG.info("stop the broker failed: " + e);
        }
    }
}
客户端:

import java.io.IOException;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.InitialContext;

import org.apache.activemq.ActiveMQConnectionFactory;


public class ActiveMQClient {
     
    public static void main(String[] args) throws IOException {
         
        // -- http://dlc.sun.com/pdf//816-5904-10/816-5904-10.pdf
        try {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        // ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://locahost");
        Connection connection = factory.createConnection();
        connection.start();
         
        // create message topic
        //Topic topic= new ActiveMQTopic("MyTopic");
        InitialContext jndiContext=new InitialContext();
        Topic topic=(Topic)jndiContext.lookup("MyTopic");  
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
         
        // register message consumer
        MessageConsumer comsumer1 = session.createConsumer(topic);
        comsumer1.setMessageListener(new MessageListener(){
            public void onMessage(Message m) {
                try {
                    System.out.println("Consumer get " + ((TextMessage)m).getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }  
            }
        });
        Thread.sleep(30000);
        session.close();
        connection.stop();
         
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
项目配置,Jar依赖:



依赖的三个Jar分别为:

activemq-all.jar
geronimo-jms_1.1_spec-1.1.1.jar
xbean-spring.jar
原文链接:http://blog.csdn.net/jia20003/article/details/7601176

使用 ActiveMQ 示例



原文出处:http://blog.chenlb.com/2010/01/activemq-hello.html

企业中各项目中相互协作的时候可能用得到消息通知机制。比如有东西更新了,可以通知做索引。

在 Java 里有 JMS 的多个实现。其中 apache 下的 ActiveMQ 就是不错的选择。还有一个比较热的是 RabbitMQ (是 erlang 语言实现的)。这里示例下使用 ActiveMQ

用 ActiveMQ 最好还是了解下 JMS
JMS 公共点对点域发布/订阅域
ConnectionFactoryQueueConnectionFactoryTopicConnectionFactory
ConnectionQueueConnectionTopicConnection
DestinationQueueTopic
SessionQueueSessionTopicSession
MessageProducerQueueSenderTopicPublisher
MessageConsumerQueueReceiverTopicSubscriber

JMS 定义了两种方式:Quere(点对点);Topic(发布/订阅)。

ConnectionFactory 是连接工厂,负责创建Connection。

Connection 负责创建 Session。

Session 创建 MessageProducer(用来发消息) 和 MessageConsumer(用来接收消息)。

Destination 是消息的目的地。

详细的可以网上找些 JMS 规范(有中文版)。

下载 apache-activemq-5.3.0。http://activemq.apache.org/download.html,解压,然后双击 bin/activemq.bat。运行后,可以在 http://localhost:8161/admin 观察。也有 demo, http://localhost:8161/demo。把 activemq-all-5.3.0.jar 加入 classpath。

Jms 发送 代码:

public static void main(String[] args) throws Exception {
    ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
 
    Connection connection = connectionFactory.createConnection();
    connection.start();
 
    Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createQueue("my-queue");
 
    MessageProducer producer = session.createProducer(destination);
    for(int i=0; i<3; i++) {
        MapMessage message = session.createMapMessage();
        message.setLong("count", new Date().getTime());
        Thread.sleep(1000);
        //通过消息生产者发出消息
        producer.send(message);
    }
    session.commit();
    session.close();
    connection.close();
}
Jms 接收代码:

public static void main(String[] args) throws Exception {
    ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
 
    Connection connection = connectionFactory.createConnection();
    connection.start();
 
    final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
    Destination destination = session.createQueue("my-queue");
 
    MessageConsumer consumer = session.createConsumer(destination);
    /*//listener 方式
    consumer.setMessageListener(new MessageListener() {

        public void onMessage(Message msg) {
            MapMessage message = (MapMessage) msg;
            //TODO something....
            System.out.println("收到消息:" + new Date(message.getLong("count")));
            session.commit();
        }

    });
    Thread.sleep(30000);
    */
    int i=0;
    while(i<3) {
        i++;
        MapMessage message = (MapMessage) consumer.receive();
        session.commit();
 
        //TODO something....
        System.out.println("收到消息:" + new Date(message.getLong("count")));
    }
 
    session.close();
    connection.close();
}
启动 JmsReceiver 和 JmsSender 可以在看输出三条时间信息。当然 Jms 还指定有其它格式的数据,如 TextMessage

结合 Spring 的 JmsTemplate 方便用:

xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<!-- 在非 web / ejb 容器中使用 pool 时,要手动 stop,spring 不会为你执行 destroy-method 的方法
    <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL" value="tcp://localhost:61616" />
            </bean>
        </property>
    </bean>
-->
    <bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:61616" />
    </bean>
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsFactory" />
        <property name="defaultDestination" ref="destination" />
        <property name="messageConverter">
            <bean class="org.springframework.jms.support.converter.SimpleMessageConverter" />
        </property>
    </bean>
 
    <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg index="0" value="my-queue" />
    </bean>
 
</beans>
sender:

public static void main(String[] args) {
    ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:app*.xml");
 
    JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");
 
    jmsTemplate.send(new MessageCreator() {
 
        public Message createMessage(Session session) throws JMSException {
            MapMessage mm = session.createMapMessage();
            mm.setLong("count", new Date().getTime());
            return mm;
        }
 
    });
}
receiver:

public static void main(String[] args) {
    ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:app*.xml");
 
    JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");
    while(true) {
        Map<String, Object> mm =  (Map<String, Object>) jmsTemplate.receiveAndConvert();
        System.out.println("收到消息:" + new Date((Long)mm.get("count")));
    }
}
注意:直接用 Jms 接口时接收了消息后要提交一下,否则下次启动接收者时还可以收到旧数据。有了 JmsTemplate 就不用自己提交 session.commit() 了。如果使用了 PooledConnectionFactory 要把 apache-activemq-5.3.0\lib\optional\activemq-pool-5.3.0.jar 加到 classpath

参考资料:

Hello ActiveMQ

Spring2.5整合ActiveMQ 5.2

spring-support

JMS 相关资料

ActiveMQ教程(二)


ProducerTool.java用于发送消息:
[java] view plaincopy
import javax.jms.Connection;    
import javax.jms.DeliveryMode;    
import javax.jms.Destination;    
import javax.jms.JMSException;    
import javax.jms.MessageProducer;    
import javax.jms.Session;    
import javax.jms.TextMessage;    
   
import org.apache.activemq.ActiveMQConnection;    
import org.apache.activemq.ActiveMQConnectionFactory;    
   
public class ProducerTool {    
   
    private String user = ActiveMQConnection.DEFAULT_USER;    
   
    private String password = ActiveMQConnection.DEFAULT_PASSWORD;    
   
    private String url = ActiveMQConnection.DEFAULT_BROKER_URL;    
   
    private String subject = "TOOL.DEFAULT";    
   
    private Destination destination = null;    
   
    private Connection connection = null;    
   
    private Session session = null;    
   
    private MessageProducer producer = null;    
   
    // 初始化    
    private void initialize() throws JMSException, Exception {    
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(    
                user, password, url);    
        connection = connectionFactory.createConnection();    
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);    
        destination = session.createQueue(subject);    
        producer = session.createProducer(destination);    
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);    
    }    
   
    // 发送消息    
    public void produceMessage(String message) throws JMSException, Exception {    
        initialize();    
        TextMessage msg = session.createTextMessage(message);    
        connection.start();    
        System.out.println("Producer:->Sending message: " + message);    
        producer.send(msg);    
        System.out.println("Producer:->Message sent complete!");    
    }    
   
    // 关闭连接    
    public void close() throws JMSException {    
        System.out.println("Producer:->Closing connection");    
        if (producer != null)    
            producer.close();    
        if (session != null)    
            session.close();    
        if (connection != null)    
            connection.close();    
    }    
}    

ConsumerTool.java用于接受消息,我用的是基于消息监听的机制,需要实现MessageListener接口,这个接口有个onMessage方法,当接受到消息的时候会自动调用这个函数对消息进行处理。
[java] view plaincopy
import javax.jms.Connection;    
import javax.jms.Destination;    
import javax.jms.JMSException;    
import javax.jms.MessageConsumer;    
import javax.jms.Session;    
import javax.jms.MessageListener;    
import javax.jms.Message;    
import javax.jms.TextMessage;    
   
import org.apache.activemq.ActiveMQConnection;    
import org.apache.activemq.ActiveMQConnectionFactory;    
   
public class ConsumerTool implements MessageListener {    
   
    private String user = ActiveMQConnection.DEFAULT_USER;    
   
    private String password = ActiveMQConnection.DEFAULT_PASSWORD;    
   
    private String url = ActiveMQConnection.DEFAULT_BROKER_URL;    
   
    private String subject = "TOOL.DEFAULT";    
   
    private Destination destination = null;    
   
    private Connection connection = null;    
   
    private Session session = null;    
   
    private MessageConsumer consumer = null;    
   
    // 初始化    
    private void initialize() throws JMSException, Exception {
     //连接工厂是用户创建连接的对象,这里使用的是ActiveMQ的ActiveMQConnectionFactory根据url,username和password创建连接工厂。
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(    
                user, password, url);  
        //连接工厂创建一个jms connection
        connection = connectionFactory.createConnection();    
        //是生产和消费的一个单线程上下文。会话用于创建消息的生产者,消费者和消息。会话提供了一个事务性的上下文。
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  //不支持事务  
        //目的地是客户用来指定他生产消息的目标还有他消费消息的来源的对象,两种消息传递方式:点对点和发布/订阅
        destination = session.createQueue(subject);  
        //会话创建消息的生产者将消息发送到目的地
        consumer = session.createConsumer(destination);    
           
    }    
   
    // 消费消息    
    public void consumeMessage() throws JMSException, Exception {    
        initialize();    
        connection.start();    
           
        System.out.println("Consumer:->Begin listening...");    
        // 开始监听    
        consumer.setMessageListener(this);    
        // Message message = consumer.receive();    
    }    
   
    // 关闭连接    
    public void close() throws JMSException {    
        System.out.println("Consumer:->Closing connection");    
        if (consumer != null)    
            consumer.close();    
        if (session != null)    
            session.close();    
        if (connection != null)    
            connection.close();    
    }    
   
    // 消息处理函数    
    public void onMessage(Message message) {    
        try {    
            if (message instanceof TextMessage) {    
                TextMessage txtMsg = (TextMessage) message;    
                String msg = txtMsg.getText();    
                System.out.println("Consumer:->Received: " + msg);    
            } else {    
                System.out.println("Consumer:->Received: " + message);    
            }    
        } catch (JMSException e) {    
            // TODO Auto-generated catch block    
            e.printStackTrace();    
        }    
    }    
}  


如果想主动的去接受消息,而不用消息监听的话,把consumer.setMessageListener(this)改为Message message = consumer.receive(),手动去调用MessageConsumer的receive方法即可。
下面是测试类Test.java:
[java] view plaincopy
import javax.jms.JMSException;    
mport org.apache.activemq.ActiveMQConnection;
   
public class Test {    
   
    /**  
     * @param args  
     */  
    public static void main(String[] args) throws JMSException, Exception {    
     
     // TODO Auto-generated method stub    
        ConsumerTool consumer = new ConsumerTool();    
        ProducerTool producer = new ProducerTool();  
        System.out.println(ActiveMQConnection.DEFAULT_BROKER_URL+"------------");
        // 开始监听    
        consumer.consumeMessage();    
           
        // 延时500毫秒之后发送消息    
        Thread.sleep(500);    
        producer.produceMessage("Hello, world!");    
        producer.close();    
           
        // 延时500毫秒之后停止接受消息    
        Thread.sleep(500);    
        consumer.close();    
    }    
}  

Apache ActiveMQ教程(一)


一、特性及优势
1、实现JMS1.1规范,支持J2EE1.4以上
2、可运行于任何jvm和大部分web容器(ActiveMQ works great in any JVM)
3、支持多种语言客户端(java, C, C++, AJAX, ACTIONSCRIPT等等)
4、支持多种协议(stomp,openwire,REST)
5、良好的spring支持(ActiveMQ has great Spring Support)
6、速度很快,JBossMQ的十倍(ActiveMQ is very fast; often 10x faster than JBossMQ.)
7、与OpenJMS、JbossMQ等开源jms provider相比,ActiveMQ有Apache的支持,持续发展的优势明显。
二、下载部署
1、下载
http://activemq.apache.org/activemq-510-release.html,下载5.1.0 Windows Distribution版本
2、安装
直接解压至任意目录(如:d:/ apache-activemq-5.1.0)
3、启动ActiveMQ服务器
方法1:
直接运行bin/activemq.bat
方法2(在JVM中嵌套启动):
cd example
ant embedBroker
4、ActiveMQ消息管理后台系统:
http://localhost:8161/admin

三、运行附带的示例程序
1、Queue消息示例:
* 启动Queue消息消费者
cd example
ant consumer
* 启动Queue消息生产者
cd example
ant producer
简要说明:生产者(producer)发消息,消费者(consumer)接消息,发送/接收2000个消息后自动关闭
2、Topic消息示例:
* 启动Topic消息消费者
cd example
ant topic-listener
* 启动Topic消息生产者
cd example
ant topic-publisher
简要说明:重复10轮,publisher每轮发送2000个消息,并等待获取listener的处理结果报告,然后进入下一轮发送,最后统计全局发送时间。

四、Queue与Topic的比较
1、JMS Queue执行load balancer语义:
一条消息仅能被一个consumer收到。如果在message发送的时候没有可用的consumer,那么它将被保存一直到能处理该message的consumer可用。如果一个consumer收到一条message后却不响应它,那么这条消息将被转到另一个consumer那儿。一个Queue可以有很多consumer,并且在多个可用的consumer中负载均衡。
2、Topic实现publish和subscribe语义:
一条消息被publish时,它将发到所有感兴趣的订阅者,所以零到多个subscriber将接收到消息的一个拷贝。但是在消息代理接收到消息时,只有激活订阅的subscriber能够获得消息的一个拷贝。
3、分别对应两种消息模式:
Point-to-Point (点对点),Publisher/Subscriber Model (发布/订阅者)
其中在Publicher/Subscriber 模式下又有Nondurable subscription(非持久订阅)和durable subscription (持久化订阅)2种消息处理方式。