2019-03-31

                            tomcat 和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的安装

    安装部分这里就不在细说了,网上的教程很多,我们直接从配置文件开始吧

1

二、配置文件

#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;

        }

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

    整个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将信息日志打到相应的位置用来观察参数是否传递过来

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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);

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

    这里简单做了两个的demo程序,做相应的测试,将项目打成war包后上传至Linux服务器,移动到tomcat/webapps中,tomcat进行热部署

    先测试当前的tomcat是否能正常运行,由于没有做区别页面,就直接看日志来判断了

1

2

    如图:以轮询方式进行访问8080和8081监听的tomcat

    上述方式是get请求进行的测试,我们来试试post

1

2

3

<!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>

1

2

3

4

5

6

7

8

9

测试结果依旧可以正常接收参数,这里就不贴图了

1

二、静态动态资源分离

现在试试直接访问

1

http://ip/tomcat

1

我们会直接跳转到tomcat的主页面,如果检索tomcat.png的话

1

http://ip/tomcat/tomcat.png

1

可以直接检索到tomcat.png,它是来自tomcat服务器的资源,如果需要检索nginx的静态资源,可以使用

1

http://ip/tomcat.png

1

    这样我们的资源就来自于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时候,图片还是会出现滴

1

三、Nginx工作模式

    如图nginx启动后会有两个进程

    如果你将nginx.conf的

1

2

worker_processes  1;更改为worker_processes  2;

1

那么出现的就是

1

    那我们来说说master和worker进程分别的是干什么的,从pid来看,matser的父进程是init进程,而worker的父进程都是master,这里就很有意思了,那nginx这两个进程都到底是干嘛的嘞???

    感谢baidu与google的强大,对于疑问的解释很清楚

    原地址:http://blog.csdn.net/hguisu/article/details/8930668

感兴趣的同学可以看一看,这里只简单总结一下

1

2

3

4

5

6

master进程

    主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

    master的平滑重启很有意思,master只负责接收外界信号,那么当我们更改了nginx.conf文件需要重新启动nginx时候怎么办????只需要通过kill向master进程发送信号就行了。比如kill -HUP pid,这时候master并不会干掉自己所有的worker然后自杀,而是重新加载nginx.conf后,重新启动一批worker,在这之后的请求全部由新的worker进行处理,而老的worker也并不是立即终止,而是在运行完当前的请求后,被终止掉,接下来的请求就全部交给新的worker了,当然这个方式后来被改成了

1

2

nginx -s reload

1

这个命令重新加载配置和上面的略有不一样,其会新启动一个nginx然后向Master发送信号,当然接下来就和上面的过程一致了

1

worker进程

    而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。

    那么worker是怎么做的呢,worker从master fork出来后,由master进行监听端口,当有相应的连接来之后,由worker争抢accept_mutex互斥锁,同一时刻此请求只能由一个worker争抢成功,并进行连接的读取、解析、处理然后断开连接

着整体是Nginx的工作的大致原理,Nginx依旧有很多细节和设计值得去深究学习,本篇博客先总结到此,后续有了更深入的了解  也会分享出来

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容