为了安装NGINX,拼了
[TOC]
文章目录
前言 {#}
客户给我们了几台vps,主要是为了给我们的应用使用,目前我们的应用程序运行在A机和B机两台VPS上,使用了weblogic的集群,但是,有一个proxy应用安装在A机上,专门负责分发应用,这样的话,无形中增加了A机的负载,年初就因为这个事情,A机每天高峰期就宕机,我又拿了一台闲置的vps专门跑应用的计划任务,目前一共A,B,C三台vps在跑应用,最近开始关注这个事情,为什么不能使用nginx去做负载呢?我还有一台闲置的vps啊,我可以安装nginx专门做负载,转发流量给其他三台,这样A机就不会有负载问题了。
规划 {#}
一共四台VPS,A,B,C,D。
设计原则:
- 利用现有网络规划;
- 不调整现有主机和应用结构,减小生产环境的影响;
- 因为没有公网,所以必须使用源码编译安装;
A机和B机主要负责正常的负载均衡,C机做备用,D机跑NGINX做流量转发。客户端向D机发送请求,D机根据NGINX的轮询机制,转发给A机或者B机,C机可以设为backup,若A机和B机出现问题,负责所有请求。很简单的设计。
APR
为什么要安装apr?
因为D机只跑了nginx,也可以再运行一个tomcat作为backup,基于这种考虑,我想把apr安装好,使得tomcat以apr的运行模式工作。
安装步骤 {#}
1. 下载源码包 {#1}
到官网下载apr和apr-utils源码包,上传至D服务器。
1
2
apr-1.5.2.tar.gz
apr-util-1.5.4.tar.gz
2. 安装APR {#2apr}
远程至D机,以root身份安装,在编译之前,需要修改一下configure文件,否则编译会报错rm: cannot remove 'libtoolT': No such file or directory
。
解压文件,进入apr目录
1
2
tar -xvf apr-1.5.2.tar.gz
cd apr-1.5.2
vi编辑configure文件,查找$RM “$cfgfile”
,注释该句,我没数行数,但是那行就这么一句代码。
vi configure
# $RM "$cfgfile"
然后开始编码和安装
./configure
make && make install
3. 安装APR-UTIL {#3aprutil}
apr-util安装没有难度,按照标准程序执行。
tar -zxvf apr-util-1.5.4.tar.gz
cd apr-util-1.5.4
./configure --with-apr=/usr/local/apr
make && make install
给ld.so.conf.d
增加库文件查找路径
1
echo '/usr/local/apr/lib' > /etc/ld.so.conf.d/apr
openssl
我将openssl编译为了PIC[^1]的动态库。
1
2
3
4
tar xvf openssl-1.0.2l.tar.gz
cd openssl-1.0.2l
./config --prefix=/usr/local/openssl -fPIC
make && make install
编译完成之后,还需要将动态库路径增加到ld.so.conf
配置文件
1
echo '/usr/local/openssl/lib' > /etc/ld.so.conf.d/openssl
openssh
1. 为什么还要编译openssh? {#1openssh}
这是因为我们编译安装了openssl,会影响到openssh,所以需要重新编译安装openssh。
2. 安装之前 {#2}
强烈建议打开telnet服务,一旦openssh启动失败,如果你没有启用telnet,你就哭去吧。
建议提前下载系统镜像到目录,方便yum安装xinetd软件包。
mount -o loop -t iso9660 /home/rhel-server-6.4-x86_64-dvd.iso /mnt
修改yum.repos.d
目录下的cd.repo
文件
[CDROM]
name=isofile
baseurl=file:///mnt
enabled=1
gpgcheck=0
gpgkey=file:///mnt/RPM-GPG-KEY-redhat-release
之后yum安装所需软件包
yum install telnet-server xinetd
配置xinetd服务,使得telnet启动,编辑/etc/xinetd.d/telnet
# default: on
# description: The telnet server serves telnet sessions; it uses \
# unencrypted username/password pairs for authentication.
service telnet {
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
disable = no ##修改为no
}
启动服务
chkconfig xinetd on
service xinetd start
提示: 如果使用了iptables,请一并关闭。
3. 安装openssh {#3openssh}
因我之前已经编译安装了openssh7.3p1,所以仍然使用这个软件包。
1
2
cd openssh-7.3p1
make clean #清除之前编译产生的文件
编译参数
./configure \
--prefix=/usr \
--sysconfdir=/etc/ssh \
--with-ssl-dir=/usr/include/openssl \
--with-md5-passwords \
--with-pam \
--with-mantype=man \
--with-tcp-wrappers
安装
make && make install
4. 验证服务 {#4}
重启openssh验证是否可以启动服务
1
service sshd restart
5. Trouble shooting {#5troubleshooting}
服务无法启动,原则先看日志,检查启动的报错信息,根据报错信息处理。
一般来说,可能都是因为配置文件的问题导致的。
配置文件路径:/etc/ssh/sshd_config
zlib
zlib目前版本1.2.11,可以直接从官方网站下载即可。
1
2
3
4
tar xvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure --shared
make && make install
nginx
1. 安装 {#1}
安装nginx之前需要准备好pcre和zlib
1
2
3
tar xvf pcre-8.40.tar.gz
tar xvf zlib-1.2.11.tar.gz
tar xvf nginx-1.12.0.tar.gz
进入nginx目录,开始编译安装
1
2
3
4
5
6
7
8
9
10
11
cd nginx-1.12.0
./configure --build=nginx --with-poll_module --with-select_module --prefix=/usr/local/nginx \
--pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module \
--with-http_dav_module --with-http_flv_module --with-http_realip_module \
--with-http_gzip_static_module --with-http_stub_status_module --with-mail \
--with-mail_ssl_module --with-pcre=../pcre-8.40 --with-zlib=../zlib-1.2.11 \
--with-debug --http-client-body-temp-path=/var/tmp/nginx/client \
--http-proxy-temp-path=/var/tmp/nginx/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
--http-scgi-temp-path=/var/tmp/nginx/scgi --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/sbin
make && make install
nginx的配置文件路径在 /etc/nginx目录,执行脚本在/usr/sbin/目录,其他文件都在/usr/local/nginx。
2. 配置 {#2}
创建一个进程用户
1
useradd -M -s /sbin/nologin web
创建日志目录
1
2
3
mkdir /var/log/nginx
chown -R web.web /var/log/nginx
ln -s /var/log/nginx /etc/nginx/logs
修改配置文件
1
vi /etc/nginx/nginx.conf
配置参数参见此文
3. 开机服务 {#3}
在/etc/init.d目录新建nginx文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/bin/bash
# nginx This shell script takes care of starting and stopping
# nginx
#
# chkconfig: - 13 68
# description: nginx is a web server
### BEGIN INIT INFO
# Provides: $named
# Short-Description: start|stop|status|restart|configtest
### END INIT INFO
#variables
NGINX_BIN="/usr/sbin/nginx"
NGINX_CONF="/etc/nginx/nginx.conf"
NGINX_PID="/var/run/nginx.pid"
NETSTAT="/bin/netstat"
alter=$1
prog=nginx
#load system function
. /etc/rc.d/init.d/functions
#function:echo ok or error
function if_no {
if [ $2 == 0 ]; then
echo -n $"$1 ${prog}:" && success && echo
else
echo -n $"$1 ${prog}:" && failure && echo
fi
}
#start nginx
function start {
if [ -s ${NGINX_PID} ]; then
echo "nginx already running"
else
if [ `${NETSTAT} -tnpl | grep nginx | wc -l` -eq 0 ]; then
rm -f ${NGINX_PID} 2>/dev/null
${NGINX_BIN} -c ${NGINX_CONF}
if_no start $?
else
${NETSTAT} -tnpl | grep nginx | awk '{ print $7}' | cut -d '/' -f 1 > ${NGINX_PID}
if_no start $?
fi
fi
}
#stp nginx
function stop {
if [ -s ${NGINX_PID} ]; then
cat ${NGINX_PID} | xargs kill -QUIT
if_no stop $?
else
if [ `${NETSTAT} -tnpl | grep nginx | wc -l` -eq 0 ]; then
rm -f ${NGINX_PID} 2>/dev/null
if_no stop 0
else
rm -f ${NGINX_PID} 2>/dev/null
kill `${NETSTAT} -tnpl | grep nginx | awk '{ print $7}' | cut -d '/' -f 1`
if_no stop $?
fi
fi
}
function restart {
if [ -s ${NGINX_PID} ]; then
cat ${NGINX_PID} | xargs kill -HUP
if_no restart $?
else
stop
sleep 1
start
fi
}
function status {
${NETSTAT} -tnpl | grep nginx | grep LISTEN
[ $? == 0 ] && echo "nginx is running" || echo "nginx is not running"
}
function configtest {
${NGINX_BIN} -t
}
case $alter in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
configtest)
configtest
;;
*)
echo "use:${NGINX} {start|stop|restart|status|configtest}"
;;
esac
给于权限和开机执行
1
2
3
4
chmod a+x /etc/init.d/nginx
chkconfig --add nginx
chkconfig nginx on
service nginx start
4. 验证服务 {#4}
访问IP,应该显示nginx的欢迎页面
5. 配置负载 {#5}
5.1 内置负载策略 {#51}
Nginx负载均衡是通过upstream模块来实现的,内置实现了三种负载策略,配置还是比较简单的。官网负载均衡配置说明:http://nginx.org/en/docs/http/load_balancing.html
轮循(默认)
Nginx根据请求次数,将每个请求均匀分配到每台服务器
最少连接
将请求分配给连接数最少的服务器。Nginx会统计哪些服务器的连接数最少。
IP Hash
绑定处理请求的服务器。第一次请求时,根据该客户端的IP算出一个HASH值,将请求分配到集群中的某一台服务器上。后面该客户端的所有请求,都将通过HASH算法,找到之前处理这台客户端请求的服务器,然后将请求交给它来处理。
5.2 配置 {#52}
参考了别人的配置文件[^2],配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http {
# ... 省略其它配置
upstream tomcats {
server A机IP:7010;
server B机IP:7010;
server C机IP:8080 backup;
}
server {
listen 80;
location / {
proxy_pass http://tomcats;
}
}
# ... 省略其它配置
}
补充后续事宜 {#}
周一上班后,我测试了一下,发现在会话的保存上存在问题,而且不能存在混合状态的主机。比如我的A机和B机是WEBLOGIC集群,C机又是tomcat,无法做负载。后来我修改了一下配置文件,
1
2
3
4
5
upstream tomcats {
iphash;
server A机IP:7010;
server B机IP:7010;
}
是可以做负载了,但是我登录系统以后,我发现我的应用的各种报表和功能菜单,点击后要么还是无故返回未登录状态,要么就是一直持续加载中。看来nginx负载均衡weblogic集群的方案还是不可行。
于是,我又求助于oracle官方站点,发现一篇文章是将apache作为前端web服务器负载均衡weblogic,弄了半天weblogic给Apache做了module,只要有那个module,Apache也可以作为负载均衡的前端。我这边安装的welogic版本是10.3.6.0,于是我在weblogic的安装目录找了半天,也没发现这个组件,我就又去google找,终于找到了。
下载地址在这里:ORACLE Webtier
根据我的weblogic的版本号,我需要下载Oracle WebLogic Server Proxy Plugins 11gR1 (11.1.1.9)这个版本。
下载以后解压出来,然后从apache的配置文件中load这个模块。
1
2
[root@tasdb2 conf.d]# cat /etc/httpd/conf.d/mod_wl.conf
LoadModule weblogic_module /u01/wlsplugin/lib/mod_wl.so
然后新建一个虚拟主机,可以使用下面的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<VirtualHost 135.149.80.36:80>
#WLSRequest On
SetHandler weblogic-handler
WebLogicCluster 135.149.80.33:7010,135.149.80.34:7010
MatchExpression *.jsp
#WLLogFile /var/log/httpd/wlproxy.log
<ifmodule mod_deflate.c>
DeflateCompressionLevel 9
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/plain text/xml
AddOutputFilterByType DEFLATE application/javscript
AddOutputFilterByType DEFLATE text/css
</ifmodule>
</VirtualHost>
注意一下配置文件里面的WebLogicCluster
,我用的是weblogic集群,所以这里这样配置,然后为了性能,我还打开了gzip压缩模块。
重启apache,然后我又测试了一次所有的菜单和报表,OK,全部都可以正常使用。终于,搞定了。
位置无关代码(Position Independent Code,PIC) ↩