您的位置:首页 > 运维架构 > Nginx

Nginx探索

2020-05-06 04:27 771 查看

重要的不是你从哪里来,而是你到哪里去,找准方向,继续努力。
It’s not where you’ve come from, it’s where you’re going

第一章 Nginx概述

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

Nginx可以作为静态页面的web服务器,同时还支持CGI协议的动态语言,比如perl、php等。但是不支持java。Java程序只能通过与tomcat配合完成。Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 ,能经受高负载的考验,有报告表明能支持高达 50,000个并发连接数。

https://lnmp.org/nginx.html

https://news.netcraft.com/archives/category/web-server-survey/

1.1 Nginx优点

Nginx 可以在大多数 UnixLinux OS 上编译运行,并有 Windows 移植版。 Nginx 的1.4.0稳定版已经于2013年4月24日发布,一般情况下,对于新建站点,建议使用最新稳定版作为生产版本。

Nginx 是一个很强大的高性能Web和反向代理服务器,它具有很多非常优越的特性:
在连接高并发的情况下,Nginx是Apache服务器不错的替代品:Nginx能够支持高达 50,000 个并发连接数的响应

1.2 为什么使用Nginx

互联网飞速发展的今天,大用户量高并发已经成为互联网的主体.怎样能让一个网站能够承载几万个或几十万个用户的持续访问呢?这是一些中小网站急需解决的问题。用单机tomcat搭建的网站,在比较理想的状态下能够承受的并发访问量在150到200左右。按照并发访问量占总用户数量的5%到10%这样计算,单点tomcat网站的用户人数在1500到4000左右。对于一个为全国范围提供服务的网站显然是不够用的,为了解决这个问题引入了负载均衡方法。负载均衡就是一个web服务器解决不了的问题可以通过多个web服务器来平均分担压力来解决,并发过来的请求被平均分配到多个后台web服务器来处理,这样压力就被分解开来。

负载均衡服务器分为两种:一种是通过硬件实现的负载均衡服务器,简称硬负载。另一种是通过软件来实现的负载均衡,简称软负载:例如apache和nginx。硬负载和软负载相比前者作用的网络层次比较多可以作用到socket接口的数据链路层对发出的请求进行分组转发但是价格成本比较贵,而软负载作用的层次在http协议层之上可以对http请求进行分组转发并且因为是开源的所以几乎是0成本,并且阿里巴巴,京东等电商网站使用的都是Nginx服务器。

1.3 正向代理

Nginx不仅可以做反向代理,实现负载均衡。还能用作正向代理来进行上网等功能。

正向代理:如果把局域网外的Internet想象成一个巨大的资源库,则局域网中的客户端要访问Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。

一般情况下,如果没有特别说明,代理技术默认说的是正向代理技术。

关于正向代理的概念如下: 正 向代理(forward)是一个位于客户端【用户A】和原始服务器(origin server)【服务器B】之间的服务器【代理服务器Z】,为了从原始服务器取得内容,用户A向代理服务器Z发送一个请求并指定目标(服务器B),然后代理服务器Z向服务器B转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

从上面的概念中,我们看出,文中所谓的正向代理就是代理服务器替代访问方【用户A】去访问目标服务器【服务器B】

这就是正向代理的意义所在。而为什么要用代理服务器去代替访问方【用户A】去访问服务器B呢?这就要从代理服务器使用的意义说起。

使用正向代理服务器作用主要有以下几点:

① 访问本无法访问的服务器B,如下图

我们抛除复杂的网络路由情节来看图,假设图中路由器从左到右命名为R1,R2假 设最初用户A要访问服务器B需要经过R1和R2路由器这样一个路由节点,如果路由器R1或者路由器R2发生故障,那么就无法访问服务器B了。但是如果用户 A让代理服务器Z去代替自己访问服务器B,由于代理服务器Z没有在路由器R1或R2节点中,而是通过其它的路由节点访问服务器B,那么用户A就可以得到服 务器B的数据了。现实中的例子就是“翻墙”。

