Nginx入门

什么是Nginx?

Nginx 是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的Web和反向代理服务器,也是一个IMAP / POP3 / SMTP代理服务器。

在高连接并发的情况下,Nginx的是Apache的服务器不错的替代品

安装配置

下载

点击下载Nginx

启动

假设nginx在d:/nginx目录下,那么就需要通过如下命令启动:

1
2
3
4
cmd
d:
cd d:/nginx
start nginx

关闭方式也是与之对应的

1
nginx -s stop

打开访问地址,就可以看到如图所示的效果

1
http://127.0.0.1

关闭方式,亦可以用任务管理器关闭
注: nginx启动之后,在任务管理里有两个nginx进程,这个是正常的,一个是1个守护进程 1个工作进程,得手动分别关闭。

启动失败

启动失败的常见问题一般是端口被占用,可以使用taskkill 杀死占用的进程,或者将 Nginx 端口修改

打开nginx目录下的conf/nginx.conf文件,然后找到listen 80,修改为9090,关闭nginx再启动,就可以通过如下地址访问了:

1
http://127.0.0.1:9090/

注: 也可以通如下命令进行重启

1
nginx -s reload

多Tomcat

Tomcat_8111下载

Tomcat_8222下载

在解释为什么要提供多个Tomcat之前,首先解释一下为什么要额外提供Tomcat。

Nginx是一个web服务器,很快速,但是不能作为Servlet 容器独立运行,所以通常的工作方式是Nginx配合Tomcat来协同工作。 这就是为什么要单独提供Tomcat,以方便配合Nginx进行工作。

那么为什么要提供多个Tomcat呢?因为在后续的 「负载均衡」,「session共享」 教程里需要多个Tomcat来配合演示。 右上角有两个Tomcat,下载后运行其中的startup.bat就可以启动,端口号分别是8111和8222

访问

下载tomcat_8111.zip,解压并运行其中bin目录下的startup.bat

启动之后访问地址:

1
http://127.0.0.1:8111/

会自动跳转到

1
http://127.0.0.1:8111/login.jsp

反向代理

概念

先说正向代理,比如要访问youtube,但是不能直接访问,只能先找个翻墙软件,通过翻墙软件才能访问youtube. 翻墙软件就叫做正向代理。
所谓的反向代理,指的是用户要访问youtube,但是youtube悄悄地把这个请求交给bilibili来做,那么bilibili就是反向代理了。
在当前教程指的就是访问nginx,但是nginx把请求交给tomcat来做。

尝试

  • 启动 8111 端口的 tomcat
  • 修改 nginx.conf ,主要30 - 42行
1
2
3
location / {
proxy_pass http://127.0.0.1:8111;
}
  • 重启nginx并访问
1
2
3
4
5
6
重启
nginx -s reload
访问
http://127.0.0.1/
地址自动跳转为
127.0.0.1/login.jsp

意义

既然直接通过127.0.0.1:8111/login.jsp 可以访问,那么干嘛要通过127.0.0.1/login.jsp 去反向代理到tomcat呢? 为什么不直接使用tomcat呢?

因为nginx在处理静态文件的吞吐量上面比tomcat好很多,通常他们俩配合,不会把所有的请求都如本例所示的交给tomcat, 而是把静态请求交给nginx,动态请求,如 jsp ,servlet , ssm,struts等请求交给tomcat. 从而达到动静分离的效果

动静分离

概念

所谓的动静分离就是指图片,css, js之类的都交给nginx来处理,nginx处理不了的,比如jsp 就交给tomcat来处理

好处是nginx处理静态内容的吞吐量很高,比tomcat高多了,这样无形中提升了性能。

修改nginx.conf

在locaction下面添加一个新的location:

1
2
3
location ~\.(css|js|png)$ {
root D:/tomcat/tomcat_8111/webapps/ROOT;
}

这表示所有的css js png访问都由nginx来做,访问的地址是:

1
D:/tomcat/tomcat_8111/webapps/ROOT

这里要注意,填写本地地址的时候,要用正斜杠 / 不要用反斜杠 \

效果

访问地址

1
http://127.0.0.1/login.jsp

