在Shopblocks ,每个客户都会收到几个临时子域,以便他们可以访问其网站,管理系统和静态资产。 默认情况下,构建Shopblock的挑战之一是向所有客户提供SSL证书。
在启动前阶段,我们的系统主要基于Apache虚拟主机,每个客户都获得了自己的虚拟主机文件。 这是必需的,因为需要基于每个客户域配置SSL证书。
扩展时解决限制
但是,当我们扩大客户群并开始使用成千上万的虚拟主机文件时,使用Apache虚拟主机的问题就开始出现。
我们发现,随着虚拟主机文件加载数量的增加,内存使用量(无任何请求吞吐量)正在增加; 优美的重载需要更长的时间才能执行。 每次客户注册时,都会启动一个过程来创建其配置文件,然后重新加载Apache。
当我们开始为托管应用程序构建基础结构时,还会出现其他问题,例如重新加载多台服务器,确保所有服务器都能够为所有站点提供服务,处理脱机的服务器以及确保服务器配置恢复联机后进行同步。
将SSL终止责任转移到HAProxy
通过消除每位客户对虚拟主机的要求,解决了许多这些问题,但这使SSL终止问题悬而未决。 我们通过将终止SSL的责任进一步移到HAProxy负载平衡器而不是Apache本身,来解决了这一问题。
在HAProxy中,我们使用映射文件和标头重写来处理所有域,而无需为新客户更改任何Apache配置。
当您注册Shopblocks时,您实际上会收到三个子域。 例如,如果您使用bowersbros
名称bowersbros
,您将收到bowersbros.myshopblocks.com
, bowersbros-admin.myshopblocks.com
和bowersbros-static.myshopblocks.com
。
这将在映射文件中为我们的HAProxy配置创建一些条目。 这些行如下所示:
...
bowersbros.myshopblocks.com <id>
bowersbros-admin.myshopblocks.com <id>
bowersbros-static.myshopblocks.com <id>
...
用您的客户的特定标识符替换<id>
,您可以根据需要引用正确的配置/数据库。 这将作为HTTP标头X-Customer-ID
传递到您的应用程序。
注册时,您不能在名称中使用破折号注册,因此我们可以安全地假定任何带有-admin
或-static
连字符都旨在打入应用程序中的那些特定路由(连字符不是客户的公共网站)。
现在,我们的HAProxy配置看起来像这样。
frontend http
bind :80
option forwardfor
# Redirect all http requests to be https with a 301 redirect
redirect scheme https code 301
frontend https
# Check for your PEM certificates
bind :443 ssl crt /path/to/certificates
# Check if the hostname is recognised in the map file
acl is_customer hdr(host),lower,map_str(/path/to/map/file.map) -m found
# If the domain is not recognised, then silently drop the conneciton
# You have the option of deny if you want to immediately reject this connection
http-request silent-drop unless is_customer
# Delete the X-Customer-ID header incase a header is sent through unexpectedly
http-request del-header X-Customer-ID
# Add a X-Forwarded-Host header with the original hostname
http-request add-header X-Forwarded-Host %[req.hdr(Host)]
http-request add-header X-Customer-ID %[hdr(host),lower,map_str(/path/to/map/file.map)]
default_backend core
backend core
balance roundrobin
http-request set-header Host app.<your domain>.com</your>
当然,这是我们使用的配置的简化版本,需要针对您的用例进行修改。
到达HTTPS前端的所有请求都将经过检查其SSL证书以解密该请求,然后根据映射文件检查其域。 如果找不到它们,则将它们从请求中静默删除。
然后,我们将其ID添加到X-Customer-ID
下的请求中,并随请求一起发送到您的Web服务器。 然后,在Web服务器内部,您可以根据该标头的值使用正确的配置和数据库连接。
结论
Host标头也将被覆盖,以便可以使用正确的Apache虚拟主机以及Apache中的通用服务器名称。 现在,这使您的Apache虚拟主机配置成为通用的,每个应用程序一个,而不是每个服务器一个。 添加新客户,域或SSL证书的唯一要求是修改file.map并在HAProxy中执行重新加载,这是一项零停机时间操作。
有了我们,就可以简单地使用HAProxy设置SaaS应用程序。
翻译自: https://www.javacodegeeks.com/2018/03/setting-haproxy-saas-application.html