tornado 环境部署 supervisor配置

这个直接安装在root 角色下面,不是在虚拟环境的,虚拟环境知识和程序有关

1、下载安装

# 使用 pip 装会出问题的, 最好用yum 安装 可以直接使用 systemctl 会有问题
#sudo pip install supervisor

yum -y install supervisor

2、创建配置文件

这一步是生成supervisor 的配置文件

echo_supervisord_conf > /etc/supervisord.conf

3、修改 里面的配置文件

[include]
files = relative/directory/*.ini

修改为

[include]
files = /etc/supervisor/*.conf

这样配置的说明,相当于给这个文件进行扩展了不然太长

4、在etc 下面创建 supervisor目录,创建xxx.conf

mkdir /etc/supervisor
touch yabg.conf

启动的时候就会找到这个文件

5、填写配置信息

[group:tornadoes]
programs=tornado-8000,tornado-8001,tornado-8002

[program:tornado-8000]
command=/home/python/.virtualenvs/tornado_py2/bin/python /home/python/Documents/demo/chat    /server.py --port=8000
directory=/home/python/Documents/demo/chat
user=python
autorestart=true
redirect_stderr=true
stdout_logfile=/home/python/tornado.log
loglevel=info

[program:tornado-8001]
command=/home/python/.virtualenvs/tornado_py2/bin/python /home/python/Documents/demo/chat    /server.py --port=8001
directory=/home/python/Documents/demo/chat
user=python
autorestart=true
redirect_stderr=true
stdout_logfile=/home/python/tornado.log
loglevel=info

[program:tornado-8002]
command=/home/python/.virtualenvs/tornado_py2/bin/python /home/python/Documents/demo/chat    /server.py --port=8002
directory=/home/python/Documents/demo/chat
user=python
autorestart=true
redirect_stderr=true
stdout_logfile=/home/python/tornado.log     存放日志的地方(标准日志输出)
loglevel=info

说明:

command 前面的是python 解释权所在的位置(这里为设置的虚拟的目录位置), 后面是tornado 的 main.py 所在的位置 –port 监听端口
directory 文件所在的目录
user 用户
上面有多个不同端口,直接监听不同的端口
现在来看下生成目前的配置

[yangxiaodong@dev conf.d]$ cat ohho.conf 
[program:ohho]

user=www
command=/data/env/yang/bin/python  /data/websites/work/main.py

process_name=%(program_name)s ; process_name expr (default %(program_name)s)
numprocs=1                    ; number of processes copies to start (def 1)
startretries=2                ;
stopsignal=TERM               ; signal used to kill process (default TERM)
redirect_stderr=true          ; redirect proc stderr to stdout (default false)
directory=/data/websites/SDevelop/
autostart=true
stdout_logfile = /data/websites/logs/ohho.out
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=10
stderr_logfile = /data/websites/logs/ohho.err
stderr_logfile_maxbytes=100MB
stderr_logfile_backups=10

直接启动报错

systemctl start supervisord.service
Failed to start supervisord.service: Unit not found.

解决办法:

最好使用 yum 安装就可以啦
使用配置文件启动

supervisord -c /etc/supervisord.conf

查看是不是启动了

ps aux | grep supervisord

supervisorctl

我们可以利用supervisorctl来管理supervisor。

supervisorctl

status # 查看程序状态
stop tornadoes:* # 关闭 tornadoes组 程序
start tornadoes:* # 启动 tornadoes组 程序
restart tornadoes:* # 重启 tornadoes组 程序
update # 重启配置文件修改过的程序

Ubuntu16.04 中 supervisor 安装到使用

supervisor 进程管理是可以让进程在后台运行,而不占用控制台影响使用。

1. 安装 supervisor

sudo apt install supervisor

2. 添加进程

supervisor 可以将每个进程分别写成一个文件,supervisor 的进程文件放在 /etc/supervisor/conf.d/ 目录下,本例创建 test.conf 进程配置文件。其中 program 为要运行的进程的名称, command 为要执行的命令,directory 要执行命令的目录,user 运行的用户。

[program:test]
command=php artisan queue:work
directory=/var/www/html/wisdom
user=ubuntu

3. 启动进程

首先要重启supervisor,让配置文件生效

sudo supervisorctl reload

然后启动进程

sudo supervisorctl start test

完成。

docker-postfix, 在 Docker 容器中,使用smtp身份验证( sasldb ) 运行后缀

源代码名称:docker-postfix
源代码网址:http://www.github.com/catatnight/docker-postfix
docker-postfix源代码文档
docker-postfix源代码下载

Git URL:

git://www.github.com/catatnight/docker-postfix.git

Git Clone代码到本地:

git clone http://www.github.com/catatnight/docker-postfix

Subversion代码到本地:

$ svn co --depth empty http://www.github.com/catatnight/docker-postfix
Checked out revision 1.
$ cd repo
$ svn up trunk

docker后缀
在 Docker 容器中运行带有smtp身份验证( sasldb )的postfix 。 TLS和OpenDKIM支持是可选的。

需求

Docker 1.0

安装

构建图像

$ sudo docker pull catatnight/postfix

用法

使用smtp身份验证创建后缀容器

$ sudo docker run -p 25:25 
 -e maildomain=mail.example.com -e smtp_user=user:pwd 
 --name postfix -d catatnight/postfix# Set multiple user credentials: -e smtp_user=user1:pwd1,user2:pwd2,...,userN:pwdN

启用 OpenDKIM: 在 /path/to/domainkeys 中保存你的域密钥 .private

$ sudo docker run -p 25:25 
 -e maildomain=mail.example.com -e smtp_user=user:pwd 
 -v/path/to/domainkeys:/etc/opendkim/domainkeys 
 --name postfix -d catatnight/postfix

启用 TLS(587): 将SSL证书 .key 和 .crt 保存到 /path/to/certs

$ sudo docker run -p 587:587 
 -e maildomain=mail.example.com -e smtp_user=user:pwd 
 -v/path/to/certs:/etc/postfix/certs 
 --name postfix -d catatnight/postfix

注释

在Smtp客户端中,登录凭据应设置为( [email protected],password )
你可以将主机的端口分配给主机,而不是 25 ( 后缀如何自动分配http://www.postfix.org/MULTI_INSTANCE_README.html)
阅读以下参考以了解如何生成域密钥并将 public 键添加到域记录的DNS

引用

后缀 SASL Howto: http://www.postfix.org/SASL_README.html
如何安装和配置在 Debian Wheezy上使用后缀的DKIM: https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy

CentOS7下搭建postfix邮箱服务器并实现extmail的web访问

闲来无事想着尝试使用postfix搭建一个邮箱服务器,我是边搭建边写这个笔记,搭建过程中遇到坑也会一并记录,使用的系统版本如下:

[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

本示例基于LNMP环境。

1. 准备工作

关闭selinux

[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce 
Permissive
[root@localhost ~]#

关闭firewalld防火墙,并清空iptables规则:

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# iptables -F
[root@localhost ~]# iptables -X
[root@localhost ~]# iptables -nvL
Chain INPUT (policy ACCEPT 38 packets, 7291 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 12 packets, 1208 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@localhost ~]#

由于CentOS7默认安装的是MariaDB,所以要添加MySQL的yum源,有些编译需要的devel包只有epel扩展源有,所以我们需要把epel源也一并添加。因为是通过wget命令从下载地址中下载,但是最小化安装的CentOS7不自带wget命令,还需要先安装这个命令:

yum install -y wget
wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm

2. 安装postfix

首先需要安装编译环境及其他所需要的包,免得一会编译过程中老报缺少包的错误,因为需要安装的包有点多,所以这个过程有点慢:

yum install nginx vim gcc gcc-c++ openssl openssl-devel db4-devel ntpdate mysql mysql-devel mysql-server bzip2 php-mysql cyrus-sasl-md5 perl-GD perl-DBD-MySQL perl-GD perl-CPAN perl-CGI perl-CGI-Session cyrus-sasl-lib cyrus-sasl-plain cyrus-sasl cyrus-sasl-devel libtool-ltdl-devel telnet mail libicu-devel  -y

安装完以上所需的包后,开始编译安装postfix:

1)首先卸载系统自带的postfix,并删除postfix用户,重新指定uid、gid创建新用户postfix,postdrop,嫌一条条命令去执行有点麻烦就写成脚本文件去执行:

yum remove postfix -y
userdel postfix
groupdel postdrop
groupadd -g 2525 postfix
useradd -g postfix -u 2525 -s /sbin/nologin -M postfix
groupadd -g 2526 postdrop
useradd -g postdrop -u 2526 -s /sbin/nologin -M postdrop

2)下载源码包并解压编译(如果下载地址失效就到官网去找下载连接):

cd /usr/local/src/
wget http://cdn.postfix.johnriley.me/mirrors/postfix-release/official/postfix-3.0.11.tar.gz
tar -zxvf postfix-3.0.11.tar.gz
cd postfix-3.0.11
make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/include/mysql -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl -DUSE_TLS ' 'AUXLIBS=-L/usr/lib64/mysql -lmysqlclient -lz -lrt -lm -L/usr/lib64/sasl2 -lsasl2   -lssl -lcrypto'
make && make install
echo $?

在make install环节的时候会有个交互式的界面,可以自定义一些目录,我这里只更改了第二项临时文件目录,其他的都选择了默认目录:

Please specify the prefix for installed file names. Specify this ONLY
if you are building ready-to-install packages for distribution to OTHER
machines. See PACKAGE_README for instructions.
install_root: [/] 

Please specify a directory for scratch files while installing Postfix. You
must have write permission in this directory.
tempdir: [/usr/local/src/postfix-3.0.11] /tmp/extmail     // 就只更改这一项为tmp目录,其他的全部默认

Please specify the final destination directory for installed Postfix
configuration files.
config_directory: [/etc/postfix] 

Please specify the final destination directory for installed Postfix
administrative commands. This directory should be in the command search
path of adminstrative users.
command_directory: [/usr/sbin] 

Please specify the final destination directory for installed Postfix
daemon programs. This directory should not be in the command search path
of any users.
daemon_directory: [/usr/libexec/postfix] 

Please specify the final destination directory for Postfix-writable
data files such as caches or random numbers. This directory should not
be shared with non-Postfix software.
data_directory: [/var/lib/postfix] 

Please specify the final destination directory for the Postfix HTML
files. Specify "no" if you do not want to install these files.
html_directory: [no] 

Please specify the owner of the Postfix queue. Specify an account with
numerical user ID and group ID values that are not used by any other
accounts on the system.
mail_owner: [postfix] 

Please specify the final destination pathname for the installed Postfix
mailq command. This is the Sendmail-compatible mail queue listing command.
mailq_path: [/usr/bin/mailq] 

Please specify the final destination directory for the Postfix on-line
manual pages. You can no longer specify "no" here.
manpage_directory: [/usr/local/man] 

Please specify the final destination pathname for the installed Postfix
newaliases command. This is the Sendmail-compatible command to build
alias databases for the Postfix local delivery agent.
newaliases_path: [/usr/bin/newaliases] 

Please specify the final destination directory for Postfix queues.
queue_directory: [/var/spool/postfix] 

Please specify the final destination directory for the Postfix README
files. Specify "no" if you do not want to install these files.
readme_directory: [no]

Please specify the final destination pathname for the installed Postfix
sendmail command. This is the Sendmail-compatible mail posting interface.
sendmail_path: [/usr/sbin/sendmail] 

Please specify the group for mail submission and for queue management
commands. Specify a group name with a numerical group ID that is
not shared with other accounts, not even with the Postfix mail_owner
account. You can no longer specify "no" here.
setgid_group: [postdrop] 

Please specify the final destination directory for Postfix shared-library
files.
shlib_directory: [no]

3)更改目录的属主和属组:

chown -R postfix:postdrop /var/spool/postfix
chown -R postfix:postdrop /var/lib/postfix/
chown root /var/spool/postfix
chown -R root /var/spool/postfix/pid

4)修改postfix的配置文件:

[root@localhost ~]# vim /etc/postfix/main.cf
myhostname = mail.everyoo.com        //设置主机名
mydomain = everyoo.com        //指定域名
myorigin = $mydomain        //指明发件人所在的域名
inet_interfaces =         //all指定postfix系统监听的网络接口
mydestination = $myhostname, localhost.$mydomain, localhost,$mydomain        //指定postfix接收邮件时收件人的域名 [使用虚拟域需要禁用]
mynetworks_style = host        //指定信任网段类型
mynetworks = 192.168.77.1/24, 127.0.0.0/8        //指定信任的客户端
relay_domains = $mydestination        //指定允许中转邮件的域名
alias_maps = hash:/etc/aliases        //设置邮件的别名

5)然后需要在/etc/init.d/目录下提供一个脚本来管理postfix的启动与停止:

[root@localhost /var/www/extsuite/extman]# vim /etc/init.d/postfix

把下面的内容放在/etc/init.d/postfix里面:

#!/bin/bash
#
# postfix      Postfix Mail Transfer Agent
#
# chkconfig: 2345 80 30
# description: Postfix is a Mail Transport Agent, which is the program 
#              that moves mail from one machine to another.
# processname: master
# pidfile: /var/spool/postfix/pid/master.pid
# config: /etc/postfix/main.cf
# config: /etc/postfix/master.cf

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ $NETWORKING = "no" ] && exit 3

[ -x /usr/sbin/postfix ] || exit 4
[ -d /etc/postfix ] || exit 5
[ -d /var/spool/postfix ] || exit 6

RETVAL=0
prog="postfix"

start() {
     # Start daemons.
     echo -n $"Starting postfix: "
        /usr/bin/newaliases >/dev/null 2>&1
     /usr/sbin/postfix start 2>/dev/null 1>&2 && success || failure $"$prog start"
     RETVAL=$?
     [ $RETVAL -eq 0 ] && touch /var/lock/subsys/postfix
        echo
     return $RETVAL
}

stop() {
  # Stop daemons.
     echo -n $"Shutting down postfix: "
     /usr/sbin/postfix stop 2>/dev/null 1>&2 && success || failure $"$prog stop"
     RETVAL=$?
     [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/postfix
     echo
     return $RETVAL
}

reload() {
     echo -n $"Reloading postfix: "
     /usr/sbin/postfix reload 2>/dev/null 1>&2 && success || failure $"$prog reload"
     RETVAL=$?
     echo
     return $RETVAL
}

abort() {
     /usr/sbin/postfix abort 2>/dev/null 1>&2 && success || failure $"$prog abort"
     return $?
}

flush() {
     /usr/sbin/postfix flush 2>/dev/null 1>&2 && success || failure $"$prog flush"
     return $?
}

check() {
     /usr/sbin/postfix check 2>/dev/null 1>&2 && success || failure $"$prog check"
     return $?
}

restart() {
     stop
     start
}

# See how we were called.
case "$1" in
  start)
     start
     ;;
  stop)
     stop
     ;;
  restart)
     stop
     start
     ;;
  reload)
     reload
     ;;
  abort)
     abort
     ;;
  flush)
     flush
     ;;
  check)
     check
     ;;
  status)
       status master
     ;;
  condrestart)
     [ -f /var/lock/subsys/postfix ] && restart || :
     ;;
  *)
     echo $"Usage: $0 {start|stop|restart|reload|abort|flush|check|status|condrestart}"
     exit 1
esac

exit $?

为脚本添加执行权限,并将服务添加到开机启动项中:

[root@localhost /var/www/extsuite/extman]# chmod +x /etc/init.d/postfix
[root@localhost /var/www/extsuite/extman]# chkconfig --add postfix
[root@localhost /var/www/extsuite/extman]# chkconfig postfix on
[root@localhost /var/www/extsuite/extman]# chown postfix.postfix -R /var/lib/postfix/
[root@localhost /var/www/extsuite/extman]# chown postfix.postfix /var/spool/ -R

3. 安装dovecot

yum安装:

[root@localhost ~]# yum install -y dovecot dovecot-mysql

配置dovecot:

[root@localhost ~]# cd /etc/dovecot/
[root@localhost dovecot]# vim dovecot.conf     //直接在配置文件最后添加即可
protocols = imap pop3
!include conf.d/*.conf
listen = *
base_dir = /var/run/dovecot/
[root@localhost dovecot]# cd conf.d/
[root@localhost conf.d]# vim 10-auth.conf
disable_plaintext_auth = no
[root@localhost conf.d]# vim 10-mail.conf
mail_location = maildir:~/Maildir
mail_location = maildir:/var/mailbox/%d/%n/Maildir
mail_privileged_group = mail
[root@localhost conf.d]# vim 10-ssl.conf
ssl = no
[root@localhost conf.d]# vim 10-logging.conf 
log_path = /var/log/dovecot.log
info_log_path = /var/log/dovecot.info
log_timestamp = "%Y-%m-%d %H:%M:%S "
[root@localhost conf.d]# cp auth-sql.conf.ext auth-sql.conf
[root@localhost conf.d]# vim auth-sql.conf
passdb {  
    driver = sql        

    # Path for SQL configuration file, see example-config/dovecot-sql.conf.ext  
    args = /etc/dovecot/dovecot-sql.conf.ext
}

userdb {  
    driver = sql  
    args = /etc/dovecot/dovecot-sql.conf.ext
}

编辑dovecot通过mysql认证的配置文件:

[root@localhost conf.d]# vim /etc/dovecot-mysql.conf
driver = mysql
connect = host=localhost dbname=extmail user=extmail password=extmail
default_pass_scheme = CRYPT
password_query = SELECT username AS user,password AS password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir, uidnumber AS uid, gidnumber AS gid FROM mailbox WHERE username = '%u'

4. 安装courier-authlib

下载解压并编译:

[root@localhost ~]# cd /usr/local/src/
[root@localhost /usr/local/src]#  wget https://sourceforge.net/projects/courier/files/authlib/0.66.2/courier-authlib-0.66.2.tar.bz2
[root@localhost /usr/local/src]# tar -jxvf courier-authlib-0.66.2.tar.bz2
[root@localhost /usr/local/src]# cd courier-authlib-0.66.2
[root@localhost /usr/local/src/courier-authlib-0.66.2]# ./configure --prefix=/usr/local/courier-authlib     --sysconfdir=/etc     --without-authpam     --without-authshadow     --without-authvchkpw     --without-authpgsql     --with-authmysql     --with-mysql-libs=/usr/lib64/mysql     --with-mysql-includes=/usr/include/mysql     --with-redhat     --with-authmysqlrc=/etc/authmysqlrc     --with-authdaemonrc=/etc/authdaemonrc     --with-mailuser=postfix
[root@localhost /usr/local/src/courier-authlib-0.66.2]# make && makeinstall

编译过程中发生了一个错误:

configure: error: The Courier Unicode Library 1.2 appears not to be installed. You may need to install a separate development subpackage, in addition to the main package

这是因为Courier Unicode Library没有安装,我们下载courier-unicode-1.2并编译安装:

[root@localhost ~]# wget https://sourceforge.net/projects/courier/files/courier-unicode/1.2/courier-unicode-1.2.tar.bz2
[root@localhost ~]# tar jxvf courier-unicode-1.2.tar.bz2 
[root@localhost ~]# cd courier-unicode-1.2
[root@localhost courier-unicode-1.2]# ./configure
[root@localhost courier-unicode-1.2]# make && make install

完成Courier Unicode Library的安装后,倒回去再次编译courier-authlib就没问题了

配置courier-authlib:

[root@localhost  courier-authlib-0.66.2]# chmod 755 /usr/local/courier-authlib/var/spool/authdaemon
[root@localhost  courier-authlib-0.66.2]# cp /etc/authdaemonrc.dist  /etc/authdaemonrc
[root@localhost  courier-authlib-0.66.2]# cp /etc/authmysqlrc.dist  /etc/authmysqlrc
[root@localhost  courier-authlib-0.66.2]# vim /etc/authdaemonrc      //配置文件里的验证方法比较多,我们这里只使用authmysql
authmodulelist="authmysql"
authmodulelistorig="authmysql"
[root@localhost  courier-authlib-0.66.2]# vim /etc/authmysqlrc     //直接添加到配置文件尾部,然后去上面将响应系统默认的注视掉,或者删除即可
MYSQL_SERVER            localhost
MYSQL_USERNAME          extmail
MYSQL_PASSWORD          extmail
MYSQL_SOCKET            /var/lib/mysql/mysql.sock
MYSQL_PORT               3306
MYSQL_DATABASE          extmail
MYSQL_USER_TABLE        mailbox
MYSQL_CRYPT_PWFIELD     password
DEFAULT_DOMAIN          test.com
MYSQL_UID_FIELD         '2525'
MYSQL_GID_FIELD         '2525'
MYSQL_LOGIN_FIELD       username
MYSQL_HOME_FIELD        concat('/var/mailbox/',homedir)
MYSQL_NAME_FIELD        name
MYSQL_MAILDIR_FIELD     concat('/var/mailbox/',maildir)

courier-authlib添加服务启动脚本及其他:

[root@localhost  courier-authlib-0.66.2]# cp courier-authlib.sysvinit /etc/init.d/courier-authlib
[root@localhost  courier-authlib-0.66.2]# chmod +x /etc/init.d/courier-authlib
[root@localhost  courier-authlib-0.66.2]# chkconfig --add courier-authlib
[root@localhost  courier-authlib-0.66.2]# chkconfig courier-authlib on
[root@localhost  courier-authlib-0.66.2]# echo "/usr/local/courier-authlib/lib/courier-authlib" >> /etc/ld.so.conf.d/courier-authlib.conf
[root@localhost  courier-authlib-0.66.1]# ldconfig
[root@localhost  courier-authlib-0.66.1]# service courier-authlib start
Starting Courier authentication services: authdaemond

smtp以及虚拟用户相关的设置:

[root@localhost ~]# vim /usr/lib64/sasl2/smtpd.conf    //文件不存在,要自己创建
pwcheck_method: authdaemond
log_level: 3
mech_list: PLAIN LOGIN
authdaemond_path:/usr/local/courier-authlib/var/spool/authdaemon/socket
[root@localhost ~]# vim /etc/postfix/main.cf
##postfix支持SMTP##
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = ''
smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
broken_sasl_auth_clients=yes
smtpd_client_restrictions = permit_sasl_authenticated
smtpd_sasl_security_options = noanonymous
##postfix支持虚拟用户##
virtual_mailbox_base = /var/mailbox
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf   //这里的配置文件需在后面extman
里复制过来
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_alias_domains =
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_uid_maps = static:2525
virtual_gid_maps = static:2525
virtual_transport = virtual

5. 安装extmail

下载extmail和extman:

[root@localhost ~]# cd /usr/local/src/
[root@localhost /usr/local/src]# wget http://7xivyw.com1.z0.glb.clouddn.com/extmail-1.2.tar.gz
[root@localhost /usr/local/src]# wget http://7xivyw.com1.z0.glb.clouddn.com/extman-1.1.tar.gz

创建站点目录并解压、重命名extmail包:

[root@localhost /usr/local/src]# mkdir -p /var/www/extsuite
[root@localhost /usr/local/src]# tar -zxvf extmail-1.2.tar.gz -C /var/www/extsuite/
[root@localhost /usr/local/src]# mv /var/www/extsuite/extmail-1.2/ /var/www/extsuite/extmail

更改extmail的配置文件:

[root@localhost ~]# cd /var/www/extsuite/extmail
[root@localhost extmail]# cp webmail.cf.default webmail.cf
[root@localhost extmail]# vim webmail.cf
SYS_SESS_DIR = /tmp/extmail
SYS_UPLOAD_TMPDIR = /tmp/extmail/upload
SYS_USER_LANG = zh_CN
SYS_MIN_PASS_LEN = 8
SYS_MAILDIR_BASE = /var/mailbox
SYS_MYSQL_USER = extmail
SYS_MYSQL_PASS = extmail
SYS_MYSQL_DB = extmail
SYS_MYSQL_HOST = localhost
SYS_MYSQL_SOCKET = /var/lib/mysql/mysql.sock
SYS_MYSQL_TABLE = mailbox
SYS_MYSQL_ATTR_USERNAME = username
SYS_MYSQL_ATTR_DOMAIN = domain
SYS_MYSQL_ATTR_PASSWD = password
SYS_AUTHLIB_SOCKET = /usr/local/courier-authlib/var/spool/authdaemon/socket

建立临时文件目录与session目录,并更改权限:

[root@localhost extmail]# mkdir -p /tmp/extmail/upload
[root@localhost extmail]# chown -R postfix.postfix /tmp/extmail/

6. 安装extman

回到extman的下载目录下,解压extman包:

[root@localhost ~]# cd /usr/local/src/
[root@localhost /usr/local/src]# tar -zxvf extman-1.1.tar.gz -C /var/www/extsuite/
[root@localhost /usr/local/src]# cd /var/www/extsuite/
[root@localhost /var/www/extsuite]# mv extman-1.1/ extman

拷贝extman的配置文件:

[root@localhost /var/www/extsuite]# cd extman/
[root@localhost /var/www/extsuite/extman]# cp webman.cf.default webman.cf

更改cgi目录的属主属组:

[root@localhost /var/www/extsuite/extman]# chown -R postfix.postfix /var/www/extsuite/extman/cgi/
[root@localhost /var/www/extsuite/extman]# chown -R postfix.postfix /var/www/extsuite/extmail/cgi/

导入数据库:

由于数据库不能识别TYPE=MyISAM,所以这里直接导入会出错,需要先编辑extmail.sql数据库文件,将文件中的TYPE=MyISAM更改为ENGINE=MyISAM,共有五处修改:

[root@localhost /var/www/extsuite/extman]# vim docs/extmail.sql
:% s/TYPE/ENGINE/g

我这里导入数据的时候发生了一个错误,提示找不到mysql.sock文件:

[root@localhost /var/www/extsuite/extman]# mysql -uroot < docs/extmail.sql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
[root@localhost /var/www/extsuite/extman]# ls /var/lib/mysql/mysql.sock
ls: 无法访问/var/lib/mysql/mysql.sock: 没有那个文件或目录

解决:然后我去查看了一下/etc/my.cnf文件,发现没问题,socket参数指向的也是 /var/lib/mysql/mysql.sock 这个路径,于是我就重启了mysql服务,然后再尝试就没有报找不到mysql.sock文件的错误了,但是报了另一个错误:

[root@localhost /var/www/extsuite/extman]# mysql -uroot < docs/extmail.sql
ERROR 1364 (HY000) at line 31: Field 'ssl_cipher' doesn't have a default value
[root@localhost /var/www/extsuite/extman]# 

这错误的意思是:字段 ‘ssl密码’ 没有默认值

于是又得去查看一下/etc/my.cnf文件,然后把sql_mode参数给注释掉:

未分类

接着重启mysql服务后,继续导入数据,这次就没问题了:

[root@localhost /var/www/extsuite/extman]# !service
service mysqld restart
Redirecting to /bin/systemctl restart  mysqld.service
[root@localhost /var/www/extsuite/extman]# mysql -uroot < docs/extmail.sql
[root@localhost /var/www/extsuite/extman]# mysql -uroot < docs/init.sql

导入数据成功后再次修改/etc/my.cnf文件,把刚刚注释的那行给去掉注释,不去掉的话,mysql服务可能会出现不能启动的问题:

未分类

数据导入成功后,登录mysql,创建一个mysql数据库用户extmail并授予权限:

[root@localhost /var/www/extsuite/extman]# mysql -uroot
mysql> GRANT ALL ON extmail.* to extmail@'%' identified by 'extmail';      //我这里是直接授予全部权限在任意的IP地址上了,实际情况根据需求而定
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql>

复制之前提到的配置文件:

[root@localhost ~]# cd /var/www/extsuite/extman/docs/
[root@localhost /var/www/extsuite/extman/docs]# cp mysql_virtual_* /etc/postfix/

为extman创建临时目录:

[root@localhost /var/www/extsuite/extman/docs]# mkdir /tmp/extman
[root@localhost /var/www/extsuite/extman/docs]# chown -R postfix.postfix /tmp/extman/

启动postfix、dovecot、saslauthd服务,并查看进程是否正常:

[root@localhost /var/www/extsuite/extman]# service postfix start
Starting postfix (via systemctl):                          [  确定  ]
[root@localhost /var/www/extsuite/extman]# ps aux |grep postfix
root      63586  0.0  0.1  95392  2160 ?        Ss   01:29   0:00 /usr/libexec/postfix/master -w
postfix   63587  0.0  0.2  95448  3808 ?        S    01:29   0:00 pickup -l -t unix -u
postfix   63588  0.0  0.2  95496  3816 ?        S    01:29   0:00 qmgr -l -t unix -u
root      63592  0.0  0.0 112680   976 pts/0    S+   01:33   0:00 grep --color=auto postfix
[root@localhost /var/www/extsuite/extman]#  ss -tnluo | grep :25
tcp    LISTEN     0      100       *:25                    *:*             
[root@localhost /var/www/extsuite/extman]# service dovecot start
Redirecting to /bin/systemctl start  dovecot.service
[root@localhost /var/www/extsuite/extman]# ps aux |grep dovecot
root      63834  0.3  0.0  15652  1484 ?        Ss   02:15   0:00 /usr/sbin/dovecot -F
dovecot   63837  0.0  0.0   9320  1012 ?        S    02:15   0:00 dovecot/anvil
root      63838  0.0  0.0   9448  1164 ?        S    02:15   0:00 dovecot/log
root      63840  0.0  0.1  12464  2196 ?        S    02:15   0:00 dovecot/config
root      63842  0.0  0.0 112680   972 pts/0    S+   02:15   0:00 grep --color=auto dovecot    
[root@localhost /var/www/extsuite/extman]# systemctl start saslauthd
[root@localhost /var/www/extsuite/extman]# ps aux |grep saslauthd
root      63131  0.0  0.0  69648   916 ?        Ss   01:19   0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam
root      63132  0.0  0.0  69648   676 ?        S    01:19   0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam
root      63133  0.0  0.0  69648   676 ?        S    01:19   0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam
root      63134  0.0  0.0  69648   676 ?        S    01:19   0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam
root      63135  0.0  0.0  69648   676 ?        S    01:19   0:00 /usr/sbin/saslauthd -m /run/saslauthd -a pam
root      63144  0.0  0.0 112680   972 pts/0    S+   01:20   0:00 grep --color=auto saslauthd
[root@localhost /var/www/extsuite/extman]# ps aux |grep courier-authlib
root      61661  0.0  0.0   4316   444 ?        S    00:07   0:00 /usr/local/courier-authlib/sbin/courierlogger -pid=/usr/local/courier-authlib/var/spool/authdaemon/pid -start /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      61662  0.0  0.0  35512  1796 ?        S    00:07   0:00 /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      61663  0.0  0.0  35512   468 ?        S    00:07   0:00 /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      61664  0.0  0.0  35512   468 ?        S    00:07   0:00 /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      61665  0.0  0.0  35512   468 ?        S    00:07   0:00 /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      61666  0.0  0.0  35512   468 ?        S    00:07   0:00 /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      61667  0.0  0.0  35512   468 ?        S    00:07   0:00 /usr/local/courier-authlib/libexec/courier-authlib/authdaemond
root      63660  0.0  0.0 112680   980 pts/0    S+   02:00   0:00 grep --color=auto courier-authlib

7. 测试

测试虚拟用户:

[root@localhost courier-authlib-0.66.2]# /usr/local/courier-authlib/sbin/authtest -s login [email protected] extmail
Authentication succeeded.                //显示这个表示成功,测试时使用的是[email protected],因为我们导入的数据库init.sql里面自带了这个。
Authenticated: [email protected]  (uid 2525, gid 2525)
Home Directory: /var/mailbox/extmail.org/postmaster  //这里需要注意/var/mailbox这个目录现在我们还没有创建,后面web访问的时候如果没有会报错,所以提前创建。
                    Maildir: /var/mailbox/extmail.org/postmaster/Maildir/
                    Quota: (none)
            Encrypted Password: $1$phz1mRrj$3ok6BjeaoJYWDBsEPZb5C0
                Cleartext Password: extmail
                    Options: (none)
[root@localhost courier-authlib-0.66.2]# mkdir /var/mailbox
[root@localhost courier-authlib-0.66.2]# chown -R postfix.postfix /var/mailbox/

测试smtp发信:

[root@localhost ~]# printf   "[email protected]" | openssl base64
cG9zdG1hc3RlckBleHRtYWlsLm9yZw==
[root@localhost ~]#  printf   "extmail" | openssl base64
ZXh0bWFpbA==
[root@localhost ~]# telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.daen.com ESMTP Postfix
auth login
334 VXNlcm5hbWU6
cG9zdG1hc3RlckBleHRtYWlsLm9yZw==
334 UGFzc3dvcmQ6
ZXh0bWFpbA==
235 2.7.0 Authentication successful     //成功
quit
221 2.0.0 Bye
Connection closed by foreign host.

8. 启动nginx实现web访问

nginx本身并不能解析cgi,extmail自带了解析cgi的程序,但是有些地方需要修改下:

[root@localhost ~]# vim /var/www/extsuite/extmail/dispatch-init
SU_UID=postfix
SU_GID=postfix

启动dispatch-init:

[root@localhost ~]# /var/www/extsuite/extmail/dispatch-init start
Starting extmail FCGI server...
[root@localhost ~]# /var/www/extsuite/extman/daemon/cmdserver -v -d 
loaded ok

添加nginx虚拟主机:

vim /etc/nginx/conf.d/extmail.conf

文件内容如下:

server {
   listen       8080;
   server_name  mail.everyoo.com;
   index index.html index.htm index.php index.cgi;
   root  /var/www/extsuite/extmail/html/;
   location /extmail/cgi/ {
             fastcgi_pass          127.0.0.1:8888;
             fastcgi_index         index.cgi;
             fastcgi_param  SCRIPT_FILENAME   /var/www/extsuite/extmail/cgi/$fastcgi_script_name;
             include               fcgi.conf;
        }
        location  /extmail/  {
             alias  /var/www/extsuite/extmail/html/;
        }
        location /extman/cgi/ {
             fastcgi_pass          127.0.0.1:8888;
             fastcgi_index         index.cgi;
             fastcgi_param  SCRIPT_FILENAME   /var/www/extsuite/extman/cgi/$fastcgi_script_name;
             include            fcgi.conf;
        }
        location /extman/ {
             alias  /var/www/extsuite/extman/html/;
        }
      access_log  /var/log/extmail_access.log;
}

创建fcgi.conf文件:

vim /etc/nginx/fcgi.conf

文件内容如下:

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

安装Unix::Syslog:

[root@localhost ~]# cd /usr/local/src/
[root@localhost /usr/local/src]# wget http://www.cpan.org/authors/id/M/MH/MHARNISCH/Unix-Syslog-1.1.tar.gz
[root@localhost /usr/local/src]# tar zxvf Unix-Syslog-1.1.tar.gz 
[root@localhost /usr/local/src]# cd Unix-Syslog-1.1
[root@localhost /usr/local/src/Unix-Syslog-1.1]# perl Makefile.PL
[root@localhost /usr/local/src/Unix-Syslog-1.1]# make && make install

启动nginx,并检查进程和监听端口是否正常:

[root@localhost ~]# service nginx start
Redirecting to /bin/systemctl start  nginx.service
[root@localhost ~]# ps aux |grep nginx
root      72338  0.0  0.1 122892  2296 ?        Ss   03:22   0:00 nginx: master process /usr/sbin/nginx
nginx     72339  0.0  0.1 123336  3192 ?        S    03:22   0:00 nginx: worker process
nginx     72340  0.0  0.1 123336  3192 ?        S    03:22   0:00 nginx: worker process
nginx     72341  0.0  0.1 123336  3192 ?        S    03:22   0:00 nginx: worker process
nginx     72342  0.0  0.1 123336  3192 ?        S    03:22   0:00 nginx: worker process
root      72344  0.0  0.0 112680   976 pts/0    S+   03:22   0:00 grep --color=auto nginx
[root@localhost ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:110             0.0.0.0:*               LISTEN      63834/dovecot       
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      63834/dovecot       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      72338/nginx: master 
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      72338/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1482/sshd           
tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      64100/dispatch.fcgi 
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      64328/master        
tcp6       0      0 :::3306                 :::*                    LISTEN      62442/mysqld        
tcp6       0      0 :::80                   :::*                    LISTEN      72338/nginx: master 
tcp6       0      0 :::22                   :::*                    LISTEN      1482/sshd           
[root@localhost ~]# 

然后到windows上访问你服务器IP的8080端口:

未分类

extman的登录账户为[email protected]密码为extmail123,首次使用需要先添加域,添加之后再修改域,改为可自由注册,再注册用户就可以登录发邮件了:

未分类

防火墙Firewalld 常用命令

运行、停止、禁用firewalld

启动:# systemctl start firewalld
查看状态:# systemctl status firewalld 或者 firewall-cmd –state
停止:# systemctl disable firewalld
禁用:# systemctl stop firewalld

配置firewalld

查看版本:$ firewall-cmd –version
查看帮助:$ firewall-cmd –help

查看设置:

显示状态:$ firewall-cmd –state
查看区域信息: $ firewall-cmd –get-active-zones
查看指定接口所属区域:$ firewall-cmd –get-zone-of-interface=eth0

拒绝所有包:# firewall-cmd –panic-on
取消拒绝状态:# firewall-cmd –panic-off
查看是否拒绝:$ firewall-cmd –query-panic
更新防火墙规则:# firewall-cmd –reload
# firewall-cmd –complete-reload
两者的区别就是第一个无需断开连接,就是firewalld特性之一动态添加规则,第二个需要断开连接,类似重启服务
将接口添加到区域,默认接口都在public

# firewall-cmd –zone=public –add-interface=eth0

永久生效再加上 –permanent 然后reload防火墙
设置默认接口区域

# firewall-cmd –set-default-zone=public

立即生效无需重启

打开端口(貌似这个才最常用)
查看所有打开的端口:

# firewall-cmd –zone=dmz –list-ports(service)

加入一个端口到区域:

# firewall-cmd –zone=dmz –add-port=8080/tcp

若要永久生效方法同上

# firewall-cmd –zone=work –add-service=smtp

移除服务

# firewall-cmd –zone=work –remove-service=smtp

cgroup限制进程内存大小

以限制mongodb的内存大小为例。
Cgroup限制方法:

mkdir /cgroup/memory/test/    
echo 50M > /cgroup/memory/test/memory.limit_in_bytes    
echo 50M > /cgroup/memory/test/memory.memsw.limit_in_bytes    
cgexec -g memory:test mongod -port 27017 --bind_ip 127.0.0.1 --dbpath /var/lib/mongo    

通过cgroup限制后,当内存达到限额,进程会被kill。

[root@centos mongo]# cgexec -g memory:test mongod -port 27017 --bind_ip 127.0.0.1 --dbpath /var/lib/mongo    
2014-07-18T23:20:53.228+0800 [initandlisten] MongoDB starting : pid=2529 port=27017 dbpath=/var/lib/mongo 64-bit host=centos    
2014-07-18T23:20:53.228+0800 [initandlisten] db version v2.6.3    
2014-07-18T23:20:53.228+0800 [initandlisten] git version: 255f67a66f9603c59380b2a389e386910bbb52cb    
2014-07-18T23:20:53.228+0800 [initandlisten] build info: Linux build12.nj1.10gen.cc 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 BOOST_LIB_VERSION=1_49    
2014-07-18T23:20:53.228+0800 [initandlisten] allocator: tcmalloc    
2014-07-18T23:20:53.228+0800 [initandlisten] options: { net: { bindIp: "127.0.0.1", port: 27017 }, storage: { dbPath: "/var/lib/mongo" } }    
2014-07-18T23:20:53.304+0800 [initandlisten] journal dir=/var/lib/mongo/journal    
2014-07-18T23:20:53.304+0800 [initandlisten] recover : no journal files present, no recovery needed    
2014-07-18T23:20:53.374+0800 [initandlisten] waiting for connections on port 27017    
2014-07-18T23:20:57.838+0800 [initandlisten] connection accepted from 127.0.0.1:36712 #1 (1 connection now open)    
2014-07-18T23:21:15.077+0800 [initandlisten] connection accepted from 127.0.0.1:36713 #2 (2 connections now open)    
2014-07-18T23:21:52.342+0800 [conn2] getmore test.my_collection cursorid:34538199491 ntoreturn:0 keyUpdates:0 numYields:39 locks(micros) r:121572 nreturned:95052 reslen:4194299 202ms    
2014-07-18T23:21:53.376+0800 [clientcursormon] mem (MB) res:136 virt:12809    
2014-07-18T23:21:53.376+0800 [clientcursormon]  mapped (incl journal view):12508    
2014-07-18T23:21:53.376+0800 [clientcursormon]  connections:2    
2014-07-18T23:21:56.790+0800 [conn2] getmore test.my_collection cursorid:34538199491 ntoreturn:0 keyUpdates:0 numYields:88 locks(micros) r:142113 nreturned:95595 reslen:4194301 244ms    
Killed    

数据查询脚本:

[root@centos data]# cat mongotestList.py    
import pymongo    
import time    

client = pymongo.MongoClient("localhost", 27017)    
db = client.test    
print db.name    
print db.my_collection    

for item in db.my_collection.find():    
    print item    

数据插入脚本:

[root@centos data]# cat mongotest2.py    
import pymongo    
import time    

client = pymongo.MongoClient("localhost", 27017)    
db = client.test    
print db.name    
print db.my_collection    

while True:    
    db.my_collection.save({time.ctime(): time.time()})   

lvs,nginx,haproxy的优缺点,适合场景

Nginx/LVS/HAProxy的基于Linux的开源免费的负载均衡软件。

LVS:使用集群技术和Linux操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性、可靠性和可管理性,是一款强大实用的开源软件。

LVS的优点:

1:抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,也保证了均衡器I/O的性能不会受到大流量的影响。;
2:lvs是专门的负载均衡软件,对任何应用都可以做负载均衡;
3:工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,目前用的比较多的是lvs+keepalived,比较大型的用的多的是lvs+heartbeat。

nginx的优点:

1:Nginx的高并发,同时能承载上万个并发连接;
2:nginx有充足的第三方功能模块的支持,主要通过upstream模块进行负载均衡;
3:nginx对网络的依赖较小,理论上只要Ping得通,网页访问正常,nginx就能连得通;
4:工作在网络的7层之上,可以针对http应用做一些分流的策略,它的正则规则比haproxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,nginx单凭这点可利用的场合就远多于lvs了。

nginx的缺点:

1:将Nginx当做反向代理时,负载均衡功能不是很好,对后端服务器的健康检查功能较弱;
2:nginx仅能支持http、https和email协议,这样就在适用范围上面小些,这个是它的缺点;
3:nginx只支持通过端口来检测,不支持通过url来检测。

haproxy的优点:

1:HAProxy的优点能够补充Nginx的一些缺点,比如支持Session的保持,Cookie的引导;同时支持通过获取指定的url来检测后端服务器的状态;
2:haproxy也是专门的负载均衡软件,Haproxy可以负载http,还可以负载均衡mysql;
3:HAProxy是支持虚拟主机的。

总结这么多,我觉得根据不同的需求,不同的功能,可以选择不同的软件类的负载均衡软件,当然也是可以选择硬件类的负载均衡器。
像对于大型的,需要进行高并发的网站或者对网络不太严格的时候,可以使用nginx;
对于大型的Web服务器的时候可以使用haproxy;
对性能有严格要求的时候可以使用lvs,就单纯从负载均衡的角度来说,lvs也许会成为主流,更适合现在大型的互联网公司。

Haproxy和pacemaker结合corosync实现负载均衡高可用,以及crm命令的使用

实验之前需要将之间做的负载均衡和高可用软件全部关掉!!!!!
server1和server9上安装Haproxy:
server1:

安装见上篇博文:
scp haproxy-1.6.11-1.x86_64.rpm 172.25.92.9:/root
scp /etc/haproxy/haproxy.cfg 172.25.92.9:/etc/haproxy
scp /etc/security/limits.conf 172.25.92.9:/etc/security
vim /etc/haproxy/haproxy.cfg 
     37         bind            172.25.92.100:80 name clear     #设置只有访问172.25.92.100才能访问集群资源
/etc/init.d/haproxy start

server9:

 rpm -ivh haproxy-1.6.11-1.x86_64.rpm 
  groupadd -g 200 haproxy
  useragdd -u 200 -g 200 haproxy
 useradd -u 200 -g 200 haproxy
  id haproxy
vim /etc/haproxy/haproxy.cfg
    37         bind            172.25.92.100:80 name clear
/etc/init.d/haproxy start

测试:打开后端服务器server2和server3:
server1和server9:curl 172.25.92.100
可以看到server3的hph页面。(之前搭建的)

server1和server9安装pacemaker和corosync:
其中corosync再之前做RHCS套件时已经安装,因为RHCS套件的高可用也时利用corosync实现心跳检测。
server1:

yum install -y pacemaker corosync
/etc/init.d/corosync start
[root@server1 ~]# cd /etc/corosync/
[root@server1 corosync]# cp corosync.conf.example corosync.conf
[root@server1 corosync]# vim corosync.conf
10                 bindnetaddr: 172.25.92.0
 11                 mcastaddr: 226.94.1.92
 12                 mcastport: 5405

 34 service{
 35         name:pacemaker
 36         ver:0
 37 }

[root@server1 corosync]# scp corosync.conf 172.25.92.9:/etc/corosync/

[root@server1 corosync]# /etc/init.d/corosync start
Starting Corosync Cluster Engine (corosync):               [  OK  ]
[root@server1 corosync]# tail -f /var/log/messages
#如果日志中有很多error,可能是因为多播地址或者端口冲突

#健康检测:
[root@server1 ~]# crm_verify -LV  发现没有fence设备报错

#安装crm管理工具:
[root@server1 ~]# yum install crmsh-1.2.6-0.rc2.2.1.x86_64.rpm pssh-2.3.1-2.1.x86_64.rpm


#配置禁掉fence功能
在主机上:/etc/fence_virtd stop
[root@server1 ~]# crm
crm(live)# configure 
crm(live)configure# property stonith-enabled=false
[root@server1 ~]# crm_verify -LV    #不报错

#关闭集群对节点数量的检查,集群默认最少量台主机,如果只是一台主机不能接管资源
crm(live)configure# property no-quorum-policy=ignore
crm(live)configure# commit

#添加资源,vip
crm(live)configure# primitive vip ocf:heartbeat:IPaddr2 params ip=172.25.92.100 cidr_netmask=24 op monitor interval=20s        #添加vip,并设置20s对资源监察一次,监控端可以发现vip资源添加上
crm(live)configure# commit

测试:在主机上访问:curl 172.25.92.100可以看见server3上的html页面。关掉其中一台corosnsc,vip会上到另一台主机上。

#添加资源haproxy:
crm(live)configure# primitive haproxy lsb:haproxy op monitor interval=30s
crm(live)configure# commit 

#添加haproxy后可以看出来vip和haproxy不再一台主机上,资源飘移:
#解决办法:建立资源组就可以解决
crm(live)configure# group westos vip haproxy
crm(live)configure# commit 

#添加资源fence:
添加fence之前首先开启主机上:systemctl start fence_virtd
yum install -y fence-virt.x86_64 fence-agents.x86_64 #两台主机上都做(server1和server9) ``!!!!! ``
crm(live)configure# property stonith-enabled=true  #开启fence功能
crm(live)configure# commit

[root@server1 ~]# stonith_admin -I   #查看主机支持fence的代理类型。本次使用fence_xvm
[root@server1 ~]# stonith_admin -M -a fence_xvm

crm(live)configure# primitive vmfence stonith:fence_xvm params  pcmk_host_map="server1:server1;server9:server9" op monitor interval=1min    #添加fence资源,并做好集群节点名和真实server的名字映射

#测试fence功能:
首先设置:corsync在两台主机上可其自启动:chkconfig corosync on
reboot(重启动)其中一台主机,等主机开启后会自动加到集群中!

#对集群 资源 的管理:
crm(live)resource# show        #显示资源种类,此处时只添加了一个资源vip,所以显示一个 
 vip    (ocf::heartbeat:IPaddr2):   Started #开启vip资源
crm(live)resource# stop vip
crm(live)resource# show
 vip    (ocf::heartbeat:IPaddr2):   Stopped  #停掉vip资源

#对集群 节点 的管理:
[root@server1 ~]# crm
crm(live)# node 
crm(live)node# standby     #停掉server1节点
crm(live)node# online      #开启sesrver1节点

server9:和server1是同步的,但此处作为监控

yum install -y pacemaker corosync
/etc/init.d/corosync start
#安装管理工具:
[root@server9 ~]# yum install pssh-2.3.1-2.1.x86_64.rpm crmsh-1.2.6-0.rc2.2.1.x86_64.rpm 
#监控集群:
[root@server9 ~]# crm_mon

haproxy TCP源端口耗尽问题

此文基本是翻译aloha的一篇文档,本人实际使用情况遇到的问题类似,但不是MySQL。

[2017.01.12 增补] 1.7版的haproxy开启了IP_BIND_ADDRESS_NO_PORT支持 ,即可以复用source port,这样可以从更基础的内核层面解决这个问题,唯一不足是需要将内核升级到4.2以上版本才可以。
参考:
http://www.haproxy.org/download/1.7/src/CHANGELOG
https://kernelnewbies.org/Linux_4.2#head-8ccffc90738ffcb0c20caa96bae6799694b8ba3a

环境描述

小公司,一个比较繁忙的PHP/MySQL构建的站点。
前端使用haproxy做负载均衡,后端web server连接MySQL数据库。
MySQL做了主从复制,前端PHP代码做了读写分离。
MySQL Master负责写入请求和一小部分读请求,MySQL Slave负责响应读请求。
另一个haproxy作为MySQL的反向代理。

拓扑图

未分类

问题描述

在请求很少的时候,工作得非常好。但当MySQL上的请求压力增大(2~3K次/秒)的时候,haproxy的本地端口耗尽。日志中报大量health check SOCKERR错误。

原因分析

haproxy作为反向代理,会使用自己的IP地址作为源地址连接后端的MySQL服务器。
根据TCP协议,无论任何类型操作系统都只能拥有64K个左右的源TCP端口,用于向外发起TCP连接。
一旦”srcIP:port => dstIP:port”建立,这个源端口将不能被重用于其它连接。
当前的MySQL Client Lib关闭连接时的操作序列如下:

Mysql Client ==> "QUIT" sequence ==> Mysql Server 
Mysql Client ==> FIN ==> MySQL Server 
Mysql Client <== FIN ACK <== MySQL Server 
Mysql Client ==> ACK ==> MySQL Server

这时候MySQL Client会进入2MSL状态,时间2分钟。
那么什么是2MSL状态呢?请看下图,这是关于TCP关闭连接时的握手序列:

未分类

上边TCP状态图中有一个TIME_WAIT状态,就是所谓的2MSL状态。
MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。
MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒。
因而,TIME_WAIT状态一般维持在1-4分钟。
该状态是为了可靠地实现TCP全双工连接的终止,保证在tcp客户端发给tcp服务端的最后一个ACK能顺利到达。
若没有TIME_WAIT状态,tcp客户端将直接进入CLOSED状态。
如果tcp客户端直接进入CLOSED状态,那么由于IP协议的不可靠性或者是其它网络原因,导致tcp服务端没有收到tcp客户端最后回复的ACK。那么tcp服务端就会在超时之后继续发送FIN,此时由于tcp客户端已经CLOSED了,就找不到与重发的FIN对应的连接,最后tcp服务端就会收到 RST而不是ACK,tcp服务端就会以为是连接错误把问题报告给高层协议。
这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。
所以,tcp客户端不是直接进入CLOSED状态,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

这里有2点需要强调一下:

1、对于tcp请求来说,tcp的客户端服务端概念和http的不同,请求双方,哪边关闭请求,哪边就是tcp客户端,另一边就为服务端。请不要与MySQL Client和MySQL Server混淆起来。
2、tcp的一个链接由4个值确定,源ip、源端口、目标ip、目标地址。

参考:http://omnitraining.net/networking-101/98-networking-101-understanding-tcp-part-2
“There is no way for the person who sent the first FIN to get an ACK back for that last ACK. You might want to reread that now. The person that initially closed the connection enters the TIME_WAIT state; in case the other person didn’t really get the ACK and thinks the connection is still open. Typically, this lasts one to two minutes.”

根据上述的论述,如果一个源端口在2分钟内不能再次使用,则超过534个/秒的MySQL Client请求将会耗尽其本地TCP源端口。
64000 (可用端口) / 120 (2分钟,即120秒) = 533.333.

因为haproxy作为反向代理,会将所有MySQL请求转发给MySQL Server,因此haproxy会比MySQL Client更快的耗尽本地TCP源端口!!

但是如果MySQL Client和MySQL Server在同一台主机上,使用looback接口通信,则MySQL关闭序列是一个相对”干净”的序列:

Mysql Client ==> "QUIT" sequence ==> Mysql Server
Mysql Client <== FIN <== MySQL Server 
Mysql Client ==> FIN ACK ==> MySQL Server 
Mysql Client <== ACK <== MySQL Server

但在非loopback接口上则不是!因此如果要解决这个问题,需要MySQL的开发者修改他们的代码……
那么是不是完全没有办法呢?也不是,请向下看。

解决方案

1、增加本地端口范围
对于单一的dstIP:port,可用的源端口默认是28K左右,可以用如下命令查看当前值:

[haproxy ~]# sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 61000

增加到64K个源端口

[haproxy ~]# vi /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1025 65000

2、允许处于TIME_WAIT状态的源端口重用

[haproxy ~]# vi /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

3、使用多个IP连接单一dstIP:port,并让haproxy来管理源端口
配置示例:

....
server mysql1     10.0.0.1:3306 check source 10.0.0.100:1025-65000
server mysql1_bis 10.0.0.1:3306 check source 10.0.0.101:1025-65000
....

经过测试,如果不让haproxy管理源端口,则4个源IP地址最多管理不超过80K个TIME_WAIT连接。
但是haproxy管理源端口可以达到170K+个TIME_WAIT连接!!!

4、使用memcached和MySQL persistant connections

参考文档:
http://blog.exceliance.fr/2012/12/12/haproxy-high-mysql-request-rate-and-tcp-source-port-exhaustion/
http://go12345.iteye.com/blog/1798119
http://ganquan.org/blog/2009/09/tcp协议的time_wait状态详解/
http://kerry.blog.51cto.com/172631/105233/

HAProxy概念、配置、生产实例

HAProxy实验环境准备

node1:扮演调度器(安装HAProxy),node2:扮演后台web服务器节点1(安装nginx),node3:扮演后台web服务器节点2(安装nginx)。有关虚拟机安装后常见操作请看上一篇文章。

先来一波,让HAProxy运行起来

先把需要的软件安装好:

node1 ]# yum install -y haproxy
node2 ]# yum install -y nginx
node3 ]# yum install -y nginx

把node2、node3的nginx服务启动起来,添加网页文件(后面可能会写一篇关于nginx的文章)。
对于node1,修改HAP的配置文件(生产环境中,修改配置文件前要先做好备份):

node1 ]# vim /etc/haproxy/haproxy.cfg
保留global段、defaults段,其他配置信息都删掉。添加以下配置:
listen NginxServers
        bind *:80
        balance static-rr
        server N1 node2:80
        server N2 node3:80
启动HAP服务:node1 ]# systemctl start haproxy.service

打开浏览器,访问node1节点80端口,刷新网页,可以看到HAP已经能够正常工作!并把HTTP请求按照轮询的方式调度给node2和node3节点的nginx服务。

未分类

未分类

HAProxy介绍

HAProxy,High Available Proxy,即高可用的代理服务器。要注意的是,这里的高可用不是指HAP服务自身实现了高可用,而是指HAP原生自带对后端服务器的健康状态检查机制,若发现某个BackEnd Server不可用,服务请求就不会再发往此后端节点。
HAP是一种软件实现的负载均衡器,因此它工作为用户空间的一个进程,基于套接字与客户端,后端主机进行通信。基于此,HAP能够很好地支持对HTTP请求的七层调度,对HTTP请求实现诸如“动静分离”,“HTTP方法分离”等。另外,HAP支持通过模拟方式实现四层调度,四层调度性能应该稍差。
总的来说,HAP是目前最主流的七层调度器实现方案之一,具有较好的性能以及配置多样性。

HAP配置详解

HAP将配置文件分为两大段。

  • Global段:用来定义进程安全相关配置,性能参数调整,Debug等服务相关的配置。

  • Proxy段:用来定义与调度的具体实现方式,Proxy段具体包括

    • listen段:listen可以直接确定一种调度工作方式
    • frontend段:定义与客户端通信的工作方式
    • backend段:定义与后端主机通信的工作方式
    • defaults段:定义listen,frontend,backend中某些变量的默认值

global:全局配置段常用变量

进程及安全配置相关参数:
       chroot  /var/lib/haproxy:禁锢根,haproxy进程以此目录作为根目录,防止haproxy进程被劫持而设定的安全性配置
       user  haproxy: 运行haproxy进程的用户和组
       group haproxy:
       daemon:表示haproxy运行于后台守护进程,而非前台(调试模式)
       nbproc <number>:指明要启动的haproxy进程数量; haproxy默认工作于基于事件驱动的单进程模型(也可以指明为启动多进程,官方并不建议)
       ulimit-n <number>:每个haproxy进程能够打开的最大文件数:此参数非常重要,因为每一个连接都需要打开一个socket file,因此该值至少大于进程数 * 每个进程接受的最大连接数。haproxy能够根据运行情况自行调整该值,一般不需要定义
       log:定义全局的syslog服务器,用于将haproxy产生的日志发往并存储
             log <address> <facility> [level]

好像现在HAP默认关闭了日志记录,要启用还挺麻烦,大家可以参考这篇文章作者的启用方式,测试有效!HAProxy启用日志

     性能调整相关参数
       maxconn 4000:单个haproxy进程所能接受的最大并发连接数
       maxpipes:使用pipe机制实现内核级tcp报文重组;每进程能够使用的最大pipe数量;haproxy能够自动调整
       spread-checks <0..50>:百分比数字,用于打散健康状态监测的时间点。例如每隔60秒对后端100台主机进行健康状态检查,此值设定为20表示,某台主机进行完一次检查后,下一次的检查时间可能是(48s,72s)内的任何一个时间,这样就打散了每台主机的检查时间,从而减轻了由于health-check带来的性能消耗
      Debug相关参数
        debug:详细输出日志信息(调试模式时)
        quiet:简化日志的输出信息

下面介绍Proxy段中的常用变量:这些变量可用于listen,frontend,backend中的一个或多个

1、bind:可用在listen,frontend;用于指明haproxy服务监听的套接字地址
   # bind <address>:<port_range>,....[param*]

e.g.    bind *:80 ssl, 192.168.1.7/24:8080 

表示haproxy监听于任意ipv4地址的80端口(外部访问),以及192.168.1.7:8080这一地址(内部访问),同时,并且受理外部请求时必须是https连接。      


2、balance:可用在listen,backend,default;用于指明对后端server使用的调度算法
     # balance <algo> [params]
              <algo>: 表示调度算法,常用的调度算法如下:
                roundrobin  [加权]轮询
                 动态算法,支持权重的运行时调整以及慢启动机制;最多4095个后端主机
                 慢启动:若共6000个连接,3台后端服务器,权重均相同,则每台处理2000个连接。此时新增一台服务器,那么应该每台处理1500个连接,所以大量的新连接都会给新增的那台,极易造成压力过大,慢启动则避免了这点
                static-rr    [加权]轮询
                 静态算法:不支持权重的运行时调整以及慢启动机制;后端主机无数量限制

                leastconn   最少连接
                推荐使用在较长时间会话场景中,如LDAP,MYSQL协议

                first    依次处理请求
                  每台后端主机可定义自己的maxconn。first算法根据maxconn的从大到小为后端主机排序,然后每次都将连接请求发给maxconn最大的那台主机,直到达到它的maxconn,才调度给下一台sever。
                  first算法的好处是能够节约虚拟机资源(backendserver一般是虚拟机实例),按需决定启动多少台虚拟机,坏处是配置麻烦,单台虚拟机处理太多连接压力过大。

               source  源地址hash ---> 会话绑定
               uri     目标地址hash ---> 提高缓存命中率

                    采用哈希调度算法时,NEW连接首次被调度至哪里可用hash-type命令由两种方式指定:
                    #  hash-type <method>
                              map-based  取模法
                              consistent    一致性哈希

                hdr(<name>)  
                      对于每个http请求,此处name指定的http报文首部会被取出做hash计算。然后再有相同的请求时,调度给同一台主机。source和uri是它最常用的hash调度子类
            e.g.   对于某个站点,可能由多个域名,如jd.com,www.jd.com,对于请求报文中不同Host,都始终调度给同一台backend_server       
                              balance  hdr(Host)
                              hash-type  map-based


3、log:用在default,frontend,backend,listen;定义日志的记录位置,做多定义两个位置。
        # log global || #  log <address> <facility> [level] || #  no log
        分别表示使用全局配置中的log记录位置或使用自定义的日志记录位置或不记录日志


4、capture request header;用在listen,frontend;用于添加指定请求报文首部信息记录于日志中
    # capture request header <name> len <length>
    e.g.  capture request header User-Agent len 10


5、capture response header ;用在listen,frontend;用于添加指定响应报文首部信息记录于日志中
    # capture response header <name> len <length>
e.g.  capture response header Cache-Control len 5


6、compression;用在listen,frontend,backend;用于压缩报文中的body部分
    # compression algo <algorithm>
    # compression type <mime type>
        支持的压缩algo:gzip,deflate
        mime type:通常只压缩文本类信息
e.g.   compression algo gzip 
         compression type  text/html
注意:compression用在frontend中表示压缩与客户端通信报文中的body,用在backend中则表示压缩与后端主机通信过程中报文的body


7、server:用于listen,backend;用来定义一个后端主机
    #  server <name> <addr:port> [params*]
        <name>:HAProxy中服务器的唯一标识,必给
        <addr:port>:后端主机监听的ip地址及端口
        [params*]:定义一个主机时同时可指定的可选参数
                backup:设定为备用服务器,仅在LB中其他服务器均不可用时才接受请求。类似于nginx-upstream定义主机时的down,用于维护时下线主机
                check:对后端主机作基于tcp端口的四层健康状态检测;check后可跟辅助参数,也可仅适用默认值
                            inter<delay>:每隔多久做一次检测
                            fall<count>:连续多少次失败从LB中移除该主机
                            rise<count>:连续多少次成功从LB中添加该主机
                maxconn:指定该服务器支持的最大连接数
                maxqueue:指定该服务器支持的最大等待队列长度
                cookie <name>:本台server的cookie信息,可任意指定
                redir <prefix>:将发往此服务器的所有GET,HEAD请求重定向至指定地址
                weight <weight>:指定权重


8、httpchk:用于listen,backend;基于7层http协议对后端主机进行状态检测
   # option httpchk  <uri>
e.g.   option httpchk  /login.html    


9、cookie:用于listen,backend;设定基于cookie的会话绑定       
    # cookie <name> [ insert | prefix | rewrite ] [params*]
            <name>:cookie标签的名字
            insert:插入某主机的cookie信息
            prefix:在cookie前添加信息
            rewrite:重写cookie
e.g.   cookie  WEBNODES insert  indirect nocache
         server node1 172.16.100.67:8100 check cookie node1
         server node1 172.16.100.67:8100 check cookie node1  
            随后,在HTTP请求报文中可以看到添加的cookie信息,并且一段时间内来自同一cip的请求被调度至了同一台server


10、mode:用在default,frontend,backend,listen;指明haproxy的工作模式
    # mode {tcp | http}
       http:后端LB集群为web server时,应设定mode为http模式,此时支持各种高级分析功能
       tcp:当后端LB集群为mysq等非基于http协议通信的服务时,应使haproxy工作于tcp模式,此时可调度mysql,ldap,ssh,ssl等协议的通信报文


11、forwardfor:在后端web server的日志文件中记录下CIP而非DIP()
 e.g.  option forwardfor  except  127.0.0.1/8
        同时修改后端httpd配置文件中的Logformat中 %h为  %{X-Forwarded-For}i


12、option http-keep-alive
        option http-server-close
前者表示启用与client端通信时的长连接功能,启用此功能时,一般需要同时启用后者,表示允许HAProxy关闭非活动状态的长连接。


13、rspadd <search>    haproxy在给client的响应报文中添加某自定义header;用于listen,backend中
        # rspdel <search>     haproxy在给client的响应报文中查找某hearder并删除
        # rspidel <search>    haproxy在给client的响应报文中基于正则表达式查找某hearder并删除
 e.g.   在响应报文中,一般我们不想让客户端知道后端real server的信息,可用以下指令完成
      rspidel  ^Server:.*     

若要实现复杂的调度能够,如“动静分离”,则需要定于ACL相关变量:

 1、 acl:用在frontend中,定义一条acl匹配规则 
# acl <aclname> <criterion> [flags] [operator] <value> ...
           criterion:acl匹配检查规则
                四层
                    dst IP  
                    dst_port PORT
                    src  IP
                    src_port  PORT
                七层
                    method <http_method>:指明http报文中的请求方法

                    path:URI精确匹配
                    path_beg:URI开头匹配
                    path_end:URI结尾匹配
                    path_reg:URI正则表达式匹配

                    url:URL精确匹配
                    url_beg:URL开头匹配
                    url_end:URL结尾匹配
                    url_end:URL正则表达式匹配

                    hdr <name><value>:请求报文中某个header值的精确匹配
                    hdr_beg <name><value>:请求报文中某个header值的开头匹配
                    hdr_end <name><value>:请求报文中某个header值的结尾匹配

          flags:   -i   表示匹配检查时忽略字符大小写

          value:匹配检查的对象


2、use_backend:用于frontend中,表示当满足某个acl时,调用指定的backend <name>
# use_backend <backend> [if | unless <acl_name>]



3、default_backend:用于frontend中,指明默认将请求调度给哪个backend <name>
# deault_backend <backend>



4、block:用于frontend中,符合acl规则时,阻止访问请求
# block if | unless <acl_name>

HAP生产配置环境案例

1、启用HAProxy内置管理页面

  listen stats  *:9001         定义访问管理页面的IP:PORT
      stats  enable                         启用此功能
      stats  uri  /haproxyadmin          定义访问的URI
      stats  realm  "ADMIN AREA"             页面提示信息,要求用户登录后访问
      stats  auth  admin:123456abc         设定登录用户的账号密码
      stats  admin  if TRUE             如果登录成功,在此页面开启管理接口权限(默认只能查看运行状态统计信息)

2、HAProxy实现模拟实现四层调度

  listen MySQLsrvs
      bind *:20002
      balance leastconn          使用最少连接调度算法
      mode tcp                   定义为四层调度
      server sqlnode1 172.16.100.67:3306 check
      server sqlnode2 172.16.100.68:3306 check

3、配置一个能够实现动静分离的调度服务器:

frontend dirctor
    bind *:80,*:8080
    acl picreq path_end -i .jpg .jepg .bmp
    acl phpreq path_end -i .php
    acl putreq method put
    acl stop src 222.222.222.0/24

    use_backend picsrvs if picreq
    use_backend phpsrvs if phpreq
    use_backend putnode if putreq
    default_backend stasrvs
    block if stop

backend picsrvs
    balance roundrobin
    server picnode1 172.16.100.67:8100 check weight 1 maxconn 2000
    server picnode2 172.16.100.77:8100 check weight 2 maxconn 2000

backend phpsrvs
    balance roundrobin
    cookie PHP insert indirect nocache
    server phpnode1 172.16.100.68:8100 check maxconn 300 cookie phpnode1
    server phpnode2 172.16.100.78:8100 check maxconn 300 cookie phpnode2

backend putnode
    balance static-rr
    server node 172.16.100.69:8100 check

backend stasrvs
    balance roundrobin
    server httpnode1 172.16.100.70:8100 check maxconn 2000 weight 1
    server httpnode2 172.16.100.80:8100 check maxconn 2000 weight 2