② 加速访问服务器B

上图,防火墙作为网关,用来过滤外网对其的访问。假设用户A和用户B都设置了代理服务器,用户A允许访问互联网,而用户B不允许访问互联网(这个在代理服 务器Z上做限制)这样用户A因为授权,可以通过代理服务器访问到服务器B,而用户B因为没有被代理服务器Z授权,所以访问服务器B时,数据包会被直接丢 弃。

⑤ 隐藏访问者的行踪

如下图 ,我们可以看出服务器B并不知道访问自己的实际是用户A,因为代理服务器Z代替用户A去直接与服务器B进行交互。

我 们总结一下 正向代理是一个位于客户端和原始服务器(originserver)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内 容返回给客户端。客户端必须设置正向代理服务器,当然前提是要知道正向代理服务器的IP地址,还有代理程序的端口。

总之一句话:正向代理服务器,隐藏的是客户端

1.4 反向代理

反向代理:其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

反向代理正好与正向代理相反,对于客户端而言代理服务器就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端。

使用反向代理服务器的作用如下:

① 保护和隐藏原始资源服务器如下图

用户A始终认为它访问的是原始服务器B而不是代理服务器Z,但实用际上反向代理服务器接受用户A的应答,从原始资源服务器B中取得用户A的需求资源,然后发送给用户A。由于防火墙的作用,只允许代理服务器Z访问原始资源服务器B。尽管在这个虚拟的环境下,防火墙和反向代理的共同作用保护了原始资源服务器B,但用户A并不知情。

总之一句话:反向代理服务器,隐藏的是服务器

1.5 没有负载均衡情况

客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。

​ 这种架构模式对于早期的系统相对单一,并发请求相对较少的情况下是比较适合的,成本也低。但是随着信息数量的不断增长,访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器相应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃。很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?

我们首先想到的可能是升级服务器的配置,比如提高CPU执行频率,加大内存等提高机器的物理性能来解决此问题,硬件的性能提升已经不能满足日益提升的需求了。最明显的一个例子,天猫双十一当天,某个热销商品的瞬时访问量是极其庞大的,那么类似上面的系统架构,将机器都增加到现有的顶级物理配置,都是不能够满足需求的。那么怎么办呢?

上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法行不通了,那么横向增加服务器的数量呢?这时候集群的概念产生了,单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的**负载均衡。

1.6 负载均衡


当反向代理服务器不止一个的时候,我们甚至可以把它们做成集群,当更多的用户访问资源服务器B的时候,让不同的代理服务器Z(x)去应答不同的用户,然后发送不同用户需要的资源。

当然反向代理服务器像正向代理服务器一样拥有CACHE的作用,它可以缓存原始资源服务器B的资源,而不是每次都要向原始资源服务器B请求数据,特别是一些静态的数据,比如图片和文件,如果这些反向代理服务器能够做到和用户X来自同一个网络,那么用户X访问反向代理服务器X,就会得到很高质量的速度。如下图

第二章 Nginx安装

2.1 Nginx下载

官方网站:

http://nginx.org/

2.2 Nginx在windows下安装


双击 nginx.exe , 一闪而过

在浏览器中访问

localhost

2.3 Nginx在linux下安装

2.3.1 进入nginx官网,下载

http://nginx.org/ nginx-1.12.2.tar.gz


2.3.2 需要的安装包

pcre-8.37.tar.gz

openssl-1.0.1t.tar.gz

zlib-1.2.8.tar.gz

nginx-1.12.2.tar.gz

2.3.3 在线安装nginx

第一步,安装pcre

  • 联网下载pcre
    wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz
  • 解压压缩文件
    使用命令 tar -zxvf pcre-8.37.tar.gz
  • ./configure完成后,回到pcre目录下执行make,最后执行make install
  • pcre-config –version 检查版本

第二步,安装openssl 、zlib 、 gcc 依赖

yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel

第三步,安装nginx

使用命令解压
./configure
make && make install
进入目录 /usr/local/nginx/sbin   执行./nginx 启动服务

