Nginx教程

nginx负载均衡

本文主要是介绍nginx负载均衡,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 常用的负载均衡
  • 负载均衡访问网站一场排错思路
  • nginx负载均衡模块
  • nginx反向代理模块
  • 要熟悉模块
  • 负载均衡企业实战应用

常用的负载均衡

# 硬件实现负载均衡
F5 硬件设备
A10硬件设备
#软件实现负载均衡
nginx(7层,19之后支持4层)
LVS(4层)
HAproxy(4层,7层)


负载均衡概念说明:1.对用户的访问请求进行调度管理 2.对用户的访问请求进行压力分担
反向代理概念说明:1.接受用户请求代替用户向后端访问 2.反向代理与数据转发概念区别说明
# 一、实现负载均衡的机器(10.0.0.5)
cd /etc/nginx/
cp nginx.conf{,.bak}
grep -Ev '^$|#' nginx.conf.bak > nginx.conf # 将 nginx.conf.bak文件中的空白行和以#开头的行过滤掉,把其它内容从定向到nginx.conf文件中
vim nginx.conf
user   www; # 用户最好统一  useradd www -u 1002 -s /sbin/nologin -M ,因为这个用户并不需要登录,所以这里创建的是一个虚拟用户

cd ./conf.d/ 

grep -Ev '^$|#' default.conf > lb.conf 

vim lb.conf
upstream clobotics {
    server 10.0.0.7:80; # 使用内网ip,这里使用的是外网,为了抓包;
    server 10.0.0.8:80;
    server 10.0.0.9:80;
}
server { # 默认再conf.d目录中的.conf文件的server区块被包含在http区块中
    listen       80;
    server_name  www.clobotics.com; # 访问www.clobotics.com网站的请求负载均衡到内网的其它主机
    location / {
        #root   /usr/share/nginx/html; 因为不是web服务器,所以不需要有家目录和主页文件index.html
        # index  index.html index.htm;
        proxy_pass http://clobotics; # 要与upstream中定义的名称一致,才能分配给upstream中定义的server中;
    }
}
vim /etc/hosts
10.0.0.7 www.clobotics.com
10.0.0.8 www.clobotics.com
10.0.0.9 www.clobotics.com

# 二、被负载的机器
# 10.0.0.7机器
for name in www bbs blog;do echo "$name 192.168.1.102">/html/$name/clobo.html;done
curl www.clobotics.com/clobo.html # 返回www 10.0.0.7
vim /etc/nginx/conf.d/web01.conf
server {
    listen       80;
    server_name  www.clobotics.com;
    location / {
        root   /html/www;
        index  index.html index.htm;
    }
}

vim /html/www/clobo.html
<h1>clobotics 10.0.0.7</h1>

vim /etc/hosts
10.0.0.7 www.clobotics.com

# 10.0.0.8机器
for name in www bbs blog;do echo "$name 10.0.0.8">/html/$name/clobo.html;done
curl www.clobotics.com/clobo.html # 返回www 10.0.0.8

vim /etc/nginx/conf.d/web01.conf
server {
    listen       80;
    server_name  www.clobotics.com;
    location / {
        root   /html/www;
        index  index.html index.htm;
    }
}

vim /html/www/clobo.html
<h1>clobotics 10.0.0.8</h1>

vim /etc/hosts
10.0.0.8 www.clobotics.com

# 10.0.0.9机器
for name in www bbs blog;do echo "$name 10.0.0.9">/html/$name/clobo.html;done
curl www.clobotics.com/clobo.html # 返回www 10.0.0.9

vim /etc/nginx/conf.d/web01.conf
server {
    listen       80;
    server_name  www.clobotics.com;
    location / {
        root   /html/www;
        index  index.html index.htm;
    }
}

vim /html/www/clobo.html
<h1>clobotics 10.0.0.9</h1>

vim /etc/hosts
10.0.0.9 www.clobotics.com

# 修改windows解析文件
10.0.0.5  www.clobotics.com blog.clobotics.com bbs.clobotics.com

# 3台被负载的机器nginx.conf配置
useradd www -u 1008 -s /sbin/nologin -M
vim /etc/nginx/nginx.conf
user www;
worker_processes 2;
error_log /var/log/nginx/error.log warn;
pid 	  /var/run/nginx.pid;
events {
	worker_connections 1024;
}
http {
	include	/etc/nginx/mime.types;
	default_type application/octet-stream;
	log_format main '$remote_addr - $remote_user [$time_local] "$request"'
				   '$status $body_bytes_sent "$http_referer"'
				   '"$http_user_agent" "$http_x_forwarded_for"';
	access_log /var/log/nginx/access.log main;
	sendfile on;
	#tcp_nopush on;
	keepalive_timeout 65;
	#gzip on;
	include /etc/nginx/conf.d/www.conf;
	# include /etc/nginx/conf.d/*.conf
}

