Nginx+Tomcat的配合使用
近期尝试使用tomcat和Nginx进行配合做负载均衡和静态与动态资源分配的Demo,期间遇到很多有意思的地方和知识短板,特此记录
一:什么是Nginx?
Nginx也是一款服务器,我们常用它做如:反向代理、负载均衡、动态与静态资源的分离的工作
反向代理:相对应的是正向代理,如果你使用过代理服务器的话就明白,我们访问某一个网站并非直接访问目标网站,而是告诉代理服务器我需要访问什么目标网站,由代理服务器发出请求给目标网站,将目标网站访问结果再转发给你,此时,你是请求代理方。而反向代理是此时代理服务器做服务器的代理,我们的访问请求并非直接访问到目标服务器上,而是访问代理服务器,由代理服务器决定什么样的请求以什么样的方式访问正式服务器
负载均衡:目前大多数的网站都会采用负载均衡手段来针对目前用户的指数级增长来减少对单点服务器的负载压力,比如目前我们拥有3台真实服务器,我们需要根据相应策略决定什么样的用户请求分配到哪个真实服务器,比如按照轮询的方式,用户请求挨个到达代理服务器,此时代理服务器按照第一个请求转发至第一台真实服务器,第二个请求转发到第二个服务器上,依次类推,这样可以防止大量的用户请求全部访问到同一台物理机上,单点物理机的性能始终有限的,当然这可能对服务器数据访问时候造成事务性的失效,在Web方面可能造成Session访问的问题,这不在本文讨论方面内
动态静态资源分离:最方便列举就是Java的JSP和静态资源如:.js/.css/.html/.png方面的资源分离,之前开发web方面的程序时候我们习惯将html、css等资源文件也放置于Tomcat之中,用户访问后tomcat需要将请求的这些静态资源文件一并返回给用户,再者如果有多台同业务逻辑的tomcat服务器的话,同样的资源还需要在每个服务器上放一份,同时也增加了tomcat服务器的网络IO,十分不合算的,如果我们只讲JSP之类的请求交给tomcat,而代理服务器上存放静态资源,当用户的请求非动态资源的时候,我们完全可以将代理服务器的静态资源直接返回给用户,而不去增大Tomcat的压力,tomcat只需要负责逻辑处理和动态资源的加载就可以了
基于上述的Nginx优势,决定搭建一下Nginx+Tomcat的组合来进行测试,包括参数传递,post、get传递参数是否有影响,还有Nginx的工作模式master和worker的工作方式进行一些浅薄的总结
一、Nginx的安装
安装部分这里就不在细说了,网上的教程很多,我们直接从配置文件开始吧
二、配置文件
#user nobody;
#这里是核心worker数,一般设置为与cpu核心数相同的数目,避免进程切换造成的上下文切换耗费资源,cpu信息可以从/proc/cpuinfo中查看
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 {
#use epoll model使用epoll模型,采用异步非阻塞模型加快处理速度
use epoll;
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;
#设定通过nginx上传文件的大小
client_max_body_size 300m;
#使用sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作,传送),从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率很高,被称之为零拷贝。
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
#连接活跃时间
keepalive_timeout 65;
#使用压缩数据减少IO量,但是在不支持数据解压浏览器可能产生乱码
#gzip on;
#静态服务器组
#设定静态资源服务器访问接口
upstream static.zh-jieli.com {
server localhost:808 weight=1;
}
#动态服务器组
upstream zh-jieli.com {
#设置Hash轮询规则
#ip_hash;
#weight: server ip:port weight=10
#默认 轮询
#fair:按照后端服务器的响应时间来分配
#url_hash:按照url规则进行分配,使得固定的请求分配到固定的服务器上
server localhost:8080;
server localhost:8081;
}
server{
listen 808;
server_name static;
location / {
}
location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
#所有静态文件直接读取硬盘内容:读取的静态资源存放位置
root /apache-tomcat-8.5.24/webapps/ROOT ;
#资源是否进行缓存与缓存时间
expires 30d; #缓存30天
}
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index1.html index.htm;
}
location ~ .*\.(js|css|ico|png|jpg|eot|svg|ttf|woff) {
#proxy_cache cache_one;
proxy_cache_valid 200 304 302 5d;
proxy_cache_valid any 5d;
proxy_cache_key '$host:$server_port$request_uri';
add_header X-Cache '$upstream_cache_status from $host';
proxy_pass http://static.zh-jieli.com;
# 所有静态文件直接读取硬盘
root /apache-tomcat-8.5.24/webapps/ROOT;
expires 30d; #缓存30天
}
#其他页面反向代理到tomcat容器
location ^~ /tomcat {
index index;
# proxy_pass http://localhost:8080/;
#设定代理服务器组
proxy_pass http://zh-jieli.com/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
整个nginx工作时当http请求到来时,由nginx针对nginx.conf配置好的规则,对location进行正则匹配,匹配到相应的正则,进行location内部的处理
关于Nginx的location配置附上一篇博客,很nice
http://seanlook.com/2015/05/17/nginx-location-rewrite/
里面很详细列出了各种要求的location匹配规则,值得注意的一点是:
location匹配遵循最长原则,即满足了之前的匹配规则后,除了遇见^会终止向下继续匹配,其他情况会依次向下搜索,知道找到合适的location匹配规则然后进行处理
Nginx在模块功能上分三个模块:
Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。
因为是测试,所以我的两个tomcat都安装到了同一台本地机器上
生产环境中根据需要进行配置相应的IP就好了
本地写好相应的测试代码+log4j将信息日志打到相应的位置用来观察参数是否传递过来
TestOne.java
package com.nginx.controllers;
import com.nginx.utils.Log4jUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/test")
public class TestOne {
@RequestMapping("/getname")
public void test(@RequestParam(value = "name") String name) {
//用来记录获取的参数name,可以通过查看日志进行确认
Log4jUtils.getLogger().info("my name is" + name);
}
}
Log4jUtils.java
package com.nginx.utils;
import org.apache.log4j.Logger;
public class Log4jUtils {
private static final Logger logger = Logger.getLogger(Logger.class);
public static Logger getLogger() {
return logger;
}
}
这里简单做了两个的demo程序,做相应的测试,将项目打成war包后上传至Linux服务器,移动到tomcat/webapps中,tomcat进行热部署
先测试当前的tomcat是否能正常运行,由于没有做区别页面,就直接看日志来判断了
如图:以轮询方式进行访问8080和8081监听的tomcat
上述方式是get请求进行的测试,我们来试试post
<!DOCTYPE html>
<html>
<body>
<form action="http://123.207.85.242/tomcat/nginx/test/getname" method="post">
<input type="text" name="name">
<input type="submit" value="提交">
</form>
</body>
</html>
测试结果依旧可以正常接收参数,这里就不贴图了
二、静态动态资源分离
现在试试直接访问
http://ip/tomcat
我们会直接跳转到tomcat的主页面,如果检索tomcat.png的话
http://ip/tomcat/tomcat.png
可以直接检索到tomcat.png,它是来自tomcat服务器的资源,如果需要检索nginx的静态资源,可以使用
http://ip/tomcat.png
这样我们的资源就来自于nginx.conf文件中配置的关于静态资源的访问路径了,为了证明此事资源来自于nginx,我尝试将8080端口的tomcat/webapps/ROOT/tomcat.png更名为tomcat1.png,然后尝试访问http://ip/tomcat1.png访问成功,这时候如果刷新http://ip/tomcat/访问tomcat主页的时候会发现图标会在出现和不出现之间轮转,原因就是这里请求了tomcat服务器本身去拿资源,tomcat:8080的图片名被更改,如果代理访问的服务器正好是tomcat:8080的话,它是找不到tomcat.png的,当然轮转到tomcat:8081时候,图片还是会出现滴
三、Nginx工作模式
如图nginx启动后会有两个进程
如果你将nginx.conf的
worker_processes 1;更改为worker_processes 2;
那么出现的就是
那我们来说说master和worker进程分别的是干什么的,从pid来看,matser的父进程是init进程,而worker的父进程都是master,这里就很有意思了,那nginx这两个进程都到底是干嘛的嘞???
感谢baidu与google的强大,对于疑问的解释很清楚
原地址:http://blog.csdn.net/hguisu/article/details/8930668
感兴趣的同学可以看一看,这里只简单总结一下
master进程
主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。
master的平滑重启很有意思,master只负责接收外界信号,那么当我们更改了nginx.conf文件需要重新启动nginx时候怎么办????只需要通过kill向master进程发送信号就行了。比如kill -HUP pid,这时候master并不会干掉自己所有的worker然后自杀,而是重新加载nginx.conf后,重新启动一批worker,在这之后的请求全部由新的worker进行处理,而老的worker也并不是立即终止,而是在运行完当前的请求后,被终止掉,接下来的请求就全部交给新的worker了,当然这个方式后来被改成了
nginx -s reload
这个命令重新加载配置和上面的略有不一样,其会新启动一个nginx然后向Master发送信号,当然接下来就和上面的过程一致了
worker进程
而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。
那么worker是怎么做的呢,worker从master fork出来后,由master进行监听端口,当有相应的连接来之后,由worker争抢accept_mutex互斥锁,同一时刻此请求只能由一个worker争抢成功,并进行连接的读取、解析、处理然后断开连接
着整体是Nginx的工作的大致原理,Nginx依旧有很多细节和设计值得去深究学习,本篇博客先总结到此,后续有了更深入的了解,也会分享出来,谢谢
Nginx+Tomcat的配合使用的更多相关文章
- Nginx +Tomcat 实现动静态分离(转)
Nginx +Tomcat 实现动静态分离 动静态分离就是Nginx处理客户端的请求的静态页面(html页面)或者图片,Tomcat处理客户端请求的动态页面(jsp页面),因为Nginx处理的静态页面 ...
- Nginx+Tomcat实现动静分离和负载均衡
一.什么是动静分离? Nginx动静分离简单来说就是把动态和静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离.严格意义上说应该是将动态请求和静态请求分开,可以理解成使用Nginx处理静态 ...
- Nginx + Tomcat Windows下的负载均衡配置
Nginx + Tomcat Windows下的负载均衡配置 一.为什么需要对Tomcat服务器做负载均衡? Tomcat服务器作为一个Web服务器,其并发数在300-500之间,如果超过50 ...
- HappyAA服务器部署笔记1(nginx+tomcat的安装与配置)
这是本人的服务器部署笔记.文章名称叫"部署笔记1"的原因是之后我对这个进行了改进之后,会有"部署笔记2","部署笔记3"...循序渐进,估计 ...
- nginx + tomcat配置负载均衡
目标:Nginx做为HttpServer,连接多个tomcat应用实例,进行负载均衡. 注:本例程以一台机器为例子,即同一台机器上装一个nginx和2个Tomcat且安装了JDK1.7. 1.安装Ng ...
- Nginx+Tomcat+Redis实现负载均衡、资源分离、session共享
Nginx+Tomcat+Redis实现负载均衡.资源分离.session共享 CentOS安装Nginx http://centoscn.com/CentosServer/www/2013/0910 ...
- nginx+tomcat+二级域名静态文件分离支持mp4视频播放配置实例
nginx+tomcat+二级域名静态文件分离支持mp4视频播放配置实例 二级域名配置 在/etc/nginx/conf.d/目录下配置二级域名同名的conf文件,路径改成对应的即可 statics. ...
- Nginx+Tomcat构建动、静分离WEB架构
一.简介 二.环境介绍 三.后端服务器安装配置 四.安装论坛 五.安装配置前端Nginx服务器 六.验证服务 一.Tomcat简介 Tomcat是Apache 软件基金会(Apache Softwar ...
- nginx+tomcat+dubbo单机部署多台dubbo应用
前面的博客已经介绍如何使用nginx+tomcat,今天做的是如何在单台服务器上如何部署多台dubbo 应用的集群. 由于在项目中遇到了这个问题,今天就把它记录下来. 1.
随机推荐
- HTML 页面内容禁止选中
写一个小笔记,怎么禁止HTML页面不被选中,复制. CSS: *{ moz-user-select: -moz-none; -moz-user-select: none; -o-user-select ...
- iOS -读书笔记-网络请求
知道"3次握手"吗?突然想起这个词 什么是3次握手? TCP三次握手/四次挥手详解 这里是3次握手的详解 3次握手就是为了可靠的传送数据,TCP(什么是TCP呢?TCP就是一种可靠 ...
- POJ 2828 线段树单点更新 离线搞
Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get ...
- 最值(min、max)与极值的理解
max(a,b)=−min(−a,−b) 如果 a≥b ⇒ max(a,b)=a,−a≤−b,⇒ 同理 min(a,b)=−max(−a,−b) 1. 最值 最小:不能更少,如果是整数关系的话,也即从 ...
- 建堆是 O(n) 的时间复杂度证明。
建堆的复杂度先考虑满二叉树,和计算完全二叉树的建堆复杂度一样. 对满二叉树而言,第 \(i\) 层(根为第 \(0\) 层)有 \(2^i\) 个节点. 由于建堆过程自底向上,以交换作为主要操作,因此 ...
- 用Fiddle跟踪调试移动表单
简介:Fiddle,调试,移动表单 http://jingyan.baidu.com/article/925f8cb81e3a52c0dde05616.html
- SuSe Linux 10 企业服务器搭建双机集群配置实例
650) this.width=650;" onclick="window.open("http://blog.51cto.com/viewpic.php?refim ...
- Fedora 10下应用网络模拟器NS心得
650) this.width=650;" onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" ...
- 洛谷 P2677 超级书架 2
P2677 超级书架 2 题目描述 Farmer John最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了.现在,只有书架的顶上还留有一点空间. 所有 ...
- C 字符/字符串经常使用函数
string.h中经常使用函数 char * strchr(char * str ,char ch); 从字符串str中查找首次出现字符ch的位置,若存在返回查找后的地址.若不存在则返回NULL vo ...