Nginx实战+高可用

Nginx实战+高可用

Nginx介绍

Ningx应用场景

Windows环境下安装Nginx

Windows环境下实现反向代理

Windows环境下实现负载均衡

Nginx实现网关接口跨域解决方案

Nginx实现防盗链

Nginx防止DDOS

Linux环境下安装Nginx

Linux环境下实现反向代理

Linux环境下nginx+keepalived实现高可用

Linux环境下Session共享解决方案

什么是集群?

 

什么是Nginx

nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定,所以现在很多知名的公司都在使用nginx。 

 

Nginx应用场景

  1. http服务器(静态网页展示)
  2. 虚拟主机。可以实现在一台服务器虚拟出多个网站。
  3. 反向代理,负载均衡。

 

 

下载地址:http://nginx.org/en/download.html

Windows环境

Windows下只需要解压就可以了,然后编写配置文件,这里windows下就简单的演示一下就可以了。

 

nginx反向代理

启动显示下面的提示表示nginx启动成功,我们也可以通过任务管理器查看

任务管理器两个进程

访问http://127.0.0.1:8888/logo.png路径可以获取到我们刚才的图片文件。这就简单的在Windows上实现了nginx的反向代理。

通过任务管理器关闭nginx则不能访问成功。

 

Linux环境

环境搭建

通过XFtp将nginx-1.6.3.tar.gz上传到/usr/local/nginx目录下。

 

安装gcc环境

Yum -y install gcc-c++

 

安装PCRE

PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:

yum install -y pcre pcre-devel

 

安装zlib

yum install -y zlib zlib-devel

 

安装openssl

yum install -y openssl openssl-devel

 

安装Nginx

解压我们得nginx压缩包

tar -zxvf nginx-1.6.3.tar.gz

 

进入到解压目录

cd nginx-1.6.3

 

编译

./configure

 

安装

make

make install

 

这里就可以将我们得安装包删除掉了

rm -rf nginx-1.6.3

rm -rf nginx-1.6.3.tar.gz

 

启动nginx

cd sbin/

./nginx

启动成功↓

 

访问IP地址+端口号80就可以访问我们的nginx

操作代码

启动命令:
/usr/local/nginx/sbin/nginx

重启:
/usr/local/nginx/sbin/nginx -s reload

停止:
/usr/local/nginx/sbin/nginx -s stop

 

Nginx配置文件

Nginx实战+高可用

Nginx介绍

Ningx应用场景

Windows环境下安装Nginx

Windows环境下实现反向代理

Windows环境下实现负载均衡

Nginx实现网关接口跨域解决方案

Nginx实现防盗链

Nginx防止DDOS

Linux环境下安装Nginx

Linux环境下实现反向代理

Linux环境下nginx+keepalived实现高可用

Linux环境下Session共享解决方案

什么是集群?

 

什么是Nginx

nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定,所以现在很多知名的公司都在使用nginx。 

 

Nginx应用场景

  1. http服务器(静态网页展示)
  2. 虚拟主机。可以实现在一台服务器虚拟出多个网站。
  3. 反向代理,负载均衡。

 

 

下载地址:http://nginx.org/en/download.html

Windows环境

Windows下只需要解压就可以了,然后编写配置文件,这里windows下就简单的演示一下就可以了。

 

nginx反向代理

启动显示下面的提示表示nginx启动成功,我们也可以通过任务管理器查看

任务管理器两个进程

访问http://127.0.0.1:8888/logo.png路径可以获取到我们刚才的图片文件。这就简单的在Windows上实现了nginx的反向代理。

通过任务管理器关闭nginx则不能访问成功。

 

Linux环境

环境搭建

通过XFtp将nginx-1.6.3.tar.gz上传到/usr/local/nginx目录下。

 

安装gcc环境

Yum -y install gcc-c++

 

安装PCRE

PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。命令:

yum install -y pcre pcre-devel

 

安装zlib

yum install -y zlib zlib-devel

 

安装openssl

yum install -y openssl openssl-devel

 

