Skip to main content

nginx的一些tips

背景#

最近公司在做流量迁移,发布系统用老的换成了新的。当时别人提的工单,看改动的代码是这个⬇️

location ^~ /page/abc-marketing-daily-redpacket-halfpage-h5 {    set $plateco_kfx_service_pro_kns "plateco_kfx_service_pro_kns";    proxy_pass http://$plateco_kfx_service_pro_kns;    proxy_set_header host app.abc.com;}

看代码意思是搞了个反向代理,转发到某个特定的服务,用户在请求此域名下的路径时,就直接请求新的服务(http://$plateco_kfx_service_pro_kns)。趁势周末顺便看了看nginx的文章,扩展总结一下,说不定以后也会做运维基建相关的。

先问下gpt,给nginx的定义是这样:一个高性能的开源 Web 服务器和反向代理服务器。

基本操作-静态资源#

第一次接触nginx,就是用做静态资源服务器,nginx可以将前端构建完成的产物(html/css/js)分发给客户端。只需要简单的配置,在nginx就可以部署静态资源。

反向代理#

公司内部后端的服务一般都有网关层,网关层就是接收用户的请求,分发流量,是典型的反向代理服务器。

区别#

正向代理和反向代理怎么区分呢?首先考虑下使用方的诉求,什么场景下需要用正向代理,什么场景需要用到反向代理。

  • 正向代理:当我想仰观宇宙之大,看看井外的景色时。使用自己的流量/wifi访问不到一些如youtube/x的网站,这时候就需要我,即「客户端侧」做一些事情,架设一个正向代理服务器,来转发我想要看的天外的请求。天外的服务端侧只能感知到这个正向代理服务器的请求,拿不到真实请求方的信息(服务器是用户架设的,可以抹去真实发起请求机器的信息)。
  • 反向代理:当我的用户数量比较多,想要做一些负载均衡的事情时,我把暴露出来的服务全都放到一个反向代理服务器上,用户的请求首先打到这个反向代理服务器,再由这个服务器来分发流量。这个是「服务端侧」做的事情。这个时候,客户端拿不到真实的处理请求的服务器的信息,只知道代理服务器返回的信息(服务器是服务端架设的,可以抹去真实处理请求机器的信息)。

负载均衡#

用户量增大时,服务压力就会变大,后端服务就得加机器。加了机器要怎么设置呢,不能光逮着一个机子薅羊毛。nginx作为流量的收集者,进行合理的配置,可以把流量分发到不同的机器上。

如下面的demo

upstream my-servers {    server 192.168.0.1:3000;    server 192.168.0.1:3001;}
server {    listen 80;    server_name localhost;    location ^~ /api {        proxy_pass http://my-servers    }}

意思是:有两个服务分别部署在192.168.0.1:3000192.168.0.1:3001上,设置了一个集群名字叫my-servers。当nginx接收到前缀是 /api的请求时,会把流量转发到这个集群上。

负载均衡一般有以下策略:

  • 默认轮询:按照请求时间的先后顺序,一个个设置,默认不需要加配置。

  • ip_hash:一般为了保持session在同一个服务上,同一个用户会持续分配到同一台机器。

  • 权重分配:维护者了解机器的性能不同,手动配置给机器不同的权重。

  • fair分配:nginx根据请求响应的时间自动分配,响应时间短的权重高。

    ip_hash,这样可以保证同一个用户一致是请求同一台服务器。

upstream my-servers {    ip_hash;    server 192.168.0.1:3000;    server 192.168.0.1:3001;}

权重分配:控制流量的分配比例,但是不能跟ip_hash混用。如:

upstream my-servers {    server 192.168.0.1:3000 weight=1;    server 192.168.0.1:3001;}

fair:

upstream my-servers {    server 192.168.0.1:3000 weight=1;    server 192.168.0.1:3001;    fair;}

使用场景#

灰度放量/AB实验#

nginx还可以实现在业务中常见的灰度放量或AB实验问题。比如线上已经有了A服务,这次新迭代的B功能要慢慢从0-100%放量,或者新开发C功能和A功能并存,做实验看哪个效果好,都是常见的业务场景。可以进行如下配置,让用户的请求分发到不同的集群上。

upstream server-a {    server 192.168.0.1:3000;}
upstream server-b {    server 192.168.0.1:3001;}
upstream server-default {    server 192.168.0.1:3000;}
server {    listen 80;    server_name localhost;        set $target "server-default";    if (http_cookie ~* "version=a") {        set $target "server-a";    }    if (http_cookie ~* "version=b") {        set $target "server-b";    }    location ^~ /api {        rewrite ^/api/(.*)$ /$1 break;        proxy_pass http://target    }}

这段配置的意思是,设置了server-aserver-b两个集群,并设置了server-default为集群a的服务,设置了一个变量target,根据用户请求cookie中的 version字段的值,如果是a,则把流量分发到a集群,b亦然。在匹配规则时,rewrite ^/api/(.*)$ /$1 break;这句会将请求路径中的/api部分删去,后面的部分保留。

总结#

本文从一个日常开发的case引出一些nginx的常见tips,介绍了正向代理和反向代理的区别。同时针对nginx的反向代理应用场景进行了介绍和demo配置。简单扩大一些知识面。nginx一般在公司层做网关,开发同学感知不到,一般都是提交工单来修改一些配置。这里多深入了解一点点,说不以后解决某些问题可以用到。嘿嘿。

written by rain
2023.12.10