1.Nginx代理服务概述
代理我们往往并不陌生, 该服务我们常常用到如(代理租房、代理收货等等)
那么在互联网请求里面, 客户端无法直接向服务端发起请求, 那么就需要用到代理服务, 来实现客户端和服务通信
Nginx作为代理服务可以实现很多的协议代理, 我们主要以http代理为主
正向代理(内部上网) 客户端<–>代理->服务端
反向代理 客户端->代理<–>服务端
正向与反向代理的区别
区别在于代理的对象不一样
正向代理代理的对象是客户端
反向代理代理的对象是服务端
1.1Nginx反向代理配置语法
1.Nginx代理配置语法
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
http://localhost:8000/uri/
http://192.168.56.11:8000/uri/
http://unix:/tmp/backend.socket:/uri/
2.url跳转修改返回Location
Syntax: proxy_redirect default;
proxy_redirect off;proxy_redirect redirect replacement;
Default: proxy_redirect default;
Context: http, server, location
3.添加发往后端服务器的请求头信息, 如图
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
# 用户请求的时候HOST的值是www.bgx.com, 那么代理服务会像后端传递请求的还是www.bgx.com
proxy_set_header Host $http_host;
# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
# 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
4.代理到后端的TCP连接、响应、返回等超时时间, 如图
//nginx代理与后端服务器连接超时时间(代理连接超时)
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
//nginx代理等待后端服务器的响应时间
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
//后端服务器数据回传给nginx代理超时时间
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
5.proxy_buffer代理缓冲区, 如图
//nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
//设置nginx代理保存用户头信息的缓冲区大小
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location
//proxy_buffers 缓冲区
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
6.Proxy代理网站常用优化配置如下,将配置写入新文件,调用时使用include引用即可
[root@Nginx ~]# vim /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
7.代理配置location时调用, 方便后续多个Location重复使用
location / {
proxy_pass http://127.0.0.1:8080;
include proxy_params;
}
1.3Nginx反向代理配置场景
Nginx反向代理配置实例
1.环境准备
角色 | 外网IP(NAT) | 内网IP(LAN) | 主机名 |
---|---|---|---|
Proxy | eth0:10.0.0.5 | eth1:172.16.1.5 | lb01 |
web01 | eth0:10.0.0.7 | eth1:172.16.1.7 | web01 |
2.web01服务器, 配置一个网站,监听在8080,仅运行172网段能访问
[root@web01 ~]# cd /etc/nginx/conf.d/
[root@web01 conf.d]# vim web.conf
server {
listen 8080;
server_name 172.16.1.7;
location / {
root /code_8080;
index index.html;
deny 10.0.0.0/24;
allow all;
}
}
[root@web01 conf.d]# mkdir /code_8080
[root@web01 conf.d]# echo "web01-7...." >/code_8080/index.html
[root@web01 conf.d]# systemctl restart nginx
2.proxy代理服务器, 配置监听在80,让10.0.0.1客户端,能够通过代理访问到后端的172.16.1.7这个网站
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# cat proxy_web_node1.conf
server {
listen 80;
server_name nginx.gl.sh.cn;
location / {
proxy_pass http://172.16.1.7:8080;
include proxy_params;
}
}
[root@lb01 conf.d]# systemctl enable nginx
[root@lb01 conf.d]# systemctl start nginx
2.Nginx负载均衡
Web服务器,直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台WEB服务器组成集群,前端使用Nginx负载均衡,将请求分散的打到我们的后端服务器集群中,实现负载的分发。那么会大大提升系统的吞吐率、请求性能、高容灾
Nginx是一个典型的SLB(Server Load Balance)网络负载均衡器
2.1Nginx负载均衡按层划分
负载均衡按层划分应用场景: 四层负载均衡
负载均衡按层划分应用场景: 七层负载均衡, Nginx最常用
2.1Nginx负载均衡配置场景
Nginx实现负载均衡需要用到proxy_pass代理模块配置.
Nginx负载均衡是将客户端请求代理转发至一组upstream虚拟服务池
Nginx upstream虚拟配置语法
Syntax: upstream name { ... }
Default: -
Context: http
//upstream例子
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
0.环境规划
角色 | 外网IP(NAT) | 内网IP(LAN) | 主机名 |
---|---|---|---|
LB01 | eth0:10.0.0.5 | eth1:172.16.1.5 | lb01 |
web01 | eth0:10.0.0.7 | eth1:172.16.1.7 | web01 |
web02 | eth0:10.0.0.8 | eth1:172.16.1.8 | web02 |
1.Web01服务器上配置nginx, 并创建对应html文件
[root@web01 ~]# cd /etc/nginx/conf.d/
[root@web01 conf.d]# cat node.conf
server {
listen 80;
server_name node.gl.sh.cn;
location / {
root /node;
index index.html;
}
}
[root@web01 conf.d]# mkdir /node
[root@web01 conf.d]# echo "Web01..." > /node/index.html
[root@web01 conf.d]# systemctl restart nginx
2.Web02服务器上配置nginx, 并创建对应html文件
[root@web02 ~]# cd /etc/nginx/conf.d/
[root@web02 conf.d]# cat node.conf
server {
listen 80;
server_name node.gl.sh.cn;
location / {
root /node;
index index.html;
}
}
[root@web02 conf.d]# mkdir /node
[root@web02 conf.d]# echo "Web02..." > /node/index.html
[root@web02 conf.d]# systemctl restart nginx
3.配置Nginx负载均衡
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# cat node_proxy.conf
upstream node {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name node.gl.sh.cn;
location / {
proxy_pass http://node;
include proxy_params;
}
}
[root@lb01 conf.d]# systemctl restart nginx
4.准备Nginx负载均衡调度使用的proxy_params
[root@Nginx ~]# vim /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
5.使用浏览器访问node.oldboy.com, 然后不断刷新测试
2.2Nginx负载均衡后端状态
后端Web服务器在前端Nginx负载均衡调度中的状态
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后, 服务暂停时间 |
max_conns | 限制最大的接收连接数 |
1.测试down状态, 测试该Server不参与负载均衡的调度
upstream load_pass {
//不参与任何调度, 一般用于停机维护
server 10.0.0.7:80 down;
}
2.测试backup以及down状态
upstream load_pass {
server 10.0.0.7:80 down;
server 10.0.0.8:80 backup;
server 10.0.0.9:80 max_fails=1 fail_timeout=10s;
}
location / {
proxy_pass http://load_pass;
include proxy_params;
}
3.测试max_fails失败次数和fail_timeout多少时间内失败多少次则标记down
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80 max_fails=2 fail_timeout=10s;
}
4.测试max_conns最大TCP连接数
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80 max_conns=1;
}
2.3Nginx负载均衡调度算法
调度算法 | 概述 |
---|---|
轮询 | 按时间顺序逐一分配到不同的后端服务器(默认) |
weight | 加权轮询,weight值越大,分配到的访问几率越高 |
ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器 |
url_hash | 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器 |
least_conn | 最少链接数,那个机器链接数少就分发 |
1.Nginx负载均衡[wrr]轮询具体配置
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
2.Nginx负载均衡[weight]权重轮询具体配置
upstream load_pass {
server 10.0.0.7:80 weight=5;
server 10.0.0.8:80;
}
3.Nginx负载均衡ip_hash具体配置, 不能和weight一起使用。
//如果客户端都走相同代理, 会导致某一台服务器连接过多
upstream load_pass {
ip_hash;
server 10.0.0.7:80 weight=5;
server 10.0.0.8:80;
}
2.4Nginx负载均衡TCP实践
配置Nginx4层负载均衡实现如下需求
1.通过访问负载均衡的5555端口,实际是后端的web01的22端口在提供服务。
2.通过访问负载均衡的6666端口,实际是后端的mysql的3306端口在提供服务。
1.Nginx四层负载均衡配置语法
stream {
upstream backend {
hash $remote_addr consistent;
server backend1.example.com:12345 weight=5;
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
server {
listen 12345;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass backend;
}
}
2.Nginx四层负载均衡实战
[root@lb01 ~]# mkdir -p /etc/nginx/conf.c
[root@lb01 ~]# vim /etc/nginx/nginx.conf
# 在events层下面,http层上面配置include
include /etc/nginx/conf.c/*.conf;
# 编写四层代理配置
[root@lb01 ~]# cd /etc/nginx/conf.c/
[root@lb01 conf.c]# cat stream.conf
stream {
#1.定义虚拟资源池
upstream ssh {
server 172.16.1.7:22;
}
upstream mysql {
server 172.16.1.51:3306;
}
#2.调用虚拟资源池
server {
listen 5555;
proxy_connect_timeout 1s;
proxy_timeout 300s;
proxy_pass ssh;
}
server {
listen 6666;
proxy_connect_timeout 1s;
proxy_timeout 300s;
proxy_pass mysql;
}
}
[root@lb01 conf.c]# systemctl restart nginx
3.Nginx四层负载均衡应用场景
3.Nginx动静分离1
动静分离,通过中间件将动态请求和静态请求进行分离, 分离资源, 减少不必要的请求消耗, 减少请求延时。
好处: 动静分离后, 即使动态服务不可用, 但静态资源不会受到影响
通过中间件将动态请求和静态请求分离
3.1Nginx动静分离应用案例
0.环境准备
系统 | 服务 | 服务 | 地址 |
---|---|---|---|
CentOS7.5 | 负载均衡 | Nginx Proxy | 10.0.0.5 |
CentOS7.5 | 静态资源 | Nginx Static | 10.0.0.7 |
CentOS7.5 | 动态资源 | Tomcat Server | 10.0.0.8 |
1.在10.0.0.7服务器上配置静态资源
[root@web01 conf.d]# cat ds_gl.conf
server{
listen 80;
server_name ds.gl.sh.cn;
root /soft/code;
index index.html;
location ~* .*\.(png|jpg|gif)$ {
root /soft/code/images;
}
}
# 准备目录, 以及静态相关图片
[root@web01 ~]# mkdir /soft/code/images -p
[root@web01 ~]# wget -O /soft/code/images/nginx.png http://nginx.org/nginx.png
[root@web01 ~]# systemctl restart nginx
2.在10.0.0.8服务器上配置动态资源
[root@web01 ~]# yum install -y tomcat
[root@web01 ~]# systemctl start tomcat
[root@web01 ~]# mkdir /usr/share/tomcat/webapps/ROOT
[root@web01 ~]# vim /usr/share/tomcat/webapps/ROOT/java_test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<HTML>
<HEAD>
<TITLE>JSP Test Page</TITLE>
</HEAD>
<BODY>
<%
Random rand = new Random();
out.println("<h1>Random number:</h1>");
out.println(rand.nextInt(99)+100);
%>
</BODY>
</HTML>
3.在负载均衡10.0.0.5上配置调度, 实现访问jsp和png
root@lb01 conf.d]# cat ds_gl.conf
upstream static {
server 10.0.0.7:80;
}
upstream java {
server 10.0.0.8:8080;
}
server {
listen 80;
server_name ds.gl.sh.cn;
location / {
root /soft/code;
index index.html;
}
location ~ .*\.(png|jpg|gif)$ {
proxy_pass http://static;
include proxy_params;
}
location ~ .*\.jsp$ {
proxy_pass http://java;
include proxy_params;
}
}
[root@lb01 conf.d]# systemctl restart nginx
4.通过负载测试访问静态资源
5.通过负载测试访问动态资源
6.在负载均衡10.0.0.5上整合动态和静态资源的html文件
[root@lb01 ~]# mkdir /soft/code -p
[root@lb01 ~]# cat /soft/code/index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>测试ajax和跨域访问</title>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
</head>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
type: "GET",
url: "http://ds.gl.sh.cn/java_test.jsp",
success: function(data) {
$("#get_data").html(data)
},
error: function() {
alert("fail!!,请刷新再试!");
}
});
});
</script>
<body>
<h1>测试动静分离</h1>
<img src="http://ds.gl.sh.cn/nginx.png">
<div id="get_data"></div>
</body>
</html>
7.测试动态和静态资源是否能正常加载在一个html文件中
8.当使用systemctl stop nginx停止Nginx后, 会发现静态内容无法访问, 动态内容依旧运行正常
9.当使用systemctl stop tomcat停止tomcat后, 静态内容依旧能正常访问, 动态内容将不会被请求到
3.2Nginx手机电脑应用案例
2.根据不同的浏览器, 以及不同的手机, 访问的效果都将不一样。
//通过浏览器来分别连接不同的浏览器访问不同的效果。
http {
...
upstream firefox {
server 172.31.57.133:80;
}
upstream chrome {
server 172.31.57.133:8080;
}
upstream iphone {
server 172.31.57.134:8080;
}
upstream android {
server 172.31.57.134:8081;
}
upstream default {
server 172.31.57.134:80;
}
...
}
//server根据判断来访问不同的页面
server {
listen 80;
server_name blog.ct99.cn;
#safari浏览器访问的效果
location / {
if ($http_user_agent ~* "Safari"){
proxy_pass http://dynamic_pools;
}
#firefox浏览器访问效果
if ($http_user_agent ~* "Firefox"){
proxy_pass http://static_pools;
}
#chrome浏览器访问效果
if ($http_user_agent ~* "Chrome"){
proxy_pass http://chrome;
}
#iphone手机访问效果
if ($http_user_agent ~* "iphone"){
proxy_pass http://iphone;
}
#android手机访问效果
if ($http_user_agent ~* "android"){
proxy_pass http://and;
}
#其他浏览器访问默认规则
proxy_pass http://dynamic_pools;
include proxy.conf;
}
}
}
3.根据访问不同目录, 代理不同的服务器
//默认动态,静态直接找设置的static,上传找upload
upstream static_pools {
server 10.0.0.9:80 weight=1;
}
upstream upload_pools {
server 10.0.0.10:80 weight=1;
}
upstream default_pools {
server 10.0.0.9:8080 weight=1;
}
server {
listen 80;
server_name blog.ct99.cn;
#url: http://blog.ct99.cn/
location / {
proxy_pass http://default_pools;
include proxy.conf;
}
#url: http://blog.ct99.cn/static/
location /static/ {
proxy_pass http://static_pools;
include proxy.conf;
}
#url: http://blog.ct99.cn/upload/
location /upload/ {
proxy_pass http://upload_pools;
include proxy.conf;
}
}
//方案2:以if语句实现。
if ($request_uri ~* "^/static/(.*)$")
{
proxy_pass http://static_pools/$1;
}
if ($request_uri ~* "^/upload/(.*)$")
{
proxy_pass http://upload_pools/$1;
}
location / {
proxy_pass http://default_pools;
include proxy.conf;
}