systemctl start nginx # 10.0.0.5  10.0.0.7  10.0.0.8  10.0.0.9

# 测试:
在10.0.0.5机器: 
curl www.clobotics.com/clobo.html # 轮询被负载的7、8、9三台机器

在10.0.0.7机器: 
curl www.clobotics.com/clobo.html

在10.0.0.8机器: 
curl www.clobotics.com/clobo.html

在10.0.0.9机器: 
curl www.clobotics.com/clobo.html

在windows机器: 
curl www.clobotics.com/clobo.html

如果出现403 forbidden,可从以下几个方面查找原因:
	1.selinux是否被禁用,修改/etc/selinux/config,SELINUX=disabled,然后重启机器
	2.启动用户和nginx工作用户是否一致 ps aux | grep nginx:
		如果不一致,修改/etc/nginx/nginx.conf的user为启动用户;
	3.我们指定的web页面目录是否有index.html文件,或者我们访问具体的html文件是否有在此目录中;
	4.nginx的worker进程是否有访问web页面目录及其内部html文件的权限;
		chown -R user:user /dir
		

负载均衡访问网站一场排错思路

1.负载均衡 测试后端web节点服务器是否能够正常访问
curl -H host:www.clobotics.com 10.0.0.7/clobo.html
curl -H host:www.clobotics.com 10.0.0.8/clobo.html
curl -H host:www.clobotics.com 10.0.0.9/clobo.html
    
2.负载均衡 利用curl命令访问负载均衡服务器
查看两个配置文件,一个主配置文件nginx.conf,一个负载均衡的配置文件lb.conf
3.打开一个xshell连接  ping www.clobotics.com

4.配置文件编写不正确

nginx负载均衡模块

ngx_http_upstream_module  -- upstream
实现不同的调度功能
1.轮询分配请求(平均)
2.权重分配请求(能力越强责任越重)
vim /etc/nginx/conf.d/lb.conf
upstream clobotics {
        server 192.168.1.102:10572 weight=2;
        server 192.168.1.105:10572 weight=1;
}

3. 实现热备功能 # 如图1
upstream clobotics {
        server 192.168.1.102:10572;
        server 192.168.1.105:10572 backup; # 当其它被负载的机器服务进程不死掉,backup的这台机器就不会被负载均衡。
}

4.定义最大失败次数
max_fails=number

5.定义失败之后重发的间隔时间
fail_timeout=10s # 当10s时间到了的时候,会给失败的服务器一次机会(在这10s以内发给其它服务器),如果还不成,会再等10s再发,,,以此类推。

6. down # 这标志着服务器永远不可用,这个参数可配合ip_hash使用;类似注释效果。
upstream clobotics {
        server 192.168.1.102:10572 down; # 请求不再发往这个服务器,其实直接注释掉就行了,这里的down显得有些鸡肋
        server 192.168.1.105:10572;
}


实现不同调度算法:
1.rr 轮询
2.wrr 加权轮询
3.ip_hash 算法(静态调度算法, 出现反复登录的时候)
	在负载均衡的场景中,登录web页面时,始终登录不进去?用户输入用户名和密码,被nginx负载到不同的机器上,在做登录和认证时不再同一台机器,导致重复输入登录名和密码。这是由两种解决方案:
	(1)session会话:使用一台缓存服务器(memcached),在用户登录输入用户名和密码时,不论用户的访问请求被调度到哪一台负载的机器上,该机器都要从缓存服务器上认证该用户是否已经登录(已登录,保存session会话),如果已经登录,不用再次输入用户名和密码;
	(2)ip_hash:每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一个节点服务器,从而导致请求分配不均。LVS负载均衡的-p参数、keepalived配置的persistence_timeout 50参数都类似这个nginx里的ip_hash参数,其功能都可以解决动态网页的session共享问题。
	但是,ip_hash只识别公网地址,在中国的局域网内的无数台机器映射成一个公网地址,所以在私网内的用户都被负载到一台机器中,导致负载不均。
	upstream clobotics {
	    ip_hash;
        server 192.168.1.102:10572;
        server 192.168.1.105:10572;
}

upstream backend {
	ip_hash;
	server backend1.example.com;
	server backend2.example.com;
	server backend3.example.com down;
	server backend4.example.com;
}

