Nginx搭建与负载均衡测试

Nginx简介

Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用 nginx 网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

Nginx 是由俄罗斯人 Igor Sysoev 采用 C 语言开发编写的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

Igor Sysoev 出生于 1970 年的阿拉木图(哈萨克斯坦共和国城市),也就是前苏联。1991年苏联解体,哈萨克斯坦宣布独立,Nginx 作者 1994 年毕业于莫斯科国立鲍曼技术大学; 毕业后继续在莫斯科工作和生活,就职于 NGINX,Inc,任 CTO。https://www.nginx.com/

正向代理和反向代理概念

正向代理类似一个跳板机,代理访问外部资源。比如:我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器,它能访问那个我不能访问的网站,于是我先连上代理服务器,告诉它我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。

反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

Nginx 主要应用

静态网站部署

Nginx 是一个 HTTP 的web 服务器,可以将服务器上的静态文件(如 HTML、图片等) 通过 HTTP 协议返回给浏览器客户端。

负载均衡

在网站创立初期,我们一般都使用单台机器对外提供集中式服务。随着业务量的增大, 我们一台服务器不够用,此时就会把多台机器组成一个集群对外提供服务,但是,我们网站对外提供的访问入口通常只有一个,比如 www.web.com。那么当用户在浏览器输入www.web.com 进行访问的时候,如何将用户的请求分发到集群中不同的机器上呢,这就是负载均衡要做的事情。

负载均衡通常是指将请求”均匀”分摊到集群中多个服务器节点上执行,这里的均匀是指在一个比较大的统计范围内是基本均匀的,并不是完全均匀

常用的负载均衡策略:轮询、权重、备机等。

静态代理

把所有静态资源的访问改为访问 nginx,而不是访问 tomcat,这种方式叫静态代理。因为 nginx 更擅长于静态资源的处理,性能更好,效率更高。

所以在实际应用中,我们将静态资源比如图片、css、html、js 等交给 nginx 处理,而不是由 tomcat 处理。

动静分离

Nginx 的负载均衡和静态代理结合在一起,我们可以实现动静分离,这是实际应用中常见的一种场景。

  • 动态资源,如jsp 由 tomcat 或其他web 服务器完成
  • 静态资源,如图片、css、js 等由 nginx 服务器完成

它们各司其职,专注于做自己擅长的事情,动静分离充分利用了它们各自的优势,从而达到更高效合理的架构。

Nginx 安装以及相关命令

1.在主节点上运行yum,安装相关依赖包

1
sudo yum -y install openssl openssl-devel pcre pcre-devel zlib zlib-devel gcc gcc-c++

2.将资料/工具下的 nginx-1.12.2.tar.gz 上传到/opt/software 下

1
2
3
(base) [dw@hadoop116 software]$ ls
Azkaban hadoop jdk-8u212-linux-x64.tar.gz kylin nginx-1.12.2.tar.gz spark superset
flume hive kafka mysql presto sqoop zookeeper

3.在/opt/module/software 下解压缩 nginx-1.12.2.tar.gz 包

1
2
3
4
(base) [dw@hadoop116 nginx-1.12.2]$ pwd
/opt/software/nginx-1.12.2
(base) [dw@hadoop116 nginx-1.12.2]$ ./configure --prefix=/opt/module/nginx
# prefix=安装目录

4.编译和安装

1
(base) [dw@hadoop116 nginx-1.12.2]$ make & make install

5.查看

1
2
3
4
5
6
7
(base) [dw@hadoop116 module]$ ls
applog db_log gmall-flink hbase hive kafka miniconda3 presto spark test.txt
azkaban flume hadoop-3.1.3 history.txt jdk1.8.0_212 kylin nginx rt_applog sqoop zookeeper-3.5.7
(base) [dw@hadoop116 nginx]$ pwd
/opt/module/nginx
(base) [dw@hadoop116 nginx]$ ls
conf html logs sbin

nginx默认端口号是80,在linux里非root用户无权限访问1024以下的端口。