第四步,关闭防火墙,访问nginx

在windows系统中访问linux中nginx,默认不能访问的,因为防火墙问题
关闭防火墙-开放访问的端口号,80端口

查看开放的端口号
firewall-cmd --list-all

设置开放的服务或端口号
firewall-cmd --add-service=http --permanent
firewall-cmd --add-port=80/tcp --permanent

重启防火墙
firewall-cmd --reload


第三章 Nginx配置与应用

3.1. Nginx虚拟机配置

3.1.1 测试针对ip地址进行配置

主要是在描述nginx它是一个http服务器。它是apache的一个替代品。

对于nginx虚拟机配置主要可以从三个方面入手:

  1. ip配置
  2. 域名配置
  3. 端口配置
    它的配置主要体现在
    nginx/conf/nginx.conf


3.1.1.2 测试针对于域名进行配置

问题:为什么通过域名可以访问到网站。
​ DNS服务器—-域名解析服务器。

windows 系统中 hosts 文件所在位置 :

C:\Windows\System32\drivers\etc

linux 系统中 hosts 文件所在位置 :

/etc/hosts

修改windows 系统中的 hosts 文件,添加如下内容

127.0.0.1 abc.com
127.0.0.1 def.com


域名作用:可以方便记忆。修改 nginx.conf

请求:

http://abc.com/
或者
http://def.com/

3.1.1.3 测试针对于端口进行配置

修改配置文件

请求路径

3.2 Nginx反向代理

实现效果:使用nginx反向代理,访问 www.localhost:80.com 直接跳转到 127.0.0.1:8080

反向代理请求流程图

Nginx反向代理 ,配置文件

worker_processes  1;

events {
worker_connections  1024;
}

http {
include       mime.types;
default_type  application/octet-stream;

sendfile        on;

keepalive_timeout  65;

# 反向代理配置
upstream server_list{
# 这个是tomcat的访问路径
server localhost:8080;

}

server {
listen       80;
server_name  localhost;

location / {
root   html;
proxy_pass http://server_list;
index  index.html index.htm;
}

error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}

}

}

双击打开tomcat ,启动tomcat ,请求的是nginx的地址,代理到tomcat 的 页面

第四章 nginx负载均衡

随着互联网信息的爆炸性增长,负载均衡(load balance)已经不再是一个很陌生的话题,顾名思义,负载均衡即是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快,给用户很好的体验。快速增长的访问量和数据流量催生了各式各样的负载均衡产品,很多专业的负载均衡硬件提供了很好的功能,但却价格不菲,这使得负载均衡软件大受欢迎,nginx就是其中的一个,在linux下有Nginx、LVS、Haproxy等等服务可以提供负载均衡服务,而且Nginx提供了几种分配方式(策略):

4.1 实现效果

浏览器地址栏输入地址 http://192.168.137.129/edu/a.html,负载均衡效果,将请求平均分配到8080和8081两台服务器上。

4.2 准备工作

(1)准备两台tomcat服务器,一台8080,一台9999

(2)在两台tomcat里面webapps目录中

4.3 轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

# 反向代理配置
upstream server_list{
# 这个是tomcat的访问路径
server localhost:8080;
server localhost:9999;
}

完整配置

worker_processes  1;

events {
worker_connections  1024;
}

http {
include       mime.types;
default_type  application/octet-stream;

sendfile        on;

keepalive_timeout  65;

# 反向代理配置
upstream server_list{
# 这个是tomcat的访问路径
server localhost:8080;
server localhost:9999;
}
server {
listen       80;
server_name  localhost;

location / {
root   html;
proxy_pass http://server_list;
index  index.html index.htm;
}

error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}

}

}

使用 两台服务器 ,拷贝一个tomcat

修改

conf
文件下面的
server.xml
配置文件 , 分别修改三个端口号

<Server port="18005" shutdown="SHUTDOWN">

<Connector port="9999" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

<Connector port="18009" protocol="AJP/1.3" redirectPort="8443" />

修改两台 tomcat 服务器下面