注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能由weight和backup,即使有也不会生效。

4.fair(动态调度算法)
此算法会根据后端节点服务器的响应时间来分配请求,响应时间的优先分配。这是更加智能的调度算法。此种算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。nginx本身不支持fair调度算法,如果需要使用这种调度算法,必须下载nginx的相关模块upstream_fair.
示例:
upstream clobotics {
        server 192.168.1.102:10572;
        server 192.168.1.105:10572;
        fair;
}

5.least_conn
least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。

图1:

nginx反向代理模块

ngx_http_proxy_module  --proxy_pass
1.访问不同的网站地址,不能显示不同的网站页面

cat -n  /etc/nginx/nginx.conf  # 显示文本的行编号
sed -i "19s/include/#include/; 20s/#include/include/g" /etc/nginx/nginx.conf # 将19行注释掉,20行取消注释

curl -H host:www.clobotics.com 192.168.1.104/clobo.html
curl -H host:blog.clobotics.com 192.168.1.104/clobo.html # 应该是 blog 192.168.1.102  blog 192.168.1.105
curl -H host:bbs.clobotics.com 192.168.1.104/clobo.html  # # 应该是 bbs 192.168.1.102  bbs 192.168.1.105
但是,得到的返回值都是:
        '''
        www 192.168.1.102
        www 192.168.1.105
        '''
需要在server中添加此字段:# 如下图1
	proxy_set_header Host $host; # 表示将用户访问的负载均衡的Host改成用户的$host  如下图2

2.访问网站用户地址信息无法进行分析统计
proxy_set_header X-Forwarded-For $remote_addr;  # 需要与nginx.conf文件中定义日志的变量http_x_forwarded_for(表示获取http请求头你面的x_forwarded_for)保持一致

upstream clobotics {
        server 192.168.1.102;
        server 192.168.1.105;
}

server {
        listen 80;
        server_name www.clobotics.com;
        location / {
                proxy_pass http://clobotics;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;   # $remote_addr,可以在官方网站上查看变量,代表客户端IP,正常客户在浏览器访问我们站点负载均衡时的客户的公网IP。
        }
}

server {
        listen 80;
        server_name bbs.clobotics.com;
        location / {
                proxy_pass http://clobotics;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
        }
}