观察tomcat 输出日志,发现只访问了 jsp,是因为 nginx 负责了其他的

负载均衡

概念

负载均衡的概念就是当访问量很大的时候,一个 Tomcat 吃不消了,这时候就准备多个 Tomcat,由Nginx按照权重来对请求进行分配,从而缓解单独一个Tomcat受到的压力

尝试

启动两个Tomcat

修改 nginx.conf

首先增加一个upstream ,用来指向这两个tomcat

1
2
3
4
upstream tomcat_8111_8222{
server 127.0.0.1:8111 weight=1;
server 127.0.0.1:8222 weight=2;
}

然后修改location,反向代理到上述配置

1
2
3
location / {
proxy_pass http://tomcat_8111_8222;
}

weight表示权重,值越大,被分配到的几率越大。 最大多少呢?我也不知道。。。反正10以内都可以用吧

重启nginx并访问

使用命令 nginx -s reload 重启,然后使劲访问

http://127.0.0.1/login.jsp

此时就可以观察到对jsp的访问,被分配到了不同的 Tomcat上

Session共享

通过「负载均衡」的介绍,我们可以把请求分发到不同的 Tomcat 来缓解服务器的压力,但是这里存在一个问题: 当同一个用户第一次访问tomcat_8111 并且登录成功, 而第二次访问却被分配到了tomcat_8222, 这里并没有记录他的登陆状态,那么就会呈现未登录状态了,严重伤害了用户体验。

办法一(ip_hash)

通过ip地址标记用户,如果多次请求都是从同一个ip来的,那么就都分配到同一个tomcat.
这样就不会出现「负载均衡 session问题」了。 处理手段也很简单,在upstream最后加上ip_hash即可。

不过这种方案并不完美,当如下几种情况发生时就有问题:

  • 大量请求来之某个局域网,那么相当于就没有负载均衡
  • 如果tomcat_8111 挂了,那么此时nginx只能把请求交给tomcat_8222,但是这里却没有记录session,用户体验依然受影响

办法二(redis+tomcat-sessoin-manager)

然第一种解决办法有问题,那么就采用第二种解决办法:用Redis来存取session.
Redis是什么呢?说简单点就是个独立的Hashmap,用来存放键值对的。
这样当tomcat1需要保存session值的时候,就可以把它放在Redis上,需要取的时候,也从Redis上取。
那么考虑这个情景:

  • 用户提交账号密码的行为被分配在了tomcat8111上,登陆信息被存放在redis里。
  • 当用户第二次访问的时候,被分配到了tomcat8222上
  • 那么此时tomcat8222就会从redis去获取相关信息,一看有对应信息,那么就会呈现登陆状态。

这样就规避了「解决办法一: ip_hash」里会出现的两种问题了。

方法二操作

接下来进行具体操作,分几个步骤

  1. 启动redis
  2. 给两个tomcat使用jar包
  3. 配置两个tomcat
  4. 重启两个tomcat
  5. 测试

启动redis

下载redis,解压后运行redis-server.exe程序

给两个tomcat使用jar包

Tomcat需要链接 redis,所以需要专门的jar包,这些包都放在了tomcat-redis.zip里。 一共有3个jar包:

1
2
3
jedis-2.5.2.jar,
commons-pool2-2.0.jar,
tomcat-redis-session-manager1.2.jar。

下载解压后,放在tomat8111的lib目录下。注:不要放在webapp里面去了哦
下载解压后,放在tomat8222的lib目录下。注:不要放在webapp里面去了哦

###配置两个tomcat

然后修改tomcat/conf/context.xml ,增加下面这些东西

1
2
3
4
5
6
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />  
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="127.0.0.1"
port="6379"
database="0"
maxInactiveInterval="60" />

重启两个Tomcat

重启 Tomcat

测试

Redis session共享机制和nginx其实无关,是发生在nginx之后的事情,所以直接访问login.jsp。

然后登陆,并观察到已登陆状态

http://127.0.0.1:8111/login.jsp

然后直接访问tomcat8222

http://127.0.0.1:8222/login.jsp

虽然没有在tomcat8222上登陆,但是可以观察到已经呈现为登陆状态了