再谈 一个入口通全球 | 如何使用同一个域名访问多地部署的同一个服务

2023年 8月 18日 20.3k 0

0 | 前言

在上篇文章《一个入口通全球 | 如何使用同一个域名访问多地部署的同一个服务》中,介绍了如何通过一个域名访问部署在不同地域的同一个服务:
image.png

在上面方案中,是通过用户在header里指定自定义字段region来实现请求的转发。这个方案有个比较大的痛点是:用户需要清楚调用的API和服务部署地域的mapping关系,然后设定region值。对用户来说,用不同的域名访问不同地域的同一个服务没有本质区别,依旧需要用户自己去决定如何调用。

1 | 方案升级

所以,为了解决这个问题,我们对旧方案再做一次升级,目标是:用户无需自定义region字段,也无需掌握API和地域的mapping关系,只需要调用同一个域名,服务端自动去判断和转发请求。

这个可以通过请求的subpath来做判断:

image.png

2 | 实操

这里,还是借助nginx来转发请求。那么,问题就聚焦成了:

如何配置nginx.conf,来实现:同一个域名,根据不同的subpath来访问不同的服务地址?

这里还是需要借助lua脚本来实现这个业务逻辑,nginx.conf配置如下:

http {
    ...
    
    map $the_region $proxy_upstream {
        cn1 server_cn_1;
        us1 server_us_1;
        default server_us_1;
    }
    upstream server_us_1 {
        server server_us_1.com;
    }
    upstream server_cn_1 {
        server server_cn_1.com;
    }
    server {
      listen 80;
      server_name server.com;

      location / {
          set $the_region '';
          access_by_lua_block {
              local subpath = ngx.var.uri
              ngx.log(ngx.ERR, "subpath=", subpath)
              local cn_vendors = {"minimax", "xunfei"}
              local us_vendors = {"openai", "claude", "google"}
              for i, vendor in ipairs(cn_vendors) do
                  if string.find(subpath, vendor) then
                      ngx.var.the_region = 'cn1'
                      break
                  end
              end
              ngx.log(ngx.ERR, "the_region=",ngx.var.the_region)
          }
          proxy_pass http://$proxy_upstream;
      }
    }
}

代码逻辑解释:

  • server模块监听来自 server.com:80 的所有请求;

  • 设置一个nginx的环境变量 the_region;

  • 在lua脚本里,首先获得请求的subpath;

  • 指定不同api供应商所在的区域,如minimax在cn,openai在us

    • local cn_vendors = {"minimax", "xunfei"}
    • local us_vendors = {"openai", "claude", "google"}
  • 根据请求的subpath,循环遍历区域cn下的所有供应商,如果有包含关系,则设置 the_region = cn;(这里只有两个区域cn和us,所以只需要遍历一个区域即可)

  • 然后通过proxy_pass转发请求,通过map方法选择对应的后端服务:

  • map $the_region $proxy_upstream { 
        cn1 server_cn_1; 
        us1 server_us_1; 
        default server_us_1; #兜底方案: 如果the_region字段为空,则默认走某一个后端服务
    } 
    upstream server_us_1 { 
        server server_us_1.com;
    }
    upstream server_cn_1 { 
        server server_cn_1.com;
    }
    
    

    3 | 一些感触

    最近看了华为心声社区的一篇文章《在华为做硬件22年,一个农村草根的逆袭之路》,里面有一句话,特别触动:

    那时候心里充满了激情,感觉每天都有进展,自发自驱地拼命往前赶,好像除了工作没有其他,单纯地快乐着。

    如果工作不能让自己快乐,工作又是为何?

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论