server {
        listen 80;
        server_name blog.clobotics.com;
        location / {
                proxy_pass http://clobotics;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
        }
    
systemctl restart nginx
tail -f /var/log/nginx/access.log # 如下图3
    
3.访问负载均衡会出现错误页面,影响用户体验
    比如:在定义的根目录下没有要寻找的.html文件,会报404错误
    可以使用 proxy_next_upstream 字段
    proxy_next_upstream error timeout http_404 http_502 http_403; # 当访问碰到这些错误时,会访问下一个正常的负载,从这个正常的负载中获得返回页面。
    
vim /etc/nginx/conf.d/lb.conf
    
upstream clobotics {
erver 192.168.1.102; 
server 192.168.1.105;
}

server {
	listen 80;
	server_name www.clobotics.com;
	location / {
		proxy_pass http://clobotics;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
}

server {
	listen 80;
	server_name bbs.clobotics.com;
	location / {
		proxy_pass http://clobotics;
		proxy_set_header Host $host;	
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
}

server {
	listen 80;
	server_name blog.clobotics.com;
	location / {
		proxy_pass http://clobotics;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
}

图1:

图2:

图3:

要熟悉模块

ngx_http_proxy_module
ngx_http_upstream_module
# 负载均衡反向代理根据请求地址分配
	1.静态请求资源
		(1)负载服务器端配置
			(1.1)配置upstream资源池
			(1.2)配置location /static/区块信息
		(2)web服务器端配置
			(1.1)创建static资源目录
			(1.2)资源目录中创建页面文件
	2.动态请求资源
		(1)负载服务器端配置
			(1.1)配置upstream资源池
			(1.2)配置location /upload/区块信息
		(2)web服务器端配置
			(1.1)创建upload资源目录
			(1.2)资源目录中创建页面文件
	3.默认请求资源
		(1)负载服务器端配置
			(1.1)配置upstream资源池
			(1.2)配置location /区块信息
		(2)web服务器端配置
			(1.1)创建默认资源目录
			(1.2)资源目录中创建页面文件

# 负载均衡反向代理根据访问软件分配
1.谷歌浏览资源
	(1)负载服务器端配置
		(1.1)配置upstream资源池
		(1.2)配置if ($http_user_agent ~* "Chrome")区块信息
2.火狐浏览资源
	(1)负载服务器端配置
		(1.1)配置upstream资源池
		(1.2)配置if ($http_user_agent ~* "Firefox")区块信息
3.手机浏览资源
	(1)负载服务器端配置
		(1.1)配置upstream资源池
		(1.2)配置if ($http_user_agent ~* "iphone")区块信息	
	

负载均衡企业实战应用

1.根据用户访问的uri信息进行负载均衡
第一个历程:架构环境规划
/upload	集群-10.0.0.8:80 html/www/upload	upload服务器集群  # web02
/static	集群-10.0.0.7:80 html/www/static	static服务器集群  # web01
/	    集群-10.0.0.9:80	html/www	# web03

web02上进行环境部署:
	mkdir /html/www/upload
	echo "upload-web集群_10.0.0.8" >/html/www/upload/clobo.html

web01上进行环境部署:
	mkdir /html/www/static
	echo "static-web集群_10.0.0.7" >/html/www/static/clobo.html

web03上进行环境部署:
	echo "default-web集群_10.0.0.9" >/html/www/clobo.html

第二个历程,编写负载均衡配置文件
# 负载均衡服务器 10.0.0.5
vim /etc/nginx/conf.d/lb.conf
upstream upload {
	server 10.0.0.8:80;
}
upstream static {
	server 10.0.0.7:80;
}
upstream default {
	server 10.0.0.9:80;
}

server {
	listen 80;
	server_name www.clobotics.com;
	location / {
		proxy_pass http://default;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
	location /upload {
		proxy_pass http://upload;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
	location /static { 
		proxy_pass http://static;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
}


# web03 10.0.0.8服务器
server {
	listen 80;
	server_name www.clobotics.com clobotics.com;
	access_log /var/log/nginx/www_access.log main;
	if ($host ~* "^clobotics.com$") {
		rewrite ^/(.*) http://www.clobotics.com/$1 permanent;
	}
	location / {
		root /html/www;
		index clobotics.html;
		#auth_basic	"clobotics-sz-01";
		#auth_basic_user_file password/htpasswd;
		#autoindex on;
		#charset utf-8;
	}
}

# web01 10.0.0.7服务器
server {
	listen 80;
	server_name www.clobotics.com clobotics.com;
	access_log /var/log/nginx/www_access.log main;
	if ($host ~* "^clobotics.com$") {
		rewrite ^/(.*) http://www.clobotics.com/$1 permanent;
	}
	location / {
		root /html/www;
		index clobotics.html;
		#auth_basic	"clobotics-sz-01";
		#auth_basic_user_file password/htpasswd;
		#autoindex on;
		#charset utf-8;
	}
}

# web03 10.0.0.9服务器
server {
	listen 80;
	server_name www.clobotics.com clobotics.com;
	access_log /var/log/nginx/www_access.log main;
	if ($host ~* "^clobotics.com$") {
		rewrite ^/(.*) http://www.clobotics.com/$1 permanent;
	}
	location / {
		root /html/www;
		index clobotics.html;
		#auth_basic	"clobotics-sz-01";
		#auth_basic_user_file password/htpasswd;
		#autoindex on;
		#charset utf-8;
	}
}

总结:实现网站集群动静分离
(1).提高网站服务安全性 有效防止了单一部署动态页面无法访问,静态资源页无法访问;
(2).管理操作工作简化,static和upload的机器只需要安装nginx即可,动态网页才需要安装对应项目的解释器
(3).可以换分不同人员管理不同集群服务器


2.根据用户访问的终端信息显示不同页面

iphone www.clobotics.com -- iphone_access 10.0.0.7:80 mobile移动端集群
谷歌  www.clobotics.com -- google_access 10.0.0.8:80 web端集群
IE 360 www.clobotics.com -- default_access 10.0.0.9:80 default端集群

编写负载均衡配置文件
vim /etc/nginx/conf.d/lb.conf
upstream mobile {
	server 10.0.0.7:80;
}
upstream google {
	server 10.0.0.8:80;
}
upstream default {
	server 10.0.0.9:80;
}

server {
	listen 80;
	server_name www.clobotics.com;
	location / {
		if ($http_User-Agent ~* iphone) {
			proxy_pass http://mobile;
		}
		if ($http_User-Agent ~* Chrome) {
			proxy_pass http://google;
		}
		proxy_pass http://default;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_next_upstream error timeout http_404 http_502 http_403;
	}
}
这篇关于nginx负载均衡的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!