1
2
(base) [dw@hadoop116 nginx]$ sbin/nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

解决:让当前用户的某个应用也可以使用 1024 以下的端口

1
sudo setcap cap_net_bind_service=+eip /opt/module/nginx/sbin/nginx

注意:要根据自己的实际路径进行配置

这里可能会出现端口早已经被使用的报错,这是因为centos默认安装了apache服务,启动了httpd服务占用了80端口,这里需要禁用掉:(注意,要查看占用端口进程,有些进程非root用户查看不到,就会显示端口占用的进程为”-“)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(base) [dw@hadoop116 sbin]$ sudo netstat -anp | grep 80
tcp 0 48 192.168.10.116:22 192.168.10.1:55515 ESTABLISHED 1580/sshd: dw [priv
tcp 0 0 192.168.10.116:10050 192.168.10.116:58180 TIME_WAIT -
tcp 0 0 192.168.10.116:10050 192.168.10.116:58280 TIME_WAIT -
tcp6 0 0 :::80 :::* LISTEN 7519/httpd
udp6 0 0 fe80::20c:29ff:fe7d:123 :::* 729/ntpd
unix 3 [ ] STREAM CONNECTED 20152 1580/sshd: dw [priv
unix 3 [ ] STREAM CONNECTED 20080 1547/zabbix_server: /var/run/zabbix/zabbix_server_lld.sock
unix 2 [ ] DGRAM 20148 1580/sshd: dw [priv
unix 3 [ ] STREAM CONNECTED 18980 1320/master
(base) [dw@hadoop116 sbin]$ sudo systemctl stop httpd.service
(base) [dw@hadoop116 sbin]$ sudo netstat -anp | grep 80
tcp 0 48 192.168.10.116:22 192.168.10.1:55515 ESTABLISHED 1580/sshd: dw [priv
tcp 0 0 192.168.10.116:10050 192.168.10.116:58280 TIME_WAIT -
udp6 0 0 fe80::20c:29ff:fe7d:123 :::* 729/ntpd
unix 3 [ ] STREAM CONNECTED 20152 1580/sshd: dw [priv
unix 3 [ ] STREAM CONNECTED 20080 1547/zabbix_server: /var/run/zabbix/zabbix_server_lld.sock
unix 2 [ ] DGRAM 20148 1580/sshd: dw [priv
unix 3 [ ] STREAM CONNECTED 18980 1320/master

查看启动情况:

1
2
3
4
5
 ps -ef |grep nginx

(base) [dw@hadoop116 nginx]$ ps -ef | grep nginx | grep -v grep
dw 22143 1 0 18:07 ? 00:00:00 nginx: master process sbin/nginx
dw 22144 22143 0 18:07 ? 00:00:00 nginx: worker process

在浏览器中输入 http://hadoop102/访问

重启Nginx

1
./nginx	-s reload

关闭Nginx

1
./nginx	-s	stop

通过配置文件启动

1
2
3
./nginx -c /opt/module/nginx/conf/nginx.conf

/opt/module/nginx/sbin/nginx -c /opt/module/nginx/conf/nginx.conf

其中-c 是指定配置文件,而且配置文件路径必须指定绝对路径。

配置检查

当修改 Nginx 配置文件后,可以使用Nginx 命令进行配置文件语法检查,用于检查 Nginx 配置文件是否正确。

1
/opt/module /nginx/sbin/nginx -c /opt/module/nginx/conf/nginx.conf –t

如果 80 端口号被占用 httpd

1
2
sudo systemctl stop httpd
sudo systemctl disable httpd

配置负载均衡测试

模拟数据以后应该发给 nginx, 然后 nginx 再转发给我们的日志服务器,日志服务器我们会分别配置在 hadoop116,hadoop117,hadoop118 三台设备上。

  1. 打开 nginx 配置文件
1
2
(base) [dw@hadoop116 nginx]$ cd /opt/module/nginx/conf/
(base) [dw@hadoop116 conf]$ vim nginx.conf
  1. 修改如下配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
http {
# 启动省略
# 申明一个变量
upstream logcluster{
server hadoop116:8081 weight=1;
server hadoop117:8081 weight=1;
server hadoop118:8081 weight=1;
}
server {
listen 80;
server_name localhost; #charset koi8-r;
#access_log logs/host.access.log main;

location / {
#root html;
#index index.html index.htm;
# 代理的服务器集群 命名随意, 但是不能出现下划线
# 引用一个变量
proxy_pass http://logcluster;
proxy_connect_timeout 10;
}

# 其他省略
}

3.重启nginx

1
2
3
4
5
6
(base) [dw@hadoop116 nginx]$ sbin/nginx -s stop
(base) [dw@hadoop116 nginx]$ ps -ef | grep nginx | grep -v grep
(base) [dw@hadoop116 nginx]$ sbin/nginx
(base) [dw@hadoop116 nginx]$ ps -ef | grep nginx | grep -v grep
dw 45255 1 0 15:06 ? 00:00:00 nginx: master process sbin/nginx
dw 45256 45255 0 15:06 ? 00:00:00 nginx: worker process

由于其他节点的服务器logger还没启动,所以会报错。

启动logger,访问

1
2
3
4
5
6
7
8
9
10
(base) [dw@hadoop116 rt_applog]$ java -jar gmall-logger.jar

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.7.RELEASE)

4.测试nginx反向代理

目前两台服务器的logger还未启动,只有hadoop116的logger服务启动了,此时访问nginx的80端口,看是否能返回请求成功,若可以则代表nginx反向代理生效。

5.分发logger jar包

1
2
3
(base) [dw@hadoop116 rt_applog]$ sudo /home/dw/bin/xcall.sh mkdir -p /opt/module/gmall-flink/rt_applog

sudo /home/dw/bin/xsync gmall-logger.jar

6.启动kafka consumer

1
./bin/kafka-console-consumer.sh --bootstrap-server hadoop116:9092 --topic 

7.写一个群起脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#! /bin/bash
JAVA_BIN=/opt/module/jdk1.8.0_212/bin/java
APPNAME=gmall-logger.jar

case $1 in
"start")
{
for i in hadoop116 hadoop117 hadoop118
do
echo "========:$i========"
ssh $i "$JAVA_BIN -Xms32m -Xmx64m -jar /opt/module/gmall-flink/rt_applog/$APPNAME > /dev/null 2>1& &"
done
};;
"stop")
{
for i in hadoop116 hadoop117 hadoop118
do
echo "========:$i========"
ssh $i "ps -ef | grep $APPNAME | grep -v grep | awk '{print\$2}' | xargs kill" > /dev/null 2>&1
done
};;
esac

测试:

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
(base) [dw@hadoop116 rt_applog]$ rt_logger.sh start
========:hadoop116========
========:hadoop117========
========:hadoop118========
(base) [dw@hadoop116 rt_applog]$ xcall.sh jps
============= hadoop116 jps =============
17778 NodeManager
60035 gmall-logger.jar
52036 ConsoleConsumer
61861 Jps
17222 NameNode
20024 QuorumPeerMain
20504 Kafka
17407 DataNode
============= hadoop117 jps =============
14416 ResourceManager
17316 gmall-logger.jar
14533 NodeManager
17336 Jps
14235 DataNode
14955 QuorumPeerMain
17261 gmall-logger.jar
15343 Kafka
============= hadoop118 jps =============
10437 DataNode
11238 Kafka
10519 SecondaryNameNode
10855 QuorumPeerMain
13287 Jps
10635 NodeManager
13198 gmall-logger.jar

在启动mock生成业务日志前,先将路径修改成nginx的:

1
(base) [dw@hadoop116 rt_applog]$ java -jar gmall2020-mock-log-2020-12-18.jar

查看各服务器下日志大小是否是均衡的,来看nginx有没起到负载均衡的作用:

可以看到,日志大小相差不大,负载均衡起作用。