代码之家  ›  专栏  ›  技术社区  ›  kitensei

如何使用Varnish vcl语言实现此行为(按键列出的控制器字典)

  •  0
  • kitensei  · 技术社区  · 6 年前

    我已经想尽了一切办法,什么都没用,我需要做的是:

    我有一个相当复杂的应用程序,它依赖于一个“节点”列表,这些节点可以根据用户帐户提供内容,我有许多节点。

    假设我有这些节点” n个 ":

    • n1型
    • 氮气
    • n3号

    这些账户” “和他们的档案” f型 "):

    • a1:一层,二层
    • a2:三层,四层
    • a3:f5层

    并非所有节点都存储所有文件,因此,例如,此处如何存储文件(根据帐户存储冗余,文件可以存储在一个或多个节点上):

     n1:   , f2, f3,   , f5
     n2: f1,   , f3, f4, f5
     n3: f1, f2,   , f4,   
    

    如您所见,每个文件在两个节点上都可用。

    现在,当客户访问其内容时: GET /account/{a1}/files/{f1} 我需要清漆才能将我的用户转发给 氮气 n3号 .

    问题是我需要很多导演 “(每个文件一个):

    • d1:氮气,n3
    • d2:n1、n3
    • d3:n1、n2
    • d4:n2、n3
    • d5:n1,n2

    当然,这个列表是完全动态的(对于某些基于redis事件的配置生成器或consun模板来说不是问题),但是选择正确的控制器是很麻烦的(假设选择文件的url是 GET /account/{aX}/files/{fX} ):

    sub vcl_recv {
      if (req.url ~ "/files/f1$") {
        req.backend_hint = d1.backend()
      }
      else if (req.url ~ "/files/f2$") {
        req.backend_hint = d2.backend()
      }
      else if (req.url ~ "/files/f3$") {
        req.backend_hint = d3.backend()
      }
      else if (req.url ~ "/files/f4$") {
        req.backend_hint = d4.backend()
      }
      else if (req.url ~ "/files/f5$") {
        req.backend_hint = d5.backend()
      }
    }
    

    这个应用程序提供上千个文件,所以这个if/else不太可能维护。。

    我想做的是一些更进化的事情(但找不到VarnishVCL语言的方法),例如定义一个字典(伪代码):

    sub vcl_init {
      # pseudo code down here
      set directors_dict = dict(
        "f1"=[d1],
        "f2"=[d2],
        "f3"=[d3],
        "f4"=[d4],
        "f5"=[d5]
      )
    }
    
    sub vcl_recv {
      set req.http.file_id = regsub(<extract file id from url>)
      set req.backend_hint = directors_dict[req.http.file_id]
    }
    

    1 回复  |  直到 6 年前
        1
  •  0
  •   Guillaume Quintard    6 年前

    所以,企业版 vmod_kvstore 包装的( https://docs.varnish-software.com/varnish-cache-plus/vmods/kvstore/#get-backend ),但您需要订阅或获取并运行一个官方实例映像(AWS market或您使用的任何云平台,如果您使用的话)

    或者,我前段时间写过一个vmod: https://github.com/gquintard/libvmod-stendhal ,但您必须检查它是否适用于您的版本,编译它并自行安装。