安装Nginx

解压我们得nginx压缩包

tar -zxvf nginx-1.6.3.tar.gz

 

进入到解压目录

cd nginx-1.6.3

 

编译

./configure

 

安装

make

make install

 

这里就可以将我们得安装包删除掉了

rm -rf nginx-1.6.3

rm -rf nginx-1.6.3.tar.gz

 

启动nginx

cd sbin/

./nginx

启动成功↓

 

访问IP地址+端口号80就可以访问我们的nginx

操作代码

启动命令:
/usr/local/nginx/sbin/nginx

重启:
/usr/local/nginx/sbin/nginx -s reload

停止:
/usr/local/nginx/sbin/nginx -s stop

 

Nginx配置文件

#user  nobody;

worker_processes  1;

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

 

events {

    worker_connections  1024;

}

 

http {

    include       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  logs/access.log  main;

 

    sendfile        on;

    #tcp_nopush     on;

    #keepalive_timeout  0;

    keepalive_timeout  65;

    #gzip  on;

    server {

        listen       80;

        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {

            root   html;

            index  index.html index.htm;

        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html

        #

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

    }

}

 

 

我们将html下的index.html默认文件内容稍作修改,然后重启nginx

 

重启命令(sbin目录下):./nginx -s reload

 

然后在访问。

(以下全在Windows中配置)

反向代理

我们放一张图片进去实现windows下相同的代理图片的功能。

 

C:\Windows\System32\drivers\etc修改一下hosts文件

最后增加一行(表示所有的sues.com的请求都转发到192.168.10.110)

#nginx

192.168.10.110 www.sues.com

192.168.10.110 8081.sues.com

192.168.10.110 8082.sues.com

 

测试成功

这里修改一下我们的配置文件

 

反向代理(多个项目)

我们这里要实现一台电脑上面利用nginx代理三个位置。

 

 

我们在html下新建一个文件夹wwwroot

然后在建立三个文件夹8080/8081/8082,我们这里就利用三个html页面去代替我们的Web项目。

 

我们将原来的html下的index.html复制到对应的三个文件夹下,将内容简单的修改一下就可以了。

 

然后修改我们的配置文件(新增两个server)。

  server {

        listen      80;

        server_name 8081.sues.com;

        location / {

            root    html/wwwroot/8081;

            index   index.html index.htm;

        }

    }

   server {

        listen      80;

        server_name 8082.sues.com;

        location / {

            root    html/wwwroot/8082;

            index   index.html index.htm;

        }

   }

    server {

        listen       80;

        server_name  www.sues.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {

            root   html/wwwroot/8080;

            index  index.html index.htm;

        }

    *************

 

访问效果

www.sues.com

8081.sues.com

8082.sues.com

 

 

负载均衡

为什么要使用负载均衡,首先就是要求项目是集群的情况下。

一、集群简介

(1) 什么是集群:集群是指一组计算机利用网络组成一个较大的计算机服务系统,这些计算机可以分布在一个机房,也可以分布在全国各地
(2) 为什么要使用集群:高性能、可伸缩性、高可用性、可管理性、......
(3) 集群的分类:负载均衡集群、高可用集群、高性能集群、网格计算集群
(4) 可实施集群的软件:Nginx 、LVS 、Haproxy 、Keepalived 、Heartbeat
(5) 可实施集群的硬件:F5 、Netscaler 、Radware 、A10

 

这里我们先删除掉我们刚才的配置。保留一个8080就好了。

 

这里我们在本地演示

 

 

配置负载均衡

upstream suesserver{

        server 127.0.0.1:8080;

        server 127.0.0.1:8081;

    }

    server {

        listen       80;

        server_name  www.sues.com;

        location / {

            proxy_pass  http://suesserver;

            index  index.html index.htm;

        }

        *******

 

启动,通过127.0.0.1的域名www.sues.com进行访问。可以发现配置成功。

负载均衡机制

通过www.sues.com访问

 

轮训机制(负载均衡策略)

默认轮训

 

Ip绑定(每个访客固定访问一个后端服务器,有效的解决了Session共享的问题)

upstream backserver{

    ip_hash;

        server 192.168.10.111:80;

        server 192.168.10.112:80;

    }

 

 

权重

在配置后面加上weight=?;

upstream backserver{

        server 192.168.10.111:80 weight=2;

        server 192.168.10.112:80 weight=1;

    }

可以发现A项目和B项目的出现频率为2:1

 

 

 

宕机解决办法

配置连接,发送信息,读取信息的等待时间,超过时间则换一个服务器(改为轮训方便测试)

server {

        listen       80;

        server_name  www.sues.com;

        location / {

    proxy_pass  http://suesserver;

index  index.html index.htm;

proxy_connect_timeout 1;

            proxy_send_timeout 1;

            proxy_read_timeout 1;

        }

}

 

 

Nginx实现防盗链

(配置表示所有的以sues.com的referer来的请求都可以访问)

 location ~ .*\.(jpg|jpeg|JPG|png|gif|icon)$ {

    valid_referers blocked www.sues.com sues.com;

    if ($invalid_referer) {

         return 403;

    }

}

 

将配置文件还原成刚开始那样

稍微修改一下html下的index页面,把一个A标签跳转到www.sues.com/sues/logo.png,这样就可以产生一个referer,随后我们在增加一个hosts跳转,直接访问图片出现403错误。

 

 

直接通过www.sues.com/sues/logo.png也是访问不到图片的,为什么呢?

因为是判断referer请求来源,直接访问是没有来源的。注意!!!!

 

 

访问referer页面http请求。

 

 

 

防止DDOS

限制请求速度

设置Nginx、Nginx Plus的连接请求在一个真实用户请求的合理范围内。比如,如果你觉得一个正常用户每两秒可以请求一次登录页面,你就可以设置Nginx每两秒钟接收一个客户端IP的请求(大约等同于每分钟30个请求)。

 

说明:区域名称为one(自定义),占用空间大小为10m,平均处理的请求频率不能超过每秒一次。

limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;

    server {

        limit_req zone=one;

        listen       80;

        server_name  www.sues.com;

    *******

 

 

快速强行刷新

 

 

问:安全架构,面试官问你有什么解决安全的方法。

答:Nginx反向代理:不暴露IP

使用Https防止抓包

搭建企业白黑名单,referer

防止模拟请求,XSS攻击,SQL注入,防止DDOS攻击

---------------------------------------------------------------------------------------------

 

Nginx搭建网关接口解决跨域问题

什么是跨域?

跨域是浏览器的限制,不是我们开发的问题,我们只需要去解决跨域就好了。

什么是同一域中:同协议,同域名,同端口。路径可以不同

 

 

Html页面

<html>

<head>

<title>sues---Nginx解决跨域问题</title>

</head>

<body>

<p th:text="'sues  Server : '+${port}"></p>

<img alt="" src="http://127.0.0.1:8080/logo.png" />

<script type="text/javascript" th:src="@{/js/jquery-3.3.1.min.js}"></script>

<script type="text/javascript">

$(document).ready(function() {

$.ajax({

type : "GET",

url : "http://127.0.0.1:8080/msg",

success : function(data) {

alert(data);

},

error : function() {

alert("error");

}

});

});

</script>

</body>

</html>

 

 

配置文件

location /A {

proxy_pass http://127.0.0.1:8080/;

}

location /B {

proxy_pass http://127.0.0.1:8081/;

}

这样通过www.mjxe.com/A和www.mjxe.com/B就可以将两个服务器设置在同一域中。

 

 

 

Nginx高可用(运维范畴了解)

什么是高可用

高可用一般指服务的冗余,一个服务挂了,可以自动切换到另外一个服务上,不影响客户体验。就是某个服务挂掉了,但是不影响用户的使用。

 

Keepalived介绍

Keepalived是一个免费开源的,用C编写的

Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。

 

集成KeepAlived

安装keepalived

地址:http://www.keepalived.org/download.html

解压安装:

tar -zxvf keepalived-1.2.18.tar.gz -C /usr/local/

yum install -y openssl openssl-devel(需要安装一个软件包)

cd keepalived-1.2.18/

 ./configure --prefix=/usr/local/keepalived

make

make install

 

加载系统服务

将keepalived安装成Linux系统服务,因为没有使用keepalived的默认安装路径(默认路径:/usr/local),安装完成之后,需要做一些修改工作:

首先创建文件夹,将keepalived配置文件进行复制:

mkdir /etc/keepalived

cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

然后复制keepalived脚本文件:

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/

cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

ln -s /usr/local/sbin/keepalived /usr/sbin/

ln -s /usr/local/keepalived/sbin/keepalived /sbin/

可以设置开机启动:chkconfig keepalived on,到此我们安装完毕!

 

service keepalived start

service keepalived stop

 

如果启动失败的情况下处理方法

cd /usr/sbin/  

rm -rf keepalived   

cp /usr/local/keepalived/sbin/keepalived  /usr/sbin/

 

两台机器同样的配置,只是主节点要做更改。

配置文件

global_defs {

   router_id bhz005 ##标识节点的字符串,通常为hostname

}

vrrp_script chk_nginx {

    script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕机以后,自动开启服务

interval 2   #检测时间间隔

weight -20  #如果条件成立的话,则权重 -20

}

# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称

vrrp_instance VI_1 {

    state MASTER   #来决定主从BACKUP

    interface ens33  # 绑定虚拟 IP 的网络接口,根据自己的机器填写

    virtual_router_id 1229 # 虚拟路由的 ID 号,节点设置必须一样

    mcast_src_ip 192.168.10.119 #填写本机ip

    priority 100  # 节点优先级,主要比从节点优先级高

    nopreempt  # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题

    advert_int 1  # 组播信息发送间隔,两个节点设置必须一样,默认 1s

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    # 将 track_script 块加入 instance 配置块

    track_script {

        chk_nginx #执行 Nginx 监控的服务

    }

    virtual_ipaddress {

        192.168.10.119 # 虚拟ip,这里配置自己的IP地址

    }

}

 

脚本文件

这里我们的配置文件因为权限问题不能直接访问脚本文件,需要赋予读取权限

chmod 777 nginx_check.sh

#!/bin/bash

A=`ps -C nginx ¨Cno-header |wc -l`

if [ $A -eq 0 ];then

    /usr/local/nginx/sbin/nginx

    sleep 2

    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then

        killall keepalived

    fi

fi

 

虚拟IP

然后就可以帮我们自动重启Nginx了

 

测试自动重启

 

 

Session共享的解决方案

学习完了Redis和Nginx,我们就可以完成Session共享的解决方案

 

集群情况下session会产生什么问题?

服务器A和服务器B

 

什么是Session会话机制?

假设你访问网页时就像逛澡堂,第一次进去你是没有钥匙的,这个时候你交了钱服务台就分配一把钥匙给你,你走到哪里都要带上,因为这是你身份的唯一标识,接下来你用这把钥匙可以去打开一个专有的储物柜存储你的衣物,游完泳,你再用钥匙去打开柜子拿出衣物,最后离开游泳池时,把钥匙归还,你的这次游泳的过程就是一次session,或者叫做会话,在这个例子中,钥匙就是session的key,而储物柜可以理解为存储用户会话信息的介质。

 

Session存放在哪里

存储在服务器的内存中,tomcat的StandardManager类将session存储在内存中,也可以持久化到file,数据库,memcache,redis等。客户端只保存sessionid到cookie中,而不会保存session,session销毁只能通过invalidate或超时,关掉浏览器并不会关闭session。

 

 

Session共享解决方案

1、用Nginx 做的负载均衡可以添加ip_hash这个配置,从而使同一个ip的请求发到同一台服务器

2、利用数据库同步session

3、利用cookie同步session数据原理图如下

  1. 使用Redis存放Session

 

Session共享解决

重现问题

SpringBoot

 

Pom

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.3.3.RELEASE</version>

</parent>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

 

Application.yml

server:

  port: 8080

 

Controller

@RestController

public class IndexController {

@Value("${server.port}")

private String PORT;

@RequestMapping("/set")

public String setSession(String key, String value, HttpSession session) {

session.setAttribute(key, value);

return "Port:" + PORT + "--SetSession Success==>key:" + key + "--value:" + value;

}

@RequestMapping("/get")

public String getSession(String key, HttpSession session) {

String value = (String) session.getAttribute(key);

return "Port:" + PORT + "--GetSession Success==>key:" + key + "--Get Value:" + value;

}

@RequestMapping("/del")

public String delSession(String key, HttpSession session) {

session.removeAttribute(key);

return "Port:" + PORT + "--DelSession Success==>key:" + key;

}

}

启动8080和8081端口,两边Session根本不会共享。

 

思考:怎么利用Nginx解决这种问题?例外有什么缺点。

 

答:ip_hash绑定,使用来自同一请求地址用户始终访问同一服务器,思考缺点:当前服务器万一宕机了,用户就不能正常访问了。缺点就是服务器重启之后Session全部失效。

--------------------------------------------------------------------------------------------------------------

 

 

 

使用Redis解决Session共享(实战解决方法)

启动redis

./redis-server /usr/local/redis/etc/redis.conf

 

Pom新增

<!--spring boot redis -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-redis</artifactId>

</dependency>

<!--spring session与redis关联配置 -->

<dependency>

<groupId>org.springframework.session</groupId>

<artifactId>spring-session-data-redis</artifactId>

</dependency>

 

Session配置

//这个类用配置redis服务器的连接

//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)

public class SessionConfig {

// 冒号后的值为没有配置文件时,制动装载的默认值

@Value("${redis.hostname:192.168.10.100}")

String HostName;

@Value("${redis.port:6379}")

int Port;

@Bean

public JedisConnectionFactory connectionFactory() {

JedisConnectionFactory connection = new JedisConnectionFactory();

connection.setPort(Port);

connection.setHostName(HostName);

return connection;

}

}

 

Session初始化配置

// 初始化Session配置

public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {

public SessionInitializer() {

super(SessionConfig.class);

}

}

 

产生Session过后可以查看redis做了记录。

 

 

 

我们将html下的index.html默认文件内容稍作修改,然后重启nginx

 

重启命令(sbin目录下):./nginx -s reload

 

然后在访问。

(以下全在Windows中配置)

反向代理

我们放一张图片进去实现windows下相同的代理图片的功能。

 

C:\Windows\System32\drivers\etc修改一下hosts文件

最后增加一行(表示所有的mjxy.com的请求都转发到192.168.10.110)

#nginx

192.168.10.110 www.sues.com

192.168.10.110 8081.sues.com

192.168.10.110 8082.sues.com

 

测试成功

这里修改一下我们的配置文件

 

反向代理(多个项目)

我们这里要实现一台电脑上面利用nginx代理三个位置。

 

 

我们在html下新建一个文件夹wwwroot

然后在建立三个文件夹8080/8081/8082,我们这里就利用三个html页面去代替我们的Web项目。

 

我们将原来的html下的index.html复制到对应的三个文件夹下,将内容简单的修改一下就可以了。

 

然后修改我们的配置文件(新增两个server)。

  server {

        listen      80;

        server_name 8081.sues.com;

        location / {

            root    html/wwwroot/8081;

            index   index.html index.htm;

        }

    }

   server {

        listen      80;

        server_name 8082.sues.com;

        location / {

            root    html/wwwroot/8082;

            index   index.html index.htm;

        }

   }

    server {

        listen       80;

        server_name  www.sues.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {

            root   html/wwwroot/8080;

            index  index.html index.htm;

        }

    *************

 

访问效果

www.mjxy.com

8081.mjxy.com

8082.mjxy.com

 

 

负载均衡

为什么要使用负载均衡,首先就是要求项目是集群的情况下。

一、集群简介

(1) 什么是集群:集群是指一组计算机利用网络组成一个较大的计算机服务系统,这些计算机可以分布在一个机房,也可以分布在全国各地
(2) 为什么要使用集群:高性能、可伸缩性、高可用性、可管理性、......
(3) 集群的分类:负载均衡集群、高可用集群、高性能集群、网格计算集群
(4) 可实施集群的软件:Nginx 、LVS 、Haproxy 、Keepalived 、Heartbeat
(5) 可实施集群的硬件:F5 、Netscaler 、Radware 、A10

 

这里我们先删除掉我们刚才的配置。保留一个8080就好了。

 

这里我们在本地演示

 

 

配置负载均衡

upstream mjxyserver{

        server 127.0.0.1:8080;

        server 127.0.0.1:8081;

    }

    server {

        listen       80;

        server_name  www.mjxy.com;

        location / {

            proxy_pass  http://mjxyserver;

            index  index.html index.htm;

        }

        *******

 

启动,通过127.0.0.1的域名www.mjxy.com进行访问。可以发现配置成功。

负载均衡机制

通过www.mjxy.com访问

 

轮训机制(负载均衡策略)

默认轮训

 

Ip绑定(每个访客固定访问一个后端服务器,有效的解决了Session共享的问题)

upstream backserver{

    ip_hash;

        server 192.168.10.111:80;

        server 192.168.10.112:80;

    }

 

 

权重

在配置后面加上weight=?;

upstream backserver{

        server 192.168.10.111:80 weight=2;

        server 192.168.10.112:80 weight=1;

    }

可以发现A项目和B项目的出现频率为2:1

 

 

 

宕机解决办法

配置连接,发送信息,读取信息的等待时间,超过时间则换一个服务器(改为轮训方便测试)

server {

        listen       80;

        server_name  www.mjxy.com;

        location / {

    proxy_pass  http://mjxyserver;

index  index.html index.htm;

proxy_connect_timeout 1;

            proxy_send_timeout 1;

            proxy_read_timeout 1;

        }

}

 

 

Nginx实现防盗链

(配置表示所有的以mjxy.com的referer来的请求都可以访问)

 location ~ .*\.(jpg|jpeg|JPG|png|gif|icon)$ {

    valid_referers blocked www.mjxy.com mjxy.com;

    if ($invalid_referer) {

         return 403;

    }

}

 

将配置文件还原成刚开始那样

稍微修改一下html下的index页面,把一个A标签跳转到www.mjxy.com/mjxy/logo.png,这样就可以产生一个referer,随后我们在增加一个hosts跳转,直接访问图片出现403错误。

 

 

直接通过www.mjxy.com/mjxy/logo.png也是访问不到图片的,为什么呢?

因为是判断referer请求来源,直接访问是没有来源的。注意!!!!

 

 

访问referer页面http请求。

 

 

 

防止DDOS

限制请求速度

设置Nginx、Nginx Plus的连接请求在一个真实用户请求的合理范围内。比如,如果你觉得一个正常用户每两秒可以请求一次登录页面,你就可以设置Nginx每两秒钟接收一个客户端IP的请求(大约等同于每分钟30个请求)。

 

说明:区域名称为one(自定义),占用空间大小为10m,平均处理的请求频率不能超过每秒一次。

limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;

    server {

        limit_req zone=one;

        listen       80;

        server_name  www.mjxy.com;

    *******

 

 

快速强行刷新

 

 

问:安全架构,面试官问你有什么解决安全的方法。

答:Nginx反向代理:不暴露IP

使用Https防止抓包

搭建企业白黑名单,referer

防止模拟请求,XSS攻击,SQL注入,防止DDOS攻击

---------------------------------------------------------------------------------------------

 

Nginx搭建网关接口解决跨域问题

什么是跨域?

跨域是浏览器的限制,不是我们开发的问题,我们只需要去解决跨域就好了。

什么是同一域中:同协议,同域名,同端口。路径可以不同

 

 

Html页面

<html>

<head>

<title>码家学院---Nginx解决跨域问题</title>

</head>

<body>

<p th:text="'MJXY  Server : '+${port}"></p>

<img alt="" src="http://127.0.0.1:8080/logo.png" />

<script type="text/javascript" th:src="@{/js/jquery-3.3.1.min.js}"></script>

<script type="text/javascript">

$(document).ready(function() {

$.ajax({

type : "GET",

url : "http://127.0.0.1:8080/msg",

success : function(data) {

alert(data);

},

error : function() {

alert("error");

}

});

});

</script>

</body>

</html>

 

 

配置文件

location /A {

proxy_pass http://127.0.0.1:8080/;

}

location /B {

proxy_pass http://127.0.0.1:8081/;

}

这样通过www.mjxe.com/A和www.mjxe.com/B就可以将两个服务器设置在同一域中。

 

 

 

Nginx高可用(运维范畴了解)

什么是高可用

高可用一般指服务的冗余,一个服务挂了,可以自动切换到另外一个服务上,不影响客户体验。就是某个服务挂掉了,但是不影响用户的使用。

 

Keepalived介绍

Keepalived是一个免费开源的,用C编写的

Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。

 

集成KeepAlived

安装keepalived

地址:http://www.keepalived.org/download.html

解压安装:

tar -zxvf keepalived-1.2.18.tar.gz -C /usr/local/

yum install -y openssl openssl-devel(需要安装一个软件包)

cd keepalived-1.2.18/

 ./configure --prefix=/usr/local/keepalived

make

make install

 

加载系统服务

将keepalived安装成Linux系统服务,因为没有使用keepalived的默认安装路径(默认路径:/usr/local),安装完成之后,需要做一些修改工作:

首先创建文件夹,将keepalived配置文件进行复制:

mkdir /etc/keepalived

cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

然后复制keepalived脚本文件:

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/

cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

ln -s /usr/local/sbin/keepalived /usr/sbin/

ln -s /usr/local/keepalived/sbin/keepalived /sbin/

可以设置开机启动:chkconfig keepalived on,到此我们安装完毕!

 

service keepalived start

service keepalived stop

 

如果启动失败的情况下处理方法

cd /usr/sbin/  

rm -rf keepalived   

cp /usr/local/keepalived/sbin/keepalived  /usr/sbin/

 

两台机器同样的配置,只是主节点要做更改。

配置文件

global_defs {

   router_id bhz005 ##标识节点的字符串,通常为hostname

}

vrrp_script chk_nginx {

    script "/etc/keepalived/nginx_check.sh" #运行脚本,脚本内容下面有,就是起到一个nginx宕机以后,自动开启服务

interval 2   #检测时间间隔

weight -20  #如果条件成立的话,则权重 -20

}

# 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称

vrrp_instance VI_1 {

    state MASTER   #来决定主从BACKUP

    interface ens33  # 绑定虚拟 IP 的网络接口,根据自己的机器填写

    virtual_router_id 1229 # 虚拟路由的 ID 号,节点设置必须一样

    mcast_src_ip 192.168.10.119 #填写本机ip

    priority 100  # 节点优先级,主要比从节点优先级高

    nopreempt  # 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题

    advert_int 1  # 组播信息发送间隔,两个节点设置必须一样,默认 1s

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    # 将 track_script 块加入 instance 配置块

    track_script {

        chk_nginx #执行 Nginx 监控的服务

    }

    virtual_ipaddress {

        192.168.10.119 # 虚拟ip,这里配置自己的IP地址

    }

}

 

脚本文件

这里我们的配置文件因为权限问题不能直接访问脚本文件,需要赋予读取权限

chmod 777 nginx_check.sh

#!/bin/bash

A=`ps -C nginx ¨Cno-header |wc -l`

if [ $A -eq 0 ];then

    /usr/local/nginx/sbin/nginx

    sleep 2

    if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then

        killall keepalived

    fi

fi

 

虚拟IP

然后就可以帮我们自动重启Nginx了

 

测试自动重启

 

 

Session共享的解决方案

学习完了Redis和Nginx,我们就可以完成Session共享的解决方案

 

集群情况下session会产生什么问题?

服务器A和服务器B

 

什么是Session会话机制?

假设你访问网页时就像逛澡堂,第一次进去你是没有钥匙的,这个时候你交了钱服务台就分配一把钥匙给你,你走到哪里都要带上,因为这是你身份的唯一标识,接下来你用这把钥匙可以去打开一个专有的储物柜存储你的衣物,游完泳,你再用钥匙去打开柜子拿出衣物,最后离开游泳池时,把钥匙归还,你的这次游泳的过程就是一次session,或者叫做会话,在这个例子中,钥匙就是session的key,而储物柜可以理解为存储用户会话信息的介质。

 

Session存放在哪里

存储在服务器的内存中,tomcat的StandardManager类将session存储在内存中,也可以持久化到file,数据库,memcache,redis等。客户端只保存sessionid到cookie中,而不会保存session,session销毁只能通过invalidate或超时,关掉浏览器并不会关闭session。

 

 

Session共享解决方案

1、用Nginx 做的负载均衡可以添加ip_hash这个配置,从而使同一个ip的请求发到同一台服务器

2、利用数据库同步session

3、利用cookie同步session数据原理图如下

  1. 使用Redis存放Session

 

Session共享解决

重现问题

SpringBoot

 

Pom

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.3.3.RELEASE</version>

</parent>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

</dependencies>

 

Application.yml

server:

  port: 8080

 

Controller

@RestController

public class IndexController {

@Value("${server.port}")

private String PORT;

@RequestMapping("/set")

public String setSession(String key, String value, HttpSession session) {

session.setAttribute(key, value);

return "Port:" + PORT + "--SetSession Success==>key:" + key + "--value:" + value;

}

@RequestMapping("/get")

public String getSession(String key, HttpSession session) {

String value = (String) session.getAttribute(key);

return "Port:" + PORT + "--GetSession Success==>key:" + key + "--Get Value:" + value;

}

@RequestMapping("/del")

public String delSession(String key, HttpSession session) {

session.removeAttribute(key);

return "Port:" + PORT + "--DelSession Success==>key:" + key;

}

}

启动8080和8081端口,两边Session根本不会共享。

 

思考:怎么利用Nginx解决这种问题?例外有什么缺点。

 

答:ip_hash绑定,使用来自同一请求地址用户始终访问同一服务器,思考缺点:当前服务器万一宕机了,用户就不能正常访问了。缺点就是服务器重启之后Session全部失效。

--------------------------------------------------------------------------------------------------------------

 

 

 

使用Redis解决Session共享(实战解决方法)

启动redis

./redis-server /usr/local/redis/etc/redis.conf

 

Pom新增

<!--spring boot redis -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-redis</artifactId>

</dependency>

<!--spring session与redis关联配置 -->

<dependency>

<groupId>org.springframework.session</groupId>

<artifactId>spring-session-data-redis</artifactId>

</dependency>

 

Session配置

/**

 * @author 作者 :码家学院 讲师 廖祥 qq:438944209

 * @version 创建时间:2018年1月28日 下午9:10:07 说明:{ }

 */

//这个类用配置redis服务器的连接

//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)

@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)

public class SessionConfig {

// 冒号后的值为没有配置文件时,制动装载的默认值

@Value("${redis.hostname:192.168.10.100}")

String HostName;

@Value("${redis.port:6379}")

int Port;

@Bean

public JedisConnectionFactory connectionFactory() {

JedisConnectionFactory connection = new JedisConnectionFactory();

connection.setPort(Port);

connection.setHostName(HostName);

return connection;

}

}

 

Session初始化配置

// 初始化Session配置

public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {

public SessionInitializer() {

super(SessionConfig.class);

}

}

 

产生Session过后可以查看redis做了记录。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值