webapps\ROOT\index.jsp

分别加上 标记 ,用以区分

<h1>main</h1>
<h1>back</h1>

4.4 weight 权重

所谓的负载均衡简单说就是将一台服务原来承受的压力由多台服务器来分配,可以在nginx中实现tomcat集群,通过weight来分配权重。

weight 代表权重,默认为1,权重越高被分配的客户端越多

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如:

# 反向代理配置
upstream server_list{
# 这个是tomcat的访问路径
server localhost:8080 weight=5;
server localhost:9999 weight=1;
}

4.5 ip_hash

每个请求按访问ip的hash值分配,这样每个访问客户端会固定访问一个后端服务器,

可以解决会话Session丢失的问题

upstream backserver {
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:9090;
}

不管刷新多少遍,始终访问的是同一台tomcat服务器

4.6 最少连接

web请求会被转发到连接数最少的服务器上

upstream backserver {
least_conn;
server 127.0.0.1:8080;
server 127.0.0.1:9090;
}

4.5 Nginx+tomcat集群+redis实现session共享

4.5.1 Session共享问题演示

  1. 在tomcat中创建项目myweb
  2. 分别启动两个tomcat,查看sessionid值

4.5.2 Session共享问题解决

思想:将原来由每一个tomcat管理的session统一存储到redis中管理

版本: apache-tomcat-7.0.79、nginx-1.8.0、redis_2.8.9

github地址: https://github.com/mzd123/session_managerc 读者可以直接下载体验一下。

实现:

1、下载:

https://github.com/ran-jit/tomcat-cluster-redis-session-manager/wiki


2、解压之后。将jar包放入tomcat的lib中(注意是
tomcat/lib
中,不是我们自己项目的lib)

3、配置解压之后的
redis-data-cache.properties
(根据你的redis配置吧)。配置完将这个文件放入
tomcat/conf
文件夹中。

4、配置
tomcat/cong/context.xml
,增加如下两行。

<Valve className="tomcat.request.session.redis.SessionHandlerValve"/>
<Manager className="tomcat.request.session.redis.SessionManager"/>


5、注意:因为tomcat-redis-session-manager这个版本的不同,classname会随着变化,2.0.4的版本是叫这两个。其实可以打开你下载的

tomcat-cluster-redis-session-manager.jar
看看他到底叫什么

测试:

1、nginx配置:

worker_processes  1;

events {
worker_connections  1024;
}

http {
include       mime.types;
default_type  application/octet-stream;

sendfile        on;

keepalive_timeout  65;

# 反向代理配置
upstream server_list{
# 这个是tomcat的访问路径
server localhost:8080;
server localhost:9999;
}
server {
listen       80;
server_name  localhost;

location / {
root   html;
proxy_pass http://server_list;
index  index.html index.htm;
}

error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}

}
}

2、准备两个tomcat,一个端口为8090,一个为9999

3、tomcat中jsp代码:新建

webapps\myweb\index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" import="java.text.SimpleDateFormat"%>
<%
request.getSession().setAttribute("mzd","123");
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String date=simpleDateFormat.format(new Date());
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>tomcat1</title>
</head>
<body>
SessionID:<%=session.getId()%>
<BR>
当前时间为:<%=date%>
<BR>
SessionPort:<%=request.getServerPort()%>
<BR>
mzd的值为:<%=session.getAttribute("mzd")%>
<BR>
<%
out.println("这是tomcat1");
%>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" import="java.text.SimpleDateFormat"%>
<%
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String date=simpleDateFormat.format(new Date());
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>tomcat2</title>
</head>
<body>
SessionID:<%=session.getId()%>
<BR>
当前时间为:<%=date%>
<BR>
SessionPort:<%=request.getServerPort()%>
<BR>
mzd的值为:<%=session.getAttribute("mzd")%>
<BR>
<%
out.println("这是tomcat2");
%>
</body>
</html>


这样就保证SessionID一致啦

END

Simplesilent 原创文章 5获赞 0访问量 167 关注 私信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: