世界上最伟大的投资就是投资自己的教育

首页Nginx
随风 · 练气

Nginx 学习笔记系列文章之 Nginx 之反向代理 (二)

随风发布于7967 次阅读

1. 什么叫反向代理服务器?

要说反向代理服务器,先来说一般的代理服务器。代理就是受委托去做一些事。假如用户 A 委托 B 去做一些事,做完之后 B 告诉 A 结果。在代理服务器中也是一样的道理,用户 A 通过代理服务器 B 访问网站 C(www.example.com),请求先到代理服务器 B,B 再转发请求到网站 C,代理服务器 B 是真正访问网站 C 的,访问之后再把网站 C 的应答结果发给用户 A。这样给用户 A 的感觉是 C 直接提供服务的一样,因为看不到 B 的整个处理过程。代理服务器是一个中间者,是充当转发请求的角色。这种代理也叫正向代理

使用正向代理是要在客户端进行设置,比如浏览器设置代理服务器的域名或 IP,还有端口等。

正向代理的作用有很多,例如,能访问本无法访问的,加速,cache,隐藏访问者的行踪等,具体的不再详述了。

反向代理(reverse proxy) 正好与正向代理相反,对于客户端而言代理服务器就像是原始服务器,并且客户端不需要进行任何特别的设置。假如用户 A 访问网站 B,这个时候网站 B 充当了 web 服务器,也充当了反向代理服务器,它充当的代理服务器的角色是这样,假如用户 A 要得到网站 C 的内容,而用户 A 又不能直接访问到 (例如网络原因),而服务器 B 可以访问到网站 C,那服务器可以得到网站 C 的内容再存起来发给用户 A,这整个过程用户 A 是直接和代理服务器 B 交互的,用户 A 不知道网站 C 的存在,这个 web 服务器 B 就是一台反向代理服务器,这个网站 C 就是上游服务器 (upstream servers)。

反向代理的作用是,隐藏和保护原始服务器,就像刚才的例子,用户 A 根本不知道服务器 C 的存在,但服务器 C 确实提供了服务。还有,就是负载均衡。当反向代理服务器不止一个的时候,就可以做成一个集群,当用户 A 访问网站 B 时,用户 A 又需要网站 C 的内容,而网站 C 有好多服务器,这些服务器就形成了集群,而网站 B 在请求网站 C,就可以有多种方式 (轮循,hash 等),把请求均匀地分配给集群中的服务器,这个就是负载均衡。

2. 示例

我们先来看最一个最简单的例子。

2.1 最简单的反向代理

nginx 的反向代理是依赖于ngx_http_proxy_module这个 module 来实现的。

反向代理服务器能代理的请求的协议包括 http(s),FastCGI,SCGI,uwsgi,memcached 等。我们这里主要集中在 http(s) 协议。

我有一个网站,用的是 https 协议来访问的。用这个协议访问的网站在 chrome 等浏览器的地址栏是可以看到一个绿色的代表安全的标志的。你请求的所有资源都要是 https 的,它才会出现。假如你请求了一张外部的图片,而这张图片是以 http 协议请求的,那这个时候那个安全的标志就不存在的。

所以我要把这个 https 协议的图片请求反向代理到 http 协议的真实图片上。https 协议的这张图片是不存在,而它有一个地址实际指向的内容是 http 协议中的图片。

# https
server {
  server_name www.example.com;
  listen       443;
  location /newchart/hollow/small/nsh000001.gif {
    proxy_pass http://image.sinajs.cn/newchart/hollow/small/nsh000001.gif;
  }

  location /newchart/hollow/small/nsz399001.gif {
    proxy_pass http://image.sinajs.cn/newchart/hollow/small/nsz399001.gif;
  }

假如我的网站是www.example.com这样就能使用https://www.example.com/newchart/hollow/small/nsh000001.gif,它指向是http://image.sinajs.cn/newchart/hollow/small/nsh000001.gif

2.2 动态转发

我们的网站不止是展示用的,我们还要处理动态请求,例如表单等。所以 nginx 也要和 php,java,ruby 等语言配合。

下面的例子是 nginx 和 unicorn(ruby 的应用服务器) 的一个例子。

upstream rails365 {
    # Path to Unicorn SOCK file, as defined previously
    server unix:///home/yinsigan/rails365/shared/tmp/sockets/unicorn.sock fail_timeout=0;
}
server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
        server_name www.rails365.net;
        root         /home/yinsigan/rails365/current/public;

        try_files $uri/index.html $uri @rails365;
        location @rails365 {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_pass http://rails365;
        }
}

先从try_files $uri/index.html $uri @rails365;这句说起,它先找根目录/home/yinsigan/rails365/current/public下的 index.html,假如是www.rails365.net/about.html还是会找根目录下的 about.html,如果都找不到,才会执行@rails365的部分,也就是location @rails365

前面两行是设置请求的头部,第三行是设置不转地址,这些先不管。来看第三行proxy_pass http://rails365;。这行会反向代理到upstream rails365指定的内容。upstream里面指定了一个服务器,这个服务器和 nginx 是同一台机器的,用的是 unix socket 来连接,连接的是一个 unicorn 进程。

总结起来是这样的。假如用户要访问https://www.qiuzhi99.com/articles/,这个请求不能只靠 nginx,因为又不是以.html 结尾,所以转发给了 upstream 所指向的服务器,转发请求的方式是 unix socket,到了 unicorn 进程,unicorn 处理后交给 nginx,nginx 才最终发给客户。在这里,nginx 还起到一个 cache 和保护的作用,unicorn 就是上游服务器。

2.3 websocket

关于 webcoket 的概念,这里不再详细,可以参照这篇文章。

upstream ws {
  server unix:///home/eason/tt_deploy/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
  location /ws/ {
    proxy_pass http://ws;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

先由 http 协议升级为 ws 协议,然后通过 unix socket 连接到 puma 进程,一个支持 ws 协议的进程。原理跟上面的 unicorn 差不多。

注意:nginx 要支持 websocket 协议,必须是 1.3.13 或以上版本。

要测试是否成功,有两种比较简单的方法。

第一种是在 chrome 浏览器上 console 那里直接访问。

比如new WebSocket('ws://www.example.com/wx');

第二种就是在 chrome 的开发者工具,network 那里看有没有 101 协议的请求。

比如。

完结。

本站文章均为原创内容,如需转载请注明出处,谢谢。

0 条回复
暂无回复~~
相关小书
nginx教程

nginx教程

最全面,最深入的nginx入门到精通的教程

发表于

喜欢
统计信息
    学员: 29915
    视频数量: 1996
    文章数量: 526

© 汕尾市求知科技有限公司 | Rails365 Gitlab | 知乎 | b 站 | csdn

粤公网安备 44152102000088号粤公网安备 44152102000088号 | 粤ICP备19038915号

Top